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