| 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 void checkType(ThreadContext context, Descriptors.FieldDescrip
tor.Type fieldType, | 67 public static IRubyObject checkType(ThreadContext context, Descriptors.Field
Descriptor.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 validateStringEncoding(context.runtime, fieldType, value); | 109 value = validateStringEncoding(context, 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; |
| 130 } | 131 } |
| 131 | 132 |
| 132 public static IRubyObject wrapPrimaryValue(ThreadContext context, Descriptor
s.FieldDescriptor.Type fieldType, Object value) { | 133 public static IRubyObject wrapPrimaryValue(ThreadContext context, Descriptor
s.FieldDescriptor.Type fieldType, Object value) { |
| 133 Ruby runtime = context.runtime; | 134 Ruby runtime = context.runtime; |
| 134 switch (fieldType) { | 135 switch (fieldType) { |
| 135 case INT32: | 136 case INT32: |
| 136 return runtime.newFixnum((Integer) value); | 137 return runtime.newFixnum((Integer) value); |
| 137 case INT64: | 138 case INT64: |
| 138 return runtime.newFixnum((Long) value); | 139 return runtime.newFixnum((Long) value); |
| 139 case UINT32: | 140 case UINT32: |
| 140 return runtime.newFixnum(((Integer) value) & (-1l >>> 32)); | 141 return runtime.newFixnum(((Integer) value) & (-1l >>> 32)); |
| 141 case UINT64: | 142 case UINT64: |
| 142 long ret = (Long) value; | 143 long ret = (Long) value; |
| 143 return ret >= 0 ? runtime.newFixnum(ret) : | 144 return ret >= 0 ? runtime.newFixnum(ret) : |
| 144 RubyBignum.newBignum(runtime, UINT64_COMPLEMENTARY.add(n
ew BigInteger(ret + ""))); | 145 RubyBignum.newBignum(runtime, UINT64_COMPLEMENTARY.add(n
ew BigInteger(ret + ""))); |
| 145 case FLOAT: | 146 case FLOAT: |
| 146 return runtime.newFloat((Float) value); | 147 return runtime.newFloat((Float) value); |
| 147 case DOUBLE: | 148 case DOUBLE: |
| 148 return runtime.newFloat((Double) value); | 149 return runtime.newFloat((Double) value); |
| 149 case BOOL: | 150 case BOOL: |
| 150 return (Boolean) value ? runtime.getTrue() : runtime.getFalse(); | 151 return (Boolean) value ? runtime.getTrue() : runtime.getFalse(); |
| 151 case BYTES: | 152 case BYTES: { |
| 152 return runtime.newString(((ByteString) value).toStringUtf8()); | 153 IRubyObject wrapped = runtime.newString(((ByteString) value).toS
tringUtf8()); |
| 153 case STRING: | 154 wrapped.setFrozen(true); |
| 154 return runtime.newString(value.toString()); | 155 return wrapped; |
| 156 } |
| 157 case STRING: { |
| 158 IRubyObject wrapped = runtime.newString(value.toString()); |
| 159 wrapped.setFrozen(true); |
| 160 return wrapped; |
| 161 } |
| 155 default: | 162 default: |
| 156 return runtime.getNil(); | 163 return runtime.getNil(); |
| 157 } | 164 } |
| 158 } | 165 } |
| 159 | 166 |
| 160 public static int num2uint(IRubyObject value) { | 167 public static int num2uint(IRubyObject value) { |
| 161 long longVal = RubyNumeric.num2long(value); | 168 long longVal = RubyNumeric.num2long(value); |
| 162 if (longVal > UINT_MAX) | 169 if (longVal > UINT_MAX) |
| 163 throw value.getRuntime().newRangeError("Integer " + longVal + " too
big to convert to 'unsigned int'"); | 170 throw value.getRuntime().newRangeError("Integer " + longVal + " too
big to convert to 'unsigned int'"); |
| 164 long num = longVal; | 171 long num = longVal; |
| 165 if (num > Integer.MAX_VALUE || num < Integer.MIN_VALUE) | 172 if (num > Integer.MAX_VALUE || num < Integer.MIN_VALUE) |
| 166 // encode to UINT32 | 173 // encode to UINT32 |
| 167 num = (-longVal ^ (-1l >>> 32) ) + 1; | 174 num = (-longVal ^ (-1l >>> 32) ) + 1; |
| 168 RubyNumeric.checkInt(value, num); | 175 RubyNumeric.checkInt(value, num); |
| 169 return (int) num; | 176 return (int) num; |
| 170 } | 177 } |
| 171 | 178 |
| 172 public static long num2ulong(Ruby runtime, IRubyObject value) { | 179 public static long num2ulong(Ruby runtime, IRubyObject value) { |
| 173 if (value instanceof RubyFloat) { | 180 if (value instanceof RubyFloat) { |
| 174 RubyBignum bignum = RubyBignum.newBignum(runtime, ((RubyFloat) value
).getDoubleValue()); | 181 RubyBignum bignum = RubyBignum.newBignum(runtime, ((RubyFloat) value
).getDoubleValue()); |
| 175 return RubyBignum.big2ulong(bignum); | 182 return RubyBignum.big2ulong(bignum); |
| 176 } else if (value instanceof RubyBignum) { | 183 } else if (value instanceof RubyBignum) { |
| 177 return RubyBignum.big2ulong((RubyBignum) value); | 184 return RubyBignum.big2ulong((RubyBignum) value); |
| 178 } else { | 185 } else { |
| 179 return RubyNumeric.num2long(value); | 186 return RubyNumeric.num2long(value); |
| 180 } | 187 } |
| 181 } | 188 } |
| 182 | 189 |
| 183 public static void validateStringEncoding(Ruby runtime, Descriptors.FieldDes
criptor.Type type, IRubyObject value) { | 190 public static IRubyObject validateStringEncoding(ThreadContext context, Desc
riptors.FieldDescriptor.Type type, IRubyObject value) { |
| 184 if (!(value instanceof RubyString)) | 191 if (!(value instanceof RubyString)) |
| 185 throw runtime.newTypeError("Invalid argument for string field."); | 192 throw context.runtime.newTypeError("Invalid argument for string fiel
d."); |
| 186 Encoding encoding = ((RubyString) value).getEncoding(); | |
| 187 switch(type) { | 193 switch(type) { |
| 188 case BYTES: | 194 case BYTES: |
| 189 if (encoding != ASCIIEncoding.INSTANCE) | 195 value = ((RubyString)value).encode(context, context.runtime.eval
Scriptlet("Encoding::ASCII_8BIT")); |
| 190 throw runtime.newTypeError("Encoding for bytes fields" + | |
| 191 " must be \"ASCII-8BIT\", but was " + encoding); | |
| 192 break; | 196 break; |
| 193 case STRING: | 197 case STRING: |
| 194 if (encoding != UTF8Encoding.INSTANCE | 198 value = ((RubyString)value).encode(context, context.runtime.eval
Scriptlet("Encoding::UTF_8")); |
| 195 && encoding != USASCIIEncoding.INSTANCE) | |
| 196 throw runtime.newTypeError("Encoding for string fields" + | |
| 197 " must be \"UTF-8\" or \"ASCII\", but was " + encodi
ng); | |
| 198 break; | 199 break; |
| 199 default: | 200 default: |
| 200 break; | 201 break; |
| 201 } | 202 } |
| 203 value.setFrozen(true); |
| 204 return value; |
| 202 } | 205 } |
| 203 | 206 |
| 204 public static void checkNameAvailability(ThreadContext context, String name)
{ | 207 public static void checkNameAvailability(ThreadContext context, String name)
{ |
| 205 if (context.runtime.getObject().getConstantAt(name) != null) | 208 if (context.runtime.getObject().getConstantAt(name) != null) |
| 206 throw context.runtime.newNameError(name + " is already defined", nam
e); | 209 throw context.runtime.newNameError(name + " is already defined", nam
e); |
| 207 } | 210 } |
| 208 | 211 |
| 209 /** | 212 /** |
| 210 * Replace invalid "." in descriptor with __DOT__ | 213 * Replace invalid "." in descriptor with __DOT__ |
| 211 * @param name | 214 * @param name |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 public static String BADNAME_REPLACEMENT = "__DOT__"; | 294 public static String BADNAME_REPLACEMENT = "__DOT__"; |
| 292 | 295 |
| 293 public static String DESCRIPTOR_INSTANCE_VAR = "@descriptor"; | 296 public static String DESCRIPTOR_INSTANCE_VAR = "@descriptor"; |
| 294 | 297 |
| 295 public static String EQUAL_SIGN = "="; | 298 public static String EQUAL_SIGN = "="; |
| 296 | 299 |
| 297 private static BigInteger UINT64_COMPLEMENTARY = new BigInteger("18446744073
709551616"); //Math.pow(2, 64) | 300 private static BigInteger UINT64_COMPLEMENTARY = new BigInteger("18446744073
709551616"); //Math.pow(2, 64) |
| 298 | 301 |
| 299 private static long UINT_MAX = 0xffffffffl; | 302 private static long UINT_MAX = 0xffffffffl; |
| 300 } | 303 } |
| OLD | NEW |