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.
89 lines
2.1 KiB
89 lines
2.1 KiB
|
|
#include "upb/sink.h" |
|
|
|
bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink *sink) { |
|
void *subc; |
|
bool ret; |
|
upb_bufhandle handle; |
|
upb_bufhandle_init(&handle); |
|
upb_bufhandle_setbuf(&handle, buf, 0); |
|
ret = upb_bytessink_start(sink, len, &subc); |
|
if (ret && len != 0) { |
|
ret = (upb_bytessink_putbuf(sink, subc, buf, len, &handle) >= len); |
|
} |
|
if (ret) { |
|
ret = upb_bytessink_end(sink); |
|
} |
|
upb_bufhandle_uninit(&handle); |
|
return ret; |
|
} |
|
|
|
struct upb_bufsink { |
|
upb_byteshandler handler; |
|
upb_bytessink sink; |
|
upb_env *env; |
|
char *ptr; |
|
size_t len, size; |
|
}; |
|
|
|
static void *upb_bufsink_start(void *_sink, const void *hd, size_t size_hint) { |
|
upb_bufsink *sink = _sink; |
|
UPB_UNUSED(hd); |
|
UPB_UNUSED(size_hint); |
|
sink->len = 0; |
|
return sink; |
|
} |
|
|
|
static size_t upb_bufsink_string(void *_sink, const void *hd, const char *ptr, |
|
size_t len, const upb_bufhandle *handle) { |
|
upb_bufsink *sink = _sink; |
|
size_t new_size = sink->size; |
|
|
|
UPB_ASSERT(new_size > 0); |
|
UPB_UNUSED(hd); |
|
UPB_UNUSED(handle); |
|
|
|
while (sink->len + len > new_size) { |
|
new_size *= 2; |
|
} |
|
|
|
if (new_size != sink->size) { |
|
sink->ptr = upb_env_realloc(sink->env, sink->ptr, sink->size, new_size); |
|
sink->size = new_size; |
|
} |
|
|
|
memcpy(sink->ptr + sink->len, ptr, len); |
|
sink->len += len; |
|
|
|
return len; |
|
} |
|
|
|
upb_bufsink *upb_bufsink_new(upb_env *env) { |
|
upb_bufsink *sink = upb_env_malloc(env, sizeof(upb_bufsink)); |
|
upb_byteshandler_init(&sink->handler); |
|
upb_byteshandler_setstartstr(&sink->handler, upb_bufsink_start, NULL); |
|
upb_byteshandler_setstring(&sink->handler, upb_bufsink_string, NULL); |
|
|
|
upb_bytessink_reset(&sink->sink, &sink->handler, sink); |
|
|
|
sink->env = env; |
|
sink->size = 32; |
|
sink->ptr = upb_env_malloc(env, sink->size); |
|
sink->len = 0; |
|
|
|
return sink; |
|
} |
|
|
|
void upb_bufsink_free(upb_bufsink *sink) { |
|
upb_env_free(sink->env, sink->ptr); |
|
upb_env_free(sink->env, sink); |
|
} |
|
|
|
upb_bytessink *upb_bufsink_sink(upb_bufsink *sink) { |
|
return &sink->sink; |
|
} |
|
|
|
const char *upb_bufsink_getdata(const upb_bufsink *sink, size_t *len) { |
|
*len = sink->len; |
|
return sink->ptr; |
|
}
|
|
|