diff --git a/upb/base/BUILD b/upb/base/BUILD index 2fce94baf5335..c1ab1d3321a8c 100644 --- a/upb/base/BUILD +++ b/upb/base/BUILD @@ -29,6 +29,7 @@ cc_library( cc_library( name = "internal", hdrs = [ + "internal/endian.h", "internal/log2.h", ], copts = UPB_DEFAULT_COPTS, diff --git a/upb/wire/internal/endian.h b/upb/base/internal/endian.h similarity index 53% rename from upb/wire/internal/endian.h rename to upb/base/internal/endian.h index 09788c9b313dc..089742752673e 100644 --- a/upb/wire/internal/endian.h +++ b/upb/base/internal/endian.h @@ -5,8 +5,8 @@ // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd -#ifndef UPB_WIRE_INTERNAL_ENDIAN_H_ -#define UPB_WIRE_INTERNAL_ENDIAN_H_ +#ifndef UPB_BASE_INTERNAL_ENDIAN_H_ +#define UPB_BASE_INTERNAL_ENDIAN_H_ #include @@ -17,23 +17,24 @@ extern "C" { #endif -UPB_INLINE bool UPB_PRIVATE(_upb_IsLittleEndian)(void) { +UPB_INLINE bool upb_IsLittleEndian(void) { const int x = 1; return *(char*)&x == 1; } -UPB_INLINE uint32_t UPB_PRIVATE(_upb_BigEndian32)(uint32_t val) { - if (UPB_PRIVATE(_upb_IsLittleEndian)()) return val; +UPB_INLINE uint32_t upb_BigEndian32(uint32_t val) { + if (upb_IsLittleEndian()) return val; return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24); } -UPB_INLINE uint64_t UPB_PRIVATE(_upb_BigEndian64)(uint64_t val) { - if (UPB_PRIVATE(_upb_IsLittleEndian)()) return val; +UPB_INLINE uint64_t upb_BigEndian64(uint64_t val) { + if (upb_IsLittleEndian()) return val; - return ((uint64_t)UPB_PRIVATE(_upb_BigEndian32)((uint32_t)val) << 32) | - UPB_PRIVATE(_upb_BigEndian32)((uint32_t)(val >> 32)); + const uint64_t hi = ((uint64_t)upb_BigEndian32((uint32_t)val)) << 32; + const uint64_t lo = upb_BigEndian32((uint32_t)(val >> 32)); + return hi | lo; } #ifdef __cplusplus @@ -42,4 +43,4 @@ UPB_INLINE uint64_t UPB_PRIVATE(_upb_BigEndian64)(uint64_t val) { #include "upb/port/undef.inc" -#endif /* UPB_WIRE_INTERNAL_ENDIAN_H_ */ +#endif /* UPB_BASE_INTERNAL_ENDIAN_H_ */ diff --git a/upb/util/BUILD b/upb/util/BUILD index e43b23959c530..b508a5f183562 100644 --- a/upb/util/BUILD +++ b/upb/util/BUILD @@ -165,6 +165,7 @@ cc_test( ":compare", "//upb:port", "//upb:wire_reader", + "//upb/base:internal", "@com_google_absl//absl/strings", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", diff --git a/upb/util/compare_test.cc b/upb/util/compare_test.cc index b29a0ccbdce66..1a1a2935d0932 100644 --- a/upb/util/compare_test.cc +++ b/upb/util/compare_test.cc @@ -15,7 +15,7 @@ #include #include -#include "upb/wire/internal/endian.h" +#include "upb/base/internal/endian.h" #include "upb/wire/types.h" // Must be last. @@ -84,11 +84,11 @@ std::string ToBinaryPayload(const UnknownFields& fields) { ret.append(val->val); } else if (const auto* val = std::get_if(&field.value)) { EncodeVarint(field.field_number << 3 | kUpb_WireType_64Bit, &ret); - uint64_t swapped = UPB_PRIVATE(_upb_BigEndian64)(val->val); + uint64_t swapped = upb_BigEndian64(val->val); ret.append(reinterpret_cast(&swapped), sizeof(swapped)); } else if (const auto* val = std::get_if(&field.value)) { EncodeVarint(field.field_number << 3 | kUpb_WireType_32Bit, &ret); - uint32_t swapped = UPB_PRIVATE(_upb_BigEndian32)(val->val); + uint32_t swapped = upb_BigEndian32(val->val); ret.append(reinterpret_cast(&swapped), sizeof(swapped)); } else if (const auto* val = std::get_if(&field.value)) { EncodeVarint(field.field_number << 3 | kUpb_WireType_StartGroup, &ret); diff --git a/upb/wire/BUILD b/upb/wire/BUILD index 93be09bd9fee8..891ed03d9cfcb 100644 --- a/upb/wire/BUILD +++ b/upb/wire/BUILD @@ -14,6 +14,7 @@ cc_library( "encode.c", "internal/constants.h", "internal/decode_fast.c", + "internal/decoder.c", "internal/decoder.h", ], hdrs = [ @@ -34,6 +35,7 @@ cc_library( "//upb:message_accessors", "//upb:mini_table", "//upb:port", + "//upb/base:internal", "//upb/mem:internal", "//upb/message:internal", "//upb/mini_table:internal", @@ -43,11 +45,10 @@ cc_library( cc_library( name = "reader", srcs = [ + "internal/reader.h", "reader.c", ], hdrs = [ - "internal/endian.h", - "internal/reader.h", "reader.h", "types.h", ], @@ -55,6 +56,7 @@ cc_library( deps = [ ":eps_copy_input_stream", "//upb:port", + "//upb/base:internal", ], ) diff --git a/upb/wire/decode.c b/upb/wire/decode.c index a80f65c11c9ea..6d52b3702e948 100644 --- a/upb/wire/decode.c +++ b/upb/wire/decode.c @@ -14,6 +14,7 @@ #include #include "upb/base/descriptor_constants.h" +#include "upb/base/internal/endian.h" #include "upb/base/string_view.h" #include "upb/hash/common.h" #include "upb/mem/arena.h" @@ -42,7 +43,6 @@ #include "upb/wire/eps_copy_input_stream.h" #include "upb/wire/internal/constants.h" #include "upb/wire/internal/decoder.h" -#include "upb/wire/internal/endian.h" #include "upb/wire/reader.h" // Must be last. @@ -212,7 +212,7 @@ static const char* upb_Decoder_DecodeSize(upb_Decoder* d, const char* ptr, } static void _upb_Decoder_MungeInt32(wireval* val) { - if (!UPB_PRIVATE(_upb_IsLittleEndian)()) { + if (!upb_IsLittleEndian()) { /* The next stage will memcpy(dst, &val, 4) */ val->uint32_val = val->uint64_val; } @@ -434,7 +434,7 @@ static const char* _upb_Decoder_DecodeFixedPacked( arr->UPB_PRIVATE(size) += count; // Note: if/when the decoder supports multi-buffer input, we will need to // handle buffer seams here. - if (UPB_PRIVATE(_upb_IsLittleEndian)()) { + if (upb_IsLittleEndian()) { ptr = upb_EpsCopyInputStream_Copy(&d->input, ptr, mem, val->size); } else { int delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, val->size); @@ -758,7 +758,7 @@ const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, } uint64_t msg_head; memcpy(&msg_head, msg, 8); - msg_head = UPB_PRIVATE(_upb_BigEndian64)(msg_head); + msg_head = upb_BigEndian64(msg_head); if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) { d->missing_required = true; } diff --git a/upb/wire/encode.c b/upb/wire/encode.c index 5797e97ec1f70..aeec7edec3928 100644 --- a/upb/wire/encode.c +++ b/upb/wire/encode.c @@ -15,6 +15,7 @@ #include #include "upb/base/descriptor_constants.h" +#include "upb/base/internal/endian.h" #include "upb/base/string_view.h" #include "upb/hash/common.h" #include "upb/hash/str_table.h" @@ -37,7 +38,6 @@ #include "upb/mini_table/message.h" #include "upb/mini_table/sub.h" #include "upb/wire/internal/constants.h" -#include "upb/wire/internal/endian.h" #include "upb/wire/types.h" // Must be last. @@ -130,12 +130,12 @@ static void encode_bytes(upb_encstate* e, const void* data, size_t len) { } static void encode_fixed64(upb_encstate* e, uint64_t val) { - val = UPB_PRIVATE(_upb_BigEndian64)(val); + val = upb_BigEndian64(val); encode_bytes(e, &val, sizeof(uint64_t)); } static void encode_fixed32(upb_encstate* e, uint32_t val) { - val = UPB_PRIVATE(_upb_BigEndian32)(val); + val = upb_BigEndian32(val); encode_bytes(e, &val, sizeof(uint32_t)); } @@ -186,18 +186,18 @@ static void encode_fixedarray(upb_encstate* e, const upb_Array* arr, const char* data = _upb_array_constptr(arr); const char* ptr = data + bytes - elem_size; - if (tag || !UPB_PRIVATE(_upb_IsLittleEndian)()) { + if (tag || !upb_IsLittleEndian()) { while (true) { if (elem_size == 4) { uint32_t val; memcpy(&val, ptr, sizeof(val)); - val = UPB_PRIVATE(_upb_BigEndian32)(val); + val = upb_BigEndian32(val); encode_bytes(e, &val, elem_size); } else { UPB_ASSERT(elem_size == 8); uint64_t val; memcpy(&val, ptr, sizeof(val)); - val = UPB_PRIVATE(_upb_BigEndian64)(val); + val = upb_BigEndian64(val); encode_bytes(e, &val, elem_size); } @@ -552,7 +552,7 @@ static void encode_message(upb_encstate* e, const upb_Message* msg, m->UPB_PRIVATE(required_count)) { uint64_t msg_head; memcpy(&msg_head, msg, 8); - msg_head = UPB_PRIVATE(_upb_BigEndian64)(msg_head); + msg_head = upb_BigEndian64(msg_head); if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) { encode_err(e, kUpb_EncodeStatus_MissingRequired); } diff --git a/upb/wire/internal/decode_fast.h b/upb/wire/internal/decode_fast.h index 5f486297196f0..53270f82eae66 100644 --- a/upb/wire/internal/decode_fast.h +++ b/upb/wire/internal/decode_fast.h @@ -39,8 +39,8 @@ // - '1' for one-byte tags (field numbers 1-15) // - '2' for two-byte tags (field numbers 16-2048) -#ifndef UPB_WIRE_DECODE_INTERNAL_FAST_H_ -#define UPB_WIRE_DECODE_INTERNAL_FAST_H_ +#ifndef UPB_WIRE_INTERNAL_DECODE_FAST_H_ +#define UPB_WIRE_INTERNAL_DECODE_FAST_H_ #include "upb/message/message.h" @@ -110,6 +110,7 @@ TAGBYTES(o) TAGBYTES(r) #undef F +#undef UTF8 #undef TAGBYTES /* sub-message fields *********************************************************/ @@ -132,9 +133,9 @@ TAGBYTES(s) TAGBYTES(o) TAGBYTES(r) -#undef TAGBYTES -#undef SIZES #undef F +#undef SIZES +#undef TAGBYTES #undef UPB_PARSE_PARAMS @@ -144,4 +145,4 @@ TAGBYTES(r) #include "upb/port/undef.inc" -#endif /* UPB_WIRE_DECODE_INTERNAL_FAST_H_ */ +#endif /* UPB_WIRE_INTERNAL_DECODE_FAST_H_ */ diff --git a/upb/wire/internal/decoder.c b/upb/wire/internal/decoder.c new file mode 100644 index 0000000000000..f4ec76770ddba --- /dev/null +++ b/upb/wire/internal/decoder.c @@ -0,0 +1,31 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "upb/wire/internal/decoder.h" + +#include "upb/message/internal/message.h" +#include "upb/wire/decode.h" +#include "upb/wire/eps_copy_input_stream.h" + +// Must be last. +#include "upb/port/def.inc" + +const char* _upb_Decoder_BufferFlipCallback(upb_EpsCopyInputStream* e, + const char* old_end, + const char* new_start) { + upb_Decoder* d = (upb_Decoder*)e; + if (!old_end) _upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed); + + if (d->unknown) { + if (!UPB_PRIVATE(_upb_Message_AddUnknown)( + d->unknown_msg, d->unknown, old_end - d->unknown, &d->arena)) { + _upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); + } + d->unknown = new_start; + } + return new_start; +} diff --git a/upb/wire/internal/decoder.h b/upb/wire/internal/decoder.h index 5ca1e1b2b2a8e..e2d418508ccab 100644 --- a/upb/wire/internal/decoder.h +++ b/upb/wire/internal/decoder.h @@ -55,8 +55,6 @@ typedef struct upb_Decoder { * noreturn. */ const char* _upb_FastDecoder_ErrorJmp(upb_Decoder* d, int status); -extern const uint8_t upb_utf8_offsets[]; - UPB_INLINE bool _upb_Decoder_VerifyUtf8Inline(const char* ptr, int len) { return utf8_range_IsValid(ptr, len); @@ -84,20 +82,9 @@ UPB_INLINE bool _upb_Decoder_IsDone(upb_Decoder* d, const char** ptr) { &d->input, ptr, &_upb_Decoder_IsDoneFallback); } -UPB_INLINE const char* _upb_Decoder_BufferFlipCallback( - upb_EpsCopyInputStream* e, const char* old_end, const char* new_start) { - upb_Decoder* d = (upb_Decoder*)e; - if (!old_end) _upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed); - - if (d->unknown) { - if (!UPB_PRIVATE(_upb_Message_AddUnknown)( - d->unknown_msg, d->unknown, old_end - d->unknown, &d->arena)) { - _upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); - } - d->unknown = new_start; - } - return new_start; -} +UPB_API const char* _upb_Decoder_BufferFlipCallback(upb_EpsCopyInputStream* e, + const char* old_end, + const char* new_start); #if UPB_FASTTABLE UPB_INLINE diff --git a/upb/wire/reader.h b/upb/wire/reader.h index c3ec1a8b1839d..9914837d73113 100644 --- a/upb/wire/reader.h +++ b/upb/wire/reader.h @@ -8,8 +8,8 @@ #ifndef UPB_WIRE_READER_H_ #define UPB_WIRE_READER_H_ +#include "upb/base/internal/endian.h" #include "upb/wire/eps_copy_input_stream.h" -#include "upb/wire/internal/endian.h" #include "upb/wire/internal/reader.h" #include "upb/wire/types.h" // IWYU pragma: export @@ -89,7 +89,7 @@ UPB_INLINE const char* upb_WireReader_ReadSize(const char* ptr, int* size) { UPB_INLINE const char* upb_WireReader_ReadFixed32(const char* ptr, void* val) { uint32_t uval; memcpy(&uval, ptr, 4); - uval = UPB_PRIVATE(_upb_BigEndian32)(uval); + uval = upb_BigEndian32(uval); memcpy(val, &uval, 4); return ptr + 4; } @@ -102,7 +102,7 @@ UPB_INLINE const char* upb_WireReader_ReadFixed32(const char* ptr, void* val) { UPB_INLINE const char* upb_WireReader_ReadFixed64(const char* ptr, void* val) { uint64_t uval; memcpy(&uval, ptr, 8); - uval = UPB_PRIVATE(_upb_BigEndian64)(uval); + uval = upb_BigEndian64(uval); memcpy(val, &uval, 8); return ptr + 8; }