diff options
author | Joshua Haberman <joshua@reverberate.org> | 2011-07-15 12:05:43 -0700 |
---|---|---|
committer | Joshua Haberman <joshua@reverberate.org> | 2011-07-15 12:05:43 -0700 |
commit | 10265aa56b22ac4f04e7ba08330138e4507534e4 (patch) | |
tree | e821c85219a10b4ee3df715ab774465fdf87cf1d /upb/pb/glue.c | |
parent | 6a1f3a66939308668ab8dce0d195afec16e02af9 (diff) |
Directory restructure.
Includes are now via upb/foo.h.
Files specific to the protobuf format are
now in upb/pb (the core library is concerned
with message definitions, handlers, and
byte streams, but knows nothing about any
particular serializationf format).
Diffstat (limited to 'upb/pb/glue.c')
-rw-r--r-- | upb/pb/glue.c | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/upb/pb/glue.c b/upb/pb/glue.c new file mode 100644 index 0000000..3763ae0 --- /dev/null +++ b/upb/pb/glue.c @@ -0,0 +1,129 @@ +/* + * upb - a minimalist implementation of protocol buffers. + * + * Copyright (c) 2010 Google Inc. See LICENSE for details. + * Author: Josh Haberman <jhaberman@gmail.com> + */ + +#include "upb/bytestream.h" +#include "upb/descriptor.h" +#include "upb/msg.h" +#include "upb/pb/decoder.h" +#include "upb/pb/glue.h" +#include "upb/pb/textprinter.h" + +void upb_strtomsg(const char *str, size_t len, void *msg, upb_msgdef *md, + upb_status *status) { + upb_stringsrc strsrc; + upb_stringsrc_init(&strsrc); + upb_stringsrc_reset(&strsrc, str, len); + + upb_decoder d; + upb_decoder_initformsgdef(&d, md); + upb_decoder_reset(&d, upb_stringsrc_bytesrc(&strsrc), 0, UINT64_MAX, msg); + upb_decoder_decode(&d, status); + + upb_stringsrc_uninit(&strsrc); + upb_decoder_uninit(&d); +} + +#if 0 +void upb_msgtotext(upb_string *str, upb_msg *msg, upb_msgdef *md, + bool single_line) { + upb_stringsink strsink; + upb_stringsink_init(&strsink); + upb_stringsink_reset(&strsink, str); + + upb_textprinter *p = upb_textprinter_new(); + upb_handlers *h = upb_handlers_new(); + upb_textprinter_reghandlers(h, md); + upb_textprinter_reset(p, upb_stringsink_bytesink(&strsink), single_line); + + upb_status status = UPB_STATUS_INIT; + upb_msg_runhandlers(msg, md, h, p, &status); + // None of {upb_msg_runhandlers, upb_textprinter, upb_stringsink} should be + // capable of returning an error. + assert(upb_ok(&status)); + upb_status_uninit(&status); + + upb_stringsink_uninit(&strsink); + upb_textprinter_free(p); + upb_handlers_unref(h); +} +#endif + +// TODO: read->load. +void upb_read_descriptor(upb_symtab *symtab, const char *str, size_t len, + upb_status *status) { + upb_stringsrc strsrc; + upb_stringsrc_init(&strsrc); + upb_stringsrc_reset(&strsrc, str, len); + + upb_handlers *h = upb_handlers_new(); + upb_descreader_reghandlers(h); + + upb_decoder d; + upb_decoder_initforhandlers(&d, h); + upb_handlers_unref(h); + upb_descreader r; + upb_symtabtxn txn; + upb_symtabtxn_init(&txn); + upb_descreader_init(&r, &txn); + upb_decoder_reset(&d, upb_stringsrc_bytesrc(&strsrc), 0, UINT64_MAX, &r); + + upb_decoder_decode(&d, status); + + // Set default accessors and layouts on all messages. + // for msgdef in symtabtxn: + upb_symtabtxn_iter i; + upb_symtabtxn_begin(&i, &txn); + for(; !upb_symtabtxn_done(&i); upb_symtabtxn_next(&i)) { + upb_def *def = upb_symtabtxn_iter_def(&i); + upb_msgdef *md = upb_dyncast_msgdef(def); + if (!md) return; + // For field in msgdef: + upb_msg_iter i; + for(i = upb_msg_begin(md); !upb_msg_done(i); i = upb_msg_next(md, i)) { + upb_fielddef *f = upb_msg_iter_field(i); + upb_fielddef_setaccessor(f, upb_stdmsg_accessor(f)); + } + upb_msgdef_layout(md); + } + + if (upb_ok(status)) upb_symtab_commit(symtab, &txn, status); + + upb_symtabtxn_uninit(&txn); + upb_descreader_uninit(&r); + upb_stringsrc_uninit(&strsrc); + upb_decoder_uninit(&d); +} + +char *upb_readfile(const char *filename, size_t *len) { + FILE *f = fopen(filename, "rb"); + if(!f) return NULL; + if(fseek(f, 0, SEEK_END) != 0) goto error; + long size = ftell(f); + if(size < 0) goto error; + if(fseek(f, 0, SEEK_SET) != 0) goto error; + char *buf = malloc(size); + if(fread(buf, size, 1, f) != 1) goto error; + fclose(f); + if (len) *len = size; + return buf; + +error: + fclose(f); + return NULL; +} + +void upb_read_descriptorfile(upb_symtab *symtab, const char *fname, + upb_status *status) { + size_t len; + char *data = upb_readfile(fname, &len); + if (!data) { + upb_status_setf(status, UPB_ERROR, "Couldn't read file: %s", fname); + return; + } + upb_read_descriptor(symtab, data, len, status); + free(data); +} |