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 map<string, string>* variables, | 48 std::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"] = FieldMessageTypeName(descriptor); | 51 (*variables)["type"] = ClassName(descriptor->message_type(), false); |
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 map<string, string> variables(variables_); | 140 std::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 map<string, string> variables(variables_); | 157 std::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:: |
184 GenerateMergeFromCodedStream(io::Printer* printer) const { | 190 GenerateMergeFromCodedStream(io::Printer* printer) const { |
| 191 const FieldDescriptor* key_field = |
| 192 descriptor_->message_type()->FindFieldByName("key"); |
185 const FieldDescriptor* value_field = | 193 const FieldDescriptor* value_field = |
186 descriptor_->message_type()->FindFieldByName("value"); | 194 descriptor_->message_type()->FindFieldByName("value"); |
187 printer->Print(variables_, | 195 bool using_entry = false; |
188 "::google::protobuf::scoped_ptr<$map_classname$> entry($name$_.NewEntry())
;\n"); | 196 string key; |
189 | 197 string value; |
190 if (IsProto3Field(descriptor_) || | 198 if (IsProto3Field(descriptor_) || |
191 value_field->type() != FieldDescriptor::TYPE_ENUM) { | 199 value_field->type() != FieldDescriptor::TYPE_ENUM) { |
192 printer->Print(variables_, | 200 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" |
193 "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
\n" | 208 "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
\n" |
194 " input, entry.get()));\n"); | 209 " input, &parser));\n"); |
195 switch (value_field->cpp_type()) { | 210 key = "parser.key()"; |
196 case FieldDescriptor::CPPTYPE_MESSAGE: | 211 value = "parser.value()"; |
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 } | |
211 } else { | 212 } 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"); |
212 printer->Print(variables_, | 218 printer->Print(variables_, |
213 "{\n" | 219 "{\n" |
214 " ::std::string data;\n" | 220 " ::std::string data;\n" |
215 " DO_(::google::protobuf::internal::WireFormatLite::ReadString(input, &
data));\n" | 221 " DO_(::google::protobuf::internal::WireFormatLite::ReadString(input, &
data));\n" |
216 " DO_(entry->ParseFromString(data));\n" | 222 " DO_(entry->ParseFromString(data));\n" |
217 " if ($val_cpp$_IsValid(*entry->mutable_value())) {\n" | 223 " if ($val_cpp$_IsValid(*entry->mutable_value())) {\n" |
218 " (*mutable_$name$())[entry->key()] =\n" | 224 " (*mutable_$name$())[entry->key()] =\n" |
219 " static_cast< $val_cpp$ >(*entry->mutable_value());\n" | 225 " static_cast< $val_cpp$ >(*entry->mutable_value());\n" |
220 " } else {\n"); | 226 " } else {\n"); |
221 if (HasDescriptorMethods(descriptor_->file(), options_)) { | 227 if (HasDescriptorMethods(descriptor_->file(), options_)) { |
222 printer->Print(variables_, | 228 printer->Print(variables_, |
223 " mutable_unknown_fields()" | 229 " mutable_unknown_fields()" |
224 "->AddLengthDelimited($number$, data);\n"); | 230 "->AddLengthDelimited($number$, data);\n"); |
225 } else { | 231 } else { |
226 printer->Print(variables_, | 232 printer->Print(variables_, |
227 " unknown_fields_stream.WriteVarint32($tag$);\n" | 233 " unknown_fields_stream.WriteVarint32($tag$u);\n" |
228 " unknown_fields_stream.WriteVarint32(data.size());\n" | 234 " unknown_fields_stream.WriteVarint32(data.size());\n" |
229 " unknown_fields_stream.WriteString(data);\n"); | 235 " unknown_fields_stream.WriteString(data);\n"); |
230 } | 236 } |
231 | 237 |
232 | |
233 printer->Print(variables_, | 238 printer->Print(variables_, |
234 " }\n" | 239 " }\n" |
235 "}\n"); | 240 "}\n"); |
236 } | 241 } |
237 | 242 |
238 const FieldDescriptor* key_field = | |
239 descriptor_->message_type()->FindFieldByName("key"); | |
240 if (key_field->type() == FieldDescriptor::TYPE_STRING) { | 243 if (key_field->type() == FieldDescriptor::TYPE_STRING) { |
241 GenerateUtf8CheckCodeForString( | 244 GenerateUtf8CheckCodeForString( |
242 key_field, options_, true, variables_, | 245 key_field, options_, true, variables_, |
243 "entry->key().data(), entry->key().length(),\n", printer); | 246 StrCat(key, ".data(), ", key, ".length(),\n").data(), printer); |
244 } | 247 } |
245 if (value_field->type() == FieldDescriptor::TYPE_STRING) { | 248 if (value_field->type() == FieldDescriptor::TYPE_STRING) { |
246 GenerateUtf8CheckCodeForString(value_field, options_, true, variables_, | 249 GenerateUtf8CheckCodeForString(value_field, options_, true, variables_, |
247 "entry->mutable_value()->data(),\n" | 250 StrCat(value, ".data(), ", value, ".length(),\n").data(), printer); |
248 "entry->mutable_value()->length(),\n", | |
249 printer); | |
250 } | 251 } |
251 | 252 |
252 // If entry is allocated by arena, its desctructor should be avoided. | 253 // If entry is allocated by arena, its desctructor should be avoided. |
253 if (SupportsArenas(descriptor_)) { | 254 if (using_entry && SupportsArenas(descriptor_)) { |
254 printer->Print(variables_, | 255 printer->Print(variables_, |
255 "if (entry->GetArena() != NULL) entry.release();\n"); | 256 "if (entry->GetArena() != NULL) entry.release();\n"); |
256 } | 257 } |
257 } | 258 } |
258 | 259 |
| 260 static void GenerateSerializationLoop(io::Printer* printer, |
| 261 const std::map<string, string>& variables, |
| 262 bool supports_arenas, |
| 263 const string& utf8_check, |
| 264 const string& loop_header, |
| 265 const string& ptr, |
| 266 bool loop_via_iterators) { |
| 267 printer->Print(variables, |
| 268 StrCat("::google::protobuf::scoped_ptr<$map_classname$> entry;\n", |
| 269 loop_header, " {\n").c_str()); |
| 270 printer->Indent(); |
| 271 |
| 272 printer->Print(variables, StrCat( |
| 273 "entry.reset($name$_.New$wrapper$(\n" |
| 274 " ", ptr, "->first, ", ptr, "->second));\n" |
| 275 "$write_entry$;\n").c_str()); |
| 276 |
| 277 // If entry is allocated by arena, its desctructor should be avoided. |
| 278 if (supports_arenas) { |
| 279 printer->Print( |
| 280 "if (entry->GetArena() != NULL) {\n" |
| 281 " entry.release();\n" |
| 282 "}\n"); |
| 283 } |
| 284 |
| 285 if (!utf8_check.empty()) { |
| 286 // If loop_via_iterators is true then ptr is actually an iterator, and we |
| 287 // create a pointer by prefixing it with "&*". |
| 288 printer->Print( |
| 289 StrCat(utf8_check, "(", (loop_via_iterators ? "&*" : ""), ptr, ");\n") |
| 290 .c_str()); |
| 291 } |
| 292 |
| 293 printer->Outdent(); |
| 294 printer->Print( |
| 295 "}\n"); |
| 296 } |
| 297 |
259 void MapFieldGenerator:: | 298 void MapFieldGenerator:: |
260 GenerateSerializeWithCachedSizes(io::Printer* printer) const { | 299 GenerateSerializeWithCachedSizes(io::Printer* printer) const { |
261 printer->Print(variables_, | 300 std::map<string, string> variables(variables_); |
262 "{\n" | 301 variables["write_entry"] = "::google::protobuf::internal::WireFormatLite::Writ
e" + |
263 " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" | 302 variables["stream_writer"] + "(\n " + |
264 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" | 303 variables["number"] + ", *entry, output)"; |
265 " it = this->$name$().begin();\n" | 304 variables["deterministic"] = "output->IsSerializationDeterministic()"; |
266 " it != this->$name$().end(); ++it) {\n"); | 305 GenerateSerializeWithCachedSizes(printer, variables); |
| 306 } |
267 | 307 |
268 // If entry is allocated by arena, its desctructor should be avoided. | 308 void MapFieldGenerator:: |
269 if (SupportsArenas(descriptor_)) { | 309 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { |
270 printer->Print(variables_, | 310 std::map<string, string> variables(variables_); |
271 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" | 311 variables["write_entry"] = |
272 " entry.release();\n" | 312 "target = ::google::protobuf::internal::WireFormatLite::\n" |
273 " }\n"); | 313 " InternalWrite" + variables["declared_type"] + |
274 } | 314 "NoVirtualToArray(\n " + variables["number"] + |
| 315 ", *entry, deterministic, target);\n"; |
| 316 variables["deterministic"] = "deterministic"; |
| 317 GenerateSerializeWithCachedSizes(printer, variables); |
| 318 } |
275 | 319 |
276 printer->Print(variables_, | 320 void MapFieldGenerator::GenerateSerializeWithCachedSizes( |
277 " entry.reset($name$_.New$wrapper$(it->first, it->second));\n" | 321 io::Printer* printer, const std::map<string, string>& variables) const { |
278 " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n
" | 322 printer->Print(variables, |
279 " $number$, *entry, output);\n"); | 323 "if (!this->$name$().empty()) {\n"); |
280 | |
281 printer->Indent(); | 324 printer->Indent(); |
282 printer->Indent(); | |
283 | |
284 const FieldDescriptor* key_field = | 325 const FieldDescriptor* key_field = |
285 descriptor_->message_type()->FindFieldByName("key"); | 326 descriptor_->message_type()->FindFieldByName("key"); |
286 const FieldDescriptor* value_field = | 327 const FieldDescriptor* value_field = |
287 descriptor_->message_type()->FindFieldByName("value"); | 328 descriptor_->message_type()->FindFieldByName("value"); |
288 if (key_field->type() == FieldDescriptor::TYPE_STRING) { | 329 const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING; |
289 GenerateUtf8CheckCodeForString(key_field, options_, false, variables_, | 330 const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING; |
290 "it->first.data(), it->first.length(),\n", | 331 |
291 printer); | 332 printer->Print(variables, |
| 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"); |
292 } | 345 } |
293 if (value_field->type() == FieldDescriptor::TYPE_STRING) { | 346 string utf8_check; |
294 GenerateUtf8CheckCodeForString(value_field, options_, false, variables_, | 347 if (string_key || string_value) { |
295 "it->second.data(), it->second.length(),\n", | 348 printer->Print( |
296 printer); | 349 "struct Utf8Check {\n" |
| 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"; |
297 } | 369 } |
298 | 370 |
299 printer->Outdent(); | 371 printer->Print(variables, |
300 printer->Outdent(); | 372 "\n" |
301 | 373 "if ($deterministic$ &&\n" |
302 printer->Print( | 374 " this->$name$().size() > 1) {\n" |
303 " }\n"); | 375 " ::google::protobuf::scoped_array<SortItem> items(\n" |
304 | 376 " new SortItem[this->$name$().size()]);\n" |
305 // If entry is allocated by arena, its desctructor should be avoided. | 377 " typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::size_type size
_type;\n" |
306 if (SupportsArenas(descriptor_)) { | 378 " size_type n = 0;\n" |
307 printer->Print(variables_, | |
308 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" | |
309 " entry.release();\n" | |
310 " }\n"); | |
311 } | |
312 | |
313 printer->Print("}\n"); | |
314 } | |
315 | |
316 void MapFieldGenerator:: | |
317 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { | |
318 printer->Print(variables_, | |
319 "{\n" | |
320 " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" | |
321 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" | 379 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" |
322 " it = this->$name$().begin();\n" | 380 " it = this->$name$().begin();\n" |
323 " it != this->$name$().end(); ++it) {\n"); | 381 " it != this->$name$().end(); ++it, ++n) {\n" |
324 | 382 " items[n] = SortItem(&*it);\n" |
325 // If entry is allocated by arena, its desctructor should be avoided. | 383 " }\n" |
326 if (SupportsArenas(descriptor_)) { | 384 " ::std::sort(&items[0], &items[n], Less());\n"); |
327 printer->Print(variables_, | |
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 | |
339 printer->Indent(); | 385 printer->Indent(); |
340 printer->Indent(); | 386 GenerateSerializationLoop(printer, variables, SupportsArenas(descriptor_), |
341 | 387 utf8_check, "for (size_type i = 0; i < n; i++)", |
342 const FieldDescriptor* key_field = | 388 string_key ? "items[i]" : "items[i].second", false); |
343 descriptor_->message_type()->FindFieldByName("key"); | |
344 const FieldDescriptor* value_field = | |
345 descriptor_->message_type()->FindFieldByName("value"); | |
346 if (key_field->type() == FieldDescriptor::TYPE_STRING) { | |
347 GenerateUtf8CheckCodeForString(key_field, options_, false, variables_, | |
348 "it->first.data(), it->first.length(),\n", | |
349 printer); | |
350 } | |
351 if (value_field->type() == FieldDescriptor::TYPE_STRING) { | |
352 GenerateUtf8CheckCodeForString(value_field, options_, false, variables_, | |
353 "it->second.data(), it->second.length(),\n", | |
354 printer); | |
355 } | |
356 | |
357 printer->Outdent(); | |
358 printer->Outdent(); | 389 printer->Outdent(); |
359 printer->Print( | 390 printer->Print( |
360 " }\n"); | 391 "} else {\n"); |
361 | 392 printer->Indent(); |
362 // If entry is allocated by arena, its desctructor should be avoided. | 393 GenerateSerializationLoop( |
363 if (SupportsArenas(descriptor_)) { | 394 printer, variables, SupportsArenas(descriptor_), utf8_check, |
364 printer->Print(variables_, | 395 "for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" |
365 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" | 396 " it = this->$name$().begin();\n" |
366 " entry.release();\n" | 397 " it != this->$name$().end(); ++it)", |
367 " }\n"); | 398 "it", true); |
368 } | 399 printer->Outdent(); |
369 | 400 printer->Print("}\n"); |
| 401 printer->Outdent(); |
370 printer->Print("}\n"); | 402 printer->Print("}\n"); |
371 } | 403 } |
372 | 404 |
373 void MapFieldGenerator:: | 405 void MapFieldGenerator:: |
374 GenerateByteSize(io::Printer* printer) const { | 406 GenerateByteSize(io::Printer* printer) const { |
375 printer->Print(variables_, | 407 printer->Print(variables_, |
376 "total_size += $tag_size$ * this->$name$_size();\n" | 408 "total_size += $tag_size$ *\n" |
| 409 " ::google::protobuf::internal::FromIntSize(this->$name$_size());\n" |
377 "{\n" | 410 "{\n" |
378 " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" | 411 " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" |
379 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" | 412 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" |
380 " it = this->$name$().begin();\n" | 413 " it = this->$name$().begin();\n" |
381 " it != this->$name$().end(); ++it) {\n"); | 414 " it != this->$name$().end(); ++it) {\n"); |
382 | 415 |
383 // If entry is allocated by arena, its desctructor should be avoided. | 416 // If entry is allocated by arena, its desctructor should be avoided. |
384 if (SupportsArenas(descriptor_)) { | 417 if (SupportsArenas(descriptor_)) { |
385 printer->Print(variables_, | 418 printer->Print(variables_, |
386 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" | 419 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" |
(...skipping 15 matching lines...) Expand all Loading... |
402 " }\n"); | 435 " }\n"); |
403 } | 436 } |
404 | 437 |
405 printer->Print("}\n"); | 438 printer->Print("}\n"); |
406 } | 439 } |
407 | 440 |
408 } // namespace cpp | 441 } // namespace cpp |
409 } // namespace compiler | 442 } // namespace compiler |
410 } // namespace protobuf | 443 } // namespace protobuf |
411 } // namespace google | 444 } // namespace google |
OLD | NEW |