| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Protocol Buffers - Google's data interchange format | 2 * Protocol Buffers - Google's data interchange format |
| 3 * Copyright 2014 Google Inc. All rights reserved. | 3 * Copyright 2014 Google Inc. All rights reserved. |
| 4 * https://developers.google.com/protocol-buffers/ | 4 * https://developers.google.com/protocol-buffers/ |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions are | 7 * modification, are permitted provided that the following conditions are |
| 8 * met: | 8 * met: |
| 9 * | 9 * |
| 10 * * Redistributions of source code must retain the above copyright | 10 * * Redistributions of source code must retain the above copyright |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 | 57 |
| 58 public static IRubyObject fieldTypeToRuby(ThreadContext context, DescriptorP
rotos.FieldDescriptorProto.Type type) { | 58 public static IRubyObject fieldTypeToRuby(ThreadContext context, DescriptorP
rotos.FieldDescriptorProto.Type type) { |
| 59 return fieldTypeToRuby(context, type.name()); | 59 return fieldTypeToRuby(context, type.name()); |
| 60 } | 60 } |
| 61 | 61 |
| 62 private static IRubyObject fieldTypeToRuby(ThreadContext context, String typ
eName) { | 62 private static IRubyObject fieldTypeToRuby(ThreadContext context, String typ
eName) { |
| 63 | 63 |
| 64 return context.runtime.newSymbol(typeName.replace("TYPE_", "").toLowerCa
se()); | 64 return context.runtime.newSymbol(typeName.replace("TYPE_", "").toLowerCa
se()); |
| 65 } | 65 } |
| 66 | 66 |
| 67 public static IRubyObject checkType(ThreadContext context, Descriptors.Field
Descriptor.Type fieldType, | 67 public static void checkType(ThreadContext context, Descriptors.FieldDescrip
tor.Type fieldType, |
| 68 IRubyObject value, RubyModule typeClass)
{ | 68 IRubyObject value, RubyModule typeClass) { |
| 69 Ruby runtime = context.runtime; | 69 Ruby runtime = context.runtime; |
| 70 Object val; | 70 Object val; |
| 71 switch(fieldType) { | 71 switch(fieldType) { |
| 72 case INT32: | 72 case INT32: |
| 73 case INT64: | 73 case INT64: |
| 74 case UINT32: | 74 case UINT32: |
| 75 case UINT64: | 75 case UINT64: |
| 76 if (!isRubyNum(value)) { | 76 if (!isRubyNum(value)) { |
| 77 throw runtime.newTypeError("Expected number type for integra
l field."); | 77 throw runtime.newTypeError("Expected number type for integra
l field."); |
| 78 } | 78 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 99 case DOUBLE: | 99 case DOUBLE: |
| 100 if (!isRubyNum(value)) | 100 if (!isRubyNum(value)) |
| 101 throw runtime.newTypeError("Expected number type for double
field."); | 101 throw runtime.newTypeError("Expected number type for double
field."); |
| 102 break; | 102 break; |
| 103 case BOOL: | 103 case BOOL: |
| 104 if (!(value instanceof RubyBoolean)) | 104 if (!(value instanceof RubyBoolean)) |
| 105 throw runtime.newTypeError("Invalid argument for boolean fie
ld."); | 105 throw runtime.newTypeError("Invalid argument for boolean fie
ld."); |
| 106 break; | 106 break; |
| 107 case BYTES: | 107 case BYTES: |
| 108 case STRING: | 108 case STRING: |
| 109 value = validateStringEncoding(context, fieldType, value); | 109 validateStringEncoding(context.runtime, fieldType, value); |
| 110 break; | 110 break; |
| 111 case MESSAGE: | 111 case MESSAGE: |
| 112 if (value.getMetaClass() != typeClass) { | 112 if (value.getMetaClass() != typeClass) { |
| 113 throw runtime.newTypeError(value, typeClass); | 113 throw runtime.newTypeError(value, typeClass); |
| 114 } | 114 } |
| 115 break; | 115 break; |
| 116 case ENUM: | 116 case ENUM: |
| 117 if (value instanceof RubySymbol) { | 117 if (value instanceof RubySymbol) { |
| 118 Descriptors.EnumDescriptor enumDescriptor = | 118 Descriptors.EnumDescriptor enumDescriptor = |
| 119 ((RubyEnumDescriptor) typeClass.getInstanceVariable(
DESCRIPTOR_INSTANCE_VAR)).getDescriptor(); | 119 ((RubyEnumDescriptor) typeClass.getInstanceVariable(
DESCRIPTOR_INSTANCE_VAR)).getDescriptor(); |
| 120 val = enumDescriptor.findValueByName(value.asJavaString()); | 120 val = enumDescriptor.findValueByName(value.asJavaString()); |
| 121 if (val == null) | 121 if (val == null) |
| 122 throw runtime.newRangeError("Enum value " + value + " is
not found."); | 122 throw runtime.newRangeError("Enum value " + value + " is
not found."); |
| 123 } else if(!isRubyNum(value)) { | 123 } else if(!isRubyNum(value)) { |
| 124 throw runtime.newTypeError("Expected number or symbol type f
or enum field."); | 124 throw runtime.newTypeError("Expected number or symbol type f
or enum field."); |
| 125 } | 125 } |
| 126 break; | 126 break; |
| 127 default: | 127 default: |
| 128 break; | 128 break; |
| 129 } | 129 } |
| 130 return value; | |
| 131 } | 130 } |
| 132 | 131 |
| 133 public static IRubyObject wrapPrimaryValue(ThreadContext context, Descriptor
s.FieldDescriptor.Type fieldType, Object value) { | 132 public static IRubyObject wrapPrimaryValue(ThreadContext context, Descriptor
s.FieldDescriptor.Type fieldType, Object value) { |
| 134 Ruby runtime = context.runtime; | 133 Ruby runtime = context.runtime; |
| 135 switch (fieldType) { | 134 switch (fieldType) { |
| 136 case INT32: | 135 case INT32: |
| 137 return runtime.newFixnum((Integer) value); | 136 return runtime.newFixnum((Integer) value); |
| 138 case INT64: | 137 case INT64: |
| 139 return runtime.newFixnum((Long) value); | 138 return runtime.newFixnum((Long) value); |
| 140 case UINT32: | 139 case UINT32: |
| 141 return runtime.newFixnum(((Integer) value) & (-1l >>> 32)); | 140 return runtime.newFixnum(((Integer) value) & (-1l >>> 32)); |
| 142 case UINT64: | 141 case UINT64: |
| 143 long ret = (Long) value; | 142 long ret = (Long) value; |
| 144 return ret >= 0 ? runtime.newFixnum(ret) : | 143 return ret >= 0 ? runtime.newFixnum(ret) : |
| 145 RubyBignum.newBignum(runtime, UINT64_COMPLEMENTARY.add(n
ew BigInteger(ret + ""))); | 144 RubyBignum.newBignum(runtime, UINT64_COMPLEMENTARY.add(n
ew BigInteger(ret + ""))); |
| 146 case FLOAT: | 145 case FLOAT: |
| 147 return runtime.newFloat((Float) value); | 146 return runtime.newFloat((Float) value); |
| 148 case DOUBLE: | 147 case DOUBLE: |
| 149 return runtime.newFloat((Double) value); | 148 return runtime.newFloat((Double) value); |
| 150 case BOOL: | 149 case BOOL: |
| 151 return (Boolean) value ? runtime.getTrue() : runtime.getFalse(); | 150 return (Boolean) value ? runtime.getTrue() : runtime.getFalse(); |
| 152 case BYTES: { | 151 case BYTES: |
| 153 IRubyObject wrapped = runtime.newString(((ByteString) value).toS
tringUtf8()); | 152 return runtime.newString(((ByteString) value).toStringUtf8()); |
| 154 wrapped.setFrozen(true); | 153 case STRING: |
| 155 return wrapped; | 154 return runtime.newString(value.toString()); |
| 156 } | |
| 157 case STRING: { | |
| 158 IRubyObject wrapped = runtime.newString(value.toString()); | |
| 159 wrapped.setFrozen(true); | |
| 160 return wrapped; | |
| 161 } | |
| 162 default: | 155 default: |
| 163 return runtime.getNil(); | 156 return runtime.getNil(); |
| 164 } | 157 } |
| 165 } | 158 } |
| 166 | 159 |
| 167 public static int num2uint(IRubyObject value) { | 160 public static int num2uint(IRubyObject value) { |
| 168 long longVal = RubyNumeric.num2long(value); | 161 long longVal = RubyNumeric.num2long(value); |
| 169 if (longVal > UINT_MAX) | 162 if (longVal > UINT_MAX) |
| 170 throw value.getRuntime().newRangeError("Integer " + longVal + " too
big to convert to 'unsigned int'"); | 163 throw value.getRuntime().newRangeError("Integer " + longVal + " too
big to convert to 'unsigned int'"); |
| 171 long num = longVal; | 164 long num = longVal; |
| 172 if (num > Integer.MAX_VALUE || num < Integer.MIN_VALUE) | 165 if (num > Integer.MAX_VALUE || num < Integer.MIN_VALUE) |
| 173 // encode to UINT32 | 166 // encode to UINT32 |
| 174 num = (-longVal ^ (-1l >>> 32) ) + 1; | 167 num = (-longVal ^ (-1l >>> 32) ) + 1; |
| 175 RubyNumeric.checkInt(value, num); | 168 RubyNumeric.checkInt(value, num); |
| 176 return (int) num; | 169 return (int) num; |
| 177 } | 170 } |
| 178 | 171 |
| 179 public static long num2ulong(Ruby runtime, IRubyObject value) { | 172 public static long num2ulong(Ruby runtime, IRubyObject value) { |
| 180 if (value instanceof RubyFloat) { | 173 if (value instanceof RubyFloat) { |
| 181 RubyBignum bignum = RubyBignum.newBignum(runtime, ((RubyFloat) value
).getDoubleValue()); | 174 RubyBignum bignum = RubyBignum.newBignum(runtime, ((RubyFloat) value
).getDoubleValue()); |
| 182 return RubyBignum.big2ulong(bignum); | 175 return RubyBignum.big2ulong(bignum); |
| 183 } else if (value instanceof RubyBignum) { | 176 } else if (value instanceof RubyBignum) { |
| 184 return RubyBignum.big2ulong((RubyBignum) value); | 177 return RubyBignum.big2ulong((RubyBignum) value); |
| 185 } else { | 178 } else { |
| 186 return RubyNumeric.num2long(value); | 179 return RubyNumeric.num2long(value); |
| 187 } | 180 } |
| 188 } | 181 } |
| 189 | 182 |
| 190 public static IRubyObject validateStringEncoding(ThreadContext context, Desc
riptors.FieldDescriptor.Type type, IRubyObject value) { | 183 public static void validateStringEncoding(Ruby runtime, Descriptors.FieldDes
criptor.Type type, IRubyObject value) { |
| 191 if (!(value instanceof RubyString)) | 184 if (!(value instanceof RubyString)) |
| 192 throw context.runtime.newTypeError("Invalid argument for string fiel
d."); | 185 throw runtime.newTypeError("Invalid argument for string field."); |
| 186 Encoding encoding = ((RubyString) value).getEncoding(); |
| 193 switch(type) { | 187 switch(type) { |
| 194 case BYTES: | 188 case BYTES: |
| 195 value = ((RubyString)value).encode(context, context.runtime.eval
Scriptlet("Encoding::ASCII_8BIT")); | 189 if (encoding != ASCIIEncoding.INSTANCE) |
| 190 throw runtime.newTypeError("Encoding for bytes fields" + |
| 191 " must be \"ASCII-8BIT\", but was " + encoding); |
| 196 break; | 192 break; |
| 197 case STRING: | 193 case STRING: |
| 198 value = ((RubyString)value).encode(context, context.runtime.eval
Scriptlet("Encoding::UTF_8")); | 194 if (encoding != UTF8Encoding.INSTANCE |
| 195 && encoding != USASCIIEncoding.INSTANCE) |
| 196 throw runtime.newTypeError("Encoding for string fields" + |
| 197 " must be \"UTF-8\" or \"ASCII\", but was " + encodi
ng); |
| 199 break; | 198 break; |
| 200 default: | 199 default: |
| 201 break; | 200 break; |
| 202 } | 201 } |
| 203 value.setFrozen(true); | |
| 204 return value; | |
| 205 } | 202 } |
| 206 | 203 |
| 207 public static void checkNameAvailability(ThreadContext context, String name)
{ | 204 public static void checkNameAvailability(ThreadContext context, String name)
{ |
| 208 if (context.runtime.getObject().getConstantAt(name) != null) | 205 if (context.runtime.getObject().getConstantAt(name) != null) |
| 209 throw context.runtime.newNameError(name + " is already defined", nam
e); | 206 throw context.runtime.newNameError(name + " is already defined", nam
e); |
| 210 } | 207 } |
| 211 | 208 |
| 212 /** | 209 /** |
| 213 * Replace invalid "." in descriptor with __DOT__ | 210 * Replace invalid "." in descriptor with __DOT__ |
| 214 * @param name | 211 * @param name |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 public static String BADNAME_REPLACEMENT = "__DOT__"; | 291 public static String BADNAME_REPLACEMENT = "__DOT__"; |
| 295 | 292 |
| 296 public static String DESCRIPTOR_INSTANCE_VAR = "@descriptor"; | 293 public static String DESCRIPTOR_INSTANCE_VAR = "@descriptor"; |
| 297 | 294 |
| 298 public static String EQUAL_SIGN = "="; | 295 public static String EQUAL_SIGN = "="; |
| 299 | 296 |
| 300 private static BigInteger UINT64_COMPLEMENTARY = new BigInteger("18446744073
709551616"); //Math.pow(2, 64) | 297 private static BigInteger UINT64_COMPLEMENTARY = new BigInteger("18446744073
709551616"); //Math.pow(2, 64) |
| 301 | 298 |
| 302 private static long UINT_MAX = 0xffffffffl; | 299 private static long UINT_MAX = 0xffffffffl; |
| 303 } | 300 } |
| OLD | NEW |