| 
8 | 8 | #ifndef GOOGLE_PROTOBUF_MICRO_STRING_H__  | 
9 | 9 | #define GOOGLE_PROTOBUF_MICRO_STRING_H__  | 
10 | 10 | 
 
  | 
 | 11 | +#include <cstddef>  | 
11 | 12 | #include <cstdint>  | 
12 | 13 | 
 
  | 
13 | 14 | #include "absl/base/config.h"  | 
@@ -97,12 +98,34 @@ class PROTOBUF_EXPORT MicroString {  | 
97 | 98 |     }  | 
98 | 99 |   };  | 
99 | 100 | 
 
  | 
 | 101 | +  struct MicroRep {  | 
 | 102 | +    uint8_t size;  | 
 | 103 | +    uint8_t capacity;  | 
 | 104 | + | 
 | 105 | +    char* data() { return reinterpret_cast<char*>(this + 1); }  | 
 | 106 | +    const char* data() const { return reinterpret_cast<const char*>(this + 1); }  | 
 | 107 | +    absl::string_view view() const { return {data(), size}; }  | 
 | 108 | + | 
 | 109 | +    void SetInitialSize(uint8_t size) {  | 
 | 110 | +      PoisonMemoryRegion(data() + size, capacity - size);  | 
 | 111 | +      this->size = size;  | 
 | 112 | +    }  | 
 | 113 | + | 
 | 114 | +    void Unpoison() { UnpoisonMemoryRegion(data(), capacity); }  | 
 | 115 | + | 
 | 116 | +    void ChangeSize(uint8_t new_size) {  | 
 | 117 | +      PoisonMemoryRegion(data() + new_size, capacity - new_size);  | 
 | 118 | +      UnpoisonMemoryRegion(data(), new_size);  | 
 | 119 | +      size = new_size;  | 
 | 120 | +    }  | 
 | 121 | +  };  | 
 | 122 | + | 
100 | 123 |  public:  | 
101 | 124 |   // We don't allow extra capacity in big-endian because it is harder to manage  | 
102 | 125 |   // the pointer to the MicroString "base".  | 
103 | 126 |   static constexpr bool kAllowExtraCapacity = IsLittleEndian();  | 
104 | 127 |   static constexpr size_t kInlineCapacity = sizeof(uintptr_t) - 1;  | 
105 |  | -  static constexpr size_t kMaxMicroRepCapacity = 255;  | 
 | 128 | +  static constexpr size_t kMaxMicroRepCapacity = 256 - sizeof(MicroRep);  | 
106 | 129 | 
 
  | 
107 | 130 |   // Empty string.  | 
108 | 131 |   constexpr MicroString() : rep_() {}  | 
@@ -311,27 +334,6 @@ class PROTOBUF_EXPORT MicroString {  | 
311 | 334 |     return cap >= kOwned ? kOwned : static_cast<LargeRepKind>(cap);  | 
312 | 335 |   }  | 
313 | 336 | 
 
  | 
314 |  | -  struct MicroRep {  | 
315 |  | -    uint8_t size;  | 
316 |  | -    uint8_t capacity;  | 
317 |  | - | 
318 |  | -    char* data() { return reinterpret_cast<char*>(this + 1); }  | 
319 |  | -    const char* data() const { return reinterpret_cast<const char*>(this + 1); }  | 
320 |  | -    absl::string_view view() const { return {data(), size}; }  | 
321 |  | - | 
322 |  | -    void SetInitialSize(uint8_t size) {  | 
323 |  | -      PoisonMemoryRegion(data() + size, capacity - size);  | 
324 |  | -      this->size = size;  | 
325 |  | -    }  | 
326 |  | - | 
327 |  | -    void Unpoison() { UnpoisonMemoryRegion(data(), capacity); }  | 
328 |  | - | 
329 |  | -    void ChangeSize(uint8_t new_size) {  | 
330 |  | -      PoisonMemoryRegion(data() + new_size, capacity - new_size);  | 
331 |  | -      UnpoisonMemoryRegion(data(), new_size);  | 
332 |  | -      size = new_size;  | 
333 |  | -    }  | 
334 |  | -  };  | 
335 | 337 |   // Micro-optimization: by using kIsMicroRepTag as 2, the MicroRep `rep_`  | 
336 | 338 |   // pointer (with the tag) is already pointing into the data buffer.  | 
337 | 339 |   static_assert(sizeof(MicroRep) == kIsMicroRepTag);  | 
 | 
0 commit comments