Skip to content

Commit 4ef3dc5

Browse files
authored
Merge pull request #3116 from tautschnig/cleanup-irep-serialization
Cleanup irep serialization
2 parents 273f490 + 2150648 commit 4ef3dc5

File tree

2 files changed

+40
-75
lines changed

2 files changed

+40
-75
lines changed

src/util/irep_serialization.cpp

Lines changed: 40 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,15 @@ void irep_serializationt::reference_convert(
6262
else
6363
{
6464
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};
6674
}
6775
}
6876

@@ -100,72 +108,29 @@ void irep_serializationt::read_irep(
100108
}
101109
}
102110

111+
/// Serialize an irept
112+
/// \param irep: source irept to serialize
113+
/// \param out: target output stream
103114
void irep_serializationt::reference_convert(
104115
const irept &irep,
105116
std::ostream &out)
106117
{
107118
std::size_t h=ireps_container.irep_full_hash_container.number(irep);
108119

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()});
112122

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)
117125
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;
138126
}
139127

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
166132
void write_gb_word(std::ostream &out, std::size_t u)
167133
{
168-
// we write 7 bits each time, until we have zero
169134

170135
while(true)
171136
{
@@ -182,9 +147,9 @@ void write_gb_word(std::ostream &out, std::size_t u)
182147
}
183148
}
184149

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
188153
std::size_t irep_serializationt::read_gb_word(std::istream &in)
189154
{
190155
std::size_t res=0;
@@ -193,19 +158,25 @@ std::size_t irep_serializationt::read_gb_word(std::istream &in)
193158

194159
while(in.good())
195160
{
161+
if(shift_distance >= sizeof(res) * 8)
162+
throw deserialization_exceptiont("input number too large");
163+
196164
unsigned char ch=static_cast<unsigned char>(in.get());
197165
res|=(size_t(ch&0x7f))<<shift_distance;
198166
shift_distance+=7;
199167
if((ch&0x80)==0)
200168
break;
201169
}
202170

171+
if(!in.good())
172+
throw deserialization_exceptiont("unexpected end of input stream");
173+
203174
return res;
204175
}
205176

206177
/// 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
209180
void write_gb_string(std::ostream &out, const std::string &s)
210181
{
211182
for(std::string::const_iterator it=s.begin();
@@ -221,7 +192,7 @@ void write_gb_string(std::ostream &out, const std::string &s)
221192
}
222193

223194
/// reads a string from the stream
224-
/// \par parameters: a stream
195+
/// \param in: input stream
225196
/// \return a string
226197
irep_idt irep_serializationt::read_gb_string(std::istream &in)
227198
{
@@ -244,9 +215,9 @@ irep_idt irep_serializationt::read_gb_string(std::istream &in)
244215
return irep_idt(std::string(read_buffer.data(), length));
245216
}
246217

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
250221
void irep_serializationt::write_string_ref(
251222
std::ostream &out,
252223
const irep_idt &s)
@@ -265,8 +236,8 @@ void irep_serializationt::write_string_ref(
265236
}
266237
}
267238

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
270241
/// \return a string
271242
irep_idt irep_serializationt::read_string_ref(std::istream &in)
272243
{
@@ -276,15 +247,12 @@ irep_idt irep_serializationt::read_string_ref(std::istream &in)
276247
ireps_container.string_rev_map.resize(1+id*2,
277248
std::pair<bool, irep_idt>(false, irep_idt()));
278249

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)
284251
{
285252
irep_idt s=read_gb_string(in);
286253
ireps_container.string_rev_map[id]=
287254
std::pair<bool, irep_idt>(true, s);
288-
return ireps_container.string_rev_map[id].second;
289255
}
256+
257+
return ireps_container.string_rev_map[id].second;
290258
}

src/util/irep_serialization.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,6 @@ class irep_serializationt
6161
clear();
6262
};
6363

64-
std::size_t insert_on_write(std::size_t h);
65-
std::size_t insert_on_read(std::size_t id, const irept &);
66-
6764
void reference_convert(std::istream &, irept &irep);
6865
void reference_convert(const irept &irep, std::ostream &);
6966

0 commit comments

Comments
 (0)