~ubuntu-branches/debian/stretch/protobuf/stretch

« back to all changes in this revision

Viewing changes to src/google/protobuf/io/coded_stream.h

  • Committer: Package Import Robot
  • Author(s): Robert S. Edmonds
  • Date: 2014-09-11 22:50:10 UTC
  • mfrom: (10.1.9 experimental)
  • Revision ID: package-import@ubuntu.com-20140911225010-wt4yo9dpc1fzuq5g
Tags: 2.6.0-3
Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
233
233
  // Read a tag.  This calls ReadVarint32() and returns the result, or returns
234
234
  // zero (which is not a valid tag) if ReadVarint32() fails.  Also, it updates
235
235
  // the last tag value, which can be checked with LastTagWas().
236
 
  // Always inline because this is only called in once place per parse loop
 
236
  // Always inline because this is only called in one place per parse loop
237
237
  // but it is called for every iteration of said loop, so it should be fast.
238
238
  // GCC doesn't want to inline this by default.
239
239
  uint32 ReadTag() GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
240
240
 
 
241
  // This usually a faster alternative to ReadTag() when cutoff is a manifest
 
242
  // constant.  It does particularly well for cutoff >= 127.  The first part
 
243
  // of the return value is the tag that was read, though it can also be 0 in
 
244
  // the cases where ReadTag() would return 0.  If the second part is true
 
245
  // then the tag is known to be in [0, cutoff].  If not, the tag either is
 
246
  // above cutoff or is 0.  (There's intentional wiggle room when tag is 0,
 
247
  // because that can arise in several ways, and for best performance we want
 
248
  // to avoid an extra "is tag == 0?" check here.)
 
249
  inline std::pair<uint32, bool> ReadTagWithCutoff(uint32 cutoff)
 
250
      GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
 
251
 
241
252
  // Usually returns true if calling ReadVarint32() now would produce the given
242
253
  // value.  Will always return false if ReadVarint32() would not return the
243
254
  // given value.  If ExpectTag() returns true, it also advances past
264
275
  // zero, and ConsumedEntireMessage() will return true.
265
276
  bool ExpectAtEnd();
266
277
 
267
 
  // If the last call to ReadTag() returned the given value, returns true.
268
 
  // Otherwise, returns false;
 
278
  // If the last call to ReadTag() or ReadTagWithCutoff() returned the
 
279
  // given value, returns true.  Otherwise, returns false;
269
280
  //
270
281
  // This is needed because parsers for some types of embedded messages
271
282
  // (with field type TYPE_GROUP) don't actually know that they've reached the
333
344
  // cause integer overflows is 512MB.  The default limit is 64MB.  Apps
334
345
  // should set shorter limits if possible.  If warning_threshold is not -1,
335
346
  // a warning will be printed to stderr after warning_threshold bytes are
336
 
  // read.  For backwards compatibility all negative values get squached to -1,
 
347
  // read.  For backwards compatibility all negative values get squashed to -1,
337
348
  // as other negative values might have special internal meanings.
338
349
  // An error will always be printed to stderr if the limit is reached.
339
350
  //
356
367
  //   something unusual.
357
368
  void SetTotalBytesLimit(int total_bytes_limit, int warning_threshold);
358
369
 
 
370
  // The Total Bytes Limit minus the Current Position, or -1 if there
 
371
  // is no Total Bytes Limit.
 
372
  int BytesUntilTotalBytesLimit() const;
 
373
 
359
374
  // Recursion Limit -------------------------------------------------
360
375
  // To prevent corrupt or malicious messages from causing stack overflows,
361
376
  // we must keep track of the depth of recursion when parsing embedded
466
481
  int overflow_bytes_;
467
482
 
468
483
  // LastTagWas() stuff.
469
 
  uint32 last_tag_;         // result of last ReadTag().
 
484
  uint32 last_tag_;         // result of last ReadTag() or ReadTagWithCutoff().
470
485
 
471
486
  // This is set true by ReadTag{Fallback/Slow}() if it is called when exactly
472
487
  // at EOF, or by ExpectAtEnd() when it returns true.  This happens when we
638
653
 
639
654
  // Write raw bytes, copying them from the given buffer.
640
655
  void WriteRaw(const void* buffer, int size);
 
656
  // Like WriteRaw()  but will try to write aliased data if aliasing is
 
657
  // turned on.
 
658
  void WriteRawMaybeAliased(const void* data, int size);
641
659
  // Like WriteRaw()  but writing directly to the target array.
642
660
  // This is _not_ inlined, as the compiler often optimizes memcpy into inline
643
661
  // copy loops. Since this gets called by every field with string or bytes
649
667
  void WriteString(const string& str);
650
668
  // Like WriteString()  but writing directly to the target array.
651
669
  static uint8* WriteStringToArray(const string& str, uint8* target);
652
 
 
 
670
  // Write the varint-encoded size of str followed by str.
 
671
  static uint8* WriteStringWithSizeToArray(const string& str, uint8* target);
 
