data-streamer-in.c revision 1.1
1/* Routines for restoring various data types from a file stream.  This deals
2   with various data types like strings, integers, enums, etc.
3
4   Copyright (C) 2011-2013 Free Software Foundation, Inc.
5   Contributed by Diego Novillo <dnovillo@google.com>
6
7This file is part of GCC.
8
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
11Software Foundation; either version 3, or (at your option) any later
12version.
13
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17for more details.
18
19You should have received a copy of the GNU General Public License
20along with GCC; see the file COPYING3.  If not see
21<http://www.gnu.org/licenses/>.  */
22
23#include "config.h"
24#include "system.h"
25#include "coretypes.h"
26#include "diagnostic.h"
27#include "data-streamer.h"
28
29/* Read a string from the string table in DATA_IN using input block
30   IB.  Write the length to RLEN.  */
31
32const char *
33string_for_index (struct data_in *data_in, unsigned int loc, unsigned int *rlen)
34{
35  struct lto_input_block str_tab;
36  unsigned int len;
37  const char *result;
38
39  if (!loc)
40    {
41      *rlen = 0;
42      return NULL;
43    }
44
45  /* Get the string stored at location LOC in DATA_IN->STRINGS.  */
46  LTO_INIT_INPUT_BLOCK (str_tab, data_in->strings, loc - 1,
47			data_in->strings_len);
48  len = streamer_read_uhwi (&str_tab);
49  *rlen = len;
50
51  if (str_tab.p + len > data_in->strings_len)
52    internal_error ("bytecode stream: string too long for the string table");
53
54  result = (const char *)(data_in->strings + str_tab.p);
55
56  return result;
57}
58
59
60/* Read a string from the string table in DATA_IN using input block
61   IB.  Write the length to RLEN.  */
62
63const char *
64streamer_read_indexed_string (struct data_in *data_in,
65			      struct lto_input_block *ib, unsigned int *rlen)
66{
67  return string_for_index (data_in, streamer_read_uhwi (ib), rlen);
68}
69
70
71/* Read a NULL terminated string from the string table in DATA_IN.  */
72
73const char *
74streamer_read_string (struct data_in *data_in, struct lto_input_block *ib)
75{
76  unsigned int len;
77  const char *ptr;
78
79  ptr = streamer_read_indexed_string (data_in, ib, &len);
80  if (!ptr)
81    return NULL;
82  if (ptr[len - 1] != '\0')
83    internal_error ("bytecode stream: found non-null terminated string");
84
85  return ptr;
86}
87
88
89/* Read a string from the string table in DATA_IN using the bitpack BP.
90   Write the length to RLEN.  */
91
92const char *
93bp_unpack_indexed_string (struct data_in *data_in,
94			  struct bitpack_d *bp, unsigned int *rlen)
95{
96  return string_for_index (data_in, bp_unpack_var_len_unsigned (bp), rlen);
97}
98
99
100/* Read a NULL terminated string from the string table in DATA_IN.  */
101
102const char *
103bp_unpack_string (struct data_in *data_in, struct bitpack_d *bp)
104{
105  unsigned int len;
106  const char *ptr;
107
108  ptr = bp_unpack_indexed_string (data_in, bp, &len);
109  if (!ptr)
110    return NULL;
111  if (ptr[len - 1] != '\0')
112    internal_error ("bytecode stream: found non-null terminated string");
113
114  return ptr;
115}
116
117
118/* Read an unsigned HOST_WIDE_INT number from IB.  */
119
120unsigned HOST_WIDE_INT
121streamer_read_uhwi (struct lto_input_block *ib)
122{
123  unsigned HOST_WIDE_INT result = 0;
124  int shift = 0;
125  unsigned HOST_WIDE_INT byte;
126
127  while (true)
128    {
129      byte = streamer_read_uchar (ib);
130      result |= (byte & 0x7f) << shift;
131      shift += 7;
132      if ((byte & 0x80) == 0)
133	return result;
134    }
135}
136
137
138/* Read a HOST_WIDE_INT number from IB.  */
139
140HOST_WIDE_INT
141streamer_read_hwi (struct lto_input_block *ib)
142{
143  HOST_WIDE_INT result = 0;
144  int shift = 0;
145  unsigned HOST_WIDE_INT byte;
146
147  while (true)
148    {
149      byte = streamer_read_uchar (ib);
150      result |= (byte & 0x7f) << shift;
151      shift += 7;
152      if ((byte & 0x80) == 0)
153	{
154	  if ((shift < HOST_BITS_PER_WIDE_INT) && (byte & 0x40))
155	    result |= - ((HOST_WIDE_INT)1 << shift);
156
157	  return result;
158	}
159    }
160}
161