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 23 matching lines...) Expand all Loading... |
34 | 34 |
35 import com.google.protobuf.*; | 35 import com.google.protobuf.*; |
36 import org.jruby.*; | 36 import org.jruby.*; |
37 import org.jruby.anno.JRubyMethod; | 37 import org.jruby.anno.JRubyMethod; |
38 import org.jruby.runtime.Block; | 38 import org.jruby.runtime.Block; |
39 import org.jruby.runtime.Helpers; | 39 import org.jruby.runtime.Helpers; |
40 import org.jruby.runtime.ThreadContext; | 40 import org.jruby.runtime.ThreadContext; |
41 import org.jruby.runtime.builtin.IRubyObject; | 41 import org.jruby.runtime.builtin.IRubyObject; |
42 import org.jruby.util.ByteList; | 42 import org.jruby.util.ByteList; |
43 | 43 |
44 import java.security.MessageDigest; | |
45 import java.security.NoSuchAlgorithmException; | |
46 import java.util.HashMap; | 44 import java.util.HashMap; |
47 import java.util.Map; | 45 import java.util.Map; |
48 | 46 |
49 public class RubyMessage extends RubyObject { | 47 public class RubyMessage extends RubyObject { |
50 public RubyMessage(Ruby ruby, RubyClass klazz, Descriptors.Descriptor descri
ptor) { | 48 public RubyMessage(Ruby ruby, RubyClass klazz, Descriptors.Descriptor descri
ptor) { |
51 super(ruby, klazz); | 49 super(ruby, klazz); |
52 this.descriptor = descriptor; | 50 this.descriptor = descriptor; |
53 } | 51 } |
54 | 52 |
55 /* | 53 /* |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 } | 157 } |
160 | 158 |
161 /* | 159 /* |
162 * call-seq: | 160 * call-seq: |
163 * Message.hash => hash_value | 161 * Message.hash => hash_value |
164 * | 162 * |
165 * Returns a hash value that represents this message's field values. | 163 * Returns a hash value that represents this message's field values. |
166 */ | 164 */ |
167 @JRubyMethod | 165 @JRubyMethod |
168 public IRubyObject hash(ThreadContext context) { | 166 public IRubyObject hash(ThreadContext context) { |
169 try { | 167 int hashCode = System.identityHashCode(this); |
170 MessageDigest digest = MessageDigest.getInstance("SHA-256"); | 168 return context.runtime.newFixnum(hashCode); |
171 for (RubyMap map : maps.values()) { | |
172 digest.update((byte) map.hashCode()); | |
173 } | |
174 for (RubyRepeatedField repeatedField : repeatedFields.values()) { | |
175 digest.update((byte) repeatedFields.hashCode()); | |
176 } | |
177 for (IRubyObject field : fields.values()) { | |
178 digest.update((byte) field.hashCode()); | |
179 } | |
180 return context.runtime.newString(new ByteList(digest.digest())); | |
181 } catch (NoSuchAlgorithmException ignore) { | |
182 return context.runtime.newFixnum(System.identityHashCode(this)); | |
183 } | |
184 } | 169 } |
185 | 170 |
186 /* | 171 /* |
187 * call-seq: | 172 * call-seq: |
188 * Message.==(other) => boolean | 173 * Message.==(other) => boolean |
189 * | 174 * |
190 * Performs a deep comparison of this message with another. Messages are equ
al | 175 * Performs a deep comparison of this message with another. Messages are equ
al |
191 * if they have the same type and if each field is equal according to the :=
= | 176 * if they have the same type and if each field is equal according to the :=
= |
192 * method's semantics (a more efficient comparison may actually be done if t
he | 177 * method's semantics (a more efficient comparison may actually be done if t
he |
193 * field is of a primitive type). | 178 * field is of a primitive type). |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 throw runtime.newTypeError("Expected number type for double
field."); | 497 throw runtime.newTypeError("Expected number type for double
field."); |
513 val = RubyNumeric.num2dbl(value); | 498 val = RubyNumeric.num2dbl(value); |
514 break; | 499 break; |
515 case BOOL: | 500 case BOOL: |
516 if (!(value instanceof RubyBoolean)) | 501 if (!(value instanceof RubyBoolean)) |
517 throw runtime.newTypeError("Invalid argument for boolean fie
ld."); | 502 throw runtime.newTypeError("Invalid argument for boolean fie
ld."); |
518 val = value.isTrue(); | 503 val = value.isTrue(); |
519 break; | 504 break; |
520 case BYTES: | 505 case BYTES: |
521 case STRING: | 506 case STRING: |
522 Utils.validateStringEncoding(context, fieldDescriptor.getType(),
value); | 507 Utils.validateStringEncoding(context.runtime, fieldDescriptor.ge
tType(), value); |
523 RubyString str = (RubyString) value; | 508 RubyString str = (RubyString) value; |
524 switch (fieldDescriptor.getType()) { | 509 switch (fieldDescriptor.getType()) { |
525 case BYTES: | 510 case BYTES: |
526 val = ByteString.copyFrom(str.getBytes()); | 511 val = ByteString.copyFrom(str.getBytes()); |
527 break; | 512 break; |
528 case STRING: | 513 case STRING: |
529 val = str.asJavaString(); | 514 val = str.asJavaString(); |
530 break; | 515 break; |
531 default: | 516 default: |
532 break; | 517 break; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 | 585 |
601 } else if (type == Descriptors.FieldDescriptor.Type.ENUM) { | 586 } else if (type == Descriptors.FieldDescriptor.Type.ENUM) { |
602 typeClass = ((RubyEnumDescriptor) descriptor).enummodule(context); | 587 typeClass = ((RubyEnumDescriptor) descriptor).enummodule(context); |
603 } | 588 } |
604 return new RubyRepeatedField(context.runtime, cRepeatedField, type, type
Class); | 589 return new RubyRepeatedField(context.runtime, cRepeatedField, type, type
Class); |
605 } | 590 } |
606 | 591 |
607 protected IRubyObject getField(ThreadContext context, Descriptors.FieldDescr
iptor fieldDescriptor) { | 592 protected IRubyObject getField(ThreadContext context, Descriptors.FieldDescr
iptor fieldDescriptor) { |
608 Descriptors.OneofDescriptor oneofDescriptor = fieldDescriptor.getContain
ingOneof(); | 593 Descriptors.OneofDescriptor oneofDescriptor = fieldDescriptor.getContain
ingOneof(); |
609 if (oneofDescriptor != null) { | 594 if (oneofDescriptor != null) { |
610 if (oneofCases.get(oneofDescriptor) == fieldDescriptor) { | 595 if (oneofCases.containsKey(oneofDescriptor)) { |
| 596 if (oneofCases.get(oneofDescriptor) != fieldDescriptor) |
| 597 return context.runtime.getNil(); |
611 return fields.get(fieldDescriptor); | 598 return fields.get(fieldDescriptor); |
612 } else { | 599 } else { |
613 Descriptors.FieldDescriptor oneofCase = builder.getOneofFieldDes
criptor(oneofDescriptor); | 600 Descriptors.FieldDescriptor oneofCase = builder.getOneofFieldDes
criptor(oneofDescriptor); |
614 if (oneofCase != fieldDescriptor) { | 601 if (oneofCase != fieldDescriptor) return context.runtime.getNil(
); |
615 if (fieldDescriptor.getType() == Descriptors.FieldDescriptor.T
ype.MESSAGE) { | |
616 return context.runtime.getNil(); | |
617 } else { | |
618 return wrapField(context, fieldDescriptor, fieldDescriptor.g
etDefaultValue()); | |
619 } | |
620 } | |
621 IRubyObject value = wrapField(context, oneofCase, builder.getFie
ld(oneofCase)); | 602 IRubyObject value = wrapField(context, oneofCase, builder.getFie
ld(oneofCase)); |
622 fields.put(fieldDescriptor, value); | 603 fields.put(fieldDescriptor, value); |
623 return value; | 604 return value; |
624 } | 605 } |
625 } | 606 } |
626 | 607 |
627 if (Utils.isMapEntry(fieldDescriptor)) { | 608 if (Utils.isMapEntry(fieldDescriptor)) { |
628 RubyMap map = maps.get(fieldDescriptor); | 609 RubyMap map = maps.get(fieldDescriptor); |
629 if (map == null) { | 610 if (map == null) { |
630 map = newMapForField(context, fieldDescriptor); | 611 map = newMapForField(context, fieldDescriptor); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 } else if (fieldType == Descriptors.FieldDescriptor.Type.ENUM) { | 684 } else if (fieldType == Descriptors.FieldDescriptor.Type.ENUM) { |
704 typeClass = ((RubyEnumDescriptor) getDescriptorForField(cont
ext, fieldDescriptor)).enummodule(context); | 685 typeClass = ((RubyEnumDescriptor) getDescriptorForField(cont
ext, fieldDescriptor)).enummodule(context); |
705 Descriptors.EnumDescriptor enumDescriptor = fieldDescriptor.
getEnumType(); | 686 Descriptors.EnumDescriptor enumDescriptor = fieldDescriptor.
getEnumType(); |
706 if (Utils.isRubyNum(value)) { | 687 if (Utils.isRubyNum(value)) { |
707 Descriptors.EnumValueDescriptor val = | 688 Descriptors.EnumValueDescriptor val = |
708 enumDescriptor.findValueByNumberCreatingIfUnknow
n(RubyNumeric.num2int(value)); | 689 enumDescriptor.findValueByNumberCreatingIfUnknow
n(RubyNumeric.num2int(value)); |
709 if (val.getIndex() != -1) value = context.runtime.newSym
bol(val.getName()); | 690 if (val.getIndex() != -1) value = context.runtime.newSym
bol(val.getName()); |
710 } | 691 } |
711 } | 692 } |
712 if (addValue) { | 693 if (addValue) { |
713 value = Utils.checkType(context, fieldType, value, (RubyModu
le) typeClass); | 694 Utils.checkType(context, fieldType, value, (RubyModule) type
Class); |
714 this.fields.put(fieldDescriptor, value); | 695 this.fields.put(fieldDescriptor, value); |
715 } else { | 696 } else { |
716 this.fields.remove(fieldDescriptor); | 697 this.fields.remove(fieldDescriptor); |
717 } | 698 } |
718 } | 699 } |
719 } | 700 } |
720 return context.runtime.getNil(); | 701 return context.runtime.getNil(); |
721 } | 702 } |
722 | 703 |
723 private String layoutInspect() { | 704 private String layoutInspect() { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 private DynamicMessage.Builder builder; | 756 private DynamicMessage.Builder builder; |
776 private RubyClass cRepeatedField; | 757 private RubyClass cRepeatedField; |
777 private RubyClass cMap; | 758 private RubyClass cMap; |
778 private Map<Descriptors.FieldDescriptor, RubyRepeatedField> repeatedFields; | 759 private Map<Descriptors.FieldDescriptor, RubyRepeatedField> repeatedFields; |
779 private Map<Descriptors.FieldDescriptor, RubyMap> maps; | 760 private Map<Descriptors.FieldDescriptor, RubyMap> maps; |
780 private Map<Descriptors.FieldDescriptor, IRubyObject> fields; | 761 private Map<Descriptors.FieldDescriptor, IRubyObject> fields; |
781 private Map<Descriptors.OneofDescriptor, Descriptors.FieldDescriptor> oneofC
ases; | 762 private Map<Descriptors.OneofDescriptor, Descriptors.FieldDescriptor> oneofC
ases; |
782 | 763 |
783 private static final int SINK_MAXIMUM_NESTING = 64; | 764 private static final int SINK_MAXIMUM_NESTING = 64; |
784 } | 765 } |
OLD | NEW |