@@ -62,7 +62,15 @@ void irep_serializationt::reference_convert(
62
62
else
63
63
{
64
64
read_irep (in, irep);
65
- insert_on_read (id, irep);
65
+
66
+ if (id >= ireps_container.ireps_on_read .size ())
67
+ ireps_container.ireps_on_read .resize (1 + id * 2 , {false , get_nil_irep ()});
68
+
69
+ // guard against self-referencing ireps
70
+ if (ireps_container.ireps_on_read [id].first )
71
+ throw deserialization_exceptiont (" irep id read twice." );
72
+
73
+ ireps_container.ireps_on_read [id] = {true , irep};
66
74
}
67
75
}
68
76
@@ -100,72 +108,29 @@ void irep_serializationt::read_irep(
100
108
}
101
109
}
102
110
111
+ // / Serialize an irept
112
+ // / \param irep: source irept to serialize
113
+ // / \param out: target output stream
103
114
void irep_serializationt::reference_convert (
104
115
const irept &irep,
105
116
std::ostream &out)
106
117
{
107
118
std::size_t h=ireps_container.irep_full_hash_container .number (irep);
108
119
109
- // should be merged with insert
110
- ireps_containert::ireps_on_writet::const_iterator fi=
111
- ireps_container.ireps_on_write .find (h);
120
+ const auto res = ireps_container.ireps_on_write .insert (
121
+ {h, ireps_container.ireps_on_write .size ()});
112
122
113
- if (fi==ireps_container.ireps_on_write .end ())
114
- {
115
- size_t id=insert_on_write (h);
116
- write_gb_word (out, id);
123
+ write_gb_word (out, res.first ->second );
124
+ if (res.second )
117
125
write_irep (out, irep);
118
- }
119
- else
120
- {
121
- write_gb_word (out, fi->second );
122
- }
123
- }
124
-
125
- // / inserts an irep into the hashtable
126
- // / \par parameters: a size_t and an irep
127
- // / \return true on success, false otherwise
128
- std::size_t irep_serializationt::insert_on_write (std::size_t h)
129
- {
130
- std::pair<ireps_containert::ireps_on_writet::const_iterator, bool > res=
131
- ireps_container.ireps_on_write .insert (
132
- std::make_pair (h, ireps_container.ireps_on_write .size ()));
133
-
134
- if (!res.second )
135
- return ireps_container.ireps_on_write .size ();
136
- else
137
- return res.first ->second ;
138
126
}
139
127
140
- // / inserts an irep into the hashtable, but only the id-hashtable (only to be
141
- // / used upon reading ireps from a file)
142
- // / \par parameters: a size_t and an irep
143
- // / \return true on success, false otherwise
144
- std::size_t irep_serializationt::insert_on_read (
145
- std::size_t id,
146
- const irept &i)
147
- {
148
- if (id>=ireps_container.ireps_on_read .size ())
149
- ireps_container.ireps_on_read .resize (1 +id*2 ,
150
- std::pair<bool , irept>(false , get_nil_irep ()));
151
-
152
- if (ireps_container.ireps_on_read [id].first )
153
- throw deserialization_exceptiont (" irep id read twice." );
154
- else
155
- {
156
- ireps_container.ireps_on_read [id]=
157
- std::pair<bool , irept>(true , i);
158
- }
159
-
160
- return id;
161
- }
162
-
163
- // / outputs 4 characters for a long, most-significant byte first
164
- // / \par parameters: an output stream and a number
165
- // / \return nothing
128
+ // / Write 7 bits of `u` each time, least-significant byte first, until we have
129
+ // / zero.
130
+ // / \param out: target stream
131
+ // / \param u: number to write
166
132
void write_gb_word (std::ostream &out, std::size_t u)
167
133
{
168
- // we write 7 bits each time, until we have zero
169
134
170
135
while (true )
171
136
{
@@ -182,9 +147,9 @@ void write_gb_word(std::ostream &out, std::size_t u)
182
147
}
183
148
}
184
149
185
- // / reads 4 characters and builds a long int from them
186
- // / \par parameters: a stream
187
- // / \return a long
150
+ // / Interpret a stream of byte as a 7-bit encoded unsigned number.
151
+ // / \param in: input stream
152
+ // / \return decoded number
188
153
std::size_t irep_serializationt::read_gb_word (std::istream &in)
189
154
{
190
155
std::size_t res=0 ;
@@ -193,19 +158,25 @@ std::size_t irep_serializationt::read_gb_word(std::istream &in)
193
158
194
159
while (in.good ())
195
160
{
161
+ if (shift_distance >= sizeof (res) * 8 )
162
+ throw deserialization_exceptiont (" input number too large" );
163
+
196
164
unsigned char ch=static_cast <unsigned char >(in.get ());
197
165
res|=(size_t (ch&0x7f ))<<shift_distance;
198
166
shift_distance+=7 ;
199
167
if ((ch&0x80 )==0 )
200
168
break ;
201
169
}
202
170
171
+ if (!in.good ())
172
+ throw deserialization_exceptiont (" unexpected end of input stream" );
173
+
203
174
return res;
204
175
}
205
176
206
177
// / outputs the string and then a zero byte.
207
- // / \par parameters: an output stream and a string
208
- // / \return nothing
178
+ // / \param out: output stream
179
+ // / \param s: string to output
209
180
void write_gb_string (std::ostream &out, const std::string &s)
210
181
{
211
182
for (std::string::const_iterator it=s.begin ();
@@ -221,7 +192,7 @@ void write_gb_string(std::ostream &out, const std::string &s)
221
192
}
222
193
223
194
// / reads a string from the stream
224
- // / \par parameters: a stream
195
+ // / \param in: input stream
225
196
// / \return a string
226
197
irep_idt irep_serializationt::read_gb_string (std::istream &in)
227
198
{
@@ -244,9 +215,9 @@ irep_idt irep_serializationt::read_gb_string(std::istream &in)
244
215
return irep_idt (std::string (read_buffer.data (), length));
245
216
}
246
217
247
- // / outputs the string reference
248
- // / \par parameters: an output stream and a string
249
- // / \return nothing
218
+ // / Output a string and maintain a reference to it
219
+ // / \param out: output stream
220
+ // / \param s: string to output
250
221
void irep_serializationt::write_string_ref (
251
222
std::ostream &out,
252
223
const irep_idt &s)
@@ -265,8 +236,8 @@ void irep_serializationt::write_string_ref(
265
236
}
266
237
}
267
238
268
- // / reads a string reference from the stream
269
- // / \par parameters: a stream
239
+ // / Read a string reference from the stream
240
+ // / \param in: input stream
270
241
// / \return a string
271
242
irep_idt irep_serializationt::read_string_ref (std::istream &in)
272
243
{
@@ -276,15 +247,12 @@ irep_idt irep_serializationt::read_string_ref(std::istream &in)
276
247
ireps_container.string_rev_map .resize (1 +id*2 ,
277
248
std::pair<bool , irep_idt>(false , irep_idt ()));
278
249
279
- if (ireps_container.string_rev_map [id].first )
280
- {
281
- return ireps_container.string_rev_map [id].second ;
282
- }
283
- else
250
+ if (!ireps_container.string_rev_map [id].first )
284
251
{
285
252
irep_idt s=read_gb_string (in);
286
253
ireps_container.string_rev_map [id]=
287
254
std::pair<bool , irep_idt>(true , s);
288
- return ireps_container.string_rev_map [id].second ;
289
255
}
256
+
257
+ return ireps_container.string_rev_map [id].second ;
290
258
}
0 commit comments