Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: third_party/protobuf/ruby/ext/google/protobuf_c/encode_decode.c

Issue 1983203003: Update third_party/protobuf to protobuf-v3.0.0-beta-3 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: owners Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2014 Google Inc. All rights reserved. 2 // Copyright 2014 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 } 633 }
634 634
635 static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) { 635 static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) {
636 if (desc->fill_method == NULL) { 636 if (desc->fill_method == NULL) {
637 desc->fill_method = new_fillmsg_decodermethod( 637 desc->fill_method = new_fillmsg_decodermethod(
638 desc, &desc->fill_method); 638 desc, &desc->fill_method);
639 } 639 }
640 return desc->fill_method; 640 return desc->fill_method;
641 } 641 }
642 642
643 static const upb_json_parsermethod *msgdef_jsonparsermethod(Descriptor* desc) {
644 if (desc->json_fill_method == NULL) {
645 desc->json_fill_method =
646 upb_json_parsermethod_new(desc->msgdef, &desc->json_fill_method);
647 }
648 return desc->json_fill_method;
649 }
650
643 651
644 // Stack-allocated context during an encode/decode operation. Contains the upb 652 // Stack-allocated context during an encode/decode operation. Contains the upb
645 // environment and its stack-based allocator, an initial buffer for allocations 653 // environment and its stack-based allocator, an initial buffer for allocations
646 // to avoid malloc() when possible, and a template for Ruby exception messages 654 // to avoid malloc() when possible, and a template for Ruby exception messages
647 // if any error occurs. 655 // if any error occurs.
648 #define STACK_ENV_STACKBYTES 4096 656 #define STACK_ENV_STACKBYTES 4096
649 typedef struct { 657 typedef struct {
650 upb_env env; 658 upb_env env;
651 upb_seededalloc alloc;
652 const char* ruby_error_template; 659 const char* ruby_error_template;
653 char allocbuf[STACK_ENV_STACKBYTES]; 660 char allocbuf[STACK_ENV_STACKBYTES];
654 } stackenv; 661 } stackenv;
655 662
656 static void stackenv_init(stackenv* se, const char* errmsg); 663 static void stackenv_init(stackenv* se, const char* errmsg);
657 static void stackenv_uninit(stackenv* se); 664 static void stackenv_uninit(stackenv* se);
658 665
659 // Callback invoked by upb if any error occurs during parsing or serialization. 666 // Callback invoked by upb if any error occurs during parsing or serialization.
660 static bool env_error_func(void* ud, const upb_status* status) { 667 static bool env_error_func(void* ud, const upb_status* status) {
661 stackenv* se = ud; 668 stackenv* se = ud;
662 // Free the env -- rb_raise will longjmp up the stack past the encode/decode 669 // Free the env -- rb_raise will longjmp up the stack past the encode/decode
663 // function so it would not otherwise have been freed. 670 // function so it would not otherwise have been freed.
664 stackenv_uninit(se); 671 stackenv_uninit(se);
665 672
666 // TODO(haberman): have a way to verify that this is actually a parse error, 673 // TODO(haberman): have a way to verify that this is actually a parse error,
667 // instead of just throwing "parse error" unconditionally. 674 // instead of just throwing "parse error" unconditionally.
668 rb_raise(cParseError, se->ruby_error_template, upb_status_errmsg(status)); 675 rb_raise(cParseError, se->ruby_error_template, upb_status_errmsg(status));
669 // Never reached: rb_raise() always longjmp()s up the stack, past all of our 676 // Never reached: rb_raise() always longjmp()s up the stack, past all of our
670 // code, back to Ruby. 677 // code, back to Ruby.
671 return false; 678 return false;
672 } 679 }
673 680
674 static void stackenv_init(stackenv* se, const char* errmsg) { 681 static void stackenv_init(stackenv* se, const char* errmsg) {
675 se->ruby_error_template = errmsg; 682 se->ruby_error_template = errmsg;
676 upb_env_init(&se->env); 683 upb_env_init2(&se->env, se->allocbuf, sizeof(se->allocbuf), NULL);
677 upb_seededalloc_init(&se->alloc, &se->allocbuf, STACK_ENV_STACKBYTES);
678 upb_env_setallocfunc(
679 &se->env, upb_seededalloc_getallocfunc(&se->alloc), &se->alloc);
680 upb_env_seterrorfunc(&se->env, env_error_func, se); 684 upb_env_seterrorfunc(&se->env, env_error_func, se);
681 } 685 }
682 686
683 static void stackenv_uninit(stackenv* se) { 687 static void stackenv_uninit(stackenv* se) {
684 upb_env_uninit(&se->env); 688 upb_env_uninit(&se->env);
685 upb_seededalloc_uninit(&se->alloc);
686 } 689 }
687 690
688 /* 691 /*
689 * call-seq: 692 * call-seq:
690 * MessageClass.decode(data) => message 693 * MessageClass.decode(data) => message
691 * 694 *
692 * Decodes the given data (as a string containing bytes in protocol buffers wire 695 * Decodes the given data (as a string containing bytes in protocol buffers wire
693 * format) under the interpretration given by this message class's definition 696 * format) under the interpretration given by this message class's definition
694 * and returns a message object with the corresponding field values. 697 * and returns a message object with the corresponding field values.
695 */ 698 */
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 rb_raise(rb_eArgError, "Expected string for JSON data."); 748 rb_raise(rb_eArgError, "Expected string for JSON data.");
746 } 749 }
747 // TODO(cfallin): Check and respect string encoding. If not UTF-8, we need to 750 // TODO(cfallin): Check and respect string encoding. If not UTF-8, we need to
748 // convert, because string handlers pass data directly to message string 751 // convert, because string handlers pass data directly to message string
749 // fields. 752 // fields.
750 753
751 msg_rb = rb_class_new_instance(0, NULL, msgklass); 754 msg_rb = rb_class_new_instance(0, NULL, msgklass);
752 TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); 755 TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
753 756
754 { 757 {
758 const upb_json_parsermethod* method = msgdef_jsonparsermethod(desc);
755 stackenv se; 759 stackenv se;
756 upb_sink sink; 760 upb_sink sink;
757 upb_json_parser* parser; 761 upb_json_parser* parser;
758 stackenv_init(&se, "Error occurred during parsing: %s"); 762 stackenv_init(&se, "Error occurred during parsing: %s");
759 763
760 upb_sink_reset(&sink, get_fill_handlers(desc), msg); 764 upb_sink_reset(&sink, get_fill_handlers(desc), msg);
761 parser = upb_json_parser_create(&se.env, &sink); 765 parser = upb_json_parser_create(&se.env, method, &sink);
762 upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data), 766 upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
763 upb_json_parser_input(parser)); 767 upb_json_parser_input(parser));
764 768
765 stackenv_uninit(&se); 769 stackenv_uninit(&se);
766 } 770 }
767 771
768 return msg_rb; 772 return msg_rb;
769 } 773 }
770 774
771 // ----------------------------------------------------------------------------- 775 // -----------------------------------------------------------------------------
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 rb_raise(rb_eRuntimeError, 1038 rb_raise(rb_eRuntimeError,
1035 "Maximum recursion depth exceeded during encoding."); 1039 "Maximum recursion depth exceeded during encoding.");
1036 } 1040 }
1037 1041
1038 TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); 1042 TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
1039 1043
1040 for (upb_msg_field_begin(&i, desc->msgdef); 1044 for (upb_msg_field_begin(&i, desc->msgdef);
1041 !upb_msg_field_done(&i); 1045 !upb_msg_field_done(&i);
1042 upb_msg_field_next(&i)) { 1046 upb_msg_field_next(&i)) {
1043 upb_fielddef *f = upb_msg_iter_field(&i); 1047 upb_fielddef *f = upb_msg_iter_field(&i);
1048 bool is_matching_oneof = false;
1044 uint32_t offset = 1049 uint32_t offset =
1045 desc->layout->fields[upb_fielddef_index(f)].offset + 1050 desc->layout->fields[upb_fielddef_index(f)].offset +
1046 sizeof(MessageHeader); 1051 sizeof(MessageHeader);
1047 1052
1048 if (upb_fielddef_containingoneof(f)) { 1053 if (upb_fielddef_containingoneof(f)) {
1049 uint32_t oneof_case_offset = 1054 uint32_t oneof_case_offset =
1050 desc->layout->fields[upb_fielddef_index(f)].case_offset + 1055 desc->layout->fields[upb_fielddef_index(f)].case_offset +
1051 sizeof(MessageHeader); 1056 sizeof(MessageHeader);
1052 // For a oneof, check that this field is actually present -- skip all the 1057 // For a oneof, check that this field is actually present -- skip all the
1053 // below if not. 1058 // below if not.
1054 if (DEREF(msg, oneof_case_offset, uint32_t) != 1059 if (DEREF(msg, oneof_case_offset, uint32_t) !=
1055 upb_fielddef_number(f)) { 1060 upb_fielddef_number(f)) {
1056 continue; 1061 continue;
1057 } 1062 }
1058 // Otherwise, fall through to the appropriate singular-field handler 1063 // Otherwise, fall through to the appropriate singular-field handler
1059 // below. 1064 // below.
1065 is_matching_oneof = true;
1060 } 1066 }
1061 1067
1062 if (is_map_field(f)) { 1068 if (is_map_field(f)) {
1063 VALUE map = DEREF(msg, offset, VALUE); 1069 VALUE map = DEREF(msg, offset, VALUE);
1064 if (map != Qnil) { 1070 if (map != Qnil) {
1065 putmap(map, f, sink, depth); 1071 putmap(map, f, sink, depth);
1066 } 1072 }
1067 } else if (upb_fielddef_isseq(f)) { 1073 } else if (upb_fielddef_isseq(f)) {
1068 VALUE ary = DEREF(msg, offset, VALUE); 1074 VALUE ary = DEREF(msg, offset, VALUE);
1069 if (ary != Qnil) { 1075 if (ary != Qnil) {
1070 putary(ary, f, sink, depth); 1076 putary(ary, f, sink, depth);
1071 } 1077 }
1072 } else if (upb_fielddef_isstring(f)) { 1078 } else if (upb_fielddef_isstring(f)) {
1073 VALUE str = DEREF(msg, offset, VALUE); 1079 VALUE str = DEREF(msg, offset, VALUE);
1074 if (RSTRING_LEN(str) > 0) { 1080 if (is_matching_oneof || RSTRING_LEN(str) > 0) {
1075 putstr(str, f, sink); 1081 putstr(str, f, sink);
1076 } 1082 }
1077 } else if (upb_fielddef_issubmsg(f)) { 1083 } else if (upb_fielddef_issubmsg(f)) {
1078 putsubmsg(DEREF(msg, offset, VALUE), f, sink, depth); 1084 putsubmsg(DEREF(msg, offset, VALUE), f, sink, depth);
1079 } else { 1085 } else {
1080 upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f)); 1086 upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
1081 1087
1082 #define T(upbtypeconst, upbtype, ctype, default_value) \ 1088 #define T(upbtypeconst, upbtype, ctype, default_value) \
1083 case upbtypeconst: { \ 1089 case upbtypeconst: { \
1084 ctype value = DEREF(msg, offset, ctype); \ 1090 ctype value = DEREF(msg, offset, ctype); \
1085 if (value != default_value) { \ 1091 if (is_matching_oneof || value != default_value) { \
1086 upb_sink_put##upbtype(sink, sel, value); \ 1092 upb_sink_put##upbtype(sink, sel, value); \
1087 } \ 1093 } \
1088 } \ 1094 } \
1089 break; 1095 break;
1090 1096
1091 switch (upb_fielddef_type(f)) { 1097 switch (upb_fielddef_type(f)) {
1092 T(UPB_TYPE_FLOAT, float, float, 0.0) 1098 T(UPB_TYPE_FLOAT, float, float, 0.0)
1093 T(UPB_TYPE_DOUBLE, double, double, 0.0) 1099 T(UPB_TYPE_DOUBLE, double, double, 0.0)
1094 T(UPB_TYPE_BOOL, bool, uint8_t, 0) 1100 T(UPB_TYPE_BOOL, bool, uint8_t, 0)
1095 case UPB_TYPE_ENUM: 1101 case UPB_TYPE_ENUM:
(...skipping 16 matching lines...) Expand all
1112 } 1118 }
1113 1119
1114 static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) { 1120 static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) {
1115 if (desc->pb_serialize_handlers == NULL) { 1121 if (desc->pb_serialize_handlers == NULL) {
1116 desc->pb_serialize_handlers = 1122 desc->pb_serialize_handlers =
1117 upb_pb_encoder_newhandlers(desc->msgdef, &desc->pb_serialize_handlers); 1123 upb_pb_encoder_newhandlers(desc->msgdef, &desc->pb_serialize_handlers);
1118 } 1124 }
1119 return desc->pb_serialize_handlers; 1125 return desc->pb_serialize_handlers;
1120 } 1126 }
1121 1127
1122 static const upb_handlers* msgdef_json_serialize_handlers(Descriptor* desc) { 1128 static const upb_handlers* msgdef_json_serialize_handlers(
1123 if (desc->json_serialize_handlers == NULL) { 1129 Descriptor* desc, bool preserve_proto_fieldnames) {
1124 desc->json_serialize_handlers = 1130 if (preserve_proto_fieldnames) {
1125 upb_json_printer_newhandlers( 1131 if (desc->json_serialize_handlers == NULL) {
1126 desc->msgdef, &desc->json_serialize_handlers); 1132 desc->json_serialize_handlers =
1133 upb_json_printer_newhandlers(
1134 desc->msgdef, true, &desc->json_serialize_handlers);
1135 }
1136 return desc->json_serialize_handlers;
1137 } else {
1138 if (desc->json_serialize_handlers_preserve == NULL) {
1139 desc->json_serialize_handlers_preserve =
1140 upb_json_printer_newhandlers(
1141 desc->msgdef, false, &desc->json_serialize_handlers_preserve);
1142 }
1143 return desc->json_serialize_handlers_preserve;
1127 } 1144 }
1128 return desc->json_serialize_handlers;
1129 } 1145 }
1130 1146
1131 /* 1147 /*
1132 * call-seq: 1148 * call-seq:
1133 * MessageClass.encode(msg) => bytes 1149 * MessageClass.encode(msg) => bytes
1134 * 1150 *
1135 * Encodes the given message object to its serialized form in protocol buffers 1151 * Encodes the given message object to its serialized form in protocol buffers
1136 * wire format. 1152 * wire format.
1137 */ 1153 */
1138 VALUE Message_encode(VALUE klass, VALUE msg_rb) { 1154 VALUE Message_encode(VALUE klass, VALUE msg_rb) {
(...skipping 24 matching lines...) Expand all
1163 return ret; 1179 return ret;
1164 } 1180 }
1165 } 1181 }
1166 1182
1167 /* 1183 /*
1168 * call-seq: 1184 * call-seq:
1169 * MessageClass.encode_json(msg) => json_string 1185 * MessageClass.encode_json(msg) => json_string
1170 * 1186 *
1171 * Encodes the given message object into its serialized JSON representation. 1187 * Encodes the given message object into its serialized JSON representation.
1172 */ 1188 */
1173 VALUE Message_encode_json(VALUE klass, VALUE msg_rb) { 1189 VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
1174 VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned); 1190 VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
1175 Descriptor* desc = ruby_to_Descriptor(descriptor); 1191 Descriptor* desc = ruby_to_Descriptor(descriptor);
1192 VALUE msg_rb;
1193 VALUE preserve_proto_fieldnames = Qfalse;
1194 stringsink sink;
1176 1195
1177 stringsink sink; 1196 if (argc < 1 || argc > 2) {
1197 rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
1198 }
1199
1200 msg_rb = argv[0];
1201
1202 if (argc == 2) {
1203 VALUE hash_args = argv[1];
1204 if (TYPE(hash_args) != T_HASH) {
1205 rb_raise(rb_eArgError, "Expected hash arguments.");
1206 }
1207 preserve_proto_fieldnames = rb_hash_lookup2(
1208 hash_args, ID2SYM(rb_intern("preserve_proto_fieldnames")), Qfalse);
1209 }
1210
1178 stringsink_init(&sink); 1211 stringsink_init(&sink);
1179 1212
1180 { 1213 {
1181 const upb_handlers* serialize_handlers = 1214 const upb_handlers* serialize_handlers =
1182 msgdef_json_serialize_handlers(desc); 1215 msgdef_json_serialize_handlers(desc, RTEST(preserve_proto_fieldnames));
1183 upb_json_printer* printer; 1216 upb_json_printer* printer;
1184 stackenv se; 1217 stackenv se;
1185 VALUE ret; 1218 VALUE ret;
1186 1219
1187 stackenv_init(&se, "Error occurred during encoding: %s"); 1220 stackenv_init(&se, "Error occurred during encoding: %s");
1188 printer = upb_json_printer_create(&se.env, serialize_handlers, &sink.sink); 1221 printer = upb_json_printer_create(&se.env, serialize_handlers, &sink.sink);
1189 1222
1190 putmsg(msg_rb, desc, upb_json_printer_input(printer), 0); 1223 putmsg(msg_rb, desc, upb_json_printer_input(printer), 0);
1191 1224
1192 ret = rb_str_new(sink.ptr, sink.len); 1225 ret = rb_enc_str_new(sink.ptr, sink.len, rb_utf8_encoding());
1193 1226
1194 stackenv_uninit(&se); 1227 stackenv_uninit(&se);
1195 stringsink_uninit(&sink); 1228 stringsink_uninit(&sink);
1196 1229
1197 return ret; 1230 return ret;
1198 } 1231 }
1199 } 1232 }
1200 1233
OLDNEW
« no previous file with comments | « third_party/protobuf/ruby/ext/google/protobuf_c/defs.c ('k') | third_party/protobuf/ruby/ext/google/protobuf_c/message.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698