OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
(...skipping 27 matching lines...) Expand all Loading... |
38 namespace protobuf { | 38 namespace protobuf { |
39 namespace compiler { | 39 namespace compiler { |
40 namespace cpp { | 40 namespace cpp { |
41 | 41 |
42 bool IsProto3Field(const FieldDescriptor* field_descriptor) { | 42 bool IsProto3Field(const FieldDescriptor* field_descriptor) { |
43 const FileDescriptor* file_descriptor = field_descriptor->file(); | 43 const FileDescriptor* file_descriptor = field_descriptor->file(); |
44 return file_descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3; | 44 return file_descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3; |
45 } | 45 } |
46 | 46 |
47 void SetMessageVariables(const FieldDescriptor* descriptor, | 47 void SetMessageVariables(const FieldDescriptor* descriptor, |
48 std::map<string, string>* variables, | 48 map<string, string>* variables, |
49 const Options& options) { | 49 const Options& options) { |
50 SetCommonFieldVariables(descriptor, variables, options); | 50 SetCommonFieldVariables(descriptor, variables, options); |
51 (*variables)["type"] = ClassName(descriptor->message_type(), false); | 51 (*variables)["type"] = FieldMessageTypeName(descriptor); |
52 (*variables)["stream_writer"] = | 52 (*variables)["stream_writer"] = |
53 (*variables)["declared_type"] + | 53 (*variables)["declared_type"] + |
54 (HasFastArraySerialization(descriptor->message_type()->file(), options) | 54 (HasFastArraySerialization(descriptor->message_type()->file(), options) |
55 ? "MaybeToArray" | 55 ? "MaybeToArray" |
56 : ""); | 56 : ""); |
57 (*variables)["full_name"] = descriptor->full_name(); | 57 (*variables)["full_name"] = descriptor->full_name(); |
58 | 58 |
59 const FieldDescriptor* key = | 59 const FieldDescriptor* key = |
60 descriptor->message_type()->FindFieldByName("key"); | 60 descriptor->message_type()->FindFieldByName("key"); |
61 const FieldDescriptor* val = | 61 const FieldDescriptor* val = |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 printer->Print(variables_, | 130 printer->Print(variables_, |
131 "$deprecated_attr$const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n
" | 131 "$deprecated_attr$const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n
" |
132 " $name$() const;\n" | 132 " $name$() const;\n" |
133 "$deprecated_attr$::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" | 133 "$deprecated_attr$::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" |
134 " mutable_$name$();\n"); | 134 " mutable_$name$();\n"); |
135 } | 135 } |
136 | 136 |
137 void MapFieldGenerator:: | 137 void MapFieldGenerator:: |
138 GenerateInlineAccessorDefinitions(io::Printer* printer, | 138 GenerateInlineAccessorDefinitions(io::Printer* printer, |
139 bool is_inline) const { | 139 bool is_inline) const { |
140 std::map<string, string> variables(variables_); | 140 map<string, string> variables(variables_); |
141 variables["inline"] = is_inline ? "inline" : ""; | 141 variables["inline"] = is_inline ? "inline" : ""; |
142 printer->Print(variables, | 142 printer->Print(variables, |
143 "$inline$ const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" | 143 "$inline$ const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" |
144 "$classname$::$name$() const {\n" | 144 "$classname$::$name$() const {\n" |
145 " // @@protoc_insertion_point(field_map:$full_name$)\n" | 145 " // @@protoc_insertion_point(field_map:$full_name$)\n" |
146 " return $name$_.GetMap();\n" | 146 " return $name$_.GetMap();\n" |
147 "}\n" | 147 "}\n" |
148 "$inline$ ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" | 148 "$inline$ ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" |
149 "$classname$::mutable_$name$() {\n" | 149 "$classname$::mutable_$name$() {\n" |
150 " // @@protoc_insertion_point(field_mutable_map:$full_name$)\n" | 150 " // @@protoc_insertion_point(field_mutable_map:$full_name$)\n" |
151 " return $name$_.MutableMap();\n" | 151 " return $name$_.MutableMap();\n" |
152 "}\n"); | 152 "}\n"); |
153 } | 153 } |
154 | 154 |
155 void MapFieldGenerator:: | 155 void MapFieldGenerator:: |
156 GenerateClearingCode(io::Printer* printer) const { | 156 GenerateClearingCode(io::Printer* printer) const { |
157 std::map<string, string> variables(variables_); | 157 map<string, string> variables(variables_); |
158 variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : ""; | 158 variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : ""; |
159 printer->Print(variables, "$this_message$$name$_.Clear();\n"); | 159 printer->Print(variables, "$this_message$$name$_.Clear();\n"); |
160 } | 160 } |
161 | 161 |
162 void MapFieldGenerator:: | 162 void MapFieldGenerator:: |
163 GenerateMergingCode(io::Printer* printer) const { | 163 GenerateMergingCode(io::Printer* printer) const { |
164 printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n"); | 164 printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n"); |
165 } | 165 } |
166 | 166 |
167 void MapFieldGenerator:: | 167 void MapFieldGenerator:: |
168 GenerateSwappingCode(io::Printer* printer) const { | 168 GenerateSwappingCode(io::Printer* printer) const { |
169 printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n"); | 169 printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n"); |
170 } | 170 } |
171 | 171 |
172 void MapFieldGenerator:: | 172 void MapFieldGenerator:: |
173 GenerateConstructorCode(io::Printer* printer) const { | 173 GenerateConstructorCode(io::Printer* printer) const { |
174 if (HasDescriptorMethods(descriptor_->file(), options_)) { | 174 if (HasDescriptorMethods(descriptor_->file(), options_)) { |
175 printer->Print(variables_, | 175 printer->Print(variables_, |
176 "$name$_.SetAssignDescriptorCallback(\n" | 176 "$name$_.SetAssignDescriptorCallback(\n" |
177 " protobuf_AssignDescriptorsOnce);\n" | 177 " protobuf_AssignDescriptorsOnce);\n" |
178 "$name$_.SetEntryDescriptor(\n" | 178 "$name$_.SetEntryDescriptor(\n" |
179 " &$type$_descriptor);\n"); | 179 " &$type$_descriptor_);\n"); |
180 } | 180 } |
181 } | 181 } |
182 | 182 |
183 void MapFieldGenerator:: | 183 void MapFieldGenerator:: |
184 GenerateCopyConstructorCode(io::Printer* printer) const { | |
185 GenerateConstructorCode(printer); | |
186 GenerateMergingCode(printer); | |
187 } | |
188 | |
189 void MapFieldGenerator:: | |
190 GenerateMergeFromCodedStream(io::Printer* printer) const { | 184 GenerateMergeFromCodedStream(io::Printer* printer) const { |
191 const FieldDescriptor* key_field = | |
192 descriptor_->message_type()->FindFieldByName("key"); | |
193 const FieldDescriptor* value_field = | 185 const FieldDescriptor* value_field = |
194 descriptor_->message_type()->FindFieldByName("value"); | 186 descriptor_->message_type()->FindFieldByName("value"); |
195 bool using_entry = false; | 187 printer->Print(variables_, |
196 string key; | 188 "::google::protobuf::scoped_ptr<$map_classname$> entry($name$_.NewEntry())
;\n"); |
197 string value; | 189 |
198 if (IsProto3Field(descriptor_) || | 190 if (IsProto3Field(descriptor_) || |
199 value_field->type() != FieldDescriptor::TYPE_ENUM) { | 191 value_field->type() != FieldDescriptor::TYPE_ENUM) { |
200 printer->Print(variables_, | 192 printer->Print(variables_, |
201 "$map_classname$::Parser< ::google::protobuf::internal::MapField$lite$<\
n" | |
202 " $key_cpp$, $val_cpp$,\n" | |
203 " $key_wire_type$,\n" | |
204 " $val_wire_type$,\n" | |
205 " $default_enum_value$ >,\n" | |
206 " ::google::protobuf::Map< $key_cpp$, $val_cpp$ > >" | |
207 " parser(&$name$_);\n" | |
208 "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
\n" | 193 "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
\n" |
209 " input, &parser));\n"); | 194 " input, entry.get()));\n"); |
210 key = "parser.key()"; | 195 switch (value_field->cpp_type()) { |
211 value = "parser.value()"; | 196 case FieldDescriptor::CPPTYPE_MESSAGE: |
| 197 printer->Print(variables_, |
| 198 "(*mutable_$name$())[entry->key()].Swap(" |
| 199 "entry->mutable_value());\n"); |
| 200 break; |
| 201 case FieldDescriptor::CPPTYPE_ENUM: |
| 202 printer->Print(variables_, |
| 203 "(*mutable_$name$())[entry->key()] =\n" |
| 204 " static_cast< $val_cpp$ >(*entry->mutable_value());\n"); |
| 205 break; |
| 206 default: |
| 207 printer->Print(variables_, |
| 208 "(*mutable_$name$())[entry->key()] = *entry->mutable_value();\n"); |
| 209 break; |
| 210 } |
212 } else { | 211 } else { |
213 using_entry = true; | |
214 key = "entry->key()"; | |
215 value = "entry->value()"; | |
216 printer->Print(variables_, | |
217 "::google::protobuf::scoped_ptr<$map_classname$> entry($name$_.NewEntry(
));\n"); | |
218 printer->Print(variables_, | 212 printer->Print(variables_, |
219 "{\n" | 213 "{\n" |
220 " ::std::string data;\n" | 214 " ::std::string data;\n" |
221 " DO_(::google::protobuf::internal::WireFormatLite::ReadString(input, &
data));\n" | 215 " DO_(::google::protobuf::internal::WireFormatLite::ReadString(input, &
data));\n" |
222 " DO_(entry->ParseFromString(data));\n" | 216 " DO_(entry->ParseFromString(data));\n" |
223 " if ($val_cpp$_IsValid(*entry->mutable_value())) {\n" | 217 " if ($val_cpp$_IsValid(*entry->mutable_value())) {\n" |
224 " (*mutable_$name$())[entry->key()] =\n" | 218 " (*mutable_$name$())[entry->key()] =\n" |
225 " static_cast< $val_cpp$ >(*entry->mutable_value());\n" | 219 " static_cast< $val_cpp$ >(*entry->mutable_value());\n" |
226 " } else {\n"); | 220 " } else {\n"); |
227 if (HasDescriptorMethods(descriptor_->file(), options_)) { | 221 if (HasDescriptorMethods(descriptor_->file(), options_)) { |
228 printer->Print(variables_, | 222 printer->Print(variables_, |
229 " mutable_unknown_fields()" | 223 " mutable_unknown_fields()" |
230 "->AddLengthDelimited($number$, data);\n"); | 224 "->AddLengthDelimited($number$, data);\n"); |
231 } else { | 225 } else { |
232 printer->Print(variables_, | 226 printer->Print(variables_, |
233 " unknown_fields_stream.WriteVarint32($tag$u);\n" | 227 " unknown_fields_stream.WriteVarint32($tag$);\n" |
234 " unknown_fields_stream.WriteVarint32(data.size());\n" | 228 " unknown_fields_stream.WriteVarint32(data.size());\n" |
235 " unknown_fields_stream.WriteString(data);\n"); | 229 " unknown_fields_stream.WriteString(data);\n"); |
236 } | 230 } |
237 | 231 |
| 232 |
238 printer->Print(variables_, | 233 printer->Print(variables_, |
239 " }\n" | 234 " }\n" |
240 "}\n"); | 235 "}\n"); |
241 } | 236 } |
242 | 237 |
| 238 const FieldDescriptor* key_field = |
| 239 descriptor_->message_type()->FindFieldByName("key"); |
243 if (key_field->type() == FieldDescriptor::TYPE_STRING) { | 240 if (key_field->type() == FieldDescriptor::TYPE_STRING) { |
244 GenerateUtf8CheckCodeForString( | 241 GenerateUtf8CheckCodeForString( |
245 key_field, options_, true, variables_, | 242 key_field, options_, true, variables_, |
246 StrCat(key, ".data(), ", key, ".length(),\n").data(), printer); | 243 "entry->key().data(), entry->key().length(),\n", printer); |
247 } | 244 } |
248 if (value_field->type() == FieldDescriptor::TYPE_STRING) { | 245 if (value_field->type() == FieldDescriptor::TYPE_STRING) { |
249 GenerateUtf8CheckCodeForString(value_field, options_, true, variables_, | 246 GenerateUtf8CheckCodeForString(value_field, options_, true, variables_, |
250 StrCat(value, ".data(), ", value, ".length(),\n").data(), printer); | 247 "entry->mutable_value()->data(),\n" |
| 248 "entry->mutable_value()->length(),\n", |
| 249 printer); |
251 } | 250 } |
252 | 251 |
253 // If entry is allocated by arena, its desctructor should be avoided. | 252 // If entry is allocated by arena, its desctructor should be avoided. |
254 if (using_entry && SupportsArenas(descriptor_)) { | 253 if (SupportsArenas(descriptor_)) { |
255 printer->Print(variables_, | 254 printer->Print(variables_, |
256 "if (entry->GetArena() != NULL) entry.release();\n"); | 255 "if (entry->GetArena() != NULL) entry.release();\n"); |
257 } | 256 } |
258 } | 257 } |
259 | 258 |
260 static void GenerateSerializationLoop(io::Printer* printer, | 259 void MapFieldGenerator:: |
261 const std::map<string, string>& variables, | 260 GenerateSerializeWithCachedSizes(io::Printer* printer) const { |
262 bool supports_arenas, | 261 printer->Print(variables_, |
263 const string& utf8_check, | 262 "{\n" |
264 const string& loop_header, | 263 " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" |
265 const string& ptr, | 264 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" |
266 bool loop_via_iterators) { | 265 " it = this->$name$().begin();\n" |
267 printer->Print(variables, | 266 " it != this->$name$().end(); ++it) {\n"); |
268 StrCat("::google::protobuf::scoped_ptr<$map_classname$> entry;\n", | 267 |
269 loop_header, " {\n").c_str()); | 268 // If entry is allocated by arena, its desctructor should be avoided. |
| 269 if (SupportsArenas(descriptor_)) { |
| 270 printer->Print(variables_, |
| 271 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" |
| 272 " entry.release();\n" |
| 273 " }\n"); |
| 274 } |
| 275 |
| 276 printer->Print(variables_, |
| 277 " entry.reset($name$_.New$wrapper$(it->first, it->second));\n" |
| 278 " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n
" |
| 279 " $number$, *entry, output);\n"); |
| 280 |
| 281 printer->Indent(); |
270 printer->Indent(); | 282 printer->Indent(); |
271 | 283 |
272 printer->Print(variables, StrCat( | 284 const FieldDescriptor* key_field = |
273 "entry.reset($name$_.New$wrapper$(\n" | 285 descriptor_->message_type()->FindFieldByName("key"); |
274 " ", ptr, "->first, ", ptr, "->second));\n" | 286 const FieldDescriptor* value_field = |
275 "$write_entry$;\n").c_str()); | 287 descriptor_->message_type()->FindFieldByName("value"); |
276 | 288 if (key_field->type() == FieldDescriptor::TYPE_STRING) { |
277 // If entry is allocated by arena, its desctructor should be avoided. | 289 GenerateUtf8CheckCodeForString(key_field, options_, false, variables_, |
278 if (supports_arenas) { | 290 "it->first.data(), it->first.length(),\n", |
279 printer->Print( | 291 printer); |
280 "if (entry->GetArena() != NULL) {\n" | |
281 " entry.release();\n" | |
282 "}\n"); | |
283 } | 292 } |
284 | 293 if (value_field->type() == FieldDescriptor::TYPE_STRING) { |
285 if (!utf8_check.empty()) { | 294 GenerateUtf8CheckCodeForString(value_field, options_, false, variables_, |
286 // If loop_via_iterators is true then ptr is actually an iterator, and we | 295 "it->second.data(), it->second.length(),\n", |
287 // create a pointer by prefixing it with "&*". | 296 printer); |
288 printer->Print( | |
289 StrCat(utf8_check, "(", (loop_via_iterators ? "&*" : ""), ptr, ");\n") | |
290 .c_str()); | |
291 } | 297 } |
292 | 298 |
293 printer->Outdent(); | 299 printer->Outdent(); |
| 300 printer->Outdent(); |
| 301 |
294 printer->Print( | 302 printer->Print( |
295 "}\n"); | 303 " }\n"); |
296 } | |
297 | 304 |
298 void MapFieldGenerator:: | 305 // If entry is allocated by arena, its desctructor should be avoided. |
299 GenerateSerializeWithCachedSizes(io::Printer* printer) const { | 306 if (SupportsArenas(descriptor_)) { |
300 std::map<string, string> variables(variables_); | 307 printer->Print(variables_, |
301 variables["write_entry"] = "::google::protobuf::internal::WireFormatLite::Writ
e" + | 308 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" |
302 variables["stream_writer"] + "(\n " + | 309 " entry.release();\n" |
303 variables["number"] + ", *entry, output)"; | 310 " }\n"); |
304 variables["deterministic"] = "output->IsSerializationDeterministic()"; | 311 } |
305 GenerateSerializeWithCachedSizes(printer, variables); | 312 |
| 313 printer->Print("}\n"); |
306 } | 314 } |
307 | 315 |
308 void MapFieldGenerator:: | 316 void MapFieldGenerator:: |
309 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { | 317 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { |
310 std::map<string, string> variables(variables_); | 318 printer->Print(variables_, |
311 variables["write_entry"] = | 319 "{\n" |
312 "target = ::google::protobuf::internal::WireFormatLite::\n" | 320 " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" |
313 " InternalWrite" + variables["declared_type"] + | 321 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" |
314 "NoVirtualToArray(\n " + variables["number"] + | 322 " it = this->$name$().begin();\n" |
315 ", *entry, deterministic, target);\n"; | 323 " it != this->$name$().end(); ++it) {\n"); |
316 variables["deterministic"] = "deterministic"; | |
317 GenerateSerializeWithCachedSizes(printer, variables); | |
318 } | |
319 | 324 |
320 void MapFieldGenerator::GenerateSerializeWithCachedSizes( | 325 // If entry is allocated by arena, its desctructor should be avoided. |
321 io::Printer* printer, const std::map<string, string>& variables) const { | 326 if (SupportsArenas(descriptor_)) { |
322 printer->Print(variables, | 327 printer->Print(variables_, |
323 "if (!this->$name$().empty()) {\n"); | 328 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" |
| 329 " entry.release();\n" |
| 330 " }\n"); |
| 331 } |
| 332 |
| 333 printer->Print(variables_, |
| 334 " entry.reset($name$_.New$wrapper$(it->first, it->second));\n" |
| 335 " target = ::google::protobuf::internal::WireFormatLite::\n" |
| 336 " Write$declared_type$NoVirtualToArray(\n" |
| 337 " $number$, *entry, target);\n"); |
| 338 |
324 printer->Indent(); | 339 printer->Indent(); |
| 340 printer->Indent(); |
| 341 |
325 const FieldDescriptor* key_field = | 342 const FieldDescriptor* key_field = |
326 descriptor_->message_type()->FindFieldByName("key"); | 343 descriptor_->message_type()->FindFieldByName("key"); |
327 const FieldDescriptor* value_field = | 344 const FieldDescriptor* value_field = |
328 descriptor_->message_type()->FindFieldByName("value"); | 345 descriptor_->message_type()->FindFieldByName("value"); |
329 const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING; | 346 if (key_field->type() == FieldDescriptor::TYPE_STRING) { |
330 const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING; | 347 GenerateUtf8CheckCodeForString(key_field, options_, false, variables_, |
331 | 348 "it->first.data(), it->first.length(),\n", |
332 printer->Print(variables, | 349 printer); |
333 "typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_pointer\n" | |
334 " ConstPtr;\n"); | |
335 if (string_key) { | |
336 printer->Print(variables, | |
337 "typedef ConstPtr SortItem;\n" | |
338 "typedef ::google::protobuf::internal::" | |
339 "CompareByDerefFirst<SortItem> Less;\n"); | |
340 } else { | |
341 printer->Print(variables, | |
342 "typedef ::google::protobuf::internal::SortItem< $key_cpp$, ConstPtr > " | |
343 "SortItem;\n" | |
344 "typedef ::google::protobuf::internal::CompareByFirstField<SortItem> Les
s;\n"); | |
345 } | 350 } |
346 string utf8_check; | 351 if (value_field->type() == FieldDescriptor::TYPE_STRING) { |
347 if (string_key || string_value) { | 352 GenerateUtf8CheckCodeForString(value_field, options_, false, variables_, |
348 printer->Print( | 353 "it->second.data(), it->second.length(),\n", |
349 "struct Utf8Check {\n" | 354 printer); |
350 " static void Check(ConstPtr p) {\n"); | |
351 printer->Indent(); | |
352 printer->Indent(); | |
353 if (string_key) { | |
354 GenerateUtf8CheckCodeForString(key_field, options_, false, variables, | |
355 "p->first.data(), p->first.length(),\n", | |
356 printer); | |
357 } | |
358 if (string_value) { | |
359 GenerateUtf8CheckCodeForString(value_field, options_, false, variables, | |
360 "p->second.data(), p->second.length(),\n", | |
361 printer); | |
362 } | |
363 printer->Outdent(); | |
364 printer->Outdent(); | |
365 printer->Print( | |
366 " }\n" | |
367 "};\n"); | |
368 utf8_check = "Utf8Check::Check"; | |
369 } | 355 } |
370 | 356 |
371 printer->Print(variables, | 357 printer->Outdent(); |
372 "\n" | |
373 "if ($deterministic$ &&\n" | |
374 " this->$name$().size() > 1) {\n" | |
375 " ::google::protobuf::scoped_array<SortItem> items(\n" | |
376 " new SortItem[this->$name$().size()]);\n" | |
377 " typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::size_type size
_type;\n" | |
378 " size_type n = 0;\n" | |
379 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" | |
380 " it = this->$name$().begin();\n" | |
381 " it != this->$name$().end(); ++it, ++n) {\n" | |
382 " items[n] = SortItem(&*it);\n" | |
383 " }\n" | |
384 " ::std::sort(&items[0], &items[n], Less());\n"); | |
385 printer->Indent(); | |
386 GenerateSerializationLoop(printer, variables, SupportsArenas(descriptor_), | |
387 utf8_check, "for (size_type i = 0; i < n; i++)", | |
388 string_key ? "items[i]" : "items[i].second", false); | |
389 printer->Outdent(); | 358 printer->Outdent(); |
390 printer->Print( | 359 printer->Print( |
391 "} else {\n"); | 360 " }\n"); |
392 printer->Indent(); | 361 |
393 GenerateSerializationLoop( | 362 // If entry is allocated by arena, its desctructor should be avoided. |
394 printer, variables, SupportsArenas(descriptor_), utf8_check, | 363 if (SupportsArenas(descriptor_)) { |
395 "for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" | 364 printer->Print(variables_, |
396 " it = this->$name$().begin();\n" | 365 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" |
397 " it != this->$name$().end(); ++it)", | 366 " entry.release();\n" |
398 "it", true); | 367 " }\n"); |
399 printer->Outdent(); | 368 } |
400 printer->Print("}\n"); | 369 |
401 printer->Outdent(); | |
402 printer->Print("}\n"); | 370 printer->Print("}\n"); |
403 } | 371 } |
404 | 372 |
405 void MapFieldGenerator:: | 373 void MapFieldGenerator:: |
406 GenerateByteSize(io::Printer* printer) const { | 374 GenerateByteSize(io::Printer* printer) const { |
407 printer->Print(variables_, | 375 printer->Print(variables_, |
408 "total_size += $tag_size$ *\n" | 376 "total_size += $tag_size$ * this->$name$_size();\n" |
409 " ::google::protobuf::internal::FromIntSize(this->$name$_size());\n" | |
410 "{\n" | 377 "{\n" |
411 " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" | 378 " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" |
412 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" | 379 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" |
413 " it = this->$name$().begin();\n" | 380 " it = this->$name$().begin();\n" |
414 " it != this->$name$().end(); ++it) {\n"); | 381 " it != this->$name$().end(); ++it) {\n"); |
415 | 382 |
416 // If entry is allocated by arena, its desctructor should be avoided. | 383 // If entry is allocated by arena, its desctructor should be avoided. |
417 if (SupportsArenas(descriptor_)) { | 384 if (SupportsArenas(descriptor_)) { |
418 printer->Print(variables_, | 385 printer->Print(variables_, |
419 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" | 386 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" |
(...skipping 15 matching lines...) Expand all Loading... |
435 " }\n"); | 402 " }\n"); |
436 } | 403 } |
437 | 404 |
438 printer->Print("}\n"); | 405 printer->Print("}\n"); |
439 } | 406 } |
440 | 407 |
441 } // namespace cpp | 408 } // namespace cpp |
442 } // namespace compiler | 409 } // namespace compiler |
443 } // namespace protobuf | 410 } // namespace protobuf |
444 } // namespace google | 411 } // namespace google |
OLD | NEW |