Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
3.0 KiB
90 lines
3.0 KiB
/* |
|
* upb - a minimalist implementation of protocol buffers. |
|
* |
|
* Copyright (c) 2013 Google Inc. See LICENSE for details. |
|
* Author: Josh Haberman <jhaberman@gmail.com> |
|
*/ |
|
|
|
#include "upb/shim/shim.h" |
|
|
|
#include <stdlib.h> |
|
|
|
// Fallback implementation if the shim is not specialized by the JIT. |
|
#define SHIM_WRITER(type, ctype) \ |
|
bool upb_shim_set ## type (void *c, const void *hd, ctype val) { \ |
|
uint8_t *m = c; \ |
|
const upb_shim_data *d = hd; \ |
|
if (d->hasbit > 0) \ |
|
*(uint8_t*)&m[d->hasbit / 8] |= 1 << (d->hasbit % 8); \ |
|
*(ctype*)&m[d->offset] = val; \ |
|
return true; \ |
|
} \ |
|
|
|
SHIM_WRITER(double, double) |
|
SHIM_WRITER(float, float) |
|
SHIM_WRITER(int32, int32_t) |
|
SHIM_WRITER(int64, int64_t) |
|
SHIM_WRITER(uint32, uint32_t) |
|
SHIM_WRITER(uint64, uint64_t) |
|
SHIM_WRITER(bool, bool) |
|
#undef SHIM_WRITER |
|
|
|
bool upb_shim_set(upb_handlers *h, const upb_fielddef *f, size_t offset, |
|
int32_t hasbit) { |
|
upb_shim_data *d = malloc(sizeof(*d)); |
|
if (!d) return false; |
|
d->offset = offset; |
|
d->hasbit = hasbit; |
|
|
|
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; |
|
upb_handlerattr_sethandlerdata(&attr, d); |
|
upb_handlerattr_setalwaysok(&attr, true); |
|
upb_handlers_addcleanup(h, d, free); |
|
|
|
#define TYPE(u, l) \ |
|
case UPB_TYPE_##u: \ |
|
ok = upb_handlers_set##l(h, f, upb_shim_set##l, &attr); break; |
|
|
|
bool ok = false; |
|
|
|
switch (upb_fielddef_type(f)) { |
|
TYPE(INT64, int64); |
|
TYPE(INT32, int32); |
|
TYPE(ENUM, int32); |
|
TYPE(UINT64, uint64); |
|
TYPE(UINT32, uint32); |
|
TYPE(DOUBLE, double); |
|
TYPE(FLOAT, float); |
|
TYPE(BOOL, bool); |
|
default: assert(false); break; |
|
} |
|
#undef TYPE |
|
|
|
upb_handlerattr_uninit(&attr); |
|
return ok; |
|
} |
|
|
|
const upb_shim_data *upb_shim_getdata(const upb_handlers *h, upb_selector_t s, |
|
upb_fieldtype_t *type) { |
|
upb_func *f = upb_handlers_gethandler(h, s); |
|
|
|
if ((upb_int64_handlerfunc*)f == upb_shim_setint64) { |
|
*type = UPB_TYPE_INT64; |
|
} else if ((upb_int32_handlerfunc*)f == upb_shim_setint32) { |
|
*type = UPB_TYPE_INT32; |
|
} else if ((upb_uint64_handlerfunc*)f == upb_shim_setuint64) { |
|
*type = UPB_TYPE_UINT64; |
|
} else if ((upb_uint32_handlerfunc*)f == upb_shim_setuint32) { |
|
*type = UPB_TYPE_UINT32; |
|
} else if ((upb_double_handlerfunc*)f == upb_shim_setdouble) { |
|
*type = UPB_TYPE_DOUBLE; |
|
} else if ((upb_float_handlerfunc*)f == upb_shim_setfloat) { |
|
*type = UPB_TYPE_FLOAT; |
|
} else if ((upb_bool_handlerfunc*)f == upb_shim_setbool) { |
|
*type = UPB_TYPE_BOOL; |
|
} else { |
|
return NULL; |
|
} |
|
|
|
return (const upb_shim_data*)upb_handlers_gethandlerdata(h, s); |
|
}
|
|
|