672
 
 
673
 
 
674
  // Instructs the CodedOutputStream to allow the underlying
 
675
  // ZeroCopyOutputStream to hold pointers to the original structure instead of
 
676
  // copying, if it supports it (i.e. output->AllowsAliasing() is true).  If the
 
677
  // underlying stream does not support aliasing, then enabling it has no
 
678
  // affect.  For now, this only affects the behavior of
 
679
  // WriteRawMaybeAliased().
 
680
  //
 
681
  // NOTE: It is caller's responsibility to ensure that the chunk of memory
 
682
  // remains live until all of the data has been consumed from the stream.
 
683
  void EnableAliasing(bool enabled);
653
684
 
654
685
  // Write a 32-bit little-endian integer.
655
686
  void WriteLittleEndian32(uint32 value);
725
756
  int buffer_size_;
726
757
  int total_bytes_;  // Sum of sizes of all buffers seen so far.
727
758
  bool had_error_;   // Whether an error occurred during output.
 
759
  bool aliasing_enabled_;  // See EnableAliasing().
728
760
 
729
761
  // Advance the buffer by a given number of bytes.
730
762
  void Advance(int amount);
733
765
  // Advance(buffer_size_).
734
766
  bool Refresh();
735
767
 
 
768
  // Like WriteRaw() but may avoid copying if the underlying
 
769
  // ZeroCopyOutputStream supports it.
 
770
  void WriteAliasedRaw(const void* buffer, int size);
 
771
 
736
772
  static uint8* WriteVarint32FallbackToArray(uint32 value, uint8* target);
737
773
 
738
774
  // Always-inlined versions of WriteVarint* functions so that code can be
850
886
  }
851
887
}
852
888
 
 
889
inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoff(
 
890
    uint32 cutoff) {
 
891
  // In performance-sensitive code we can expect cutoff to be a compile-time
 
892
  // constant, and things like "cutoff >= kMax1ByteVarint" to be evaluated at
 
893
  // compile time.
 
894
  if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) {
 
895
    // Hot case: buffer_ non_empty, buffer_[0] in [1, 128).
 
896
    // TODO(gpike): Is it worth rearranging this? E.g., if the number of fields
 
897
    // is large enough then is it better to check for the two-byte case first?
 
898
    if (static_cast<int8>(buffer_[0]) > 0) {
 
899
      const uint32 kMax1ByteVarint = 0x7f;
 
900
      uint32 tag = last_tag_ = buffer_[0];
 
901
      Advance(1);
 
902
      return make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff);
 
903
    }
 
904
    // Other hot case: cutoff >= 0x80, buffer_ has at least two bytes available,
 
905
    // and tag is two bytes.  The latter is tested by bitwise-and-not of the
 
906
    // first byte and the second byte.
 
907
    if (cutoff >= 0x80 &&
 
908
        GOOGLE_PREDICT_TRUE(buffer_ + 1 < buffer_end_) &&
 
909
        GOOGLE_PREDICT_TRUE((buffer_[0] & ~buffer_[1]) >= 0x80)) {
 
910
      const uint32 kMax2ByteVarint = (0x7f << 7) + 0x7f;
 
911
      uint32 tag = last_tag_ = (1u << 7) * buffer_[1] + (buffer_[0] - 0x80);
 
912
      Advance(2);
 
913
      // It might make sense to test for tag == 0 now, but it is so rare that
 
914
      // that we don't bother.  A varint-encoded 0 should be one byte unless
 
915
      // the encoder lost its mind.  The second part of the return value of
 
916
      // this function is allowed to be either true or false if the tag is 0,
 
917
      // so we don't have to check for tag == 0.  We may need to check whether
 
918
      // it exceeds cutoff.
 
919
      bool at_or_below_cutoff = cutoff >= kMax2ByteVarint || tag <= cutoff;
 
920
      return make_pair(tag, at_or_below_cutoff);
 
921
    }
 
922
  }
 
923
  // Slow path
 
924
  last_tag_ = ReadTagFallback();
 
925
  return make_pair(last_tag_, static_cast<uint32>(last_tag_ - 1) < cutoff);
 
926
}
 
927
 
853
928
inline bool CodedInputStream::LastTagWas(uint32 expected) {
854
929
  return last_tag_ == expected;
855
930
}
1029
1104
  WriteRaw(str.data(), static_cast<int>(str.size()));
1030
1105
}
1031
1106
 
 
1107
inline void CodedOutputStream::WriteRawMaybeAliased(
 
1108
    const void* data, int size) {
 
1109
  if (aliasing_enabled_) {
 
1110
    WriteAliasedRaw(data, size);
 
1111
  } else {
 
1112
    WriteRaw(data, size);
 
1113
  }
 
1114
}
 
1115
 
1032
1116
inline uint8* CodedOutputStream::WriteStringToArray(
1033
1117
    const string& str, uint8* target) {
1034
1118
  return WriteRawToArray(str.data(), static_cast<int>(str.size()), target);