proto_writer.cc
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
32 
33 #include <functional>
34 #include <stack>
35 
46 
47 
48 #include <google/protobuf/port_def.inc>
49 
50 namespace google {
51 namespace protobuf {
52 namespace util {
53 namespace converter {
54 
55 using io::CodedOutputStream;
56 using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite;
57 using util::Status;
58 using util::StatusOr;
60 
61 
64  strings::ByteSink* output, ErrorListener* listener)
65  : master_type_(type),
66  typeinfo_(TypeInfo::NewTypeInfo(type_resolver)),
67  own_typeinfo_(true),
68  done_(false),
69  ignore_unknown_fields_(false),
70  ignore_unknown_enum_values_(false),
71  use_lower_camel_for_enums_(false),
72  case_insensitive_enum_parsing_(true),
73  element_(nullptr),
74  size_insert_(),
75  output_(output),
76  buffer_(),
77  adapter_(&buffer_),
78  stream_(new CodedOutputStream(&adapter_)),
79  listener_(listener),
80  invalid_depth_(0),
81  tracker_(new ObjectLocationTracker()) {}
82 
85  strings::ByteSink* output, ErrorListener* listener)
86  : master_type_(type),
87  typeinfo_(typeinfo),
88  own_typeinfo_(false),
89  done_(false),
90  ignore_unknown_fields_(false),
91  ignore_unknown_enum_values_(false),
92  use_lower_camel_for_enums_(false),
93  case_insensitive_enum_parsing_(true),
94  element_(nullptr),
95  size_insert_(),
96  output_(output),
97  buffer_(),
98  adapter_(&buffer_),
99  stream_(new CodedOutputStream(&adapter_)),
100  listener_(listener),
101  invalid_depth_(0),
102  tracker_(new ObjectLocationTracker()) {}
103 
105  if (own_typeinfo_) {
106  delete typeinfo_;
107  }
108  if (element_ == nullptr) return;
109  // Cleanup explicitly in order to avoid destructor stack overflow when input
110  // is deeply nested.
111  // Cast to BaseElement to avoid doing additional checks (like missing fields)
112  // during pop().
113  std::unique_ptr<BaseElement> element(
114  static_cast<BaseElement*>(element_.get())->pop<BaseElement>());
115  while (element != nullptr) {
116  element.reset(element->pop<BaseElement>());
117  }
118 }
119 
120 namespace {
121 
122 // Writes an INT32 field, including tag to the stream.
123 inline Status WriteInt32(int field_number, const DataPiece& data,
125  StatusOr<int32> i32 = data.ToInt32();
126  if (i32.ok()) {
127  WireFormatLite::WriteInt32(field_number, i32.ValueOrDie(), stream);
128  }
129  return i32.status();
130 }
131 
132 // writes an SFIXED32 field, including tag, to the stream.
133 inline Status WriteSFixed32(int field_number, const DataPiece& data,
134  CodedOutputStream* stream) {
135  StatusOr<int32> i32 = data.ToInt32();
136  if (i32.ok()) {
137  WireFormatLite::WriteSFixed32(field_number, i32.ValueOrDie(), stream);
138  }
139  return i32.status();
140 }
141 
142 // Writes an SINT32 field, including tag, to the stream.
143 inline Status WriteSInt32(int field_number, const DataPiece& data,
144  CodedOutputStream* stream) {
145  StatusOr<int32> i32 = data.ToInt32();
146  if (i32.ok()) {
147  WireFormatLite::WriteSInt32(field_number, i32.ValueOrDie(), stream);
148  }
149  return i32.status();
150 }
151 
152 // Writes a FIXED32 field, including tag, to the stream.
153 inline Status WriteFixed32(int field_number, const DataPiece& data,
154  CodedOutputStream* stream) {
155  StatusOr<uint32> u32 = data.ToUint32();
156  if (u32.ok()) {
157  WireFormatLite::WriteFixed32(field_number, u32.ValueOrDie(), stream);
158  }
159  return u32.status();
160 }
161 
162 // Writes a UINT32 field, including tag, to the stream.
163 inline Status WriteUInt32(int field_number, const DataPiece& data,
164  CodedOutputStream* stream) {
165  StatusOr<uint32> u32 = data.ToUint32();
166  if (u32.ok()) {
167  WireFormatLite::WriteUInt32(field_number, u32.ValueOrDie(), stream);
168  }
169  return u32.status();
170 }
171 
172 // Writes an INT64 field, including tag, to the stream.
173 inline Status WriteInt64(int field_number, const DataPiece& data,
174  CodedOutputStream* stream) {
175  StatusOr<int64> i64 = data.ToInt64();
176  if (i64.ok()) {
177  WireFormatLite::WriteInt64(field_number, i64.ValueOrDie(), stream);
178  }
179  return i64.status();
180 }
181 
182 // Writes an SFIXED64 field, including tag, to the stream.
183 inline Status WriteSFixed64(int field_number, const DataPiece& data,
184  CodedOutputStream* stream) {
185  StatusOr<int64> i64 = data.ToInt64();
186  if (i64.ok()) {
187  WireFormatLite::WriteSFixed64(field_number, i64.ValueOrDie(), stream);
188  }
189  return i64.status();
190 }
191 
192 // Writes an SINT64 field, including tag, to the stream.
193 inline Status WriteSInt64(int field_number, const DataPiece& data,
194  CodedOutputStream* stream) {
195  StatusOr<int64> i64 = data.ToInt64();
196  if (i64.ok()) {
197  WireFormatLite::WriteSInt64(field_number, i64.ValueOrDie(), stream);
198  }
199  return i64.status();
200 }
201 
202 // Writes a FIXED64 field, including tag, to the stream.
203 inline Status WriteFixed64(int field_number, const DataPiece& data,
204  CodedOutputStream* stream) {
205  StatusOr<uint64> u64 = data.ToUint64();
206  if (u64.ok()) {
207  WireFormatLite::WriteFixed64(field_number, u64.ValueOrDie(), stream);
208  }
209  return u64.status();
210 }
211 
212 // Writes a UINT64 field, including tag, to the stream.
213 inline Status WriteUInt64(int field_number, const DataPiece& data,
214  CodedOutputStream* stream) {
215  StatusOr<uint64> u64 = data.ToUint64();
216  if (u64.ok()) {
217  WireFormatLite::WriteUInt64(field_number, u64.ValueOrDie(), stream);
218  }
219  return u64.status();
220 }
221 
222 // Writes a DOUBLE field, including tag, to the stream.
223 inline Status WriteDouble(int field_number, const DataPiece& data,
224  CodedOutputStream* stream) {
225  StatusOr<double> d = data.ToDouble();
226  if (d.ok()) {
227  WireFormatLite::WriteDouble(field_number, d.ValueOrDie(), stream);
228  }
229  return d.status();
230 }
231 
232 // Writes a FLOAT field, including tag, to the stream.
233 inline Status WriteFloat(int field_number, const DataPiece& data,
234  CodedOutputStream* stream) {
235  StatusOr<float> f = data.ToFloat();
236  if (f.ok()) {
237  WireFormatLite::WriteFloat(field_number, f.ValueOrDie(), stream);
238  }
239  return f.status();
240 }
241 
242 // Writes a BOOL field, including tag, to the stream.
243 inline Status WriteBool(int field_number, const DataPiece& data,
244  CodedOutputStream* stream) {
245  StatusOr<bool> b = data.ToBool();
246  if (b.ok()) {
247  WireFormatLite::WriteBool(field_number, b.ValueOrDie(), stream);
248  }
249  return b.status();
250 }
251 
252 // Writes a BYTES field, including tag, to the stream.
253 inline Status WriteBytes(int field_number, const DataPiece& data,
254  CodedOutputStream* stream) {
255  StatusOr<std::string> c = data.ToBytes();
256  if (c.ok()) {
257  WireFormatLite::WriteBytes(field_number, c.ValueOrDie(), stream);
258  }
259  return c.status();
260 }
261 
262 // Writes a STRING field, including tag, to the stream.
263 inline Status WriteString(int field_number, const DataPiece& data,
264  CodedOutputStream* stream) {
265  StatusOr<std::string> s = data.ToString();
266  if (s.ok()) {
267  WireFormatLite::WriteString(field_number, s.ValueOrDie(), stream);
268  }
269  return s.status();
270 }
271 
272 // Given a google::protobuf::Type, returns the set of all required fields.
273 std::set<const google::protobuf::Field*> GetRequiredFields(
274  const google::protobuf::Type& type) {
275  std::set<const google::protobuf::Field*> required;
276  for (int i = 0; i < type.fields_size(); i++) {
277  const google::protobuf::Field& field = type.fields(i);
278  if (field.cardinality() ==
280  required.insert(&field);
281  }
282  }
283  return required;
284 }
285 
286 } // namespace
287 
290  ProtoWriter* enclosing)
291  : BaseElement(nullptr),
292  ow_(enclosing),
293  parent_field_(nullptr),
294  typeinfo_(typeinfo),
295  proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3),
296  type_(type),
297  size_index_(-1),
298  array_index_(-1),
299  // oneof_indices_ values are 1-indexed (0 means not present).
300  oneof_indices_(type.oneofs_size() + 1) {
301  if (!proto3_) {
302  required_fields_ = GetRequiredFields(type_);
303  }
304 }
305 
309  bool is_list)
310  : BaseElement(parent),
311  ow_(this->parent()->ow_),
312  parent_field_(field),
313  typeinfo_(this->parent()->typeinfo_),
314  proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3),
315  type_(type),
316  size_index_(!is_list && field->kind() ==
318  ? ow_->size_insert_.size()
319  : -1),
320  array_index_(is_list ? 0 : -1),
321  // oneof_indices_ values are 1-indexed (0 means not present).
322  oneof_indices_(type_.oneofs_size() + 1) {
323  if (!is_list) {
324  if (ow_->IsRepeated(*field)) {
325  // Update array_index_ if it is an explicit list.
326  if (this->parent()->array_index_ >= 0) this->parent()->array_index_++;
327  } else if (!proto3_) {
328  // For required fields tracking.
329  this->parent()->RegisterField(field);
330  }
331 
333  if (!proto3_) {
334  required_fields_ = GetRequiredFields(type_);
335  }
336  int start_pos = ow_->stream_->ByteCount();
337  // length of serialized message is the final buffer position minus
338  // starting buffer position, plus length adjustments for size fields
339  // of any nested messages. We start with -start_pos here, so we only
340  // need to add the final buffer position to it at the end.
341  SizeInfo info = {start_pos, -start_pos};
342  ow_->size_insert_.push_back(info);
343  }
344  }
345 }
346 
348  if (!proto3_) {
349  // Calls the registered error listener for any required field(s) not yet
350  // seen.
351  for (std::set<const google::protobuf::Field*>::iterator it =
352  required_fields_.begin();
353  it != required_fields_.end(); ++it) {
354  ow_->MissingField((*it)->name());
355  }
356  }
357  // Computes the total number of proto bytes used by a message, also adjusts
358  // the size of all parent messages by the length of this size field.
359  // If size_index_ < 0, this is not a message, so no size field is added.
360  if (size_index_ >= 0) {
361  // Add the final buffer position to compute the total length of this
362  // serialized message. The stored value (before this addition) already
363  // contains the total length of the size fields of all nested messages
364  // minus the initial buffer position.
365  ow_->size_insert_[size_index_].size += ow_->stream_->ByteCount();
366  // Calculate the length required to serialize the size field of the
367  // message, and propagate this additional size information upward to
368  // all enclosing messages.
369  int size = ow_->size_insert_[size_index_].size;
371  for (ProtoElement* e = parent(); e != nullptr; e = e->parent()) {
372  // Only nested messages have size field, lists do not have size field.
373  if (e->size_index_ >= 0) {
374  ow_->size_insert_[e->size_index_].size += length;
375  }
376  }
377  }
378  return BaseElement::pop<ProtoElement>();
379 }
380 
383  if (!required_fields_.empty() &&
384  field->cardinality() ==
386  required_fields_.erase(field);
387  }
388 }
389 
391  std::string loc = "";
392 
393  // first populate a stack with the nodes since we need to process them
394  // from root to leaf when generating the string location
395  const ProtoWriter::ProtoElement* now = this;
396  std::stack<const ProtoWriter::ProtoElement*> element_stack;
397  while (now->parent() != nullptr) {
398  element_stack.push(now);
399  now = now->parent();
400  }
401 
402  // now pop each node from the stack and append to the location string
403  while (!element_stack.empty()) {
404  now = element_stack.top();
405  element_stack.pop();
406 
407  if (!ow_->IsRepeated(*(now->parent_field_)) ||
408  now->parent()->parent_field_ != now->parent_field_) {
409  std::string name = now->parent_field_->name();
410  int i = 0;
411  while (i < name.size() && (ascii_isalnum(name[i]) || name[i] == '_')) ++i;
412  if (i > 0 && i == name.size()) { // safe field name
413  if (loc.empty()) {
414  loc = name;
415  } else {
416  StrAppend(&loc, ".", name);
417  }
418  } else {
419  StrAppend(&loc, "[\"", CEscape(name), "\"]");
420  }
421  }
422 
423  int array_index_now = now->array_index_;
424  if (ow_->IsRepeated(*(now->parent_field_)) && array_index_now > 0) {
425  StrAppend(&loc, "[", array_index_now - 1, "]");
426  }
427  }
428 
429  return loc;
430 }
431 
433  return oneof_indices_[index];
434 }
435 
437  oneof_indices_[index] = true;
438 }
439 
442  listener_->InvalidName(location(), ToSnakeCase(unknown_name), message);
443 }
444 
446  StringPiece value) {
447  listener_->InvalidValue(location(), type_name, value);
448 }
449 
451  listener_->MissingField(location(), missing_name);
452 }
453 
455  // Starting the root message. Create the root ProtoElement and return.
456  if (element_ == nullptr) {
457  if (!name.empty()) {
458  InvalidName(name, "Root element should not be named.");
459  }
460  element_.reset(new ProtoElement(typeinfo_, master_type_, this));
461  return this;
462  }
463 
464  const google::protobuf::Field* field = nullptr;
465  field = BeginNamed(name, false);
466  if (field == nullptr) return this;
467 
468  // Check to see if this field is a oneof and that no oneof in that group has
469  // already been set.
470  if (!ValidOneof(*field, name)) {
471  ++invalid_depth_;
472  return this;
473  }
474 
476  if (type == nullptr) {
477  ++invalid_depth_;
478  InvalidName(name, StrCat("Missing descriptor for field: ",
479  field->type_url()));
480  return this;
481  }
482 
483  return StartObjectField(*field, *type);
484 }
485 
487  if (invalid_depth_ > 0) {
488  --invalid_depth_;
489  return this;
490  }
491 
492  if (element_ != nullptr) {
493  element_.reset(element_->pop());
494  }
495 
496 
497  // If ending the root element,
498  // then serialize the full message with calculated sizes.
499  if (element_ == nullptr) {
501  }
502  return this;
503 }
504 
507  if (field == nullptr) return this;
508 
509  if (!ValidOneof(*field, name)) {
510  ++invalid_depth_;
511  return this;
512  }
513 
515  if (type == nullptr) {
516  ++invalid_depth_;
517  InvalidName(name, StrCat("Missing descriptor for field: ",
518  field->type_url()));
519  return this;
520  }
521 
522  return StartListField(*field, *type);
523 }
524 
526  if (invalid_depth_ > 0) {
527  --invalid_depth_;
528  } else if (element_ != nullptr) {
529  element_.reset(element_->pop());
530  }
531  return this;
532 }
533 
535  const DataPiece& data) {
536  Status status;
537  if (invalid_depth_ > 0) return this;
538 
540  if (field == nullptr) return this;
541 
542  if (!ValidOneof(*field, name)) return this;
543 
545  if (type == nullptr) {
546  InvalidName(name, StrCat("Missing descriptor for field: ",
547  field->type_url()));
548  return this;
549  }
550 
551  return RenderPrimitiveField(*field, *type, data);
552 }
553 
555  StringPiece unnormalized_name) {
556  if (element_ == nullptr) return true;
557 
558  if (field.oneof_index() > 0) {
559  if (element_->IsOneofIndexTaken(field.oneof_index())) {
560  InvalidValue(
561  "oneof",
562  StrCat(
563  "oneof field '", element_->type().oneofs(field.oneof_index() - 1),
564  "' is already set. Cannot set '", unnormalized_name, "'"));
565  return false;
566  }
567  element_->TakeOneofIndex(field.oneof_index());
568  }
569  return true;
570 }
571 
573  return field.cardinality() ==
575 }
576 
578  const google::protobuf::Type& type) {
579  WriteTag(field);
580  element_.reset(new ProtoElement(element_.release(), &field, type, false));
581  return this;
582 }
583 
585  const google::protobuf::Type& type) {
586  element_.reset(new ProtoElement(element_.release(), &field, type, true));
587  return this;
588 }
589 
590 Status ProtoWriter::WriteEnum(int field_number, const DataPiece& data,
593  bool use_lower_camel_for_enums,
594  bool case_insensitive_enum_parsing,
595  bool ignore_unknown_values) {
596  bool is_unknown_enum_value = false;
597  StatusOr<int> e = data.ToEnum(enum_type, use_lower_camel_for_enums,
598  case_insensitive_enum_parsing,
599  ignore_unknown_values, &is_unknown_enum_value);
600  if (e.ok() && !is_unknown_enum_value) {
601  WireFormatLite::WriteEnum(field_number, e.ValueOrDie(), stream);
602  }
603  return e.status();
604 }
605 
608  const DataPiece& data) {
609  Status status;
610 
611  // Pushing a ProtoElement and then pop it off at the end for 2 purposes:
612  // error location reporting and required field accounting.
613  //
614  // For proto3, since there is no required field tracking, we only need to push
615  // ProtoElement for error cases.
616  if (!element_->proto3()) {
617  element_.reset(new ProtoElement(element_.release(), &field, type, false));
618  }
619 
622  // Push a ProtoElement for location reporting purposes.
623  if (element_->proto3()) {
624  element_.reset(new ProtoElement(element_.release(), &field, type, false));
625  }
626  InvalidValue(field.type_url().empty()
628  : field.type_url(),
629  data.ValueAsStringOrDefault(""));
630  element_.reset(element()->pop());
631  return this;
632  }
633 
634  switch (field.kind()) {
636  status = WriteInt32(field.number(), data, stream_.get());
637  break;
638  }
640  status = WriteSFixed32(field.number(), data, stream_.get());
641  break;
642  }
644  status = WriteSInt32(field.number(), data, stream_.get());
645  break;
646  }
648  status = WriteFixed32(field.number(), data, stream_.get());
649  break;
650  }
652  status = WriteUInt32(field.number(), data, stream_.get());
653  break;
654  }
656  status = WriteInt64(field.number(), data, stream_.get());
657  break;
658  }
660  status = WriteSFixed64(field.number(), data, stream_.get());
661  break;
662  }
664  status = WriteSInt64(field.number(), data, stream_.get());
665  break;
666  }
668  status = WriteFixed64(field.number(), data, stream_.get());
669  break;
670  }
672  status = WriteUInt64(field.number(), data, stream_.get());
673  break;
674  }
676  status = WriteDouble(field.number(), data, stream_.get());
677  break;
678  }
680  status = WriteFloat(field.number(), data, stream_.get());
681  break;
682  }
684  status = WriteBool(field.number(), data, stream_.get());
685  break;
686  }
688  status = WriteBytes(field.number(), data, stream_.get());
689  break;
690  }
692  status = WriteString(field.number(), data, stream_.get());
693  break;
694  }
696  status = WriteEnum(
697  field.number(), data, typeinfo_->GetEnumByTypeUrl(field.type_url()),
700  break;
701  }
702  default: // TYPE_GROUP or TYPE_MESSAGE
704  data.ToString().ValueOrDie());
705  }
706 
707  if (!status.ok()) {
708  // Push a ProtoElement for location reporting purposes.
709  if (element_->proto3()) {
710  element_.reset(new ProtoElement(element_.release(), &field, type, false));
711  }
713  status.message());
714  element_.reset(element()->pop());
715  return this;
716  }
717 
718  if (!element_->proto3()) element_.reset(element()->pop());
719 
720  return this;
721 }
722 
724  bool is_list) {
725  if (invalid_depth_ > 0) {
726  ++invalid_depth_;
727  return nullptr;
728  }
730  if (field == nullptr) {
731  ++invalid_depth_;
732  // InvalidName() already called in Lookup().
733  return nullptr;
734  }
735  if (is_list && !IsRepeated(*field)) {
736  ++invalid_depth_;
737  InvalidName(name, "Proto field is not repeating, cannot start list.");
738  return nullptr;
739  }
740  return field;
741 }
742 
744  StringPiece unnormalized_name) {
745  ProtoElement* e = element();
746  if (e == nullptr) {
747  InvalidName(unnormalized_name, "Root element must be a message.");
748  return nullptr;
749  }
750  if (unnormalized_name.empty()) {
751  // Objects in repeated field inherit the same field descriptor.
752  if (e->parent_field() == nullptr) {
753  InvalidName(unnormalized_name, "Proto fields must have a name.");
754  } else if (!IsRepeated(*e->parent_field())) {
755  InvalidName(unnormalized_name, "Proto fields must have a name.");
756  return nullptr;
757  }
758  return e->parent_field();
759  }
761  typeinfo_->FindField(&e->type(), unnormalized_name);
762  if (field == nullptr && !ignore_unknown_fields_) {
763  InvalidName(unnormalized_name, "Cannot find field.");
764  }
765  return field;
766 }
767 
770  return ((field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE ||
772  ? typeinfo_->GetTypeByTypeUrl(field->type_url())
773  : &element_->type());
774 }
775 
778  int curr_pos = 0;
779  // Calls the destructor of CodedOutputStream to remove any uninitialized
780  // memory from the Cord before we read it.
781  stream_.reset(nullptr);
782  const void* data;
783  int length;
784  io::ArrayInputStream input_stream(buffer_.data(), buffer_.size());
785  while (input_stream.Next(&data, &length)) {
786  if (length == 0) continue;
787  int num_bytes = length;
788  // Write up to where we need to insert the size field.
789  // The number of bytes we may write is the smaller of:
790  // - the current fragment size
791  // - the distance to the next position where a size field needs to be
792  // inserted.
793  if (!size_insert_.empty() &&
794  size_insert_.front().pos - curr_pos < num_bytes) {
795  num_bytes = size_insert_.front().pos - curr_pos;
796  }
797  output_->Append(static_cast<const char*>(data), num_bytes);
798  if (num_bytes < length) {
799  input_stream.BackUp(length - num_bytes);
800  }
801  curr_pos += num_bytes;
802  // Insert the size field.
803  // size_insert_.front(): the next <index, size> pair to be written.
804  // size_insert_.front().pos: position of the size field.
805  // size_insert_.front().size: the size (integer) to be inserted.
806  if (!size_insert_.empty() && curr_pos == size_insert_.front().pos) {
807  // Varint32 occupies at most 10 bytes.
808  uint8 insert_buffer[10];
809  uint8* insert_buffer_pos = CodedOutputStream::WriteVarint32ToArray(
810  size_insert_.front().size, insert_buffer);
811  output_->Append(reinterpret_cast<const char*>(insert_buffer),
812  insert_buffer_pos - insert_buffer);
813  size_insert_.pop_front();
814  }
815  }
816  output_->Flush();
817  stream_.reset(new CodedOutputStream(&adapter_));
818  done_ = true;
819 }
820 
823  static_cast<WireFormatLite::FieldType>(field.kind()));
824  stream_->WriteTag(WireFormatLite::MakeTag(field.number(), wire_type));
825 }
826 
827 
828 } // namespace converter
829 } // namespace util
830 } // namespace protobuf
831 } // namespace google
google::protobuf::util::converter::ProtoWriter::EndList
ProtoWriter * EndList() override
Definition: proto_writer.cc:525
google::protobuf::util::converter::ProtoWriter::ignore_unknown_fields_
bool ignore_unknown_fields_
Definition: proto_writer.h:325
google::protobuf::util::converter::ErrorListener::InvalidValue
virtual void InvalidValue(const LocationTrackerInterface &loc, StringPiece type_name, StringPiece value)=0
google::protobuf::util::converter::ErrorListener::InvalidName
virtual void InvalidName(const LocationTrackerInterface &loc, StringPiece invalid_name, StringPiece message)=0
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
SYNTAX_PROTO3
@ SYNTAX_PROTO3
Definition: type.pb.h:157
google::protobuf::util::converter::ProtoWriter::ValidOneof
bool ValidOneof(const google::protobuf::Field &field, StringPiece unnormalized_name)
Definition: proto_writer.cc:554
google::protobuf.internal::WireFormatLite::WireTypeForFieldType
static WireFormatLite::WireType WireTypeForFieldType(WireFormatLite::FieldType type)
Definition: wire_format_lite.h:152
google::protobuf::util::converter::ProtoWriter::StartList
ProtoWriter * StartList(StringPiece name) override
Definition: proto_writer.cc:505
map_util.h
google::protobuf::util::converter::ProtoWriter::EndObject
ProtoWriter * EndObject() override
Definition: proto_writer.cc:486
google::protobuf::util::converter::ProtoWriter::location
const LocationTrackerInterface & location()
Definition: proto_writer.h:120
Field_Kind_TYPE_SFIXED64
@ Field_Kind_TYPE_SFIXED64
Definition: type.pb.h:103
google::protobuf.internal::WireFormatLite::WriteUInt64
static void WriteUInt64(int field_number, uint64 value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:420
wire_format_lite.h
google::protobuf::util::converter::ProtoWriter::element
ProtoElement * element() override
Definition: proto_writer.h:248
google::protobuf::util::converter::ProtoWriter::ProtoElement
Definition: proto_writer.h:158
google::protobuf::Enum
stream
GLuint GLuint stream
Definition: glcorearb.h:3946
google::protobuf::util::StatusOr::ValueOrDie
const T & ValueOrDie() const
Definition: statusor.h:251
google::protobuf::StrCat
string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: strutil.cc:1480
google::protobuf::util::converter::TypeInfo::GetEnumByTypeUrl
virtual const google::protobuf::Enum * GetEnumByTypeUrl(StringPiece type_url) const =0
length
GLenum GLuint GLenum GLsizei length
Definition: glcorearb.h:2695
google::protobuf::util::converter::ProtoWriter::done_
bool done_
Definition: proto_writer.h:322
google::protobuf::uint8
uint8_t uint8
Definition: protobuf/src/google/protobuf/stubs/port.h:153
google::protobuf::util::converter::ProtoWriter::MissingField
void MissingField(StringPiece missing_name)
Definition: proto_writer.cc:450
Field_Kind_TYPE_FIXED32
@ Field_Kind_TYPE_FIXED32
Definition: type.pb.h:94
Field_Kind_TYPE_SFIXED32
@ Field_Kind_TYPE_SFIXED32
Definition: type.pb.h:102
google::protobuf::util::converter::ProtoWriter::use_lower_camel_for_enums_
bool use_lower_camel_for_enums_
Definition: proto_writer.h:332
GOOGLE_DCHECK
#define GOOGLE_DCHECK
Definition: logging.h:194
s
XmlRpcServer s
Field_Cardinality_CARDINALITY_REQUIRED
@ Field_Cardinality_CARDINALITY_REQUIRED
Definition: type.pb.h:131
google::protobuf::util::StatusOr::status
const Status & status() const
Definition: statusor.h:241
google::protobuf::util::converter::ProtoWriter::InvalidName
void InvalidName(StringPiece unknown_name, StringPiece message)
Definition: proto_writer.cc:440
Field_Kind_TYPE_MESSAGE
@ Field_Kind_TYPE_MESSAGE
Definition: type.pb.h:98
Field_Kind_TYPE_UINT32
@ Field_Kind_TYPE_UINT32
Definition: type.pb.h:100
google::protobuf::util::converter::ProtoWriter::WriteTag
void WriteTag(const google::protobuf::Field &field)
Definition: proto_writer.cc:821
google::protobuf::CEscape
string CEscape(const string &src)
Definition: strutil.cc:615
google::protobuf.internal::WireFormatLite::WriteUInt32
static void WriteUInt32(int field_number, uint32 value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:415
statusor.h
google::protobuf::util::converter::ProtoWriter::StartListField
ProtoWriter * StartListField(const google::protobuf::Field &field, const google::protobuf::Type &type)
Definition: proto_writer.cc:584
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
object_location_tracker.h
Field_Kind_TYPE_DOUBLE
@ Field_Kind_TYPE_DOUBLE
Definition: type.pb.h:88
enum_type
zend_class_entry * enum_type
Definition: php/ext/google/protobuf/message.c:1904
google::protobuf::util::converter::ToSnakeCase
std::string ToSnakeCase(StringPiece input)
Definition: utility.cc:293
utility.h
google::protobuf::util::converter::ProtoWriter::ProtoElement::RegisterField
void RegisterField(const google::protobuf::Field *field)
Definition: proto_writer.cc:381
google::protobuf::util::converter::ProtoWriter::ProtoWriter
ProtoWriter(TypeResolver *type_resolver, const google::protobuf::Type &type, strings::ByteSink *output, ErrorListener *listener)
Definition: proto_writer.cc:62
google::protobuf::io::CodedOutputStream::WriteVarint32ToArray
static uint8 * WriteVarint32ToArray(uint32 value, uint8 *target)
Definition: coded_stream.h:1149
Field_Kind_TYPE_GROUP
@ Field_Kind_TYPE_GROUP
Definition: type.pb.h:97
google::protobuf.internal::WireFormatLite::WriteDouble
static void WriteDouble(int field_number, double value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:460
google::protobuf::util::converter::ProtoWriter::size_insert_
std::deque< SizeInfo > size_insert_
Definition: proto_writer.h:343
google::protobuf::util::converter::ProtoWriter::ProtoElement::pop
ProtoElement * pop()
Definition: proto_writer.cc:347
google::protobuf::util::converter::TypeInfo::GetTypeByTypeUrl
virtual const google::protobuf::Type * GetTypeByTypeUrl(StringPiece type_url) const =0
output_
std::string output_
Definition: text_format.cc:1531
Field_Kind_TYPE_SINT64
@ Field_Kind_TYPE_SINT64
Definition: type.pb.h:105
b
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:3228
google::protobuf::io::ArrayInputStream::BackUp
void BackUp(int count) override
Definition: zero_copy_stream_impl_lite.cc:79
google::protobuf.internal::WireFormatLite::WriteBytes
static void WriteBytes(int field_number, const std::string &value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:493
google::protobuf::int32
int32_t int32
Definition: protobuf/src/google/protobuf/stubs/port.h:150
i32
UNITY_INT32 i32
Definition: unity.c:1225
Field_Kind_TYPE_SINT32
@ Field_Kind_TYPE_SINT32
Definition: type.pb.h:104
google::protobuf.internal::WireFormatLite::WriteBool
static void WriteBool(int field_number, bool value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:465
google::protobuf::util::converter::ProtoWriter::StartObjectField
ProtoWriter * StartObjectField(const google::protobuf::Field &field, const google::protobuf::Type &type)
Definition: proto_writer.cc:577
Field_Kind_TYPE_INT64
@ Field_Kind_TYPE_INT64
Definition: type.pb.h:90
google::protobuf::util::converter::ProtoWriter::~ProtoWriter
~ProtoWriter() override
Definition: proto_writer.cc:104
strutil.h
google::protobuf::StringPiece::empty
bool empty() const
Definition: stringpiece.h:250
google::protobuf::util::TypeResolver
Definition: type_resolver.h:52
google::protobuf::util::converter::ProtoWriter::LookupType
const google::protobuf::Type * LookupType(const google::protobuf::Field *field)
Definition: proto_writer.cc:768
google::protobuf::util::converter::ProtoWriter::ProtoElement::array_index_
int array_index_
Definition: proto_writer.h:230
google::protobuf.internal::WireFormatLite::WriteFixed32
static void WriteFixed32(int field_number, uint32 value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:435
google::protobuf::StringPiece
Definition: stringpiece.h:180
google::protobuf::util::converter::ProtoWriter::ProtoElement::required_fields_
std::set< const google::protobuf::Field * > required_fields_
Definition: proto_writer.h:226
google::protobuf.internal::WireFormatLite::WriteString
static void WriteString(int field_number, const std::string &value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:476
Field_Kind_TYPE_INT32
@ Field_Kind_TYPE_INT32
Definition: type.pb.h:92
google::protobuf::io::CodedOutputStream::VarintSize32
static size_t VarintSize32(uint32 value)
Definition: coded_stream.h:1245
Field_Kind_TYPE_BOOL
@ Field_Kind_TYPE_BOOL
Definition: type.pb.h:95
time.h
google::protobuf::util::converter::ProtoWriter::ProtoElement::type_
const google::protobuf::Type & type_
Definition: proto_writer.h:225
google::protobuf::io::ArrayInputStream
Definition: zero_copy_stream_impl_lite.h:65
google::protobuf::util::converter::TypeInfo
Definition: type_info.h:49
field_mask_utility.h
Field_Kind_TYPE_FIXED64
@ Field_Kind_TYPE_FIXED64
Definition: type.pb.h:93
Field_Cardinality_CARDINALITY_REPEATED
@ Field_Cardinality_CARDINALITY_REPEATED
Definition: type.pb.h:132
google::protobuf.internal::WireFormatLite::FieldType
FieldType
Definition: wire_format_lite.h:111
google::protobuf::util::converter::ProtoWriter::ProtoElement::parent_field_
const google::protobuf::Field * parent_field_
Definition: proto_writer.h:211
google::protobuf.internal::WireFormatLite::MakeTag
constexpr static uint32 MakeTag(int field_number, WireType type)
Definition: wire_format_lite.h:768
d
d
google::protobuf.internal::WireFormatLite::WriteInt64
static void WriteInt64(int field_number, int64 value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:410
google::protobuf.internal::WireFormatLite::WriteFloat
static void WriteFloat(int field_number, float value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:455
google::protobuf::util::converter::ProtoWriter::WriteRootMessage
void WriteRootMessage()
Definition: proto_writer.cc:776
Field_Kind_TYPE_UNKNOWN
@ Field_Kind_TYPE_UNKNOWN
Definition: type.pb.h:87
google::protobuf::util::converter::TypeInfo::FindField
virtual const google::protobuf::Field * FindField(const google::protobuf::Type *type, StringPiece camel_case_name) const =0
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
google::protobuf::util::converter::ProtoWriter::ProtoElement::parent_field
const google::protobuf::Field * parent_field() const
Definition: proto_writer.h:180
google::protobuf::util::error::INVALID_ARGUMENT
@ INVALID_ARGUMENT
Definition: status.h:50
google::protobuf::util::converter::ProtoWriter::BeginNamed
const google::protobuf::Field * BeginNamed(StringPiece name, bool is_list)
Definition: proto_writer.cc:723
google::protobuf::util::converter::ProtoWriter::RenderDataPiece
virtual ProtoWriter * RenderDataPiece(StringPiece name, const DataPiece &value)
Definition: proto_writer.cc:534
google::protobuf::util::converter::ProtoWriter
Definition: proto_writer.h:67
google::protobuf::util::converter::ProtoWriter::case_insensitive_enum_parsing_
bool case_insensitive_enum_parsing_
Definition: proto_writer.h:335
google::protobuf::util::converter::ProtoWriter::invalid_depth_
int invalid_depth_
Definition: proto_writer.h:360
google::protobuf::util::StatusOr
Definition: statusor.h:99
google::protobuf::io::CodedOutputStream
Definition: coded_stream.h:693
aditof::Status
Status
Status of any operation that the TOF sdk performs.
Definition: status_definitions.h:48
google::protobuf::util::converter::StructuredObjectWriter::BaseElement
Definition: structured_objectwriter.h:68
Field_Kind_TYPE_UINT64
@ Field_Kind_TYPE_UINT64
Definition: type.pb.h:91
i
int i
Definition: gmock-matchers_test.cc:764
google::protobuf::util::Status::ok
bool ok() const
Definition: status.h:87
Field
struct Field Field
Definition: php/ext/google/protobuf/protobuf.h:638
google::protobuf.internal::WireFormatLite::WriteSInt64
static void WriteSInt64(int field_number, int64 value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:430
google::protobuf::io::ArrayInputStream::Next
bool Next(const void **data, int *size) override
Definition: zero_copy_stream_impl_lite.cc:65
type
GLenum type
Definition: glcorearb.h:2695
google::protobuf.internal::WireFormatLite::WriteEnum
static void WriteEnum(int field_number, int value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:470
google::protobuf::util::converter::ProtoWriter::ProtoElement::ow_
ProtoWriter * ow_
Definition: proto_writer.h:207
google::protobuf::util::converter::ProtoWriter::stream_
std::unique_ptr< io::CodedOutputStream > stream_
Definition: proto_writer.h:353
google::protobuf::util::converter::ProtoWriter::WriteEnum
static util::Status WriteEnum(int field_number, const DataPiece &data, const google::protobuf::Enum *enum_type, io::CodedOutputStream *stream, bool use_lower_camel_for_enums, bool case_insensitive_enum_parsing, bool ignore_unknown_values)
Definition: proto_writer.cc:590
google::protobuf::util::converter::ProtoWriter::ProtoElement::ToString
std::string ToString() const override
Definition: proto_writer.cc:390
google::protobuf::util::converter::ProtoWriter::ProtoElement::type
const google::protobuf::Type & type() const
Definition: proto_writer.h:183
google::protobuf::util::converter::ProtoWriter::output_
strings::ByteSink * output_
Definition: proto_writer.h:350
google::protobuf::util::converter::ProtoWriter::SizeInfo
Definition: proto_writer.h:240
proto_writer.h
google::protobuf::util::Status::message
StringPiece message() const
Definition: status.h:99
google::protobuf.internal::WireFormatLite::WriteSFixed64
static void WriteSFixed64(int field_number, int64 value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:450
size
GLsizeiptr size
Definition: glcorearb.h:2943
constants.h
pop
static upb_refcounted * pop(tarjan *t)
Definition: ruby/ext/google/protobuf_c/upb.c:5904
google::protobuf::util::converter::ObjectLocationTracker
Definition: object_location_tracker.h:45
Field_Kind_TYPE_STRING
@ Field_Kind_TYPE_STRING
Definition: type.pb.h:96
once.h
google::protobuf::util::converter::ProtoWriter::ProtoElement::ProtoElement
ProtoElement(const TypeInfo *typeinfo, const google::protobuf::Type &type, ProtoWriter *enclosing)
Definition: proto_writer.cc:288
google::protobuf::util::converter::ProtoWriter::ignore_unknown_enum_values_
bool ignore_unknown_enum_values_
Definition: proto_writer.h:328
google::protobuf::util::converter::ProtoWriter::StartObject
ProtoWriter * StartObject(StringPiece name) override
Definition: proto_writer.cc:454
google::protobuf::util::Status
Definition: status.h:67
type_resolver
TypeResolver * type_resolver
Definition: conformance_cpp.cc:97
google::protobuf::ascii_isalnum
bool ascii_isalnum(char c)
Definition: strutil.h:67
Field_Kind_TYPE_FLOAT
@ Field_Kind_TYPE_FLOAT
Definition: type.pb.h:89
google::protobuf::util::converter::ProtoWriter::element_
std::unique_ptr< ProtoElement > element_
Definition: proto_writer.h:342
google::protobuf.internal::WireFormatLite::WireType
WireType
Definition: wire_format_lite.h:101
google::protobuf::util::converter::ProtoWriter::IsRepeated
bool IsRepeated(const google::protobuf::Field &field)
Definition: proto_writer.cc:572
google::protobuf::util::converter::ProtoWriter::buffer_
std::string buffer_
Definition: proto_writer.h:351
Type
struct Type Type
Definition: php/ext/google/protobuf/protobuf.h:664
google::protobuf::util::converter::ProtoWriter::ProtoElement::parent
ProtoElement * parent() const override
Definition: proto_writer.h:191
google::protobuf::util::StatusOr::ok
bool ok() const
Definition: statusor.h:246
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
google::protobuf::util::converter::ProtoWriter::ProtoElement::IsOneofIndexTaken
bool IsOneofIndexTaken(int32 index)
Definition: proto_writer.cc:432
google::protobuf.internal::WireFormatLite::WriteSInt32
static void WriteSInt32(int field_number, int32 value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:425
google::protobuf::util::converter::ProtoWriter::InvalidValue
void InvalidValue(StringPiece type_name, StringPiece value)
Definition: proto_writer.cc:445
true
#define true
Definition: cJSON.c:65
Field_Kind_Name
const std::string & Field_Kind_Name(T enum_t_value)
Definition: type.pb.h:116
buffer_
static uint8 buffer_[kBufferSize]
Definition: coded_stream_unittest.cc:136
google::protobuf.internal::WireFormatLite::WriteFixed64
static void WriteFixed64(int field_number, uint64 value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:440
google::protobuf::util::converter::ProtoWriter::typeinfo_
const TypeInfo * typeinfo_
Definition: proto_writer.h:317
google::protobuf::util::converter::ProtoWriter::listener_
ErrorListener * listener_
Definition: proto_writer.h:359
f
GLfloat f
Definition: glcorearb.h:3964
google::protobuf::util::converter::ProtoWriter::adapter_
io::StringOutputStream adapter_
Definition: proto_writer.h:352
google::protobuf::util::converter::ProtoWriter::own_typeinfo_
bool own_typeinfo_
Definition: proto_writer.h:319
Field_Kind_TYPE_ENUM
@ Field_Kind_TYPE_ENUM
Definition: type.pb.h:101
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
google::protobuf::util::converter::ProtoWriter::ProtoElement::proto3_
bool proto3_
Definition: proto_writer.h:217
output
const upb_json_parsermethod const upb_symtab upb_sink * output
Definition: ruby/ext/google/protobuf_c/upb.h:10503
google::protobuf::util::converter::ProtoWriter::ProtoElement::TakeOneofIndex
void TakeOneofIndex(int32 index)
Definition: proto_writer.cc:436
google::protobuf::util::converter::DataPiece
Definition: datapiece.h:59
google::protobuf::util::converter::ProtoWriter::master_type_
const google::protobuf::Type & master_type_
Definition: proto_writer.h:316
false
#define false
Definition: cJSON.c:70
google::protobuf::util::converter::ProtoWriter::RenderPrimitiveField
ProtoWriter * RenderPrimitiveField(const google::protobuf::Field &field, const google::protobuf::Type &type, const DataPiece &value)
Definition: proto_writer.cc:606
Field_Kind_TYPE_BYTES
@ Field_Kind_TYPE_BYTES
Definition: type.pb.h:99
index
GLuint index
Definition: glcorearb.h:3055
google::protobuf::util::converter::StructuredObjectWriter::BaseElement::pop
ElementType * pop()
Definition: structured_objectwriter.h:77
google::protobuf::util::converter::ErrorListener
Definition: error_listener.h:53
google::protobuf.internal::WireFormatLite::WriteSFixed32
static void WriteSFixed32(int field_number, int32 value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:445
it
MapIter it
Definition: php/ext/google/protobuf/map.c:205
google
Definition: data_proto2_to_proto3_util.h:11
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695
google::protobuf::util::converter::ErrorListener::MissingField
virtual void MissingField(const LocationTrackerInterface &loc, StringPiece missing_name)=0
google::protobuf.internal::WireFormatLite::WriteInt32
static void WriteInt32(int field_number, int32 value, io::CodedOutputStream *output)
Definition: wire_format_lite.cc:405
google::protobuf::util::converter::ProtoWriter::Lookup
const google::protobuf::Field * Lookup(StringPiece name)
Definition: proto_writer.cc:743
google::protobuf::StrAppend
void StrAppend(string *result, const AlphaNum &a)
Definition: strutil.cc:1581


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:57