33 package com.google.protobuf.jruby;
38 import org.jcodings.Encoding;
39 import org.jcodings.specific.ASCIIEncoding;
40 import org.jcodings.specific.USASCIIEncoding;
41 import org.jcodings.specific.UTF8Encoding;
43 import org.jruby.runtime.Block;
44 import org.jruby.runtime.ThreadContext;
45 import org.jruby.runtime.builtin.IRubyObject;
47 import java.math.BigInteger;
58 public static IRubyObject
fieldTypeToRuby(ThreadContext context, DescriptorProtos.FieldDescriptorProto.Type
type) {
62 private static IRubyObject
fieldTypeToRuby(ThreadContext context, String typeName) {
64 return context.runtime.newSymbol(typeName.replace(
"TYPE_",
"").toLowerCase());
68 IRubyObject
value, RubyModule typeClass) {
69 Ruby runtime = context.runtime;
77 throw runtime.newTypeError(
"Expected number type for integral field.");
81 RubyNumeric.num2int(
value);
84 RubyNumeric.num2long(
value);
97 throw runtime.newTypeError(
"Expected number type for float field.");
101 throw runtime.newTypeError(
"Expected number type for double field.");
104 if (!(
value instanceof RubyBoolean))
105 throw runtime.newTypeError(
"Invalid argument for boolean field.");
112 if (
value.getMetaClass() != typeClass) {
113 throw runtime.newTypeError(
value, typeClass);
117 if (
value instanceof RubySymbol) {
122 throw runtime.newRangeError(
"Enum value " +
value +
" is not found.");
124 throw runtime.newTypeError(
"Expected number or symbol type for enum field.");
134 Ruby runtime = context.runtime;
137 return runtime.newFixnum((Integer)
value);
139 return runtime.newFixnum((Long)
value);
141 return runtime.newFixnum(((Integer)
value) & (-1l >>> 32));
143 long ret = (Long)
value;
144 return ret >= 0 ? runtime.newFixnum(ret) :
151 return (Boolean)
value ? runtime.getTrue() : runtime.getFalse();
153 IRubyObject wrapped = runtime.newString(((
ByteString)
value).toStringUtf8());
154 wrapped.setFrozen(
true);
158 IRubyObject wrapped = runtime.newString(
value.toString());
159 wrapped.setFrozen(
true);
163 return runtime.getNil();
168 long longVal = RubyNumeric.num2long(
value);
170 throw value.getRuntime().newRangeError(
"Integer " + longVal +
" too big to convert to 'unsigned int'");
172 if (num > Integer.MAX_VALUE || num < Integer.MIN_VALUE)
174 num = (-longVal ^ (-1l >>> 32) ) + 1;
175 RubyNumeric.checkInt(
value, num);
180 if (
value instanceof RubyFloat) {
181 RubyBignum bignum = RubyBignum.newBignum(runtime, ((RubyFloat)
value).getDoubleValue());
182 return RubyBignum.big2ulong(bignum);
183 }
else if (
value instanceof RubyBignum) {
184 return RubyBignum.big2ulong((RubyBignum)
value);
186 return RubyNumeric.num2long(
value);
191 if (!(
value instanceof RubyString))
192 throw context.runtime.newTypeError(
"Invalid argument for string field.");
195 value = ((RubyString)
value).encode(context, context.runtime.evalScriptlet(
"Encoding::ASCII_8BIT"));
198 value = ((RubyString)
value).encode(context, context.runtime.evalScriptlet(
"Encoding::UTF_8"));
203 value.setFrozen(
true);
208 if (context.runtime.getObject().getConstantAt(
name) !=
null)
209 throw context.runtime.newNameError(
name +
" is already defined",
name);
232 fieldDescriptor.isRepeated() &&
233 fieldDescriptor.getMessageType().getOptions().getMapEntry();
238 Ruby runtime = context.runtime;
245 if (!typeClass.isNil()) {
246 if (!(typeClass instanceof RubyString)) {
247 throw runtime.newArgumentError(
"expected string for type class");
255 if (
value instanceof RubyFloat) {
256 double doubleVal = RubyNumeric.num2dbl(
value);
257 if (Math.floor(doubleVal) != doubleVal) {
258 throw context.runtime.newRangeError(
"Non-integral floating point value assigned to integer field.");
262 if (RubyNumeric.num2dbl(
value) < 0) {
263 throw context.runtime.newRangeError(
"Assigning negative value to unsigned integer field.");
269 return value instanceof RubyFixnum ||
value instanceof RubyFloat ||
value instanceof RubyBignum;
273 Ruby runtime = context.runtime;
274 if (!(
value instanceof RubyModule)) {
275 throw runtime.newArgumentError(
"TypeClass has incorrect type");
280 throw runtime.newArgumentError(
"Type class has no descriptor. Please pass a " +
281 "class or enum as returned by the DescriptorPool.");
285 throw runtime.newArgumentError(
"Descriptor has an incorrect type");
289 throw runtime.newArgumentError(
"Descriptor has an incorrect type");