31 #ifndef GOOGLE_PROTOBUF_PARSE_CONTEXT_H__
32 #define GOOGLE_PROTOBUF_PARSE_CONTEXT_H__
48 #include <google/protobuf/port_def.inc>
109 enum { kSlopBytes = 16, kMaxCordBytesToCopy = 512 };
112 : aliasing_(enable_aliasing ? kOnPatch : kNoAliasing) {}
118 count =
static_cast<int>(buffer_end_ + kSlopBytes - ptr);
120 count = size_ +
static_cast<int>(buffer_end_ - ptr);
126 PROTOBUF_MUST_USE_RESULT
int PushLimit(
const char* ptr,
int limit) {
128 limit +=
static_cast<int>(ptr - buffer_end_);
129 limit_end_ = buffer_end_ + (std::min)(0, limit);
130 auto old_limit = limit_;
132 return old_limit - limit;
135 PROTOBUF_MUST_USE_RESULT
bool PopLimit(
int delta) {
136 if (PROTOBUF_PREDICT_FALSE(!EndedAtLimit()))
return false;
137 limit_ = limit_ + delta;
140 limit_end_ = buffer_end_ + (std::min)(0, limit_);
144 PROTOBUF_MUST_USE_RESULT
const char*
Skip(
const char* ptr,
int size) {
145 if (
size <= buffer_end_ + kSlopBytes - ptr) {
148 return SkipFallback(ptr,
size);
152 if (
size <= buffer_end_ + kSlopBytes - ptr) {
153 s->assign(ptr,
size);
156 return ReadStringFallback(ptr,
size,
s);
160 if (
size <= buffer_end_ + kSlopBytes - ptr) {
161 s->append(ptr,
size);
164 return AppendStringFallback(ptr,
size,
s);
167 template <
typename Tag,
typename T>
168 PROTOBUF_MUST_USE_RESULT
const char* ReadRepeatedFixed(
const char* ptr,
172 template <
typename T>
173 PROTOBUF_MUST_USE_RESULT
const char* ReadPackedFixed(
const char* ptr,
176 template <
typename Add>
177 PROTOBUF_MUST_USE_RESULT
const char* ReadPackedVarint(
const char* ptr,
182 bool res = last_tag_minus_1_ == start_tag;
183 last_tag_minus_1_ = 0;
191 return ptr > limit_end_ &&
192 (next_chunk_ ==
nullptr || ptr - buffer_end_ > limit_);
204 if (PROTOBUF_PREDICT_TRUE(*ptr < limit_end_))
return false;
206 if ((*ptr - buffer_end_) == limit_)
return true;
207 auto res = DoneFallback(*ptr,
d);
214 if (flat.
size() > kSlopBytes) {
216 limit_end_ = buffer_end_ = flat.
end() - kSlopBytes;
218 if (aliasing_ == kOnPatch) aliasing_ = kNoDelta;
224 next_chunk_ =
nullptr;
225 if (aliasing_ == kOnPatch) {
226 aliasing_ =
reinterpret_cast<std::uintptr_t
>(flat.
data()) -
227 reinterpret_cast<std::uintptr_t
>(
buffer_);
236 overall_limit_ = limit;
237 auto res = InitFrom(zcis);
238 limit_ = limit -
static_cast<int>(buffer_end_ - res);
239 limit_end_ = buffer_end_ + (std::min)(0, limit_);
251 enum { kNoAliasing = 0, kOnPatch = 1, kNoDelta = 2 };
252 std::uintptr_t aliasing_ = kNoAliasing;
267 int overall_limit_ = INT_MAX;
269 std::pair<const char*, bool> DoneFallback(
const char* ptr,
int d);
270 const char* Next(
int overrun,
int d);
271 const char* SkipFallback(
const char* ptr,
int size);
275 template <
typename A>
277 int chunk_size = buffer_end_ + kSlopBytes - ptr;
286 if (limit_ == kSlopBytes)
return nullptr;
287 auto res = DoneFallback(ptr, -1);
288 if (res.second)
return nullptr;
290 chunk_size = buffer_end_ + kSlopBytes - ptr;
291 }
while (
size > chunk_size);
301 template <
typename A>
303 while (!DoneWithCheck(&ptr, -1)) {
304 append(ptr, limit_end_ - ptr);
312 return AppendUntilEnd(
313 ptr, [
str](
const char*
p, ptrdiff_t
s) {
str->append(
p,
s); });
329 template <
typename...
T>
332 *
start = InitFrom(std::forward<T>(
args)...);
337 bool Done(
const char** ptr) {
return DoneWithCheck(ptr, group_depth_); }
340 int depth()
const {
return depth_; }
345 template <
typename T>
346 PROTOBUF_MUST_USE_RESULT PROTOBUF_ALWAYS_INLINE
const char*
ParseMessage(
347 T* msg,
const char* ptr);
352 template <
typename T>
353 PROTOBUF_MUST_USE_RESULT PROTOBUF_ALWAYS_INLINE
const char*
ParseGroup(
354 T* msg,
const char* ptr,
uint32 tag) {
355 if (--depth_ < 0)
return nullptr;
357 ptr = msg->_InternalParse(ptr,
this);
360 if (PROTOBUF_PREDICT_FALSE(!ConsumeEndGroup(tag)))
return nullptr;
373 int group_depth_ = INT_MIN;
377 template <
typename T>
380 memcpy(&res,
p,
sizeof(
T));
389 template <
int size,
typename T>
392 for (
int i = 0;
i <
size;
i++) {
394 res += (
byte - 1) << (
i * 7);
396 if (PROTOBUF_PREDICT_TRUE(
byte < 128)) {
417 uint32_t
x =
static_cast<int8_t
>(
value);
424 *ptr +=
value <
x ? 2 : 1;
440 res += (second - 1) << 7;
455 *preload = UnalignedLoad<uint16>(
p + 1);
459 res += (second - 1) << 7;
462 *preload = UnalignedLoad<uint16>(
p + 2);
473 for (std::uint32_t
i = 0;
i < 4;
i++) {
474 auto pnew =
p + 2 *
i;
476 res += (
static_cast<std::uint64_t
>(tmp) - 2) << (14 * (
i + 1) - 1);
477 if (PROTOBUF_PREDICT_TRUE(std::int16_t(tmp) >= 0)) {
481 return {
nullptr, res};
486 if (PROTOBUF_PREDICT_TRUE(
static_cast<int16>(tmp) >= 0)) {
499 if (PROTOBUF_PREDICT_TRUE(
static_cast<int16>(tmp) >= 0)) {
571 template <
typename T>
573 T* msg,
const char* ptr) {
575 if (!ptr)
return nullptr;
577 if (--
depth_ < 0)
return nullptr;
578 ptr = msg->_InternalParse(ptr,
this);
579 if (PROTOBUF_PREDICT_FALSE(ptr ==
nullptr))
return nullptr;
585 template <
typename Add>
588 if (ptr ==
nullptr)
return nullptr;
590 if (old < 0)
return nullptr;
594 if (!ptr)
return nullptr;
609 PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT
const char*
611 const char* field_name);
615 const char* field_name) {
626 #define GOOGLE_PROTOBUF_ASSERT_RETURN(predicate, ret) \
627 if (!(predicate)) { \
633 #define GOOGLE_PROTOBUF_PARSER_ASSERT(predicate) \
634 GOOGLE_PROTOBUF_ASSERT_RETURN(predicate, nullptr)
636 template <
typename T>
658 ptr = field_parser.ParseLengthDelimited(
number, ptr, ctx);
663 ptr = field_parser.ParseGroup(
number, ptr, ctx);
683 template <
typename T>
687 while (!ctx->
Done(&ptr)) {
691 if (tag == 0 || (tag & 7) == 4) {
706 void*
object,
const char* ptr, ParseContext* ctx);
708 void*
object,
const char* ptr, ParseContext* ctx);
710 void*
object,
const char* ptr, ParseContext* ctx);
712 void*
object,
const char* ptr, ParseContext* ctx);
714 void*
object,
const char* ptr, ParseContext* ctx);
716 void*
object,
const char* ptr, ParseContext* ctx);
718 void*
object,
const char* ptr, ParseContext* ctx);
720 void*
object,
const char* ptr, ParseContext* ctx,
bool (*is_valid)(
int),
721 InternalMetadataWithArenaLite*
metadata,
int field_num);
723 void*
object,
const char* ptr, ParseContext* ctx,
724 bool (*is_valid)(
const void*,
int),
const void*
data,
725 InternalMetadataWithArenaLite*
metadata,
int field_num);
728 void*
object,
const char* ptr, ParseContext* ctx);
730 void*
object,
const char* ptr, ParseContext* ctx);
732 void*
object,
const char* ptr, ParseContext* ctx);
734 void*
object,
const char* ptr, ParseContext* ctx);
736 void*
object,
const char* ptr, ParseContext* ctx);
738 void*
object,
const char* ptr, ParseContext* ctx);
740 void*
object,
const char* ptr, ParseContext* ctx);
744 std::string* unknown,
const char* ptr, ParseContext* ctx);
751 uint32 tag, InternalMetadataWithArenaLite*
metadata,
const char* ptr,
758 #include <google/protobuf/port_undef.inc>
760 #endif // GOOGLE_PROTOBUF_PARSE_CONTEXT_H__