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 |