1b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Protocol Buffers - Google's data interchange format 2b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Copyright 2014 Google Inc. All rights reserved. 3b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// https://developers.google.com/protocol-buffers/ 4b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// 5b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Redistribution and use in source and binary forms, with or without 6b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// modification, are permitted provided that the following conditions are 7b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// met: 8b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// 9b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// * Redistributions of source code must retain the above copyright 10b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// notice, this list of conditions and the following disclaimer. 11b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// * Redistributions in binary form must reproduce the above 12b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// copyright notice, this list of conditions and the following disclaimer 13b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// in the documentation and/or other materials provided with the 14b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// distribution. 15b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// * Neither the name of Google Inc. nor the names of its 16b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// contributors may be used to endorse or promote products derived from 17b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// this software without specific prior written permission. 18b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// 19b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 31b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include "protobuf.h" 32b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 33b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// ----------------------------------------------------------------------------- 34b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor 35b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// instances. 36b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// ----------------------------------------------------------------------------- 37b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 38b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// This is a hash table from def objects (encoded by converting pointers to 39b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Ruby integers) to MessageDef/EnumDef instances (as Ruby values). 40b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerVALUE upb_def_to_ruby_obj_map; 41b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 42b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerVALUE cError; 43b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerVALUE cParseError; 44b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 45b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid add_def_obj(const void* def, VALUE value) { 46b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer rb_hash_aset(upb_def_to_ruby_obj_map, ULL2NUM((intptr_t)def), value); 47b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 48b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 49b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerVALUE get_def_obj(const void* def) { 50b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return rb_hash_aref(upb_def_to_ruby_obj_map, ULL2NUM((intptr_t)def)); 51b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 52b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 53b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// ----------------------------------------------------------------------------- 54b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Utilities. 55b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// ----------------------------------------------------------------------------- 56b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 57b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Raises a Ruby error if |status| is not OK, using its error message. 58b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid check_upb_status(const upb_status* status, const char* msg) { 59b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (!upb_ok(status)) { 60b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer rb_raise(rb_eRuntimeError, "%s: %s\n", msg, upb_status_errmsg(status)); 61b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 62b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 63b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 64b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// String encodings: we look these up once, at load time, and then cache them 65b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// here. 66b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerrb_encoding* kRubyStringUtf8Encoding; 67b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerrb_encoding* kRubyStringASCIIEncoding; 68b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerrb_encoding* kRubyString8bitEncoding; 69b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 70b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Ruby-interned string: "descriptor". We use this identifier to store an 71b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// instance variable on message classes we create in order to link them back to 72b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// their descriptors. 73b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// 74b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// We intern this once at module load time then use the interned identifier at 75b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// runtime in order to avoid the cost of repeatedly interning in hot paths. 76b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerconst char* kDescriptorInstanceVar = "descriptor"; 77b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerID descriptor_instancevar_interned; 78b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 79b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// ----------------------------------------------------------------------------- 80b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Initialization/entry point. 81b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// ----------------------------------------------------------------------------- 82b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 83b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// This must be named "Init_protobuf_c" because the Ruby module is named 84b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// "protobuf_c" -- the VM looks for this symbol in our .so. 85b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid Init_protobuf_c() { 86b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer VALUE google = rb_define_module("Google"); 87b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer VALUE protobuf = rb_define_module_under(google, "Protobuf"); 88b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer VALUE internal = rb_define_module_under(protobuf, "Internal"); 89b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 90b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer descriptor_instancevar_interned = rb_intern(kDescriptorInstanceVar); 91b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer DescriptorPool_register(protobuf); 92b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer Descriptor_register(protobuf); 93b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer FieldDescriptor_register(protobuf); 94b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer OneofDescriptor_register(protobuf); 95b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer EnumDescriptor_register(protobuf); 96b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer MessageBuilderContext_register(internal); 97b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer OneofBuilderContext_register(internal); 98b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer EnumBuilderContext_register(internal); 99b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer Builder_register(internal); 100b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer RepeatedField_register(protobuf); 101b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer Map_register(protobuf); 102b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 103b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer cError = rb_const_get(protobuf, rb_intern("Error")); 104b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer cParseError = rb_const_get(protobuf, rb_intern("ParseError")); 105b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 106b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer rb_define_singleton_method(protobuf, "deep_copy", 107b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer Google_Protobuf_deep_copy, 1); 108b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 109b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer kRubyStringUtf8Encoding = rb_utf8_encoding(); 110b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer kRubyStringASCIIEncoding = rb_usascii_encoding(); 111b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer kRubyString8bitEncoding = rb_ascii8bit_encoding(); 112b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 113b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer upb_def_to_ruby_obj_map = rb_hash_new(); 114b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer rb_gc_register_address(&upb_def_to_ruby_obj_map); 115b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 116