File indexing completed on 2025-01-31 10:12:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 #ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
0087 #define GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
0088
0089 #include <assert.h>
0090
0091 #include <atomic>
0092 #include <climits>
0093 #include <cstddef>
0094 #include <cstdint>
0095 #include <cstring>
0096 #include <limits>
0097 #include <string>
0098 #include <type_traits>
0099 #include <utility>
0100
0101 #if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
0102
0103
0104 #pragma runtime_checks("c", off)
0105 #endif
0106
0107
0108 #include "google/protobuf/stubs/common.h"
0109 #include "absl/base/attributes.h"
0110 #include "absl/log/absl_check.h"
0111 #include "absl/numeric/bits.h"
0112 #include "absl/strings/cord.h"
0113 #include "absl/strings/string_view.h"
0114 #include "google/protobuf/port.h"
0115
0116
0117
0118 #include "google/protobuf/port_def.inc"
0119
0120 namespace google {
0121 namespace protobuf {
0122
0123 class DescriptorPool;
0124 class MessageFactory;
0125 class ZeroCopyCodedInputStream;
0126
0127 namespace internal {
0128 void MapTestForceDeterministic();
0129 class EpsCopyByteStream;
0130 }
0131
0132 namespace io {
0133
0134
0135 class CodedInputStream;
0136 class CodedOutputStream;
0137
0138
0139 class ZeroCopyInputStream;
0140 class ZeroCopyOutputStream;
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151 class PROTOBUF_EXPORT CodedInputStream {
0152 public:
0153
0154 explicit CodedInputStream(ZeroCopyInputStream* input);
0155
0156
0157
0158
0159 explicit CodedInputStream(const uint8_t* buffer, int size);
0160 CodedInputStream(const CodedInputStream&) = delete;
0161 CodedInputStream& operator=(const CodedInputStream&) = delete;
0162
0163
0164
0165
0166
0167
0168 ~CodedInputStream();
0169
0170
0171
0172 inline bool IsFlat() const;
0173
0174
0175
0176 inline bool Skip(int count);
0177
0178
0179
0180
0181
0182
0183
0184
0185 bool GetDirectBufferPointer(const void** data, int* size);
0186
0187
0188
0189 PROTOBUF_ALWAYS_INLINE
0190 void GetDirectBufferPointerInline(const void** data, int* size);
0191
0192
0193 bool ReadRaw(void* buffer, int size);
0194
0195
0196 bool ReadString(std::string* buffer, int size);
0197
0198
0199 bool ReadCord(absl::Cord* output, int size);
0200
0201
0202
0203 bool ReadLittleEndian32(uint32_t* value);
0204
0205 bool ReadLittleEndian64(uint64_t* value);
0206
0207
0208
0209
0210 static const uint8_t* ReadLittleEndian32FromArray(const uint8_t* buffer,
0211 uint32_t* value);
0212
0213 static const uint8_t* ReadLittleEndian64FromArray(const uint8_t* buffer,
0214 uint64_t* value);
0215
0216
0217
0218
0219 bool ReadVarint32(uint32_t* value);
0220
0221 bool ReadVarint64(uint64_t* value);
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232 bool ReadVarintSizeAsInt(int* value);
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242 PROTOBUF_ALWAYS_INLINE uint32_t ReadTag() {
0243 return last_tag_ = ReadTagNoLastTag();
0244 }
0245
0246 PROTOBUF_ALWAYS_INLINE uint32_t ReadTagNoLastTag();
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256 PROTOBUF_ALWAYS_INLINE
0257 std::pair<uint32_t, bool> ReadTagWithCutoff(uint32_t cutoff) {
0258 std::pair<uint32_t, bool> result = ReadTagWithCutoffNoLastTag(cutoff);
0259 last_tag_ = result.first;
0260 return result;
0261 }
0262
0263 PROTOBUF_ALWAYS_INLINE
0264 std::pair<uint32_t, bool> ReadTagWithCutoffNoLastTag(uint32_t cutoff);
0265
0266
0267
0268
0269
0270
0271
0272
0273 PROTOBUF_ALWAYS_INLINE bool ExpectTag(uint32_t expected);
0274
0275
0276
0277
0278
0279
0280
0281
0282 PROTOBUF_ALWAYS_INLINE
0283 static const uint8_t* ExpectTagFromArray(const uint8_t* buffer,
0284 uint32_t expected);
0285
0286
0287
0288
0289
0290 bool ExpectAtEnd();
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303 bool LastTagWas(uint32_t expected);
0304 void SetLastTag(uint32_t tag) { last_tag_ = tag; }
0305
0306
0307
0308
0309
0310
0311
0312 bool ConsumedEntireMessage();
0313 void SetConsumed() { legitimate_message_end_ = true; }
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325 typedef int Limit;
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338 Limit PushLimit(int byte_limit);
0339
0340
0341
0342 void PopLimit(Limit limit);
0343
0344
0345
0346 int BytesUntilLimit() const;
0347
0348
0349 int CurrentPosition() const;
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368 void SetTotalBytesLimit(int total_bytes_limit);
0369
0370
0371
0372 int BytesUntilTotalBytesLimit() const;
0373
0374
0375
0376
0377
0378
0379
0380
0381 void SetRecursionLimit(int limit);
0382 int RecursionBudget() { return recursion_budget_; }
0383
0384 static int GetDefaultRecursionLimit() { return default_recursion_limit_; }
0385
0386
0387
0388 bool IncrementRecursionDepth();
0389
0390
0391 void DecrementRecursionDepth();
0392
0393
0394
0395
0396 void UnsafeDecrementRecursionDepth();
0397
0398
0399
0400
0401
0402
0403 std::pair<CodedInputStream::Limit, int> IncrementRecursionDepthAndPushLimit(
0404 int byte_limit);
0405
0406
0407 Limit ReadLengthAndPushLimit();
0408
0409
0410
0411
0412
0413
0414
0415
0416 bool DecrementRecursionDepthAndPopLimit(Limit limit);
0417
0418
0419
0420
0421
0422
0423 bool CheckEntireMessageConsumedAndPopLimit(Limit limit);
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493 void SetExtensionRegistry(const DescriptorPool* pool,
0494 MessageFactory* factory);
0495
0496
0497
0498 const DescriptorPool* GetExtensionPool();
0499
0500
0501
0502 MessageFactory* GetExtensionFactory();
0503
0504 private:
0505 const uint8_t* buffer_;
0506 const uint8_t* buffer_end_;
0507 ZeroCopyInputStream* input_;
0508 int total_bytes_read_;
0509
0510
0511
0512
0513 int overflow_bytes_;
0514
0515
0516 uint32_t last_tag_;
0517
0518
0519
0520
0521 bool legitimate_message_end_;
0522
0523
0524 bool aliasing_enabled_;
0525
0526
0527 bool force_eager_parsing_;
0528
0529
0530 Limit current_limit_;
0531
0532
0533
0534
0535
0536
0537
0538
0539 int buffer_size_after_limit_;
0540
0541
0542
0543 int total_bytes_limit_;
0544
0545
0546
0547
0548 int recursion_budget_;
0549
0550 int recursion_limit_;
0551
0552
0553 const DescriptorPool* extension_pool_;
0554 MessageFactory* extension_factory_;
0555
0556
0557
0558
0559 bool SkipFallback(int count, int original_buffer_size);
0560
0561
0562 void Advance(int amount);
0563
0564
0565 void BackUpInputToCurrentPosition();
0566
0567
0568
0569 void RecomputeBufferLimits();
0570
0571
0572 void PrintTotalBytesLimitError();
0573
0574
0575
0576 bool Refresh();
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589 int64_t ReadVarint32Fallback(uint32_t first_byte_or_zero);
0590 int ReadVarintSizeAsIntFallback();
0591 std::pair<uint64_t, bool> ReadVarint64Fallback();
0592 bool ReadVarint32Slow(uint32_t* value);
0593 bool ReadVarint64Slow(uint64_t* value);
0594 int ReadVarintSizeAsIntSlow();
0595 bool ReadLittleEndian32Fallback(uint32_t* value);
0596 bool ReadLittleEndian64Fallback(uint64_t* value);
0597
0598
0599
0600
0601 uint32_t ReadTagFallback(uint32_t first_byte_or_zero);
0602 uint32_t ReadTagSlow();
0603 bool ReadStringFallback(std::string* buffer, int size);
0604
0605
0606 int BufferSize() const;
0607
0608 static const int kDefaultTotalBytesLimit = INT_MAX;
0609
0610 static int default_recursion_limit_;
0611
0612 friend class google::protobuf::ZeroCopyCodedInputStream;
0613 friend class google::protobuf::internal::EpsCopyByteStream;
0614 };
0615
0616
0617
0618
0619
0620
0621
0622 class PROTOBUF_EXPORT EpsCopyOutputStream {
0623 public:
0624 enum { kSlopBytes = 16 };
0625
0626
0627 EpsCopyOutputStream(ZeroCopyOutputStream* stream, bool deterministic,
0628 uint8_t** pp)
0629 : end_(buffer_),
0630 stream_(stream),
0631 is_serialization_deterministic_(deterministic) {
0632 *pp = buffer_;
0633 }
0634
0635
0636
0637
0638 EpsCopyOutputStream(void* data, int size, bool deterministic)
0639 : end_(static_cast<uint8_t*>(data) + size),
0640 buffer_end_(nullptr),
0641 stream_(nullptr),
0642 is_serialization_deterministic_(deterministic) {}
0643
0644
0645 EpsCopyOutputStream(void* data, int size, ZeroCopyOutputStream* stream,
0646 bool deterministic, uint8_t** pp)
0647 : stream_(stream), is_serialization_deterministic_(deterministic) {
0648 *pp = SetInitialBuffer(data, size);
0649 }
0650
0651
0652
0653 uint8_t* Trim(uint8_t* ptr);
0654
0655
0656
0657
0658 PROTOBUF_NODISCARD uint8_t* EnsureSpace(uint8_t* ptr) {
0659 if (PROTOBUF_PREDICT_FALSE(ptr >= end_)) {
0660 return EnsureSpaceFallback(ptr);
0661 }
0662 return ptr;
0663 }
0664
0665 uint8_t* WriteRaw(const void* data, int size, uint8_t* ptr) {
0666 if (PROTOBUF_PREDICT_FALSE(end_ - ptr < size)) {
0667 return WriteRawFallback(data, size, ptr);
0668 }
0669 std::memcpy(ptr, data, static_cast<unsigned int>(size));
0670 return ptr + size;
0671 }
0672
0673
0674
0675
0676 #ifndef NDEBUG
0677 PROTOBUF_NOINLINE
0678 #endif
0679 uint8_t* WriteRawMaybeAliased(const void* data, int size, uint8_t* ptr) {
0680 if (aliasing_enabled_) {
0681 return WriteAliasedRaw(data, size, ptr);
0682 } else {
0683 return WriteRaw(data, size, ptr);
0684 }
0685 }
0686
0687 uint8_t* WriteCord(const absl::Cord& cord, uint8_t* ptr);
0688
0689 #ifndef NDEBUG
0690 PROTOBUF_NOINLINE
0691 #endif
0692 uint8_t* WriteStringMaybeAliased(uint32_t num, const std::string& s,
0693 uint8_t* ptr) {
0694 std::ptrdiff_t size = s.size();
0695 if (PROTOBUF_PREDICT_FALSE(
0696 size >= 128 || end_ - ptr + 16 - TagSize(num << 3) - 1 < size)) {
0697 return WriteStringMaybeAliasedOutline(num, s, ptr);
0698 }
0699 ptr = UnsafeVarint((num << 3) | 2, ptr);
0700 *ptr++ = static_cast<uint8_t>(size);
0701 std::memcpy(ptr, s.data(), size);
0702 return ptr + size;
0703 }
0704 uint8_t* WriteBytesMaybeAliased(uint32_t num, const std::string& s,
0705 uint8_t* ptr) {
0706 return WriteStringMaybeAliased(num, s, ptr);
0707 }
0708
0709 template <typename T>
0710 PROTOBUF_ALWAYS_INLINE uint8_t* WriteString(uint32_t num, const T& s,
0711 uint8_t* ptr) {
0712 std::ptrdiff_t size = s.size();
0713 if (PROTOBUF_PREDICT_FALSE(
0714 size >= 128 || end_ - ptr + 16 - TagSize(num << 3) - 1 < size)) {
0715 return WriteStringOutline(num, s, ptr);
0716 }
0717 ptr = UnsafeVarint((num << 3) | 2, ptr);
0718 *ptr++ = static_cast<uint8_t>(size);
0719 std::memcpy(ptr, s.data(), size);
0720 return ptr + size;
0721 }
0722
0723 uint8_t* WriteString(uint32_t num, const absl::Cord& s, uint8_t* ptr) {
0724 ptr = EnsureSpace(ptr);
0725 ptr = WriteTag(num, 2, ptr);
0726 return WriteCordOutline(s, ptr);
0727 }
0728
0729 template <typename T>
0730 #ifndef NDEBUG
0731 PROTOBUF_NOINLINE
0732 #endif
0733 uint8_t* WriteBytes(uint32_t num, const T& s, uint8_t* ptr) {
0734 return WriteString(num, s, ptr);
0735 }
0736
0737 template <typename T>
0738 PROTOBUF_ALWAYS_INLINE uint8_t* WriteInt32Packed(int num, const T& r,
0739 int size, uint8_t* ptr) {
0740 return WriteVarintPacked(num, r, size, ptr, Encode64);
0741 }
0742 template <typename T>
0743 PROTOBUF_ALWAYS_INLINE uint8_t* WriteUInt32Packed(int num, const T& r,
0744 int size, uint8_t* ptr) {
0745 return WriteVarintPacked(num, r, size, ptr, Encode32);
0746 }
0747 template <typename T>
0748 PROTOBUF_ALWAYS_INLINE uint8_t* WriteSInt32Packed(int num, const T& r,
0749 int size, uint8_t* ptr) {
0750 return WriteVarintPacked(num, r, size, ptr, ZigZagEncode32);
0751 }
0752 template <typename T>
0753 PROTOBUF_ALWAYS_INLINE uint8_t* WriteInt64Packed(int num, const T& r,
0754 int size, uint8_t* ptr) {
0755 return WriteVarintPacked(num, r, size, ptr, Encode64);
0756 }
0757 template <typename T>
0758 PROTOBUF_ALWAYS_INLINE uint8_t* WriteUInt64Packed(int num, const T& r,
0759 int size, uint8_t* ptr) {
0760 return WriteVarintPacked(num, r, size, ptr, Encode64);
0761 }
0762 template <typename T>
0763 PROTOBUF_ALWAYS_INLINE uint8_t* WriteSInt64Packed(int num, const T& r,
0764 int size, uint8_t* ptr) {
0765 return WriteVarintPacked(num, r, size, ptr, ZigZagEncode64);
0766 }
0767 template <typename T>
0768 PROTOBUF_ALWAYS_INLINE uint8_t* WriteEnumPacked(int num, const T& r, int size,
0769 uint8_t* ptr) {
0770 return WriteVarintPacked(num, r, size, ptr, Encode64);
0771 }
0772
0773 template <typename T>
0774 PROTOBUF_ALWAYS_INLINE uint8_t* WriteFixedPacked(int num, const T& r,
0775 uint8_t* ptr) {
0776 ptr = EnsureSpace(ptr);
0777 constexpr auto element_size = sizeof(typename T::value_type);
0778 auto size = r.size() * element_size;
0779 ptr = WriteLengthDelim(num, size, ptr);
0780 return WriteRawLittleEndian<element_size>(r.data(), static_cast<int>(size),
0781 ptr);
0782 }
0783
0784
0785
0786 bool HadError() const { return had_error_; }
0787
0788
0789
0790
0791
0792
0793
0794
0795
0796
0797 void EnableAliasing(bool enabled);
0798
0799
0800 void SetSerializationDeterministic(bool value) {
0801 is_serialization_deterministic_ = value;
0802 }
0803
0804
0805 bool IsSerializationDeterministic() const {
0806 return is_serialization_deterministic_;
0807 }
0808
0809
0810
0811 int64_t ByteCount(uint8_t* ptr) const;
0812
0813
0814 private:
0815 uint8_t* end_;
0816 uint8_t* buffer_end_ = buffer_;
0817 uint8_t buffer_[2 * kSlopBytes];
0818 ZeroCopyOutputStream* stream_;
0819 bool had_error_ = false;
0820 bool aliasing_enabled_ = false;
0821 bool is_serialization_deterministic_;
0822 bool skip_check_consistency = false;
0823
0824 uint8_t* EnsureSpaceFallback(uint8_t* ptr);
0825 inline uint8_t* Next();
0826 int Flush(uint8_t* ptr);
0827 std::ptrdiff_t GetSize(uint8_t* ptr) const {
0828 ABSL_DCHECK(ptr <= end_ + kSlopBytes);
0829 return end_ + kSlopBytes - ptr;
0830 }
0831
0832 uint8_t* Error() {
0833 had_error_ = true;
0834
0835 end_ = buffer_ + kSlopBytes;
0836 return buffer_;
0837 }
0838
0839 static constexpr int TagSize(uint32_t tag) {
0840 return (tag < (1 << 7)) ? 1
0841 : (tag < (1 << 14)) ? 2
0842 : (tag < (1 << 21)) ? 3
0843 : (tag < (1 << 28)) ? 4
0844 : 5;
0845 }
0846
0847 PROTOBUF_ALWAYS_INLINE uint8_t* WriteTag(uint32_t num, uint32_t wt,
0848 uint8_t* ptr) {
0849 ABSL_DCHECK(ptr < end_);
0850 return UnsafeVarint((num << 3) | wt, ptr);
0851 }
0852
0853 PROTOBUF_ALWAYS_INLINE uint8_t* WriteLengthDelim(int num, uint32_t size,
0854 uint8_t* ptr) {
0855 ptr = WriteTag(num, 2, ptr);
0856 return UnsafeWriteSize(size, ptr);
0857 }
0858
0859 uint8_t* WriteRawFallback(const void* data, int size, uint8_t* ptr);
0860
0861 uint8_t* WriteAliasedRaw(const void* data, int size, uint8_t* ptr);
0862
0863 uint8_t* WriteStringMaybeAliasedOutline(uint32_t num, const std::string& s,
0864 uint8_t* ptr);
0865 uint8_t* WriteStringOutline(uint32_t num, const std::string& s, uint8_t* ptr);
0866 uint8_t* WriteStringOutline(uint32_t num, absl::string_view s, uint8_t* ptr);
0867 uint8_t* WriteCordOutline(const absl::Cord& c, uint8_t* ptr);
0868
0869 template <typename T, typename E>
0870 PROTOBUF_ALWAYS_INLINE uint8_t* WriteVarintPacked(int num, const T& r,
0871 int size, uint8_t* ptr,
0872 const E& encode) {
0873 ptr = EnsureSpace(ptr);
0874 ptr = WriteLengthDelim(num, size, ptr);
0875 auto it = r.data();
0876 auto end = it + r.size();
0877 do {
0878 ptr = EnsureSpace(ptr);
0879 ptr = UnsafeVarint(encode(*it++), ptr);
0880 } while (it < end);
0881 return ptr;
0882 }
0883
0884 static uint32_t Encode32(uint32_t v) { return v; }
0885 static uint64_t Encode64(uint64_t v) { return v; }
0886 static uint32_t ZigZagEncode32(int32_t v) {
0887 return (static_cast<uint32_t>(v) << 1) ^ static_cast<uint32_t>(v >> 31);
0888 }
0889 static uint64_t ZigZagEncode64(int64_t v) {
0890 return (static_cast<uint64_t>(v) << 1) ^ static_cast<uint64_t>(v >> 63);
0891 }
0892
0893 template <typename T>
0894 PROTOBUF_ALWAYS_INLINE static uint8_t* UnsafeVarint(T value, uint8_t* ptr) {
0895 static_assert(std::is_unsigned<T>::value,
0896 "Varint serialization must be unsigned");
0897 while (PROTOBUF_PREDICT_FALSE(value >= 0x80)) {
0898 *ptr = static_cast<uint8_t>(value | 0x80);
0899 value >>= 7;
0900 ++ptr;
0901 }
0902 *ptr++ = static_cast<uint8_t>(value);
0903 return ptr;
0904 }
0905
0906 PROTOBUF_ALWAYS_INLINE static uint8_t* UnsafeWriteSize(uint32_t value,
0907 uint8_t* ptr) {
0908 while (PROTOBUF_PREDICT_FALSE(value >= 0x80)) {
0909 *ptr = static_cast<uint8_t>(value | 0x80);
0910 value >>= 7;
0911 ++ptr;
0912 }
0913 *ptr++ = static_cast<uint8_t>(value);
0914 return ptr;
0915 }
0916
0917 template <int S>
0918 uint8_t* WriteRawLittleEndian(const void* data, int size, uint8_t* ptr);
0919 #if !defined(ABSL_IS_LITTLE_ENDIAN) || \
0920 defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
0921 uint8_t* WriteRawLittleEndian32(const void* data, int size, uint8_t* ptr);
0922 uint8_t* WriteRawLittleEndian64(const void* data, int size, uint8_t* ptr);
0923 #endif
0924
0925
0926
0927
0928 public:
0929 uint8_t* SetInitialBuffer(void* data, int size) {
0930 auto ptr = static_cast<uint8_t*>(data);
0931 if (size > kSlopBytes) {
0932 end_ = ptr + size - kSlopBytes;
0933 buffer_end_ = nullptr;
0934 return ptr;
0935 } else {
0936 end_ = buffer_ + size;
0937 buffer_end_ = ptr;
0938 return buffer_;
0939 }
0940 }
0941
0942 private:
0943
0944
0945 uint8_t* FlushAndResetBuffer(uint8_t*);
0946
0947
0948
0949
0950 bool Skip(int count, uint8_t** pp);
0951 bool GetDirectBufferPointer(void** data, int* size, uint8_t** pp);
0952 uint8_t* GetDirectBufferForNBytesAndAdvance(int size, uint8_t** pp);
0953
0954 friend class CodedOutputStream;
0955 };
0956
0957 template <>
0958 inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<1>(const void* data,
0959 int size,
0960 uint8_t* ptr) {
0961 return WriteRaw(data, size, ptr);
0962 }
0963 template <>
0964 inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<4>(const void* data,
0965 int size,
0966 uint8_t* ptr) {
0967 #if defined(ABSL_IS_LITTLE_ENDIAN) && \
0968 !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
0969 return WriteRaw(data, size, ptr);
0970 #else
0971 return WriteRawLittleEndian32(data, size, ptr);
0972 #endif
0973 }
0974 template <>
0975 inline uint8_t* EpsCopyOutputStream::WriteRawLittleEndian<8>(const void* data,
0976 int size,
0977 uint8_t* ptr) {
0978 #if defined(ABSL_IS_LITTLE_ENDIAN) && \
0979 !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
0980 return WriteRaw(data, size, ptr);
0981 #else
0982 return WriteRawLittleEndian64(data, size, ptr);
0983 #endif
0984 }
0985
0986
0987
0988
0989
0990
0991
0992
0993
0994
0995
0996
0997
0998
0999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032 class PROTOBUF_EXPORT CodedOutputStream {
1033 public:
1034
1035
1036 template <class Stream, class = typename std::enable_if<std::is_base_of<
1037 ZeroCopyOutputStream, Stream>::value>::type>
1038 explicit CodedOutputStream(Stream* stream);
1039
1040
1041
1042
1043 template <class Stream, class = typename std::enable_if<std::is_base_of<
1044 ZeroCopyOutputStream, Stream>::value>::type>
1045 CodedOutputStream(Stream* stream, bool eager_init);
1046 CodedOutputStream(const CodedOutputStream&) = delete;
1047 CodedOutputStream& operator=(const CodedOutputStream&) = delete;
1048
1049
1050
1051 ~CodedOutputStream();
1052
1053
1054
1055
1056 bool HadError() {
1057 cur_ = impl_.FlushAndResetBuffer(cur_);
1058 ABSL_DCHECK(cur_);
1059 return impl_.HadError();
1060 }
1061
1062
1063
1064
1065
1066
1067 void Trim() { cur_ = impl_.Trim(cur_); }
1068
1069
1070
1071
1072
1073
1074
1075 bool Skip(int count) { return impl_.Skip(count, &cur_); }
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085 bool GetDirectBufferPointer(void** data, int* size) {
1086 return impl_.GetDirectBufferPointer(data, size, &cur_);
1087 }
1088
1089
1090
1091
1092
1093
1094
1095
1096 inline uint8_t* GetDirectBufferForNBytesAndAdvance(int size) {
1097 return impl_.GetDirectBufferForNBytesAndAdvance(size, &cur_);
1098 }
1099
1100
1101 void WriteRaw(const void* buffer, int size) {
1102 cur_ = impl_.WriteRaw(buffer, size, cur_);
1103 }
1104
1105
1106 void WriteRawMaybeAliased(const void* data, int size);
1107
1108
1109
1110
1111
1112 static uint8_t* WriteRawToArray(const void* buffer, int size,
1113 uint8_t* target);
1114
1115
1116 void WriteString(const std::string& str);
1117
1118 static uint8_t* WriteStringToArray(const std::string& str, uint8_t* target);
1119
1120 static uint8_t* WriteStringWithSizeToArray(const std::string& str,
1121 uint8_t* target);
1122
1123
1124 void WriteCord(const absl::Cord& cord) { cur_ = impl_.WriteCord(cord, cur_); }
1125
1126
1127 static uint8_t* WriteCordToArray(const absl::Cord& cord, uint8_t* target);
1128
1129
1130
1131 void WriteLittleEndian32(uint32_t value) {
1132 cur_ = impl_.EnsureSpace(cur_);
1133 SetCur(WriteLittleEndian32ToArray(value, Cur()));
1134 }
1135
1136 static uint8_t* WriteLittleEndian32ToArray(uint32_t value, uint8_t* target);
1137
1138 void WriteLittleEndian64(uint64_t value) {
1139 cur_ = impl_.EnsureSpace(cur_);
1140 SetCur(WriteLittleEndian64ToArray(value, Cur()));
1141 }
1142
1143 static uint8_t* WriteLittleEndian64ToArray(uint64_t value, uint8_t* target);
1144
1145
1146
1147
1148 void WriteVarint32(uint32_t value);
1149
1150 static uint8_t* WriteVarint32ToArray(uint32_t value, uint8_t* target);
1151
1152 [[deprecated("Please use WriteVarint32ToArray() instead")]] static uint8_t*
1153 WriteVarint32ToArrayOutOfLine(uint32_t value, uint8_t* target) {
1154 return WriteVarint32ToArray(value, target);
1155 }
1156
1157 void WriteVarint64(uint64_t value);
1158
1159 static uint8_t* WriteVarint64ToArray(uint64_t value, uint8_t* target);
1160
1161
1162
1163 void WriteVarint32SignExtended(int32_t value);
1164
1165 static uint8_t* WriteVarint32SignExtendedToArray(int32_t value,
1166 uint8_t* target);
1167
1168
1169
1170
1171
1172
1173 void WriteTag(uint32_t value);
1174
1175 PROTOBUF_ALWAYS_INLINE
1176 static uint8_t* WriteTagToArray(uint32_t value, uint8_t* target);
1177
1178
1179 static size_t VarintSize32(uint32_t value);
1180
1181 static size_t VarintSize64(uint64_t value);
1182
1183
1184 static size_t VarintSize32SignExtended(int32_t value);
1185
1186
1187 static size_t VarintSize32PlusOne(uint32_t value);
1188 static size_t VarintSize64PlusOne(uint64_t value);
1189 static size_t VarintSize32SignExtendedPlusOne(int32_t value);
1190
1191
1192 template <uint32_t Value>
1193 struct StaticVarintSize32 {
1194 static const size_t value = (Value < (1 << 7)) ? 1
1195 : (Value < (1 << 14)) ? 2
1196 : (Value < (1 << 21)) ? 3
1197 : (Value < (1 << 28)) ? 4
1198 : 5;
1199 };
1200
1201
1202 int ByteCount() const {
1203 return static_cast<int>(impl_.ByteCount(cur_) - start_count_);
1204 }
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215 void EnableAliasing(bool enabled) { impl_.EnableAliasing(enabled); }
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238 void SetSerializationDeterministic(bool value) {
1239 impl_.SetSerializationDeterministic(value);
1240 }
1241
1242
1243 bool IsSerializationDeterministic() const {
1244 return impl_.IsSerializationDeterministic();
1245 }
1246
1247 static bool IsDefaultSerializationDeterministic() {
1248 return default_serialization_deterministic_.load(
1249 std::memory_order_relaxed) != 0;
1250 }
1251
1252 template <typename Func>
1253 void Serialize(const Func& func);
1254
1255 uint8_t* Cur() const { return cur_; }
1256 void SetCur(uint8_t* ptr) { cur_ = ptr; }
1257 EpsCopyOutputStream* EpsCopy() { return &impl_; }
1258
1259 private:
1260 template <class Stream>
1261 void InitEagerly(Stream* stream);
1262
1263 EpsCopyOutputStream impl_;
1264 uint8_t* cur_;
1265 int64_t start_count_;
1266 static std::atomic<bool> default_serialization_deterministic_;
1267
1268
1269
1270
1271
1272
1273
1274
1275 friend void google::protobuf::internal::MapTestForceDeterministic();
1276 static void SetDefaultSerializationDeterministic() {
1277 default_serialization_deterministic_.store(true, std::memory_order_relaxed);
1278 }
1279 };
1280
1281
1282
1283
1284
1285 inline bool CodedInputStream::ReadVarint32(uint32_t* value) {
1286 uint32_t v = 0;
1287 if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) {
1288 v = *buffer_;
1289 if (v < 0x80) {
1290 *value = v;
1291 Advance(1);
1292 return true;
1293 }
1294 }
1295 int64_t result = ReadVarint32Fallback(v);
1296 *value = static_cast<uint32_t>(result);
1297 return result >= 0;
1298 }
1299
1300 inline bool CodedInputStream::ReadVarint64(uint64_t* value) {
1301 if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) {
1302 *value = *buffer_;
1303 Advance(1);
1304 return true;
1305 }
1306 std::pair<uint64_t, bool> p = ReadVarint64Fallback();
1307 *value = p.first;
1308 return p.second;
1309 }
1310
1311 inline bool CodedInputStream::ReadVarintSizeAsInt(int* value) {
1312 if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) {
1313 int v = *buffer_;
1314 if (v < 0x80) {
1315 *value = v;
1316 Advance(1);
1317 return true;
1318 }
1319 }
1320 *value = ReadVarintSizeAsIntFallback();
1321 return *value >= 0;
1322 }
1323
1324
1325 inline const uint8_t* CodedInputStream::ReadLittleEndian32FromArray(
1326 const uint8_t* buffer, uint32_t* value) {
1327 #if defined(ABSL_IS_LITTLE_ENDIAN) && \
1328 !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
1329 memcpy(value, buffer, sizeof(*value));
1330 return buffer + sizeof(*value);
1331 #else
1332 *value = (static_cast<uint32_t>(buffer[0])) |
1333 (static_cast<uint32_t>(buffer[1]) << 8) |
1334 (static_cast<uint32_t>(buffer[2]) << 16) |
1335 (static_cast<uint32_t>(buffer[3]) << 24);
1336 return buffer + sizeof(*value);
1337 #endif
1338 }
1339
1340 inline const uint8_t* CodedInputStream::ReadLittleEndian64FromArray(
1341 const uint8_t* buffer, uint64_t* value) {
1342 #if defined(ABSL_IS_LITTLE_ENDIAN) && \
1343 !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
1344 memcpy(value, buffer, sizeof(*value));
1345 return buffer + sizeof(*value);
1346 #else
1347 uint32_t part0 = (static_cast<uint32_t>(buffer[0])) |
1348 (static_cast<uint32_t>(buffer[1]) << 8) |
1349 (static_cast<uint32_t>(buffer[2]) << 16) |
1350 (static_cast<uint32_t>(buffer[3]) << 24);
1351 uint32_t part1 = (static_cast<uint32_t>(buffer[4])) |
1352 (static_cast<uint32_t>(buffer[5]) << 8) |
1353 (static_cast<uint32_t>(buffer[6]) << 16) |
1354 (static_cast<uint32_t>(buffer[7]) << 24);
1355 *value = static_cast<uint64_t>(part0) | (static_cast<uint64_t>(part1) << 32);
1356 return buffer + sizeof(*value);
1357 #endif
1358 }
1359
1360 inline bool CodedInputStream::ReadLittleEndian32(uint32_t* value) {
1361 #if defined(ABSL_IS_LITTLE_ENDIAN) && \
1362 !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
1363 if (PROTOBUF_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) {
1364 buffer_ = ReadLittleEndian32FromArray(buffer_, value);
1365 return true;
1366 } else {
1367 return ReadLittleEndian32Fallback(value);
1368 }
1369 #else
1370 return ReadLittleEndian32Fallback(value);
1371 #endif
1372 }
1373
1374 inline bool CodedInputStream::ReadLittleEndian64(uint64_t* value) {
1375 #if defined(ABSL_IS_LITTLE_ENDIAN) && \
1376 !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
1377 if (PROTOBUF_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) {
1378 buffer_ = ReadLittleEndian64FromArray(buffer_, value);
1379 return true;
1380 } else {
1381 return ReadLittleEndian64Fallback(value);
1382 }
1383 #else
1384 return ReadLittleEndian64Fallback(value);
1385 #endif
1386 }
1387
1388 inline uint32_t CodedInputStream::ReadTagNoLastTag() {
1389 uint32_t v = 0;
1390 if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) {
1391 v = *buffer_;
1392 if (v < 0x80) {
1393 Advance(1);
1394 return v;
1395 }
1396 }
1397 v = ReadTagFallback(v);
1398 return v;
1399 }
1400
1401 inline std::pair<uint32_t, bool> CodedInputStream::ReadTagWithCutoffNoLastTag(
1402 uint32_t cutoff) {
1403
1404
1405
1406 uint32_t first_byte_or_zero = 0;
1407 if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_)) {
1408
1409
1410
1411 first_byte_or_zero = buffer_[0];
1412 if (static_cast<int8_t>(buffer_[0]) > 0) {
1413 const uint32_t kMax1ByteVarint = 0x7f;
1414 uint32_t tag = buffer_[0];
1415 Advance(1);
1416 return std::make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff);
1417 }
1418
1419
1420
1421 if (cutoff >= 0x80 && PROTOBUF_PREDICT_TRUE(buffer_ + 1 < buffer_end_) &&
1422 PROTOBUF_PREDICT_TRUE((buffer_[0] & ~buffer_[1]) >= 0x80)) {
1423 const uint32_t kMax2ByteVarint = (0x7f << 7) + 0x7f;
1424 uint32_t tag = (1u << 7) * buffer_[1] + (buffer_[0] - 0x80);
1425 Advance(2);
1426
1427
1428
1429
1430
1431
1432 bool at_or_below_cutoff = cutoff >= kMax2ByteVarint || tag <= cutoff;
1433 return std::make_pair(tag, at_or_below_cutoff);
1434 }
1435 }
1436
1437 const uint32_t tag = ReadTagFallback(first_byte_or_zero);
1438 return std::make_pair(tag, static_cast<uint32_t>(tag - 1) < cutoff);
1439 }
1440
1441 inline bool CodedInputStream::LastTagWas(uint32_t expected) {
1442 return last_tag_ == expected;
1443 }
1444
1445 inline bool CodedInputStream::ConsumedEntireMessage() {
1446 return legitimate_message_end_;
1447 }
1448
1449 inline bool CodedInputStream::ExpectTag(uint32_t expected) {
1450 if (expected < (1 << 7)) {
1451 if (PROTOBUF_PREDICT_TRUE(buffer_ < buffer_end_) &&
1452 buffer_[0] == expected) {
1453 Advance(1);
1454 return true;
1455 } else {
1456 return false;
1457 }
1458 } else if (expected < (1 << 14)) {
1459 if (PROTOBUF_PREDICT_TRUE(BufferSize() >= 2) &&
1460 buffer_[0] == static_cast<uint8_t>(expected | 0x80) &&
1461 buffer_[1] == static_cast<uint8_t>(expected >> 7)) {
1462 Advance(2);
1463 return true;
1464 } else {
1465 return false;
1466 }
1467 } else {
1468
1469 return false;
1470 }
1471 }
1472
1473 inline const uint8_t* CodedInputStream::ExpectTagFromArray(
1474 const uint8_t* buffer, uint32_t expected) {
1475 if (expected < (1 << 7)) {
1476 if (buffer[0] == expected) {
1477 return buffer + 1;
1478 }
1479 } else if (expected < (1 << 14)) {
1480 if (buffer[0] == static_cast<uint8_t>(expected | 0x80) &&
1481 buffer[1] == static_cast<uint8_t>(expected >> 7)) {
1482 return buffer + 2;
1483 }
1484 }
1485 return nullptr;
1486 }
1487
1488 inline void CodedInputStream::GetDirectBufferPointerInline(const void** data,
1489 int* size) {
1490 *data = buffer_;
1491 *size = static_cast<int>(buffer_end_ - buffer_);
1492 }
1493
1494 inline bool CodedInputStream::ExpectAtEnd() {
1495
1496
1497
1498 if (buffer_ == buffer_end_ && ((buffer_size_after_limit_ != 0) ||
1499 (total_bytes_read_ == current_limit_))) {
1500 last_tag_ = 0;
1501 legitimate_message_end_ = true;
1502 return true;
1503 } else {
1504 return false;
1505 }
1506 }
1507
1508 inline int CodedInputStream::CurrentPosition() const {
1509 return total_bytes_read_ - (BufferSize() + buffer_size_after_limit_);
1510 }
1511
1512 inline void CodedInputStream::Advance(int amount) { buffer_ += amount; }
1513
1514 inline void CodedInputStream::SetRecursionLimit(int limit) {
1515 recursion_budget_ += limit - recursion_limit_;
1516 recursion_limit_ = limit;
1517 }
1518
1519 inline bool CodedInputStream::IncrementRecursionDepth() {
1520 --recursion_budget_;
1521 return recursion_budget_ >= 0;
1522 }
1523
1524 inline void CodedInputStream::DecrementRecursionDepth() {
1525 if (recursion_budget_ < recursion_limit_) ++recursion_budget_;
1526 }
1527
1528 inline void CodedInputStream::UnsafeDecrementRecursionDepth() {
1529 assert(recursion_budget_ < recursion_limit_);
1530 ++recursion_budget_;
1531 }
1532
1533 inline void CodedInputStream::SetExtensionRegistry(const DescriptorPool* pool,
1534 MessageFactory* factory) {
1535 extension_pool_ = pool;
1536 extension_factory_ = factory;
1537 }
1538
1539 inline const DescriptorPool* CodedInputStream::GetExtensionPool() {
1540 return extension_pool_;
1541 }
1542
1543 inline MessageFactory* CodedInputStream::GetExtensionFactory() {
1544 return extension_factory_;
1545 }
1546
1547 inline int CodedInputStream::BufferSize() const {
1548 return static_cast<int>(buffer_end_ - buffer_);
1549 }
1550
1551 inline CodedInputStream::CodedInputStream(ZeroCopyInputStream* input)
1552 : buffer_(nullptr),
1553 buffer_end_(nullptr),
1554 input_(input),
1555 total_bytes_read_(0),
1556 overflow_bytes_(0),
1557 last_tag_(0),
1558 legitimate_message_end_(false),
1559 aliasing_enabled_(false),
1560 force_eager_parsing_(false),
1561 current_limit_(std::numeric_limits<int32_t>::max()),
1562 buffer_size_after_limit_(0),
1563 total_bytes_limit_(kDefaultTotalBytesLimit),
1564 recursion_budget_(default_recursion_limit_),
1565 recursion_limit_(default_recursion_limit_),
1566 extension_pool_(nullptr),
1567 extension_factory_(nullptr) {
1568
1569 Refresh();
1570 }
1571
1572 inline CodedInputStream::CodedInputStream(const uint8_t* buffer, int size)
1573 : buffer_(buffer),
1574 buffer_end_(buffer + size),
1575 input_(nullptr),
1576 total_bytes_read_(size),
1577 overflow_bytes_(0),
1578 last_tag_(0),
1579 legitimate_message_end_(false),
1580 aliasing_enabled_(false),
1581 force_eager_parsing_(false),
1582 current_limit_(size),
1583 buffer_size_after_limit_(0),
1584 total_bytes_limit_(kDefaultTotalBytesLimit),
1585 recursion_budget_(default_recursion_limit_),
1586 recursion_limit_(default_recursion_limit_),
1587 extension_pool_(nullptr),
1588 extension_factory_(nullptr) {
1589
1590
1591 }
1592
1593 inline bool CodedInputStream::IsFlat() const { return input_ == nullptr; }
1594
1595 inline bool CodedInputStream::Skip(int count) {
1596 if (count < 0) return false;
1597
1598 const int original_buffer_size = BufferSize();
1599
1600 if (count <= original_buffer_size) {
1601
1602 Advance(count);
1603 return true;
1604 }
1605
1606 return SkipFallback(count, original_buffer_size);
1607 }
1608
1609 template <class Stream, class>
1610 inline CodedOutputStream::CodedOutputStream(Stream* stream)
1611 : impl_(stream, IsDefaultSerializationDeterministic(), &cur_),
1612 start_count_(stream->ByteCount()) {
1613 InitEagerly(stream);
1614 }
1615
1616 template <class Stream, class>
1617 inline CodedOutputStream::CodedOutputStream(Stream* stream, bool eager_init)
1618 : impl_(stream, IsDefaultSerializationDeterministic(), &cur_),
1619 start_count_(stream->ByteCount()) {
1620 if (eager_init) {
1621 InitEagerly(stream);
1622 }
1623 }
1624
1625 template <class Stream>
1626 inline void CodedOutputStream::InitEagerly(Stream* stream) {
1627 void* data;
1628 int size;
1629 if (PROTOBUF_PREDICT_TRUE(stream->Next(&data, &size) && size > 0)) {
1630 cur_ = impl_.SetInitialBuffer(data, size);
1631 }
1632 }
1633
1634 inline uint8_t* CodedOutputStream::WriteVarint32ToArray(uint32_t value,
1635 uint8_t* target) {
1636 return EpsCopyOutputStream::UnsafeVarint(value, target);
1637 }
1638
1639 inline uint8_t* CodedOutputStream::WriteVarint64ToArray(uint64_t value,
1640 uint8_t* target) {
1641 return EpsCopyOutputStream::UnsafeVarint(value, target);
1642 }
1643
1644 inline void CodedOutputStream::WriteVarint32SignExtended(int32_t value) {
1645 WriteVarint64(static_cast<uint64_t>(value));
1646 }
1647
1648 inline uint8_t* CodedOutputStream::WriteVarint32SignExtendedToArray(
1649 int32_t value, uint8_t* target) {
1650 return WriteVarint64ToArray(static_cast<uint64_t>(value), target);
1651 }
1652
1653 inline uint8_t* CodedOutputStream::WriteLittleEndian32ToArray(uint32_t value,
1654 uint8_t* target) {
1655 #if defined(ABSL_IS_LITTLE_ENDIAN) && \
1656 !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
1657 memcpy(target, &value, sizeof(value));
1658 #else
1659 target[0] = static_cast<uint8_t>(value);
1660 target[1] = static_cast<uint8_t>(value >> 8);
1661 target[2] = static_cast<uint8_t>(value >> 16);
1662 target[3] = static_cast<uint8_t>(value >> 24);
1663 #endif
1664 return target + sizeof(value);
1665 }
1666
1667 inline uint8_t* CodedOutputStream::WriteLittleEndian64ToArray(uint64_t value,
1668 uint8_t* target) {
1669 #if defined(ABSL_IS_LITTLE_ENDIAN) && \
1670 !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
1671 memcpy(target, &value, sizeof(value));
1672 #else
1673 uint32_t part0 = static_cast<uint32_t>(value);
1674 uint32_t part1 = static_cast<uint32_t>(value >> 32);
1675
1676 target[0] = static_cast<uint8_t>(part0);
1677 target[1] = static_cast<uint8_t>(part0 >> 8);
1678 target[2] = static_cast<uint8_t>(part0 >> 16);
1679 target[3] = static_cast<uint8_t>(part0 >> 24);
1680 target[4] = static_cast<uint8_t>(part1);
1681 target[5] = static_cast<uint8_t>(part1 >> 8);
1682 target[6] = static_cast<uint8_t>(part1 >> 16);
1683 target[7] = static_cast<uint8_t>(part1 >> 24);
1684 #endif
1685 return target + sizeof(value);
1686 }
1687
1688 inline void CodedOutputStream::WriteVarint32(uint32_t value) {
1689 cur_ = impl_.EnsureSpace(cur_);
1690 SetCur(WriteVarint32ToArray(value, Cur()));
1691 }
1692
1693 inline void CodedOutputStream::WriteVarint64(uint64_t value) {
1694 cur_ = impl_.EnsureSpace(cur_);
1695 SetCur(WriteVarint64ToArray(value, Cur()));
1696 }
1697
1698 inline void CodedOutputStream::WriteTag(uint32_t value) {
1699 WriteVarint32(value);
1700 }
1701
1702 inline uint8_t* CodedOutputStream::WriteTagToArray(uint32_t value,
1703 uint8_t* target) {
1704 return WriteVarint32ToArray(value, target);
1705 }
1706
1707 #if (defined(__x86__) || defined(__x86_64__) || defined(_M_IX86) || \
1708 defined(_M_X64)) && \
1709 !(defined(__LZCNT__) || defined(__AVX2__))
1710
1711
1712
1713 #define PROTOBUF_CODED_STREAM_H_PREFER_BSR 1
1714 #else
1715 #define PROTOBUF_CODED_STREAM_H_PREFER_BSR 0
1716 #endif
1717 inline size_t CodedOutputStream::VarintSize32(uint32_t value) {
1718 #if PROTOBUF_CODED_STREAM_H_PREFER_BSR
1719
1720
1721 uint32_t log2value = (std::numeric_limits<uint32_t>::digits - 1) -
1722 absl::countl_zero(value | 0x1);
1723 return static_cast<size_t>((log2value * 9 + (64 + 9)) / 64);
1724 #else
1725 uint32_t clz = absl::countl_zero(value);
1726 return static_cast<size_t>(
1727 ((std::numeric_limits<uint32_t>::digits * 9 + 64) - (clz * 9)) / 64);
1728 #endif
1729 }
1730
1731 inline size_t CodedOutputStream::VarintSize32PlusOne(uint32_t value) {
1732
1733 #if PROTOBUF_CODED_STREAM_H_PREFER_BSR
1734 uint32_t log2value = (std::numeric_limits<uint32_t>::digits - 1) -
1735 absl::countl_zero(value | 0x1);
1736 return static_cast<size_t>((log2value * 9 + (64 + 9) + 64) / 64);
1737 #else
1738 uint32_t clz = absl::countl_zero(value);
1739 return static_cast<size_t>(
1740 ((std::numeric_limits<uint32_t>::digits * 9 + 64 + 64) - (clz * 9)) / 64);
1741 #endif
1742 }
1743
1744 inline size_t CodedOutputStream::VarintSize64(uint64_t value) {
1745 #if PROTOBUF_CODED_STREAM_H_PREFER_BSR
1746
1747
1748 uint32_t log2value = (std::numeric_limits<uint64_t>::digits - 1) -
1749 absl::countl_zero(value | 0x1);
1750 return static_cast<size_t>((log2value * 9 + (64 + 9)) / 64);
1751 #else
1752 uint32_t clz = absl::countl_zero(value);
1753 return static_cast<size_t>(
1754 ((std::numeric_limits<uint64_t>::digits * 9 + 64) - (clz * 9)) / 64);
1755 #endif
1756 }
1757
1758 inline size_t CodedOutputStream::VarintSize64PlusOne(uint64_t value) {
1759
1760 #if PROTOBUF_CODED_STREAM_H_PREFER_BSR
1761 uint32_t log2value = (std::numeric_limits<uint64_t>::digits - 1) -
1762 absl::countl_zero(value | 0x1);
1763 return static_cast<size_t>((log2value * 9 + (64 + 9) + 64) / 64);
1764 #else
1765 uint32_t clz = absl::countl_zero(value);
1766 return static_cast<size_t>(
1767 ((std::numeric_limits<uint64_t>::digits * 9 + 64 + 64) - (clz * 9)) / 64);
1768 #endif
1769 }
1770
1771 inline size_t CodedOutputStream::VarintSize32SignExtended(int32_t value) {
1772 return VarintSize64(static_cast<uint64_t>(int64_t{value}));
1773 }
1774
1775 inline size_t CodedOutputStream::VarintSize32SignExtendedPlusOne(
1776 int32_t value) {
1777 return VarintSize64PlusOne(static_cast<uint64_t>(int64_t{value}));
1778 }
1779 #undef PROTOBUF_CODED_STREAM_H_PREFER_BSR
1780
1781 inline void CodedOutputStream::WriteString(const std::string& str) {
1782 WriteRaw(str.data(), static_cast<int>(str.size()));
1783 }
1784
1785 inline void CodedOutputStream::WriteRawMaybeAliased(const void* data,
1786 int size) {
1787 cur_ = impl_.WriteRawMaybeAliased(data, size, cur_);
1788 }
1789
1790 inline uint8_t* CodedOutputStream::WriteRawToArray(const void* data, int size,
1791 uint8_t* target) {
1792 memcpy(target, data, static_cast<unsigned int>(size));
1793 return target + size;
1794 }
1795
1796 inline uint8_t* CodedOutputStream::WriteStringToArray(const std::string& str,
1797 uint8_t* target) {
1798 return WriteRawToArray(str.data(), static_cast<int>(str.size()), target);
1799 }
1800
1801 }
1802 }
1803 }
1804
1805 #if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
1806 #pragma runtime_checks("c", restore)
1807 #endif
1808
1809 #include "google/protobuf/port_undef.inc"
1810
1811 #endif