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