Changeset 26:3b888f173cfb in rrlib_serialization-java


Ignore:
Timestamp:
08.06.2017 03:02:37 (22 months ago)
Author:
Max Reichardt <mreichardt@…>
Branch:
17.03
Phase:
public
Message:

Adapts to changes in rrlib_serialization and rrlib_rtti (Finroc17). These include versioned serialization and introduction of register auto-publishing mechanism.

Files:
4 added
2 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • BinaryInputStream.java

    r23 r26  
    2525import java.io.StringReader; 
    2626 
    27 import org.rrlib.logging.Log; 
    2827import org.rrlib.serialization.compression.Compressible; 
    2928import org.rrlib.serialization.compression.DataCompressor; 
    30 import org.rrlib.serialization.rtti.DataTypeBase; 
    3129import org.rrlib.xml.XMLDocument; 
    3230import org.rrlib.xml.XMLNode; 
     
    5755    protected Source source = null; 
    5856 
    59     /** Manager that handles, where the data blocks come from etc. */ 
    60     protected ConstSource constSource = null; 
    61  
    6257    /** Current absolute buffer read position of buffer start - relevant when using Source; 64bit value, because we might transfer several GB over a stream */ 
    6358    protected long absoluteReadPos = 0; 
     
    7570    protected int timeout = -1; 
    7671 
    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 codec 
    82     } 
    83  
    84     /** Data type encoding that is used */ 
    85     protected TypeEncoding encoding; 
    86  
    87     /** Custom type encoder */ 
    88     protected TypeEncoder customEncoder; 
    89  
    9072    /** ByteArrayInputStream helper for reading strings in Java */ 
    9173    protected ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    9274 
    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; 
    142112    } 
    143113 
     
    155125     */ 
    156126    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; 
    166130        curBuffer = sourceBuffer; 
    167131        absoluteReadPos = 0; 
     
    174138     * @param source New Source 
    175139     */ 
    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()); 
    181142    } 
    182143 
     
    186147     * 
    187148     * @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) { 
    190152        close(); 
    191153        this.source = source; 
    192         this.constSource = null; 
     154        setSerializationSource(sourceInfo); 
    193155        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; 
    194213    } 
    195214 
     
    201220            if (source != null) { 
    202221                source.close(this, sourceBuffer); 
    203             } else if (constSource != null) { 
    204                 constSource.close(this, sourceBuffer); 
    205222            } 
    206223        } 
     
    370387    protected void fetchNextBytes(int minRequired2) { 
    371388        assert(minRequired2 <= 8); 
    372         assert(source != null || constSource != null); 
     389        assert(source != null); 
    373390 
    374391        // are we finished using boundary buffer? 
     
    397414            int initialSleep = 20; // timeout-related 
    398415            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))) { 
    400417                initialSleep *= 2; 
    401418                try { 
     
    410427 
    411428        // 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); 
    417430        assert(sourceBuffer.remaining() >= minRequired2); 
    418431        assert(sourceBuffer.position >= 0); 
     
    570583 
    571584    /** 
     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) 
    572604     * @return String/Line from stream (ends either at line delimiter or 0-character) 
    573605     */ 
     
    702734        } 
    703735        //System.out.println("Not here"); 
    704         return source != null ? source.moreDataAvailable(this, sourceBuffer) : constSource.moreDataAvailable(this, sourceBuffer); 
     736        return source.moreDataAvailable(this, sourceBuffer); 
    705737    } 
    706738 
     
    724756    public void setTimeout(int timeout) { 
    725757        this.timeout = timeout; 
    726     } 
    727  
    728     /** 
    729      * @return Reads type from stream 
    730      */ 
    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         } 
    739758    } 
    740759 
     
    882901    } 
    883902 
    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    } 
    885942} 
  • BinaryOutputStream.java

    r23 r26  
    2222package org.rrlib.serialization; 
    2323 
    24 import org.rrlib.serialization.rtti.DataTypeBase; 
     24import java.util.ArrayList; 
     25 
    2526import org.rrlib.xml.XMLDocument; 
    2627import org.rrlib.xml.XMLNode; 
     
    8283    private boolean directWriteSupport = false; 
    8384 
    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; 
    134136    } 
    135137 
     
    147149    public int remaining() { 
    148150        return buffer.remaining(); 
    149     } 
    150  
    151     /** 
    152      * Use buffer with different sink (closes old one) 
    153      * 
    154      * @param sink New Sink to use 
    155      */ 
    156     public void reset(Sink sink) { 
    157         close(); 
    158         this.sink = sink; 
    159         reset(); 
    160151    } 
    161152 
     
    169160        bufferCopyFraction = (int)(buffer.capacity() * BUFFER_COPY_FRACTION); 
    170161        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; 
    171224    } 
    172225 
     
    377430 
    378431    /** 
    379      * @param v 32 bit integer 
    380      */ 
    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 integer 
    389      */ 
    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 integer 
    398      */ 
    399     public void writeShort(int v) { 
    400         ensureAdditionalCapacity(2); 
    401         buffer.buffer.putShort(buffer.position, (short)v); 
    402         buffer.position += 2; 
    403     } 
    404  
    405     /** 
    406432     * @param v 64 bit floating point 
    407433     */ 
     
    412438    } 
    413439 
    414     /** 
    415      * @param v 32 bit floating point 
    416      */ 
    417     public void writeFloat(float v) { 
    418         ensureAdditionalCapacity(4); 
    419         buffer.buffer.putFloat(buffer.position, v); 
    420         buffer.position += 4; 
    421     } 
    422440 
    423441    /** 
     
    447465 
    448466    /** 
     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    /** 
    449526     * Print line to StreamBuffer. 
    450527     * 
     
    536613            write(inputStream.curBuffer.buffer, inputStream.curBuffer.position, inputStream.curBuffer.remaining()); 
    537614            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); 
    553615        } 
    554616    } 
     
    663725        writeLong(duration * 1000000); 
    664726    } 
     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    } 
    665800} 
  • BufferInfo.java

    r0 r26  
    2424 
    2525/** 
     26 * @author Max Reichardt 
     27 * 
    2628 * Buffer information 
    2729 * (can be passed to and modified by Manager (by reference)) 
  • FixedBuffer.java

    r0 r26  
    6363    /** 
    6464     * @param capacity Capacity of buffer to allocate 
    65      * @param allocatDirect Allocate direct byte buffer? (in heap outside of JVM - mainly relevant for JNI code) 
    66      */ 
    67     public FixedBuffer(int capacity, boolean allocatDirect) { 
    68         this(allocatDirect ? 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)); 
    6969    } 
    7070 
  • MemoryBuffer.java

    r16 r26  
    3939 * Writing and reading concurrently is not supported - due to resize. 
    4040 */ 
    41 public class MemoryBuffer implements BinarySerializable, ConstSource, Sink, Copyable<MemoryBuffer>, GenericChangeable<MemoryBuffer> { 
     41public class MemoryBuffer implements BinarySerializable, Source, Sink, Copyable<MemoryBuffer>, GenericChangeable<MemoryBuffer> { 
    4242 
    4343    /** Size of temporary array */ 
     
    7474 
    7575    public MemoryBuffer(int size) { 
    76         this(size, DEFAULT_RESIZE_FACTOR, true); 
     76        this(size, DEFAULT_RESIZE_FACTOR, false); 
    7777    } 
    7878 
     
    8080     * @param size Initial buffer size 
    8181     * @param resizeFactor When buffer needs to be reallocated, new size is multiplied with this factor to have some bytes in reserve 
    82      * @param allocatDirect Allocate direct byte buffer? (in heap outside of JVM - mainly relevant for JNI code) 
    83      */ 
    84     public MemoryBuffer(int size, float resizeFactor, boolean allocatDirect) { 
    85         backend = new FixedBuffer(size, allocatDirect); 
     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); 
    8686        resizeReserveFactor = resizeFactor; 
    8787    } 
  • PortDataListImpl.java

    r19 r26  
    5353    public void serialize(BinaryOutputStream os) { 
    5454        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) 
    5656        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             } 
    6857            wrapped.get(i).serialize(os); 
    6958        } 
     
    7564        int size = is.readInt(); 
    7665        boolean constType = is.readBoolean(); 
     66        if (!constType) { 
     67            throw new RuntimeException("Non-const types are not supported"); 
     68        } 
     69 
    7770        for (int i = 0; i < size; i++) { 
    7871            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             } 
    8672            if (i < wrapped.size() && wrapped.get(i).getClass().equals(type.getJavaClass())) { 
    8773                ((T)wrapped.get(i)).deserialize(is); 
  • StringOutputStream.java

    r15 r26  
    2121//---------------------------------------------------------------------- 
    2222package org.rrlib.serialization; 
     23 
     24import org.rrlib.serialization.rtti.GenericObject; 
    2325 
    2426 
     
    130132        } else if (type.isPrimitive() || Number.class.isAssignableFrom(type) || Boolean.class.equals(type)) { 
    131133            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            } 
    132140        } else { 
    133141            assert(object != null && (object.getClass() == type)); 
  • StringSerializable.java

    r0 r26  
    2222package org.rrlib.serialization; 
    2323 
     24import org.rrlib.serialization.rtti.DataType; 
     25import org.rrlib.serialization.rtti.DataTypeBase; 
     26 
    2427 
    2528/** 
     
    4346     */ 
    4447    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    } 
    4573} 
  • rtti/DataType.java

    r18 r26  
    4848    public DataType(Class<?> javaClass, String name, boolean createListTypes) { 
    4949        super(name != null ? name : javaClass.getSimpleName()); 
    50         type = Classification.PLAIN; 
    5150        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); 
    5455        if (javaClass.isEnum()) { 
    5556            ArrayList<String> constants = new ArrayList<String>(); 
     
    6263 
    6364        if (createListTypes && listType == null) { 
    64             listType = new DataType(this, Classification.LIST); 
    65             //sharedPtrListType = new DataType(this, Classification.PTR_LIST); 
     65            listType = new DataType(this); 
    6666        } 
    6767    } 
     
    7070    public DataType(Class<?> javaClass, Class<?> dedicatedListType, String name) { 
    7171        this(javaClass, name, false); 
    72         listType = new DataType(this, Classification.LIST); 
     72        listType = new DataType(this); 
    7373        listType.javaClass = dedicatedListType; 
    7474    } 
     
    7777     * Constructor for list types 
    7878     */ 
    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() + ">"); 
    8281        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); 
    8483    } 
    8584 
     
    8887    public Object createInstance() { 
    8988        Object result = null; 
    90         if (javaClass == null && (getType() == Classification.LIST || getType() == Classification.PTR_LIST)) { 
     89        if (javaClass == null && (typeTraits & IS_LIST_TYPE) != 0) { 
    9190            return new PortDataListImpl(getElementType()); 
    9291        } 
  • rtti/DataTypeBase.java

    r21 r26  
    2222package org.rrlib.serialization.rtti; 
    2323 
    24 import java.util.ArrayList; 
    2524import java.util.HashMap; 
    2625import java.util.concurrent.atomic.AtomicInteger; 
     
    2827import org.rrlib.logging.Log; 
    2928import org.rrlib.logging.LogLevel; 
     29import org.rrlib.serialization.BinaryInputStream; 
     30import org.rrlib.serialization.BinaryOutputStream; 
     31import org.rrlib.serialization.PublishedRegisters; 
     32import org.rrlib.serialization.Register; 
     33import org.rrlib.serialization.PublishedRegisters.RemoteEntryBase; 
    3034 
    3135 
     
    4751public class DataTypeBase { 
    4852 
    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); 
    6475 
    6576    /** Null type */ 
    66     public static DataTypeBase NULL_TYPE = new DataTypeBase(true); 
     77    public static DataTypeBase NULL_TYPE = new DataTypeBase("NULL"); 
    6778 
    6879    /** Maximum number of annotations */ 
     
    7283    private final static int MAX_TYPES = 2000; 
    7384 
    74     /** Type of data type */ 
    75     protected Classification type; 
    76  
    7785    /** Name of data type */ 
    7886    private final String name; 
     
    102110    protected long[] enumValues; 
    103111 
    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  
    107112    /** Lookup for data type annotation index */ 
    108113    private static final HashMap < Class<?>, Integer > annotationIndexLookup = new HashMap < Class<?>, Integer > (); 
     
    112117 
    113118    /** Type traits of this type (bit vector - see constants above) */ 
    114     protected byte typeTraits; 
     119    protected int typeTraits; 
    115120 
    116121    ///** Is this a remote type? */ 
     
    121126            uid = (short)types.size(); 
    122127            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)) { 
    125130                    Log.log(LogLevel.WARNING, "Two types with the same name were registered: " + name); 
    126131                } 
     
    136141    } 
    137142 
    138     private DataTypeBase(boolean nulltype) { 
    139         this.name = "NULL"; 
    140         this.uid = -1; 
    141         this.type = Classification.NULL; 
    142     } 
    143  
    144143    /** 
    145144     * @return Name of data type 
     
    164163 
    165164    /** 
    166      * @return return "Type" of data type (see enum) 
    167      */ 
    168     public Classification getType() { 
    169         return type; 
    170     } 
    171  
    172     /** 
    173165     * @return In case of element: list type (std::vector<T>) 
    174166     */ 
     
    201193     * @return Bit vector of type traits 
    202194     */ 
    203     public byte getTypeTraits() { 
     195    public int getTypeTraits() { 
    204196        return typeTraits; 
    205197    } 
     
    322314    /** 
    323315     * Can object of this data type be converted to specified type? 
    324      * (In C++ currently only returns true, when types are equal) 
    325316     * 
    326317     * @param dataType Other type 
     
    332323            return true; 
    333324        } 
    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()); 
    342327        } 
    343328        if ((javaClass != null) && (dataType.javaClass != null)) { 
     
    392377        return enumConstants; 
    393378    } 
     379 
    394380    /** 
    395381     * @return Array with enum values - if this is a remote enum type with non-standard values 
     
    398384        return enumValues; 
    399385    } 
     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    } 
    400418} 
Note: See TracChangeset for help on using the changeset viewer.