Changeset 26:3b888f173cfb in rrlib_serialization-java
- Timestamp:
- 08.06.2017 03:02:37 (4 years ago)
- Branch:
- 17.03
- Phase:
- public
- Files:
-
- 4 added
- 2 deleted
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
BinaryInputStream.java
r23 r26 25 25 import java.io.StringReader; 26 26 27 import org.rrlib.logging.Log;28 27 import org.rrlib.serialization.compression.Compressible; 29 28 import org.rrlib.serialization.compression.DataCompressor; 30 import org.rrlib.serialization.rtti.DataTypeBase;31 29 import org.rrlib.xml.XMLDocument; 32 30 import org.rrlib.xml.XMLNode; … … 57 55 protected Source source = null; 58 56 59 /** Manager that handles, where the data blocks come from etc. */60 protected ConstSource constSource = null;61 62 57 /** Current absolute buffer read position of buffer start - relevant when using Source; 64bit value, because we might transfer several GB over a stream */ 63 58 protected long absoluteReadPos = 0; … … 75 70 protected int timeout = -1; 76 71 77 /** Data type encoding */78 public enum TypeEncoding {79 LocalUids, // use local uids. fastest. Can, however, only be used with streams encoded by this runtime.80 Names, // use names. Can be decoded in any runtime that knows types.81 Custom // use custom type codec82 }83 84 /** Data type encoding that is used */85 protected TypeEncoding encoding;86 87 /** Custom type encoder */88 protected TypeEncoder customEncoder;89 90 72 /** ByteArrayInputStream helper for reading strings in Java */ 91 73 protected ByteArrayOutputStream baos = new ByteArrayOutputStream(); 92 74 93 public BinaryInputStream() { 94 this(TypeEncoding.LocalUids); 95 } 96 97 public BinaryInputStream(ConstSource source_) { 98 this(source_, TypeEncoding.LocalUids); 99 } 100 101 public BinaryInputStream(TypeEncoding encoding) { 102 boundaryBuffer.buffer = boundaryBufferBackend; 103 this.encoding = encoding; 104 } 105 106 public BinaryInputStream(TypeEncoder encoder) { 107 boundaryBuffer.buffer = boundaryBufferBackend; 108 customEncoder = encoder; 109 encoding = TypeEncoding.Custom; 110 } 111 112 public BinaryInputStream(ConstSource source_, TypeEncoding encoding) { 113 boundaryBuffer.buffer = boundaryBufferBackend; 114 this.encoding = encoding; 115 reset(source_); 116 } 117 118 public BinaryInputStream(ConstSource source_, TypeEncoder encoder) { 119 boundaryBuffer.buffer = boundaryBufferBackend; 120 customEncoder = encoder; 121 encoding = TypeEncoding.Custom; 122 reset(source_); 123 } 124 125 126 /** 127 * @param source Source that handles, where the data blocks come from etc. 128 */ 129 public BinaryInputStream(Source source_) { 130 boundaryBuffer.buffer = boundaryBufferBackend; 131 reset(source_); 132 } 133 134 /** 135 * @param source Source that handles, where the data blocks come from etc. 136 */ 137 public BinaryInputStream(Source source_, TypeEncoder encoder) { 138 boundaryBuffer.buffer = boundaryBufferBackend; 139 customEncoder = encoder; 140 encoding = TypeEncoding.Custom; 141 reset(source_); 75 /** Info on source that created data currently read (at least the included revision is required for deserialization) */ 76 private SerializationInfo serializationSource; 77 78 /** Replicated remote registers */ 79 PublishedRegisters.RemoteRegister[] remoteRegisters; 80 81 82 public BinaryInputStream() {} 83 84 /** 85 * @param source Source to use 86 */ 87 public BinaryInputStream(Source source) { 88 this(source, new SerializationInfo()); 89 } 90 91 /** 92 * @param source Source to use 93 * @param sourceInfo Info on source that created data currently read (at least the included revision is required for deserialization) 94 */ 95 public BinaryInputStream(Source source, SerializationInfo sourceInfo) { 96 reset(source, sourceInfo); 97 } 98 99 /** 100 * @param source Source to use 101 * @param sharedSerializationInfoFrom Serialization info (SerializationInfo and published registers) is taken from and shared with this input stream 102 */ 103 public BinaryInputStream(Source source, BinaryInputStream sharedSerializationInfoFrom) { 104 reset(source, sharedSerializationInfoFrom); 105 } 106 107 /** 108 * @return Info on source that created data currently read (at least the included revision is required for deserialization) 109 */ 110 public SerializationInfo getSourceInfo() { 111 return serializationSource; 142 112 } 143 113 … … 155 125 */ 156 126 public void reset() { 157 if (source != null) { 158 source.reset(this, sourceBuffer); 159 directReadSupport = source.directReadSupport(); 160 closed = false; 161 } else if (constSource != null) { 162 constSource.reset(this, sourceBuffer); 163 directReadSupport = constSource.directReadSupport(); 164 closed = false; 165 } 127 source.reset(this, sourceBuffer); 128 directReadSupport = source.directReadSupport(); 129 closed = false; 166 130 curBuffer = sourceBuffer; 167 131 absoluteReadPos = 0; … … 174 138 * @param source New Source 175 139 */ 176 public void reset(ConstSource source) { 177 close(); 178 this.source = null; 179 this.constSource = source; 180 reset(); 140 public void reset(Source source) { 141 reset(source, new SerializationInfo()); 181 142 } 182 143 … … 186 147 * 187 148 * @param source New Source 188 */ 189 public void reset(Source source) { 149 * @param sourceInfo Info on source that created data currently read (at least the included revision is required for deserialization) 150 */ 151 public void reset(Source source, SerializationInfo sourceInfo) { 190 152 close(); 191 153 this.source = source; 192 this.constSource = null;154 setSerializationSource(sourceInfo); 193 155 reset(); 156 } 157 158 /** 159 * Sets shared serialization source of this stream without changing sink 160 * 161 * @param sourceInfo Info on source that created data currently read (at least the included revision is required for deserialization) 162 */ 163 public void setSerializationSource(SerializationInfo sourceInfo) { 164 this.serializationSource = sourceInfo; 165 if (sourceInfo.hasPublishedRegisters()) { 166 this.remoteRegisters = new PublishedRegisters.RemoteRegister[SerializationInfo.MAX_PUBLISHED_REGISTERS]; 167 for (int i = 0; i < SerializationInfo.MAX_PUBLISHED_REGISTERS; i++) { 168 if (sourceInfo.getRegisterEntryEncoding(i) == SerializationInfo.RegisterEntryEncoding.PUBLISH_REGISTER_ON_CHANGE || sourceInfo.getRegisterEntryEncoding(i) == SerializationInfo.RegisterEntryEncoding.PUBLISH_REGISTER_ON_DEMAND) { 169 this.remoteRegisters[i] = PublishedRegisters.get(i).createRemoteRegister(); 170 } 171 } 172 173 } else { 174 this.remoteRegisters = null; 175 } 176 } 177 178 179 /** 180 * Use this object with different source. 181 * Current source will be closed. 182 * 183 * @param source New Source 184 * @param sharedSerializationInfoFrom Serialization info (SerializationInfo and published registers) is taken from and shared with this input stream 185 */ 186 public void reset(Source source, BinaryInputStream sharedSerializationInfoFrom) { 187 close(); 188 this.source = source; 189 this.serializationSource = sharedSerializationInfoFrom.serializationSource; 190 this.remoteRegisters = sharedSerializationInfoFrom.remoteRegisters; 191 reset(); 192 } 193 194 /** 195 * Sets shared serialization info of this stream without changing source 196 * 197 * @param sharedSerializationInfoFrom Serialization info (SerializationInfo and published registers) is taken from and shared with this input stream 198 */ 199 public void setSharedSerializationInfo(BinaryInputStream sharedSerializationInfoFrom) { 200 this.serializationSource = sharedSerializationInfoFrom.serializationSource; 201 this.remoteRegisters = sharedSerializationInfoFrom.remoteRegisters; 202 } 203 204 /** 205 * Sets shared serialization info of this stream without changing source 206 * 207 * @param sourceInfo Info on source that created data currently read 208 * @param remoteRegistersFrom Remote registers from this stream are used 209 */ 210 public void setSharedSerializationInfo(SerializationInfo sourceInfo, BinaryInputStream remoteRegistersFrom) { 211 this.serializationSource = sourceInfo; 212 this.remoteRegisters = remoteRegistersFrom.remoteRegisters; 194 213 } 195 214 … … 201 220 if (source != null) { 202 221 source.close(this, sourceBuffer); 203 } else if (constSource != null) {204 constSource.close(this, sourceBuffer);205 222 } 206 223 } … … 370 387 protected void fetchNextBytes(int minRequired2) { 371 388 assert(minRequired2 <= 8); 372 assert(source != null || constSource != null);389 assert(source != null); 373 390 374 391 // are we finished using boundary buffer? … … 397 414 int initialSleep = 20; // timeout-related 398 415 int slept = 0; // timeout-related 399 while (timeout > 0 && (! (source != null ? source.moreDataAvailable(this, sourceBuffer) : constSource.moreDataAvailable(this, sourceBuffer)))) {416 while (timeout > 0 && (!source.moreDataAvailable(this, sourceBuffer))) { 400 417 initialSleep *= 2; 401 418 try { … … 410 427 411 428 // read next block 412 if (source != null) { 413 source.read(this, sourceBuffer, minRequired2); 414 } else { 415 constSource.read(this, sourceBuffer, minRequired2); 416 } 429 source.read(this, sourceBuffer, minRequired2); 417 430 assert(sourceBuffer.remaining() >= minRequired2); 418 431 assert(sourceBuffer.position >= 0); … … 570 583 571 584 /** 585 * @return sizeOf Size of integer in byte (1, 2, 4, or 8) 586 */ 587 public long readInt(int sizeOf) { 588 switch (sizeOf) { 589 case 1: 590 return readByte(); 591 case 2: 592 return readShort(); 593 case 4: 594 return readInt(); 595 case 8: 596 return readLong(); 597 default: 598 throw new RuntimeException("Invalid size"); 599 } 600 } 601 602 603 /**Info on source that created data currently read (at least the included revision is required for deserialization) 572 604 * @return String/Line from stream (ends either at line delimiter or 0-character) 573 605 */ … … 702 734 } 703 735 //System.out.println("Not here"); 704 return source != null ? source.moreDataAvailable(this, sourceBuffer) : constSource.moreDataAvailable(this, sourceBuffer);736 return source.moreDataAvailable(this, sourceBuffer); 705 737 } 706 738 … … 724 756 public void setTimeout(int timeout) { 725 757 this.timeout = timeout; 726 }727 728 /**729 * @return Reads type from stream730 */731 public DataTypeBase readType() {732 if (encoding == TypeEncoding.LocalUids) {733 return DataTypeBase.getType(readShort());734 } else if (encoding == TypeEncoding.Names) {735 return DataTypeBase.findType(readString());736 } else {737 return customEncoder.readType(this);738 }739 758 } 740 759 … … 882 901 } 883 902 884 903 /** 904 * @param registerUid Uid of register to serialize remote entry of 905 * @return Remote register entry of specified type 906 */ 907 public PublishedRegisters.RemoteEntryBase<?> readRegisterEntry(int registerUid) throws Exception { 908 if (remoteRegisters == null) { 909 throw new Exception("BinaryInputStream: No shared serialization info set"); 910 } 911 Register<?> localRegister = PublishedRegisters.get(registerUid).register; 912 int handle = (int)readInt(localRegister.getSizeOfHandle()); 913 if (handle == -2) { 914 readRegisterUpdates(); 915 handle = (int)readInt(localRegister.getSizeOfHandle()); 916 } 917 if (handle == -1) { 918 return PublishedRegisters.getMinusOneElement(); 919 } 920 return remoteRegisters[registerUid].get(handle); 921 } 922 923 /** 924 * @return Reads register updates 925 */ 926 void readRegisterUpdates() throws Exception { 927 928 // Read register updates 929 if (getSourceInfo().getRevision() == 0) { 930 remoteRegisters[0].deserializeEntries(this); 931 } else { 932 byte uid = readByte(); 933 while (uid != -1) { 934 if (uid >= remoteRegisters.length || uid < 0) { 935 throw new RuntimeException("Invalid register uid " + uid); 936 } 937 remoteRegisters[uid].deserializeEntries(this); 938 uid = readByte(); 939 } 940 } 941 } 885 942 } -
BinaryOutputStream.java
r23 r26 22 22 package org.rrlib.serialization; 23 23 24 import org.rrlib.serialization.rtti.DataTypeBase; 24 import java.util.ArrayList; 25 25 26 import org.rrlib.xml.XMLDocument; 26 27 import org.rrlib.xml.XMLNode; … … 82 83 private boolean directWriteSupport = false; 83 84 84 /** Data type encoding */ 85 public enum TypeEncoding { 86 LocalUids, // use local uids. fastest. Can, however, only be decoded in this runtime. 87 Names, // use names. Can be decoded in any runtime that knows types. 88 Custom // use custom type codec 89 } 90 91 /** Data type encoding that is used */ 92 private TypeEncoding encoding; 93 94 /** Custom type encoder */ 95 private TypeEncoder customEncoder; 96 97 public BinaryOutputStream() { 98 this(TypeEncoding.LocalUids); 99 } 100 101 public BinaryOutputStream(Sink sink_) { 102 this(sink_, TypeEncoding.LocalUids); 103 } 104 105 /** 106 * @param encoding Data type encoding that is used 107 */ 108 public BinaryOutputStream(TypeEncoding encoding) { 109 this.encoding = encoding; 110 } 111 112 public BinaryOutputStream(TypeEncoder encoder) { 113 customEncoder = encoder; 114 encoding = TypeEncoding.Custom; 115 } 116 117 /** 118 * @param sink_ Sink to write to 119 * @param encoding Data type encoding that is used 120 */ 121 public BinaryOutputStream(Sink sink_, TypeEncoding encoding) { 122 this.encoding = encoding; 123 reset(sink_); 124 } 125 126 /** 127 * @param sink_ Sink to write to 128 * @param encoder Custom type encoder 129 */ 130 public BinaryOutputStream(Sink sink_, TypeEncoder encoder) { 131 customEncoder = encoder; 132 encoding = TypeEncoding.Custom; 133 reset(sink_); 85 /** Info on target that serialization is created for */ 86 private SerializationInfo serializationTarget; 87 88 /** Info on a single published registers */ 89 class PublishedRegisterStatus { 90 91 /** Contains number of entries from register that were already written to stream */ 92 final int[] elementsWritten = new int[SerializationInfo.MAX_PUBLISHED_REGISTERS]; 93 94 /** Published entries of register that are updates on change */ 95 int publishedOnChangedEntries; 96 97 /** Registers that are updated on change */ 98 ArrayList<Register<?>> onChangeRegisters = new ArrayList<Register<?>>(); 99 } 100 101 /** Info on published registers - possibly null */ 102 PublishedRegisterStatus publishedRegisterStatus; 103 104 105 /** 106 * @param sink Sink to use 107 */ 108 public BinaryOutputStream(Sink sink) { 109 this(sink, new SerializationInfo()); 110 } 111 112 /** 113 * @param sink Sink to use 114 * @param serializationTarget Info on target that serialization is created for 115 */ 116 public BinaryOutputStream(Sink sink, SerializationInfo serializationTarget) { 117 reset(sink, serializationTarget); 118 } 119 120 /** 121 * @param sink Sink to use 122 * @param sharedSerializationInfoFrom Serialization info (SerializationInfo and published registers) is taken from and shared with this output stream 123 */ 124 public BinaryOutputStream(Sink sink, BinaryOutputStream sharedSerializationInfoFrom) { 125 reset(sink, sharedSerializationInfoFrom); 126 } 127 128 129 public BinaryOutputStream() {} 130 131 /** 132 * @return Info on target that serialization is created for 133 */ 134 public SerializationInfo getTargetInfo() { 135 return serializationTarget; 134 136 } 135 137 … … 147 149 public int remaining() { 148 150 return buffer.remaining(); 149 }150 151 /**152 * Use buffer with different sink (closes old one)153 *154 * @param sink New Sink to use155 */156 public void reset(Sink sink) {157 close();158 this.sink = sink;159 reset();160 151 } 161 152 … … 169 160 bufferCopyFraction = (int)(buffer.capacity() * BUFFER_COPY_FRACTION); 170 161 directWriteSupport = sink.directWriteSupport(); 162 } 163 164 /** 165 * Use buffer with different sink (closes old one) 166 * 167 * @param sink New Sink to use 168 */ 169 public void reset(Sink sink) { 170 reset(sink, new SerializationInfo()); 171 } 172 173 /** 174 * Use buffer with different sink (closes old one) 175 * 176 * @param sink New Sink to use 177 * @param serializationTarget Info on target that serialization is created for 178 */ 179 public void reset(Sink sink, SerializationInfo serializationTarget) { 180 close(); 181 this.sink = sink; 182 setSerializationTarget(serializationTarget); 183 reset(); 184 } 185 186 /** 187 * Sets shared serialization target of this stream without changing sink 188 * 189 * serializationTarget Info on target that serialization is created for 190 */ 191 public void setSerializationTarget(SerializationInfo serializationTarget) { 192 this.serializationTarget = serializationTarget; 193 publishedRegisterStatus = serializationTarget.hasPublishedRegisters() ? new PublishedRegisterStatus() : null; 194 if (serializationTarget.hasPublishedRegisters()) { 195 for (int i = 0; i < SerializationInfo.MAX_PUBLISHED_REGISTERS; i++) { 196 if (serializationTarget.getRegisterEntryEncoding(i) == SerializationInfo.RegisterEntryEncoding.PUBLISH_REGISTER_ON_CHANGE) { 197 publishedRegisterStatus.onChangeRegisters.add(PublishedRegisters.get(i).register); 198 } 199 } 200 } 201 } 202 203 /** 204 * Use buffer with different sink (closes old one) 205 * 206 * @param sink New Sink to use 207 * @param sharedSerializationInfoFrom Serialization info (SerializationInfo and published registers) is taken from and shared with this output stream 208 */ 209 public void reset(Sink sink, BinaryOutputStream sharedSerializationInfoFrom) { 210 close(); 211 this.sink = sink; 212 setSharedSerializationInfo(sharedSerializationInfoFrom); 213 reset(); 214 } 215 216 /** 217 * Sets shared serialization info of this stream without changing sink 218 * 219 * @param sharedSerializationInfoFrom Serialization info (SerializationInfo and published registers) is taken from and shared with this output stream 220 */ 221 public void setSharedSerializationInfo(BinaryOutputStream sharedSerializationInfoFrom) { 222 this.serializationTarget = sharedSerializationInfoFrom.serializationTarget; 223 this.publishedRegisterStatus = sharedSerializationInfoFrom.publishedRegisterStatus; 171 224 } 172 225 … … 377 430 378 431 /** 379 * @param v 32 bit integer380 */381 public void writeInt(int v) {382 ensureAdditionalCapacity(4);383 buffer.buffer.putInt(buffer.position, v);384 buffer.position += 4;385 }386 387 /**388 * @param v 64 bit integer389 */390 public void writeLong(long v) {391 ensureAdditionalCapacity(8);392 buffer.buffer.putLong(buffer.position, v);393 buffer.position += 8;394 }395 396 /**397 * @param v 16 bit integer398 */399 public void writeShort(int v) {400 ensureAdditionalCapacity(2);401 buffer.buffer.putShort(buffer.position, (short)v);402 buffer.position += 2;403 }404 405 /**406 432 * @param v 64 bit floating point 407 433 */ … … 412 438 } 413 439 414 /**415 * @param v 32 bit floating point416 */417 public void writeFloat(float v) {418 ensureAdditionalCapacity(4);419 buffer.buffer.putFloat(buffer.position, v);420 buffer.position += 4;421 }422 440 423 441 /** … … 447 465 448 466 /** 467 * @param v 32 bit floating point 468 */ 469 public void writeFloat(float v) { 470 ensureAdditionalCapacity(4); 471 buffer.buffer.putFloat(buffer.position, v); 472 buffer.position += 4; 473 } 474 475 /** 476 * @param v 32 bit integer 477 */ 478 public void writeInt(int v) { 479 ensureAdditionalCapacity(4); 480 buffer.buffer.putInt(buffer.position, v); 481 buffer.position += 4; 482 } 483 484 /** 485 * @param v sizeof byte integer 486 * @param sizeof Size of integer (1, 2, 4, or 8) 487 */ 488 public void writeInt(long v, int sizeof) { 489 switch (sizeof) { 490 case 1: 491 writeByte((byte)v); 492 break; 493 case 2: 494 writeShort((short)v); 495 break; 496 case 4: 497 writeInt((int)v); 498 break; 499 case 8: 500 writeLong(v); 501 break; 502 default: 503 throw new RuntimeException("Invalid size"); 504 } 505 } 506 507 /** 508 * @param v 64 bit integer 509 */ 510 public void writeLong(long v) { 511 ensureAdditionalCapacity(8); 512 buffer.buffer.putLong(buffer.position, v); 513 buffer.position += 8; 514 } 515 516 /** 517 * @param v 16 bit integer 518 */ 519 public void writeShort(int v) { 520 ensureAdditionalCapacity(2); 521 buffer.buffer.putShort(buffer.position, (short)v); 522 buffer.position += 2; 523 } 524 525 /** 449 526 * Print line to StreamBuffer. 450 527 * … … 536 613 write(inputStream.curBuffer.buffer, inputStream.curBuffer.position, inputStream.curBuffer.remaining()); 537 614 inputStream.curBuffer.position = inputStream.curBuffer.end; 538 }539 }540 541 /**542 * @param type Data type to write/reference (using encoding specified in constructor)543 */544 public void writeType(DataTypeBase type) {545 type = type == null ? DataTypeBase.NULL_TYPE : type;546 547 if (encoding == TypeEncoding.LocalUids) {548 writeShort(type.getUid());549 } else if (encoding == TypeEncoding.Names) {550 writeString(type.getName());551 } else {552 customEncoder.writeType(this, type);553 615 } 554 616 } … … 663 725 writeLong(duration * 1000000); 664 726 } 727 728 /** 729 * Writes any required updates to stream 730 * 731 * @param registerUid UID of register whose entry is to be serialized after call 732 * @param entryHandle Handle of entry to be serialized after call 733 * @param handleSize Size of register's handle (in bytes) 734 * @return Whether any register updates have been written to stream 735 */ 736 public boolean writeRegisterUpdates(int registerUid, int entryHandle, int handleSize) { 737 int newCounter = 0; 738 if (publishedRegisterStatus.onChangeRegisters != null) { 739 for (Register<?> register : publishedRegisterStatus.onChangeRegisters) { 740 newCounter += register.size(); 741 } 742 } 743 if (newCounter < publishedRegisterStatus.publishedOnChangedEntries || entryHandle > publishedRegisterStatus.elementsWritten[registerUid]) { 744 publishedRegisterStatus.publishedOnChangedEntries = newCounter; 745 746 boolean escapeSignalWritten = false; 747 748 // Update on_change registers 749 for (int i = 0; i < SerializationInfo.MAX_PUBLISHED_REGISTERS; i++) { 750 PublishedRegisters.PerRegisterInfo localRegister = PublishedRegisters.get(i); 751 boolean may_require_update = i == registerUid || serializationTarget.getRegisterEntryEncoding(i) == SerializationInfo.RegisterEntryEncoding.PUBLISH_REGISTER_ON_CHANGE; 752 if (may_require_update && localRegister != null) { 753 754 int currentSize = localRegister.register.size(); 755 if (currentSize > publishedRegisterStatus.elementsWritten[i]) { 756 if (!escapeSignalWritten) { 757 if (handleSize == 1) { 758 writeByte(-2); 759 } else if (handleSize == 2) { 760 writeShort(-2); 761 } else if (handleSize == 4) { 762 writeInt(-2); 763 } 764 escapeSignalWritten = true; 765 } 766 767 if (getTargetInfo().getRevision() == 0) { 768 if (publishedRegisterStatus.elementsWritten[i] == 0) { 769 writeShort(40); 770 } 771 772 // compatibility with legacy parts 773 PublishedRegisters.get(registerUid).serializeEntries(this, publishedRegisterStatus.elementsWritten[i], currentSize); 774 writeShort(-1); 775 } else { 776 writeByte(i); 777 writeInt(currentSize - publishedRegisterStatus.elementsWritten[i]); 778 PublishedRegisters.get(registerUid).serializeEntries(this, publishedRegisterStatus.elementsWritten[i], currentSize); 779 } 780 publishedRegisterStatus.elementsWritten[i] = currentSize; 781 } 782 } 783 } 784 if (escapeSignalWritten && getTargetInfo().getRevision() != 0) { // non-legacy parts require this terminator 785 writeByte(-1); 786 } 787 return escapeSignalWritten; 788 } 789 return false; 790 } 791 792 /** 793 * Writes remote register entry to stream (typically only its handle) 794 * 795 * @param entry Entry to write to stream 796 */ 797 public void writeRemoteRegisterEntry(PublishedRegisters.RemoteEntryBase<?> entry) { 798 writeInt(entry.getHandle(), entry.getHandleSize()); 799 } 665 800 } -
BufferInfo.java
r0 r26 24 24 25 25 /** 26 * @author Max Reichardt 27 * 26 28 * Buffer information 27 29 * (can be passed to and modified by Manager (by reference)) -
FixedBuffer.java
r0 r26 63 63 /** 64 64 * @param capacity Capacity of buffer to allocate 65 * @param allocat Direct Allocate direct byte buffer? (in heap outside of JVM - mainly relevant for JNI code)66 */ 67 public FixedBuffer(int capacity, boolean allocat Direct) {68 this(allocat Direct ? ByteBuffer.allocateDirect(capacity) : ByteBuffer.allocate(capacity));65 * @param allocateDirect Allocate direct byte buffer? (in heap outside of JVM - mainly relevant for JNI code) 66 */ 67 public FixedBuffer(int capacity, boolean allocateDirect) { 68 this(allocateDirect ? ByteBuffer.allocateDirect(capacity) : ByteBuffer.allocate(capacity)); 69 69 } 70 70 -
MemoryBuffer.java
r16 r26 39 39 * Writing and reading concurrently is not supported - due to resize. 40 40 */ 41 public class MemoryBuffer implements BinarySerializable, ConstSource, Sink, Copyable<MemoryBuffer>, GenericChangeable<MemoryBuffer> {41 public class MemoryBuffer implements BinarySerializable, Source, Sink, Copyable<MemoryBuffer>, GenericChangeable<MemoryBuffer> { 42 42 43 43 /** Size of temporary array */ … … 74 74 75 75 public MemoryBuffer(int size) { 76 this(size, DEFAULT_RESIZE_FACTOR, true);76 this(size, DEFAULT_RESIZE_FACTOR, false); 77 77 } 78 78 … … 80 80 * @param size Initial buffer size 81 81 * @param resizeFactor When buffer needs to be reallocated, new size is multiplied with this factor to have some bytes in reserve 82 * @param allocat Direct Allocate direct byte buffer? (in heap outside of JVM - mainly relevant for JNI code)83 */ 84 public MemoryBuffer(int size, float resizeFactor, boolean allocat Direct) {85 backend = new FixedBuffer(size, allocat Direct);82 * @param allocateDirect Allocate direct byte buffer? (in heap outside of JVM - mainly relevant for JNI code) 83 */ 84 public MemoryBuffer(int size, float resizeFactor, boolean allocateDirect) { 85 backend = new FixedBuffer(size, allocateDirect); 86 86 resizeReserveFactor = resizeFactor; 87 87 } -
PortDataListImpl.java
r19 r26 53 53 public void serialize(BinaryOutputStream os) { 54 54 os.writeInt(wrapped.size()); 55 boolean constType = true;55 os.writeBoolean(true); // const type? (possibly unnecessary; if we remove it, this will break binary compatibility to 13.10 though) 56 56 for (int i = 0; i < wrapped.size(); i++) { 57 constType &= wrapped.get(i).getClass().equals(elementType.getJavaClass());58 }59 os.writeBoolean(constType);60 for (int i = 0; i < wrapped.size(); i++) {61 if (!constType) {62 if (wrapped.get(i) == null) {63 os.writeType(DataTypeBase.NULL_TYPE);64 continue;65 }66 os.writeType(DataTypeBase.findType(wrapped.get(i).getClass(), elementType));67 }68 57 wrapped.get(i).serialize(os); 69 58 } … … 75 64 int size = is.readInt(); 76 65 boolean constType = is.readBoolean(); 66 if (!constType) { 67 throw new RuntimeException("Non-const types are not supported"); 68 } 69 77 70 for (int i = 0; i < size; i++) { 78 71 DataTypeBase type = elementType; 79 if (!constType) {80 type = is.readType();81 if (type == null || type == DataTypeBase.NULL_TYPE) {82 wrapped.set(i, null);83 continue;84 }85 }86 72 if (i < wrapped.size() && wrapped.get(i).getClass().equals(type.getJavaClass())) { 87 73 ((T)wrapped.get(i)).deserialize(is); -
StringOutputStream.java
r15 r26 21 21 //---------------------------------------------------------------------- 22 22 package org.rrlib.serialization; 23 24 import org.rrlib.serialization.rtti.GenericObject; 23 25 24 26 … … 130 132 } else if (type.isPrimitive() || Number.class.isAssignableFrom(type) || Boolean.class.equals(type)) { 131 133 append(object.toString()); 134 } else if (type.equals(GenericObject.class)) { 135 try { 136 ((GenericObject)object).serialize(this); 137 } catch (Exception e) { 138 throw new RuntimeException("Generic object has unsupported type"); 139 } 132 140 } else { 133 141 assert(object != null && (object.getClass() == type)); -
StringSerializable.java
r0 r26 22 22 package org.rrlib.serialization; 23 23 24 import org.rrlib.serialization.rtti.DataType; 25 import org.rrlib.serialization.rtti.DataTypeBase; 26 24 27 25 28 /** … … 43 46 */ 44 47 public void deserialize(StringInputStream stream) throws Exception; 48 49 50 /** Data type of this class */ 51 public final static DataTypeBase TYPE = new DataType<StringSerializable>(StringSerializable.class); 52 53 /** 54 * Empty String serializable 55 */ 56 public static class Empty extends BinarySerializable.Empty implements StringSerializable { 57 58 public final static DataType<StringSerializable.Empty> TYPE = new DataType<>(StringSerializable.Empty.class, "EmptyStringSerializable"); 59 60 @Override 61 public void serialize(StringOutputStream stream) { 62 } 63 64 @Override 65 public void deserialize(StringInputStream stream) throws Exception { 66 } 67 68 @Override 69 public String toString() { 70 return ""; 71 } 72 } 45 73 } -
rtti/DataType.java
r18 r26 48 48 public DataType(Class<?> javaClass, String name, boolean createListTypes) { 49 49 super(name != null ? name : javaClass.getSimpleName()); 50 type = Classification.PLAIN;51 50 this.javaClass = javaClass; 52 typeTraits = (byte)((Serialization.isBinarySerializable(javaClass) ? IS_BINARY_SERIALIZABLE : 0) | 53 (Serialization.isStringSerializable(javaClass) ? IS_STRING_SERIALIZABLE : 0) | (Serialization.isXmlSerializable(javaClass) ? IS_XML_SERIALIZABLE : 0)); 51 typeTraits = IS_DATA_TYPE | 52 (Serialization.isBinarySerializable(javaClass) ? IS_BINARY_SERIALIZABLE : 0) | 53 (Serialization.isStringSerializable(javaClass) ? IS_STRING_SERIALIZABLE : 0) | 54 (Serialization.isXmlSerializable(javaClass) ? IS_XML_SERIALIZABLE : 0); 54 55 if (javaClass.isEnum()) { 55 56 ArrayList<String> constants = new ArrayList<String>(); … … 62 63 63 64 if (createListTypes && listType == null) { 64 listType = new DataType(this, Classification.LIST); 65 //sharedPtrListType = new DataType(this, Classification.PTR_LIST); 65 listType = new DataType(this); 66 66 } 67 67 } … … 70 70 public DataType(Class<?> javaClass, Class<?> dedicatedListType, String name) { 71 71 this(javaClass, name, false); 72 listType = new DataType(this , Classification.LIST);72 listType = new DataType(this); 73 73 listType.javaClass = dedicatedListType; 74 74 } … … 77 77 * Constructor for list types 78 78 */ 79 private DataType(DataTypeBase e, Classification type) { 80 super(type == Classification.LIST ? ("List<" + e.getName() + ">") : ("List<" + e.getName() + "*>")); 81 this.type = type; 79 private DataType(DataTypeBase e) { 80 super("List<" + e.getName() + ">"); 82 81 this.elementType = e; 83 this.typeTraits = ( byte)(e.typeTraits & (IS_BINARY_SERIALIZABLE | IS_STRING_SERIALIZABLE | IS_XML_SERIALIZABLE));82 this.typeTraits = (e.typeTraits & (IS_BINARY_SERIALIZABLE | IS_STRING_SERIALIZABLE | IS_XML_SERIALIZABLE) | IS_DATA_TYPE | IS_LIST_TYPE); 84 83 } 85 84 … … 88 87 public Object createInstance() { 89 88 Object result = null; 90 if (javaClass == null && ( getType() == Classification.LIST || getType() == Classification.PTR_LIST)) {89 if (javaClass == null && (typeTraits & IS_LIST_TYPE) != 0) { 91 90 return new PortDataListImpl(getElementType()); 92 91 } -
rtti/DataTypeBase.java
r21 r26 22 22 package org.rrlib.serialization.rtti; 23 23 24 import java.util.ArrayList;25 24 import java.util.HashMap; 26 25 import java.util.concurrent.atomic.AtomicInteger; … … 28 27 import org.rrlib.logging.Log; 29 28 import org.rrlib.logging.LogLevel; 29 import org.rrlib.serialization.BinaryInputStream; 30 import org.rrlib.serialization.BinaryOutputStream; 31 import org.rrlib.serialization.PublishedRegisters; 32 import org.rrlib.serialization.Register; 33 import org.rrlib.serialization.PublishedRegisters.RemoteEntryBase; 30 34 31 35 … … 47 51 public class DataTypeBase { 48 52 49 /** type of data type */ 50 public enum Classification { 51 PLAIN, // Plain type 52 LIST, // List of objects of same type 53 PTR_LIST, // List of objects with possibly objects of different types 54 NULL, // Null type 55 OTHER, // Other data type 56 UNKNOWN // Unknown data type in current process 57 } 58 59 /** Relevant type traits across runtime environments */ 60 public static final byte IS_BINARY_SERIALIZABLE = 1 << 0; 61 public static final byte IS_STRING_SERIALIZABLE = 1 << 1; 62 public static final byte IS_XML_SERIALIZABLE = 1 << 2; 63 public static final byte IS_ENUM = 1 << 3; 53 /** Relevant type traits across runtime environments (equals C++ traits) */ 54 public static final int 55 IS_BINARY_SERIALIZABLE = 1 << 8, 56 IS_STRING_SERIALIZABLE = 1 << 9, 57 IS_XML_SERIALIZABLE = 1 << 10, 58 IS_ENUM = 1 << 11, 59 IS_DATA_TYPE = 1 << 12, 60 IS_RPC_TYPE = 1 << 13, 61 // the traits below are only set in C++ 62 HAS_LIST_TYPE = 1 << 14, 63 HAS_UNDERLYING_TYPE = 1 << 15, 64 IS_CAST_TO_UNDERLYING_TYPE_IMPLICIT = 1 << 16, 65 IS_REINTERPRET_CAST_FROM_UNDERLYING_TYPE_VALID = 1 << 17, 66 IS_CAST_FROM_UNDERLYING_TYPE_IMPLICIT = 1 << 18, 67 IS_UNDERLYING_TYPE_BINARY_SERIALIZATION_DIFFERENT = 1 << 19, 68 SUPPORTS_BITWISE_COPY = 1 << 20, 69 IS_INTEGRAL = 1 << 21, 70 IS_LIST_TYPE = 1 << 22, 71 HAS_TRIVIAL_DESTRUCTOR = 1 << 23; 72 73 /** Register with all registered data types */ 74 private static Register<DataTypeBase> types = new Register<DataTypeBase>(32, 128, 2); 64 75 65 76 /** Null type */ 66 public static DataTypeBase NULL_TYPE = new DataTypeBase( true);77 public static DataTypeBase NULL_TYPE = new DataTypeBase("NULL"); 67 78 68 79 /** Maximum number of annotations */ … … 72 83 private final static int MAX_TYPES = 2000; 73 84 74 /** Type of data type */75 protected Classification type;76 77 85 /** Name of data type */ 78 86 private final String name; … … 102 110 protected long[] enumValues; 103 111 104 /** List with all registered data types (preallocated to avoid reallocations => concurrent use is possible) */105 private static ArrayList<DataTypeBase> types = new ArrayList<DataTypeBase>(MAX_TYPES);106 107 112 /** Lookup for data type annotation index */ 108 113 private static final HashMap < Class<?>, Integer > annotationIndexLookup = new HashMap < Class<?>, Integer > (); … … 112 117 113 118 /** Type traits of this type (bit vector - see constants above) */ 114 protected bytetypeTraits;119 protected int typeTraits; 115 120 116 121 ///** Is this a remote type? */ … … 121 126 uid = (short)types.size(); 122 127 this.name = name; 123 for ( DataTypeBase type : types) {124 if (type .getName().equals(name)) {128 for (int i = 0, n = types.size(); i < n; i++) { 129 if (types.get(i).getName().equals(name)) { 125 130 Log.log(LogLevel.WARNING, "Two types with the same name were registered: " + name); 126 131 } … … 136 141 } 137 142 138 private DataTypeBase(boolean nulltype) {139 this.name = "NULL";140 this.uid = -1;141 this.type = Classification.NULL;142 }143 144 143 /** 145 144 * @return Name of data type … … 164 163 165 164 /** 166 * @return return "Type" of data type (see enum)167 */168 public Classification getType() {169 return type;170 }171 172 /**173 165 * @return In case of element: list type (std::vector<T>) 174 166 */ … … 201 193 * @return Bit vector of type traits 202 194 */ 203 public bytegetTypeTraits() {195 public int getTypeTraits() { 204 196 return typeTraits; 205 197 } … … 322 314 /** 323 315 * Can object of this data type be converted to specified type? 324 * (In C++ currently only returns true, when types are equal)325 316 * 326 317 * @param dataType Other type … … 332 323 return true; 333 324 } 334 if (type == Classification.NULL || dataType.type == Classification.NULL) { 335 return false; 336 } 337 if (getType() == Classification.UNKNOWN || dataType.getType() == Classification.UNKNOWN) { 338 return false; 339 } 340 if (getType() == Classification.LIST && dataType.getType() == Classification.LIST) { 341 return getElementType().isConvertibleTo(dataType.getElementType()); 325 if ((typeTraits & dataType.typeTraits & IS_LIST_TYPE) != 0) { 326 return getElementType() != null && dataType.getElementType() != null && getElementType().isConvertibleTo(dataType.getElementType()); 342 327 } 343 328 if ((javaClass != null) && (dataType.javaClass != null)) { … … 392 377 return enumConstants; 393 378 } 379 394 380 /** 395 381 * @return Array with enum values - if this is a remote enum type with non-standard values … … 398 384 return enumValues; 399 385 } 386 387 /** 388 * @param stream Stream to serialize this type to 389 */ 390 public void serialize(BinaryOutputStream stream) { 391 if (types.writeEntry(stream, getUid())) { 392 stream.writeString(getName()); 393 } 394 } 395 396 /** 397 * @param stream Stream to deserialize (local) type from 398 * @return Deserialized type 399 */ 400 public static DataTypeBase deserialize(BinaryInputStream stream) throws Exception { 401 DataTypeBase result = types.readEntry(stream); 402 if (result == null) { 403 return findType(stream.readString()); 404 } 405 return result; 406 } 407 408 /** 409 * Registers type register for use in auto-publishing mechanism. 410 * 411 * @param uid Uid to assign to register (must be <= MAX_PUBLISHED_REGISTERS) 412 * @param remoteEntryClass Type to deserialize in remote runtime environment. It needs to be derived from PublishedRegisters.RemoteEntryBase and be default-constructible. 413 * @throw Throws exception on already occupied uid 414 */ 415 public static void registerForPublishing(int uid, Class<? extends RemoteEntryBase<?>> remoteEntryClass) throws Exception { 416 PublishedRegisters.register(types, uid, remoteEntryClass); 417 } 400 418 }
Note: See TracChangeset
for help on using the changeset viewer.