| 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 |