| 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 |