pull/13171/head
Joshua Haberman 8 years ago
parent 277c4d584f
commit edad06a9fa
  1. 48
      upb/decode.c

@ -1,5 +1,6 @@
#include "upb/decode.h" #include "upb/decode.h"
#include "upb/structs.int.h"
typedef enum { typedef enum {
UPB_WIRE_TYPE_VARINT = 0, UPB_WIRE_TYPE_VARINT = 0,
@ -17,6 +18,13 @@ typedef struct {
const char *ptr; const char *ptr;
} upb_decstate; } upb_decstate;
typedef struct {
int32_t group_number; /* 0 if we are not parsing a group. */
char *msg;
const upb_msglayout_msginit_v1 *m;
const char *limit;
} upb_decframe;
#define CHK(x) if (!(x)) { return false; } #define CHK(x) if (!(x)) { return false; }
static void upb_decode_seterr(upb_env *env, const char *msg) { static void upb_decode_seterr(upb_env *env, const char *msg) {
@ -160,6 +168,25 @@ static bool upb_decode_unknownfielddata(upb_decstate *d, const char *ptr,
} while (true); } while (true);
} }
static bool upb_decode_knownfield(upb_decstate *d, const char *ptr,
const char *limit, char *msg,
const upb_msglayout_msginit_v1 *l,
const upb_msglayout_fieldinit_v1 *l) {
switch (wire_type) {
case UPB_WIRE_TYPE_VARINT:
return upb_decode_varintfield(d, ptr, limit, msg, l, f);
case UPB_WIRE_TYPE_32BIT:
return upb_decode_32bitfield(d, ptr, limit, msg, l, f);
case UPB_WIRE_TYPE_64BIT:
return upb_decode_64bitfield(d, ptr, limit, msg, l, f);
case UPB_WIRE_TYPE_DELIMITED:
return upb_decode_delimitedfield(d, ptr, limit, msg, l, f);
case UPB_WIRE_TYPE_START_GROUP:
case UPB_WIRE_TYPE_END_GROUP:
}
}
static bool upb_decode_field(upb_decstate *d, const char *limit, char *msg, static bool upb_decode_field(upb_decstate *d, const char *limit, char *msg,
const upb_msglayout_msginit_v1 *l) { const upb_msglayout_msginit_v1 *l) {
uint32_t tag; uint32_t tag;
@ -366,12 +393,9 @@ static bool upb_decode_field(upb_decstate *d, const char *limit, char *msg,
return true; return true;
} }
static bool upb_decode_message(upb_decstate *d, upb_stringview buf, static bool upb_decode_message(upb_decstate *d, upb_decframe *frame) {
char *msg, const upb_msglayout_msginit_v1 *l) { while (d->ptr < frame->limit) {
const char *limit = ptr + buf.size; if (!upb_decode_field(d, frame)) {
while (d->ptr < limit) {
if (!upb_decode_field(&ptr, limit, msg, l, env)) {
return false; return false;
} }
} }
@ -381,5 +405,15 @@ static bool upb_decode_message(upb_decstate *d, upb_stringview buf,
bool upb_decode(upb_stringview buf, void *msg, bool upb_decode(upb_stringview buf, void *msg,
const upb_msglayout_msginit_v1 *l, upb_env *env) { const upb_msglayout_msginit_v1 *l, upb_env *env) {
return upb_decode_message(buf, msg, l, env); upb_decstate state;
state.ptr = buf.data;
state.env = env;
upb_decframe frame;
frame.msg = msg;
frame.l = l;
frame.group_number = 0;
frame.limit = buf.data + buf.size
return upb_decode_message(&state, &frame);
} }

Loading…
Cancel
Save