@ -181,28 +181,31 @@ typedef union {
uint32_t size ;
} wireval ;
static const char * decode_msg ( upb_Decoder * d , const char * ptr , upb_Message * msg ,
static const char * _upb_Decoder_DecodeMessage ( upb_Decoder * d , const char * ptr ,
upb_Message * msg ,
const upb_MiniTable * layout ) ;
UPB_NORETURN static void * decode_err ( upb_Decoder * d , upb_DecodeStatus status ) {
UPB_NORETURN static void * _upb_Decoder_ErrorJmp ( upb_Decoder * d ,
upb_DecodeStatus status ) {
assert ( status ! = kUpb_DecodeStatus_Ok ) ;
UPB_LONGJMP ( d - > err , status ) ;
}
const char * fastdecode_err ( upb_Decoder * d , int status ) {
const char * _upb_FastDecoder_ErrorJmp ( upb_Decoder * d , int status ) {
assert ( status ! = kUpb_DecodeStatus_Ok ) ;
UPB_LONGJMP ( d - > err , status ) ;
return NULL ;
}
static void decode_verifyutf8 ( upb_Decoder * d , const char * buf , int len ) {
if ( ! decode_verifyutf8_inl ( buf , len ) )
decode_err ( d , kUpb_DecodeStatus_BadUtf8 ) ;
static void _upb_Decoder_VerifyUtf8 ( upb_Decoder * d , const char * buf , int len ) {
if ( ! _upb_Decoder_VerifyUtf8Inline ( buf , len ) ) {
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_BadUtf8 ) ;
}
}
static bool decode_r eserve( upb_Decoder * d , upb_Array * arr , size_t elem ) {
static bool _upb_Decoder_R eserve( upb_Decoder * d , upb_Array * arr , size_t elem ) {
bool need_realloc = arr - > capacity - arr - > size < elem ;
if ( need_realloc & & ! _upb_array_realloc ( arr , arr - > size + elem , & d - > arena ) ) {
decode_err ( d , kUpb_DecodeStatus_OutOfMemory ) ;
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_OutOfMemory ) ;
}
return need_realloc ;
}
@ -210,11 +213,12 @@ static bool decode_reserve(upb_Decoder* d, upb_Array* arr, size_t elem) {
typedef struct {
const char * ptr ;
uint64_t val ;
} decode_vret ;
} _upb_DecodeLongVarintReturn ;
UPB_NOINLINE
static decode_vret decode_longvarint64 ( const char * ptr , uint64_t val ) {
decode_vret ret = { NULL , 0 } ;
static _upb_DecodeLongVarintReturn _upb_Decoder_DecodeLongVarint (
const char * ptr , uint64_t val ) {
_upb_DecodeLongVarintReturn ret = { NULL , 0 } ;
uint64_t byte ;
int i ;
for ( i = 1 ; i < 10 ; i + + ) {
@ -230,31 +234,32 @@ static decode_vret decode_longvarint64(const char* ptr, uint64_t val) {
}
UPB_FORCEINLINE
static const char * decode_varint64 ( upb_Decoder * d , const char * ptr ,
static const char * _upb_Decoder_DecodeVarint ( upb_Decoder * d , const char * ptr ,
uint64_t * val ) {
uint64_t byte = ( uint8_t ) * ptr ;
if ( UPB_LIKELY ( ( byte & 0x80 ) = = 0 ) ) {
* val = byte ;
return ptr + 1 ;
} else {
decode_vret res = decode_longvarint64 ( ptr , byte ) ;
if ( ! res . ptr ) return decode_err ( d , kUpb_DecodeStatus_Malformed ) ;
_upb_DecodeLongVarintReturn res = _upb_Decoder_DecodeLongVarint ( ptr , byte ) ;
if ( ! res . ptr ) _upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_Malformed ) ;
* val = res . val ;
return res . ptr ;
}
}
UPB_FORCEINLINE
static const char * decode_tag ( upb_Decoder * d , const char * ptr , uint32_t * val ) {
static const char * _upb_Decoder_DecodeTag ( upb_Decoder * d , const char * ptr ,
uint32_t * val ) {
uint64_t byte = ( uint8_t ) * ptr ;
if ( UPB_LIKELY ( ( byte & 0x80 ) = = 0 ) ) {
* val = byte ;
return ptr + 1 ;
} else {
const char * start = ptr ;
decode_vret res = decode_longvarint64 ( ptr , byte ) ;
_upb_DecodeLongVarintReturn res = _upb_Decoder_DecodeLongVarint ( ptr , byte ) ;
if ( ! res . ptr | | res . ptr - start > 5 | | res . val > UINT32_MAX ) {
return decode_err ( d , kUpb_DecodeStatus_Malformed ) ;
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_Malformed ) ;
}
* val = res . val ;
return res . ptr ;
@ -265,22 +270,22 @@ UPB_FORCEINLINE
static const char * upb_Decoder_DecodeSize ( upb_Decoder * d , const char * ptr ,
uint32_t * size ) {
uint64_t size64 ;
ptr = decode_varint64 ( d , ptr , & size64 ) ;
ptr = _upb_Decoder_DecodeVarint ( d , ptr , & size64 ) ;
if ( size64 > = INT32_MAX | | ptr - d - > end + ( int ) size64 > d - > limit ) {
decode_err ( d , kUpb_DecodeStatus_Malformed ) ;
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_Malformed ) ;
}
* size = size64 ;
return ptr ;
}
static void decode_munge_i nt32( wireval * val ) {
static void _upb_Decoder_MungeI nt32( wireval * val ) {
if ( ! _upb_IsLittleEndian ( ) ) {
/* The next stage will memcpy(dst, &val, 4) */
val - > uint32_val = val - > uint64_val ;
}
}
static void decode_m unge( int type , wireval * val ) {
static void _upb_Decoder_M unge( int type , wireval * val ) {
switch ( type ) {
case kUpb_FieldType_Bool :
val - > bool_val = val - > uint64_val ! = 0 ;
@ -298,38 +303,36 @@ static void decode_munge(int type, wireval* val) {
case kUpb_FieldType_Int32 :
case kUpb_FieldType_UInt32 :
case kUpb_FieldType_Enum :
decode_munge_i nt32( val ) ;
_upb_Decoder_MungeI nt32( val ) ;
break ;
}
}
static upb_Message * decode_newsubmsg ( upb_Decoder * d ,
const upb_MiniTable_Sub * subs ,
static upb_Message * _upb_Decoder_NewSubMessage (
upb_Decoder * d , const upb_MiniTable_Sub * subs ,
const upb_MiniTable_Field * field ) {
const upb_MiniTable * subl = subs [ field - > submsg_index ] . submsg ;
upb_Message * msg = _upb_Message_New_inl ( subl , & d - > arena ) ;
if ( ! msg ) decode_err ( d , kUpb_DecodeStatus_OutOfMemory ) ;
if ( ! msg ) _upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_OutOfMemory ) ;
return msg ;
}
UPB_NOINLINE
const char * decode_isdonef allback( upb_Decoder * d , const char * ptr ,
const char * _upb_Decoder_IsDoneF allback( upb_Decoder * d , const char * ptr ,
int overrun ) {
int status ;
ptr = decode_isdonefallback_inl ( d , ptr , overrun , & status ) ;
if ( ptr = = NULL ) {
return decode_err ( d , status ) ;
}
ptr = _upb_Decoder_IsDoneFallbackInline ( d , ptr , overrun , & status ) ;
if ( ptr = = NULL ) _upb_Decoder_ErrorJmp ( d , status ) ;
return ptr ;
}
static const char * decode_readstr ( upb_Decoder * d , const char * ptr , int size ,
upb_StringView * str ) {
static const char * _upb_Decoder_ReadString ( upb_Decoder * d , const char * ptr ,
int size , upb_StringView * str ) {
if ( d - > options & kUpb_DecodeOption_AliasString ) {
str - > data = ptr ;
} else {
char * data = upb_Arena_Malloc ( & d - > arena , size ) ;
if ( ! data ) return decode_err ( d , kUpb_DecodeStatus_OutOfMemory ) ;
if ( ! data ) _upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_OutOfMemory ) ;
memcpy ( data , ptr , size ) ;
str - > data = data ;
}
@ -338,50 +341,56 @@ static const char* decode_readstr(upb_Decoder* d, const char* ptr, int size,
}
UPB_FORCEINLINE
static const char * decode_tosubmsg2 ( upb_Decoder * d , const char * ptr ,
upb_Message * submsg ,
const upb_MiniTable * subl , int size ) {
int saved_delta = decode_pushlimit ( d , ptr , size ) ;
if ( - - d - > depth < 0 ) return decode_err ( d , kUpb_DecodeStatus_MaxDepthExceeded ) ;
ptr = decode_msg ( d , ptr , submsg , subl ) ;
if ( d - > end_group ! = DECODE_NOGROUP )
return decode_err ( d , kUpb_DecodeStatus_Malformed ) ;
decode_poplimit ( d , ptr , saved_delta ) ;
static const char * _upb_Decoder_DecodeSubMessage (
upb_Decoder * d , const char * ptr , upb_Message * submsg ,
const upb_MiniTable_Sub * subs , const upb_MiniTable_Field * field , int size ) {
int saved_delta = _upb_Decoder_PushLimit ( d , ptr , size ) ;
const upb_MiniTable * subl = subs [ field - > submsg_index ] . submsg ;
if ( - - d - > depth < 0 ) {
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_MaxDepthExceeded ) ;
}
ptr = _upb_Decoder_DecodeMessage ( d , ptr , submsg , subl ) ;
if ( d - > end_group ! = DECODE_NOGROUP ) {
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_Malformed ) ;
}
_upb_Decoder_PopLimit ( d , ptr , saved_delta ) ;
d - > depth + + ;
return ptr ;
}
UPB_FORCEINLINE
static const char * decode_tosubmsg ( upb_Decoder * d , const char * ptr ,
static const char * _upb_Decoder_DoDecodeGroup ( upb_Decoder * d , const char * ptr ,
upb_Message * submsg ,
const upb_MiniTable_Sub * subs ,
const upb_MiniTable_Field * field , int size ) {
return decode_tosubmsg2 ( d , ptr , submsg , subs [ field - > submsg_index ] . submsg ,
size ) ;
}
UPB_FORCEINLINE
static const char * decode_group ( upb_Decoder * d , const char * ptr ,
upb_Message * submsg , const upb_MiniTable * subl ,
const upb_MiniTable * subl ,
uint32_t number ) {
if ( - - d - > depth < 0 ) return decode_err ( d , kUpb_DecodeStatus_MaxDepthExceeded ) ;
if ( decode_isdone ( d , & ptr ) ) {
return decode_err ( d , kUpb_DecodeStatus_Malformed ) ;
if ( - - d - > depth < 0 ) {
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_MaxDepthExceeded ) ;
}
if ( _upb_Decoder_IsDone ( d , & ptr ) ) {
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_Malformed ) ;
}
ptr = _upb_Decoder_DecodeMessage ( d , ptr , submsg , subl ) ;
if ( d - > end_group ! = number ) {
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_Malformed ) ;
}
ptr = decode_msg ( d , ptr , submsg , subl ) ;
if ( d - > end_group ! = number ) return decode_err ( d , kUpb_DecodeStatus_Malformed ) ;
d - > end_group = DECODE_NOGROUP ;
d - > depth + + ;
return ptr ;
}
UPB_FORCEINLINE
static const char * decode_togroup ( upb_Decoder * d , const char * ptr ,
upb_Message * submsg ,
const upb_MiniTable_Sub * subs ,
const upb_MiniTable_Field * field ) {
static const char * _upb_Decoder_DecodeUnknownGroup ( upb_Decoder * d ,
const char * ptr ,
uint32_t number ) {
return _upb_Decoder_DoDecodeGroup ( d , ptr , NULL , NULL , number ) ;
}
UPB_FORCEINLINE
static const char * _upb_Decoder_DecodeKnownGroup (
upb_Decoder * d , const char * ptr , upb_Message * submsg ,
const upb_MiniTable_Sub * subs , const upb_MiniTable_Field * field ) {
const upb_MiniTable * subl = subs [ field - > submsg_index ] . submsg ;
return decode_group ( d , ptr , submsg , subl , field - > number ) ;
return _upb_Decoder_DoDecodeG roup( d , ptr , submsg , subl , field - > number ) ;
}
static char * upb_Decoder_EncodeVarint32 ( uint32_t val , char * ptr ) {
@ -394,7 +403,7 @@ static char* upb_Decoder_EncodeVarint32(uint32_t val, char* ptr) {
return ptr ;
}
static void upb_Decode_AddUnknownVarints ( upb_Decoder * d , upb_Message * msg ,
static void _ upb_Decoder _AddUnknownVarints( upb_Decoder * d , upb_Message * msg ,
uint32_t val1 , uint32_t val2 ) {
char buf [ 20 ] ;
char * end = buf ;
@ -402,13 +411,14 @@ static void upb_Decode_AddUnknownVarints(upb_Decoder* d, upb_Message* msg,
end = upb_Decoder_EncodeVarint32 ( val2 , end ) ;
if ( ! _upb_Message_AddUnknown ( msg , buf , end - buf , & d - > arena ) ) {
decode_err ( d , kUpb_DecodeStatus_OutOfMemory ) ;
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_OutOfMemory ) ;
}
}
UPB_NOINLINE
static bool decode_checkenum_slow ( upb_Decoder * d , const char * ptr ,
upb_Message * msg , const upb_MiniTable_Enum * e ,
static bool _upb_Decoder_CheckEnumSlow ( upb_Decoder * d , const char * ptr ,
upb_Message * msg ,
const upb_MiniTable_Enum * e ,
const upb_MiniTable_Field * field ,
uint32_t v ) {
// OPT: binary search long lists?
@ -423,29 +433,30 @@ static bool decode_checkenum_slow(upb_Decoder* d, const char* ptr,
uint32_t tag = ( ( uint32_t ) field - > number < < 3 ) | kUpb_WireType_Varint ;
upb_Message * unknown_msg =
field - > mode & kUpb_LabelFlags_IsExtension ? d - > unknown_msg : msg ;
upb_Decode_AddUnknownVarints ( d , unknown_msg , tag , v ) ;
_ upb_Decoder _AddUnknownVarints( d , unknown_msg , tag , v ) ;
return false ;
}
UPB_FORCEINLINE
static bool decode_checkenum ( upb_Decoder * d , const char * ptr , upb_Message * msg ,
static bool _upb_Decoder_CheckEnum ( upb_Decoder * d , const char * ptr ,
upb_Message * msg ,
const upb_MiniTable_Enum * e ,
const upb_MiniTable_Field * field , wireval * val ) {
const upb_MiniTable_Field * field ,
wireval * val ) {
uint32_t v = val - > uint32_val ;
if ( UPB_LIKELY ( v < 64 ) & & UPB_LIKELY ( ( ( 1ULL < < v ) & e - > mask ) ) ) return true ;
return decode_checkenum_s low( d , ptr , msg , e , field , v ) ;
return _upb_Decoder_CheckEnumS low( d , ptr , msg , e , field , v ) ;
}
UPB_NOINLINE
static const char * decode_enum_toarray ( upb_Decoder * d , const char * ptr ,
upb_Message * msg , upb_Array * arr ,
const upb_MiniTable_Sub * subs ,
const upb_MiniTable_Field * field ,
static const char * _upb_Decoder_DecodeEnumArray (
upb_Decoder * d , const char * ptr , upb_Message * msg , upb_Array * arr ,
const upb_MiniTable_Sub * subs , const upb_MiniTable_Field * field ,
wireval * val ) {
const upb_MiniTable_Enum * e = subs [ field - > submsg_index ] . subenum ;
if ( ! decode_checke num( d , ptr , msg , e , field , val ) ) return ptr ;
if ( ! _upb_Decoder_CheckE num( d , ptr , msg , e , field , val ) ) return ptr ;
void * mem = UPB_PTR_AT ( _upb_array_ptr ( arr ) , arr - > size * 4 , void ) ;
arr - > size + + ;
memcpy ( mem , val , 4 ) ;
@ -453,17 +464,16 @@ static const char* decode_enum_toarray(upb_Decoder* d, const char* ptr,
}
UPB_FORCEINLINE
static const char * decode_fixed_packed ( upb_Decoder * d , const char * ptr ,
upb_Array * arr , wireval * val ,
const upb_MiniTable_Field * field ,
int lg2 ) {
static const char * _upb_Decoder_DecodeFixedPacked (
upb_Decoder * d , const char * ptr , upb_Array * arr , wireval * val ,
const upb_MiniTable_Field * field , int lg2 ) {
int mask = ( 1 < < lg2 ) - 1 ;
size_t count = val - > size > > lg2 ;
if ( ( val - > size & mask ) ! = 0 ) {
// Length isn't a round multiple of elem size.
return decode_err ( d , kUpb_DecodeStatus_Malformed ) ;
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_Malformed ) ;
}
decode_r eserve( d , arr , count ) ;
_upb_Decoder_R eserve( d , arr , count ) ;
void * mem = UPB_PTR_AT ( _upb_array_ptr ( arr ) , arr - > size < < lg2 , void ) ;
arr - > size + = count ;
// Note: if/when the decoder supports multi-buffer input, we will need to
@ -496,56 +506,54 @@ static const char* decode_fixed_packed(upb_Decoder* d, const char* ptr,
}
UPB_FORCEINLINE
static const char * decode_varint_packed ( upb_Decoder * d , const char * ptr ,
upb_Array * arr , wireval * val ,
const upb_MiniTable_Field * field ,
int lg2 ) {
static const char * _upb_Decoder_DecodeVarintPacked (
upb_Decoder * d , const char * ptr , upb_Array * arr , wireval * val ,
const upb_MiniTable_Field * field , int lg2 ) {
int scale = 1 < < lg2 ;
int saved_limit = decode_pushl imit( d , ptr , val - > size ) ;
int saved_limit = _upb_Decoder_PushL imit( d , ptr , val - > size ) ;
char * out = UPB_PTR_AT ( _upb_array_ptr ( arr ) , arr - > size < < lg2 , void ) ;
while ( ! decode_isd one( d , & ptr ) ) {
while ( ! _upb_Decoder_IsD one( d , & ptr ) ) {
wireval elem ;
ptr = decode_varint64 ( d , ptr , & elem . uint64_val ) ;
decode_m unge( field - > descriptortype , & elem ) ;
if ( decode_r eserve( d , arr , 1 ) ) {
ptr = _upb_Decoder_DecodeVarint ( d , ptr , & elem . uint64_val ) ;
_upb_Decoder_M unge( field - > descriptortype , & elem ) ;
if ( _upb_Decoder_R eserve( d , arr , 1 ) ) {
out = UPB_PTR_AT ( _upb_array_ptr ( arr ) , arr - > size < < lg2 , void ) ;
}
arr - > size + + ;
memcpy ( out , & elem , scale ) ;
out + = scale ;
}
decode_popl imit( d , ptr , saved_limit ) ;
_upb_Decoder_PopL imit( d , ptr , saved_limit ) ;
return ptr ;
}
UPB_NOINLINE
static const char * decode_enum_packed ( upb_Decoder * d , const char * ptr ,
upb_Message * msg , upb_Array * arr ,
const upb_MiniTable_Sub * subs ,
const upb_MiniTable_Field * field ,
static const char * _upb_Decoder_DecodeEnumPacked (
upb_Decoder * d , const char * ptr , upb_Message * msg , upb_Array * arr ,
const upb_MiniTable_Sub * subs , const upb_MiniTable_Field * field ,
wireval * val ) {
const upb_MiniTable_Enum * e = subs [ field - > submsg_index ] . subenum ;
int saved_limit = decode_pushl imit( d , ptr , val - > size ) ;
int saved_limit = _upb_Decoder_PushL imit( d , ptr , val - > size ) ;
char * out = UPB_PTR_AT ( _upb_array_ptr ( arr ) , arr - > size * 4 , void ) ;
while ( ! decode_isd one( d , & ptr ) ) {
while ( ! _upb_Decoder_IsD one( d , & ptr ) ) {
wireval elem ;
ptr = decode_varint64 ( d , ptr , & elem . uint64_val ) ;
decode_munge_i nt32( & elem ) ;
if ( ! decode_checke num( d , ptr , msg , e , field , & elem ) ) {
ptr = _upb_Decoder_DecodeVarint ( d , ptr , & elem . uint64_val ) ;
_upb_Decoder_MungeI nt32( & elem ) ;
if ( ! _upb_Decoder_CheckE num( d , ptr , msg , e , field , & elem ) ) {
continue ;
}
if ( decode_r eserve( d , arr , 1 ) ) {
if ( _upb_Decoder_R eserve( d , arr , 1 ) ) {
out = UPB_PTR_AT ( _upb_array_ptr ( arr ) , arr - > size * 4 , void ) ;
}
arr - > size + + ;
memcpy ( out , & elem , 4 ) ;
out + = 4 ;
}
decode_popl imit( d , ptr , saved_limit ) ;
_upb_Decoder_PopL imit( d , ptr , saved_limit ) ;
return ptr ;
}
static const char * decode_toa rray( upb_Decoder * d , const char * ptr ,
static const char * _upb_Decoder_DecodeToA rray( upb_Decoder * d , const char * ptr ,
upb_Message * msg ,
const upb_MiniTable_Sub * subs ,
const upb_MiniTable_Field * field ,
@ -555,11 +563,11 @@ static const char* decode_toarray(upb_Decoder* d, const char* ptr,
void * mem ;
if ( arr ) {
decode_r eserve( d , arr , 1 ) ;
_upb_Decoder_R eserve( d , arr , 1 ) ;
} else {
size_t lg2 = desctype_to_elem_size_lg2 [ field - > descriptortype ] ;
arr = _upb_Array_New ( & d - > arena , 4 , lg2 ) ;
if ( ! arr ) return decode_err ( d , kUpb_DecodeStatus_OutOfMemory ) ;
if ( ! arr ) _upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_OutOfMemory ) ;
* arrp = arr ;
}
@ -573,46 +581,48 @@ static const char* decode_toarray(upb_Decoder* d, const char* ptr,
memcpy ( mem , val , 1 < < op ) ;
return ptr ;
case OP_STRING :
decode_verifyu tf8( d , ptr , val - > size ) ;
_upb_Decoder_VerifyU tf8( d , ptr , val - > size ) ;
/* Fallthrough. */
case OP_BYTES : {
/* Append bytes. */
upb_StringView * str = ( upb_StringView * ) _upb_array_ptr ( arr ) + arr - > size ;
arr - > size + + ;
return decode_readstr ( d , ptr , val - > size , str ) ;
return _upb_Decoder_ReadString ( d , ptr , val - > size , str ) ;
}
case OP_SUBMSG : {
/* Append submessage / group. */
upb_Message * submsg = decode_newsubmsg ( d , subs , field ) ;
upb_Message * submsg = _upb_Decoder_NewSubMessage ( d , subs , field ) ;
* UPB_PTR_AT ( _upb_array_ptr ( arr ) , arr - > size * sizeof ( void * ) ,
upb_Message * ) = submsg ;
arr - > size + + ;
if ( UPB_UNLIKELY ( field - > descriptortype = = kUpb_FieldType_Group ) ) {
return decode_tog roup( d , ptr , submsg , subs , field ) ;
return _upb_Decoder_DecodeKnownG roup( d , ptr , submsg , subs , field ) ;
} else {
return decode_tosubmsg ( d , ptr , submsg , subs , field , val - > size ) ;
return _upb_Decoder_DecodeSubMessage ( d , ptr , submsg , subs , field ,
val - > size ) ;
}
}
case OP_FIXPCK_LG2 ( 2 ) :
case OP_FIXPCK_LG2 ( 3 ) :
return decode_fixed_p acked( d , ptr , arr , val , field ,
return _upb_Decoder_DecodeFixedP acked( d , ptr , arr , val , field ,
op - OP_FIXPCK_LG2 ( 0 ) ) ;
case OP_VARPCK_LG2 ( 0 ) :
case OP_VARPCK_LG2 ( 2 ) :
case OP_VARPCK_LG2 ( 3 ) :
return decode_varint_p acked( d , ptr , arr , val , field ,
return _upb_Decoder_DecodeVarintP acked( d , ptr , arr , val , field ,
op - OP_VARPCK_LG2 ( 0 ) ) ;
case OP_ENUM :
return decode_enum_toa rray( d , ptr , msg , arr , subs , field , val ) ;
return _upb_Decoder_DecodeEnumA rray( d , ptr , msg , arr , subs , field , val ) ;
case OP_PACKED_ENUM :
return decode_enum_p acked( d , ptr , msg , arr , subs , field , val ) ;
return _upb_Decoder_DecodeEnumP acked( d , ptr , msg , arr , subs , field , val ) ;
default :
UPB_UNREACHABLE ( ) ;
}
}
static const char * decode_tomap ( upb_Decoder * d , const char * ptr ,
upb_Message * msg , const upb_MiniTable_Sub * subs ,
static const char * _upb_Decoder_DecodeToMap ( upb_Decoder * d , const char * ptr ,
upb_Message * msg ,
const upb_MiniTable_Sub * subs ,
const upb_MiniTable_Field * field ,
wireval * val ) {
upb_Map * * map_p = UPB_PTR_AT ( msg , field - > offset , upb_Map * ) ;
@ -643,35 +653,35 @@ static const char* decode_tomap(upb_Decoder* d, const char* ptr,
}
const char * start = ptr ;
ptr = decode_tosubmsg ( d , ptr , & ent . k , subs , field , val - > size ) ;
ptr = _upb_Decoder_DecodeSubMessage ( d , ptr , & ent . k , subs , field , val - > size ) ;
// check if ent had any unknown fields
size_t size ;
upb_Message_GetUnknown ( & ent . k , & size ) ;
if ( size ! = 0 ) {
uint32_t tag = ( ( uint32_t ) field - > number < < 3 ) | kUpb_WireType_Delimited ;
upb_Decode_AddUnknownVarints ( d , msg , tag , ( uint32_t ) ( ptr - start ) ) ;
_ upb_Decoder _AddUnknownVarints( d , msg , tag , ( uint32_t ) ( ptr - start ) ) ;
if ( ! _upb_Message_AddUnknown ( msg , start , ptr - start , & d - > arena ) ) {
decode_err ( d , kUpb_DecodeStatus_OutOfMemory ) ;
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_OutOfMemory ) ;
}
} else {
if ( _upb_Map_Insert ( map , & ent . k , map - > key_size , & ent . v , map - > val_size ,
& d - > arena ) = = _kUpb_MapInsertStatus_OutOfMemory ) {
decode_err ( d , kUpb_DecodeStatus_OutOfMemory ) ;
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_OutOfMemory ) ;
}
}
return ptr ;
}
static const char * decode_tomsg ( upb_Decoder * d , const char * ptr ,
upb_Message * msg , const upb_MiniTable_Sub * subs ,
const upb_MiniTable_Field * field , wireval * val ,
int op ) {
static const char * _upb_Decoder_DecodeToSubMessage (
upb_Decoder * d , const char * ptr , upb_Message * msg ,
const upb_MiniTable_Sub * subs , const upb_MiniTable_Field * field ,
wireval * val , int op ) {
void * mem = UPB_PTR_AT ( msg , field - > offset , void ) ;
int type = field - > descriptortype ;
if ( UPB_UNLIKELY ( op = = OP_ENUM ) & &
! decode_checke num( d , ptr , msg , subs [ field - > submsg_index ] . subenum , field ,
val ) ) {
! _upb_Decoder_CheckE num( d , ptr , msg , subs [ field - > submsg_index ] . subenum ,
field , val ) ) {
return ptr ;
}
@ -693,21 +703,22 @@ static const char* decode_tomsg(upb_Decoder* d, const char* ptr,
upb_Message * * submsgp = mem ;
upb_Message * submsg = * submsgp ;
if ( ! submsg ) {
submsg = decode_newsubmsg ( d , subs , field ) ;
submsg = _upb_Decoder_NewSubMessage ( d , subs , field ) ;
* submsgp = submsg ;
}
if ( UPB_UNLIKELY ( type = = kUpb_FieldType_Group ) ) {
ptr = decode_tog roup( d , ptr , submsg , subs , field ) ;
ptr = _upb_Decoder_DecodeKnownG roup( d , ptr , submsg , subs , field ) ;
} else {
ptr = decode_tosubmsg ( d , ptr , submsg , subs , field , val - > size ) ;
ptr = _upb_Decoder_DecodeSubMessage ( d , ptr , submsg , subs , field ,
val - > size ) ;
}
break ;
}
case OP_STRING :
decode_verifyu tf8( d , ptr , val - > size ) ;
_upb_Decoder_VerifyU tf8( d , ptr , val - > size ) ;
/* Fallthrough. */
case OP_BYTES :
return decode_readstr ( d , ptr , val - > size , mem ) ;
return _upb_Decoder_ReadString ( d , ptr , val - > size , mem ) ;
case OP_SCALAR_LG2 ( 3 ) :
memcpy ( mem , val , 8 ) ;
break ;
@ -726,7 +737,7 @@ static const char* decode_tomsg(upb_Decoder* d, const char* ptr,
}
UPB_NOINLINE
const char * decode_checkr equired( upb_Decoder * d , const char * ptr ,
const char * _upb_Decoder_CheckR equired( upb_Decoder * d , const char * ptr ,
const upb_Message * msg ,
const upb_MiniTable * l ) {
assert ( l - > required_count ) ;
@ -743,14 +754,14 @@ const char* decode_checkrequired(upb_Decoder* d, const char* ptr,
}
UPB_FORCEINLINE
static bool decode_tryfastd ispatch( upb_Decoder * d , const char * * ptr ,
static bool _upb_Decoder_TryFastD ispatch( upb_Decoder * d , const char * * ptr ,
upb_Message * msg ,
const upb_MiniTable * layout ) {
# if UPB_FASTTABLE
if ( layout & & layout - > table_mask ! = ( unsigned char ) - 1 ) {
uint16_t tag = fastdecode_loadt ag( * ptr ) ;
uint16_t tag = _upb_FastDecoder_LoadT ag( * ptr ) ;
intptr_t table = decode_totable ( layout ) ;
* ptr = fastdecode_tagd ispatch( d , * ptr , msg , table , 0 , tag ) ;
* ptr = _upb_FastDecoder_TagD ispatch( d , * ptr , msg , table , 0 , tag ) ;
return true ;
}
# endif
@ -764,7 +775,7 @@ static const char* upb_Decoder_SkipField(upb_Decoder* d, const char* ptr,
switch ( wire_type ) {
case kUpb_WireType_Varint : {
uint64_t val ;
return decode_varint64 ( d , ptr , & val ) ;
return _upb_Decoder_DecodeVarint ( d , ptr , & val ) ;
}
case kUpb_WireType_64Bit :
return ptr + 8 ;
@ -776,9 +787,9 @@ static const char* upb_Decoder_SkipField(upb_Decoder* d, const char* ptr,
return ptr + size ;
}
case kUpb_WireType_StartGroup :
return decode_g roup( d , ptr , NULL , NULL , field_number ) ;
return _upb_Decoder_DecodeUnknownG roup( d , ptr , field_number ) ;
default :
decode_err ( d , kUpb_DecodeStatus_Malformed ) ;
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_Malformed ) ;
}
}
@ -794,12 +805,15 @@ static void upb_Decoder_AddKnownMessageSetItem(
const char * data , uint32_t size ) {
upb_Message_Extension * ext =
_upb_Message_GetOrCreateExtension ( msg , item_mt , & d - > arena ) ;
if ( UPB_UNLIKELY ( ! ext ) ) decode_err ( d , kUpb_DecodeStatus_OutOfMemory ) ;
upb_Message * submsg = decode_newsubmsg ( d , & ext - > ext - > sub , & ext - > ext - > field ) ;
if ( UPB_UNLIKELY ( ! ext ) ) {
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_OutOfMemory ) ;
}
upb_Message * submsg =
_upb_Decoder_NewSubMessage ( d , & ext - > ext - > sub , & ext - > ext - > field ) ;
upb_DecodeStatus status = upb_Decode ( data , size , submsg , item_mt - > sub . submsg ,
d - > extreg , d - > options , & d - > arena ) ;
memcpy ( & ext - > data , & submsg , sizeof ( submsg ) ) ;
if ( status ! = kUpb_DecodeStatus_Ok ) decode_err ( d , status ) ;
if ( status ! = kUpb_DecodeStatus_Ok ) _upb_Decoder_ErrorJmp ( d , status ) ;
}
static void upb_Decoder_AddUnknownMessageSetItem ( upb_Decoder * d ,
@ -822,7 +836,7 @@ static void upb_Decoder_AddUnknownMessageSetItem(upb_Decoder* d,
if ( ! _upb_Message_AddUnknown ( msg , buf , split - buf , & d - > arena ) | |
! _upb_Message_AddUnknown ( msg , message_data , message_size , & d - > arena ) | |
! _upb_Message_AddUnknown ( msg , split , end - split , & d - > arena ) ) {
decode_err ( d , kUpb_DecodeStatus_OutOfMemory ) ;
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_OutOfMemory ) ;
}
}
@ -849,15 +863,15 @@ static const char* upb_Decoder_DecodeMessageSetItem(
kUpb_HavePayload = 1 < < 1 ,
} StateMask ;
StateMask state_mask = 0 ;
while ( ! decode_isd one( d , & ptr ) ) {
while ( ! _upb_Decoder_IsD one( d , & ptr ) ) {
uint32_t tag ;
ptr = decode_t ag( d , ptr , & tag ) ;
ptr = _upb_Decoder_DecodeT ag( d , ptr , & tag ) ;
switch ( tag ) {
case kEndItemTag :
return ptr ;
case kTypeIdTag : {
uint64_t tmp ;
ptr = decode_varint64 ( d , ptr , & tmp ) ;
ptr = _upb_Decoder_DecodeVarint ( d , ptr , & tmp ) ;
if ( state_mask & kUpb_HaveId ) break ; // Ignore dup.
state_mask | = kUpb_HaveId ;
type_id = tmp ;
@ -889,12 +903,11 @@ static const char* upb_Decoder_DecodeMessageSetItem(
break ;
}
}
decode_err ( d , kUpb_DecodeStatus_Malformed ) ;
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_Malformed ) ;
}
static const upb_MiniTable_Field * decode_findfield ( upb_Decoder * d ,
const upb_MiniTable * l ,
uint32_t field_number ,
static const upb_MiniTable_Field * _upb_Decoder_FindField (
upb_Decoder * d , const upb_MiniTable * l , uint32_t field_number ,
int * last_field_index ) {
static upb_MiniTable_Field none = { 0 , 0 , 0 , 0 , 0 , 0 } ;
if ( l = = NULL ) return & none ;
@ -948,14 +961,14 @@ found:
}
UPB_FORCEINLINE
static const char * decode_wireval ( upb_Decoder * d , const char * ptr ,
const upb_MiniTable_Field * field ,
static const char * _upb_Decoder_DecodeWireValue (
upb_Decoder * d , const char * ptr , const upb_MiniTable_Field * field ,
int wire_type , wireval * val , int * op ) {
switch ( wire_type ) {
case kUpb_WireType_Varint :
ptr = decode_varint64 ( d , ptr , & val - > uint64_val ) ;
ptr = _upb_Decoder_DecodeVarint ( d , ptr , & val - > uint64_val ) ;
* op = varint_ops [ field - > descriptortype ] ;
decode_m unge( field - > descriptortype , val ) ;
_upb_Decoder_M unge( field - > descriptortype , val ) ;
return ptr ;
case kUpb_WireType_32Bit :
memcpy ( & val - > uint32_val , ptr , 4 ) ;
@ -993,13 +1006,13 @@ static const char* decode_wireval(upb_Decoder* d, const char* ptr,
default :
break ;
}
return decode_err ( d , kUpb_DecodeStatus_Malformed ) ;
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_Malformed ) ;
}
UPB_FORCEINLINE
static const char * decode_known ( upb_Decoder * d , const char * ptr ,
upb_Message * msg , const upb_MiniTable * layout ,
const upb_MiniTable_Field * field , int op ,
static const char * _upb_Decoder_DecodeKnownField (
upb_Decoder * d , const char * ptr , upb_Message * msg ,
const upb_MiniTable * layout , const upb_MiniTable_Field * field , int op ,
wireval * val ) {
const upb_MiniTable_Sub * subs = layout - > subs ;
uint8_t mode = field - > mode ;
@ -1009,7 +1022,9 @@ static const char* decode_known(upb_Decoder* d, const char* ptr,
( const upb_MiniTable_Extension * ) field ;
upb_Message_Extension * ext =
_upb_Message_GetOrCreateExtension ( msg , ext_layout , & d - > arena ) ;
if ( UPB_UNLIKELY ( ! ext ) ) return decode_err ( d , kUpb_DecodeStatus_OutOfMemory ) ;
if ( UPB_UNLIKELY ( ! ext ) ) {
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_OutOfMemory ) ;
}
d - > unknown_msg = msg ;
msg = & ext - > data ;
subs = & ext - > ext - > sub ;
@ -1017,17 +1032,18 @@ static const char* decode_known(upb_Decoder* d, const char* ptr,
switch ( mode & kUpb_FieldMode_Mask ) {
case kUpb_FieldMode_Array :
return decode_toa rray( d , ptr , msg , subs , field , val , op ) ;
return _upb_Decoder_DecodeToA rray( d , ptr , msg , subs , field , val , op ) ;
case kUpb_FieldMode_Map :
return decode_tom ap( d , ptr , msg , subs , field , val ) ;
return _upb_Decoder_DecodeToM ap( d , ptr , msg , subs , field , val ) ;
case kUpb_FieldMode_Scalar :
return decode_tomsg ( d , ptr , msg , subs , field , val , op ) ;
return _upb_Decoder_DecodeToSubMessage ( d , ptr , msg , subs , field , val , op ) ;
default :
UPB_UNREACHABLE ( ) ;
}
}
static const char * decode_reverse_skip_varint ( const char * ptr , uint32_t val ) {
static const char * _upb_Decoder_ReverseSkipVarint ( const char * ptr ,
uint32_t val ) {
uint32_t seen = 0 ;
do {
ptr - - ;
@ -1037,10 +1053,12 @@ static const char* decode_reverse_skip_varint(const char* ptr, uint32_t val) {
return ptr ;
}
static const char * decode_unknown ( upb_Decoder * d , const char * ptr ,
upb_Message * msg , int field_number ,
static const char * _upb_Decoder_DecodeUnknownField ( upb_Decoder * d ,
const char * ptr ,
upb_Message * msg ,
int field_number ,
int wire_type , wireval val ) {
if ( field_number = = 0 ) return decode_err ( d , kUpb_DecodeStatus_Malformed ) ;
if ( field_number = = 0 ) _upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_Malformed ) ;
// Since unknown fields are the uncommon case, we do a little extra work here
// to walk backwards through the buffer to find the field start. This frees
@ -1068,37 +1086,38 @@ static const char* decode_unknown(upb_Decoder* d, const char* ptr,
assert ( start = = d - > debug_valstart ) ;
uint32_t tag = ( ( uint32_t ) field_number < < 3 ) | wire_type ;
start = decode_reverse_skip_v arint( start , tag ) ;
start = _upb_Decoder_ReverseSkipV arint( start , tag ) ;
assert ( start = = d - > debug_tagstart ) ;
if ( wire_type = = kUpb_WireType_StartGroup ) {
d - > unknown = start ;
d - > unknown_msg = msg ;
ptr = decode_g roup( d , ptr , NULL , NULL , field_number ) ;
ptr = _upb_Decoder_DecodeUnknownG roup( d , ptr , field_number ) ;
start = d - > unknown ;
d - > unknown = NULL ;
}
if ( ! _upb_Message_AddUnknown ( msg , start , ptr - start , & d - > arena ) ) {
return decode_err ( d , kUpb_DecodeStatus_OutOfMemory ) ;
_upb_Decoder_ErrorJmp ( d , kUpb_DecodeStatus_OutOfMemory ) ;
}
} else if ( wire_type = = kUpb_WireType_StartGroup ) {
ptr = decode_g roup( d , ptr , NULL , NULL , field_number ) ;
ptr = _upb_Decoder_DecodeUnknownG roup( d , ptr , field_number ) ;
}
return ptr ;
}
UPB_NOINLINE
static const char * decode_msg ( upb_Decoder * d , const char * ptr , upb_Message * msg ,
static const char * _upb_Decoder_DecodeMessage ( upb_Decoder * d , const char * ptr ,
upb_Message * msg ,
const upb_MiniTable * layout ) {
int last_field_index = 0 ;
# if UPB_FASTTABLE
// The first time we want to skip fast dispatch, because we may have just been
// invoked by the fast parser to handle a case that it bailed on.
if ( ! decode_isd one( d , & ptr ) ) goto nofast ;
if ( ! _upb_Decoder_IsD one( d , & ptr ) ) goto nofast ;
# endif
while ( ! decode_isd one( d , & ptr ) ) {
while ( ! _upb_Decoder_IsD one( d , & ptr ) ) {
uint32_t tag ;
const upb_MiniTable_Field * field ;
int field_number ;
@ -1106,7 +1125,7 @@ static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg,
wireval val ;
int op ;
if ( decode_tryfastd ispatch( d , & ptr , msg , layout ) ) break ;
if ( _upb_Decoder_TryFastD ispatch( d , & ptr , msg , layout ) ) break ;
# if UPB_FASTTABLE
nofast :
@ -1117,7 +1136,7 @@ static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg,
# endif
UPB_ASSERT ( ptr < d - > limit_ptr ) ;
ptr = decode_t ag( d , ptr , & tag ) ;
ptr = _upb_Decoder_DecodeT ag( d , ptr , & tag ) ;
field_number = tag > > 3 ;
wire_type = tag & 7 ;
@ -1130,15 +1149,16 @@ static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg,
return ptr ;
}
field = decode_findf ield( d , layout , field_number , & last_field_index ) ;
ptr = decode_wireval ( d , ptr , field , wire_type , & val , & op ) ;
field = _upb_Decoder_FindF ield( d , layout , field_number , & last_field_index ) ;
ptr = _upb_Decoder_DecodeWireValue ( d , ptr , field , wire_type , & val , & op ) ;
if ( op > = 0 ) {
ptr = decode_known ( d , ptr , msg , layout , field , op , & val ) ;
ptr = _upb_Decoder_DecodeKnownField ( d , ptr , msg , layout , field , op , & val ) ;
} else {
switch ( op ) {
case OP_UNKNOWN :
ptr = decode_unknown ( d , ptr , msg , field_number , wire_type , val ) ;
ptr = _upb_Decoder_DecodeUnknownField ( d , ptr , msg , field_number ,
wire_type , val ) ;
break ;
case OP_MSGSET_ITEM :
ptr = upb_Decoder_DecodeMessageSetItem ( d , ptr , msg , layout ) ;
@ -1148,22 +1168,24 @@ static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg,
}
return UPB_UNLIKELY ( layout & & layout - > required_count )
? decode_checkr equired( d , ptr , msg , layout )
? _upb_Decoder_CheckR equired( d , ptr , msg , layout )
: ptr ;
}
const char * fastdecode_generic ( struct upb_Decoder * d , const char * ptr ,
upb_Message * msg , intptr_t table ,
uint64_t hasbits , uint64_t data ) {
const char * _upb_FastDecoder_DecodeGeneric ( struct upb_Decoder * d ,
const char * ptr , upb_Message * msg ,
intptr_t table , uint64_t hasbits ,
uint64_t data ) {
( void ) data ;
* ( uint32_t * ) msg | = hasbits ;
return decode_msg ( d , ptr , msg , decode_totablep ( table ) ) ;
return _upb_Decoder_DecodeMessage ( d , ptr , msg , decode_totablep ( table ) ) ;
}
static upb_DecodeStatus decode_top ( struct upb_Decoder * d , const char * buf ,
void * msg , const upb_MiniTable * l ) {
if ( ! decode_tryfastdispatch ( d , & buf , msg , l ) ) {
decode_msg ( d , buf , msg , l ) ;
static upb_DecodeStatus _upb_Decoder_DecodeTop ( struct upb_Decoder * d ,
const char * buf , void * msg ,
const upb_MiniTable * l ) {
if ( ! _upb_Decoder_TryFastDispatch ( d , & buf , msg , l ) ) {
_upb_Decoder_DecodeMessage ( d , buf , msg , l ) ;
}
if ( d - > end_group ! = DECODE_NOGROUP ) return kUpb_DecodeStatus_Malformed ;
if ( d - > missing_required ) return kUpb_DecodeStatus_MissingRequired ;
@ -1203,7 +1225,7 @@ upb_DecodeStatus upb_Decode(const char* buf, size_t size, void* msg,
upb_DecodeStatus status = UPB_SETJMP ( state . err ) ;
if ( UPB_LIKELY ( status = = kUpb_DecodeStatus_Ok ) ) {
status = decode_t op( & state , buf , msg , l ) ;
status = _upb_Decoder_DecodeT op( & state , buf , msg , l ) ;
}
arena - > head . ptr = state . arena . head . ptr ;