net.i2p.data
Class SimpleDataStructure

java.lang.Object
  extended by net.i2p.data.DataStructureImpl
      extended by net.i2p.data.SimpleDataStructure
All Implemented Interfaces:
DataStructure
Direct Known Subclasses:
Hash, NodeInfo, PrivateKey, PublicKey, SessionKey, SessionTag, SHA1Hash, Signature, SigningPrivateKey, SigningPublicKey

public abstract class SimpleDataStructure
extends DataStructureImpl

A SimpleDataStructure contains only a single fixed-length byte array. The main reason to do this is to override toByteArray() and fromByteArray(), which are used by toBase64(), fromBase64(), and calculateHash() in DataStructureImpl - otherwise these would go through a wasteful array-to-stream-to-array pass. It also centralizes a lot of common code. Implemented in 0.8.2 and retrofitted over several of the classes in this package. As of 0.8.3, SDS objects may be cached. An SDS may be instantiated with null data, and setData(null) is also OK. However, once non-null data is set, the data reference is immutable; subsequent attempts to set the data via setData(), readBytes(), fromByteArray(), or fromBase64() will throw a RuntimeException.

Since:
0.8.2
Author:
zzz

Field Summary
protected  byte[] _data
           
protected  int _length
          this is just to avoid lots of calls to length()
 
Constructor Summary
SimpleDataStructure()
          A new instance with the data set to null.
SimpleDataStructure(byte[] data)
           
 
Method Summary
 Hash calculateHash()
          Calculate the SHA256 value of this object (useful for a few scenarios)
 boolean equals(Object obj)
          Warning - this returns true for two different classes with the same size and same data, e.g.
 void fromBase64(String data)
          Sets the data.
 void fromByteArray(byte[] data)
          Overridden for efficiency.
 byte[] getData()
          Get the data reference (not a copy)
 int hashCode()
          We assume the data has enough randomness in it, so use the first 4 bytes for speed.
abstract  int length()
          The legal length of the byte array in this data structure
 void readBytes(InputStream in)
          Sets the data.
 void setData(byte[] data)
          Sets the data.
 String toBase64()
          render the structure into modified base 64 notation
 byte[] toByteArray()
          Overridden for efficiency.
 String toString()
           
 void writeBytes(OutputStream out)
          Write out the data structure to the stream, using the format defined in the I2P data structure specification.
 
Methods inherited from class net.i2p.data.DataStructureImpl
read
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

_data

protected byte[] _data

_length

protected final int _length
this is just to avoid lots of calls to length()

Constructor Detail

SimpleDataStructure

public SimpleDataStructure()
A new instance with the data set to null. Call readBytes(), setData(), or fromByteArray() after this to set the data


SimpleDataStructure

public SimpleDataStructure(byte[] data)
Throws:
IllegalArgumentException - if data is not the legal number of bytes (but null is ok)
Method Detail

length

public abstract int length()
The legal length of the byte array in this data structure

Since:
0.8.2

getData

public byte[] getData()
Get the data reference (not a copy)

Returns:
the byte array, or null if unset

setData

public void setData(byte[] data)
Sets the data.

Parameters:
data - of correct length, or null
Throws:
IllegalArgumentException - if data is not the legal number of bytes (but null is ok)
RuntimeException - if data already set.

readBytes

public void readBytes(InputStream in)
               throws DataFormatException,
                      IOException
Sets the data.

Parameters:
in - the stream to read
Throws:
RuntimeException - if data already set.
DataFormatException - if the data is improperly formatted
IOException - if there was a problem reading the stream

writeBytes

public void writeBytes(OutputStream out)
                throws DataFormatException,
                       IOException
Description copied from interface: DataStructure
Write out the data structure to the stream, using the format defined in the I2P data structure specification.

Parameters:
out - stream to write to
Throws:
DataFormatException - if the data was incomplete or not yet ready to be written
IOException - if there was a problem writing to the stream

toBase64

public String toBase64()
Description copied from interface: DataStructure
render the structure into modified base 64 notation

Specified by:
toBase64 in interface DataStructure
Overrides:
toBase64 in class DataStructureImpl
Returns:
null on error

fromBase64

public void fromBase64(String data)
                throws DataFormatException
Sets the data.

Specified by:
fromBase64 in interface DataStructure
Overrides:
fromBase64 in class DataStructureImpl
Throws:
DataFormatException - if decoded data is not the legal number of bytes or on decoding error
RuntimeException - if data already set.

calculateHash

public Hash calculateHash()
Description copied from interface: DataStructure
Calculate the SHA256 value of this object (useful for a few scenarios)

Specified by:
calculateHash in interface DataStructure
Overrides:
calculateHash in class DataStructureImpl
Returns:
the SHA256 hash of the byte array, or null if the data is null

toByteArray

public byte[] toByteArray()
Overridden for efficiency.

Specified by:
toByteArray in interface DataStructure
Overrides:
toByteArray in class DataStructureImpl
Returns:
same thing as getData()

fromByteArray

public void fromByteArray(byte[] data)
                   throws DataFormatException
Overridden for efficiency. Does the same thing as setData() but null not allowed.

Specified by:
fromByteArray in interface DataStructure
Overrides:
fromByteArray in class DataStructureImpl
Parameters:
data - non-null
Throws:
DataFormatException - if null or wrong length
RuntimeException - if data already set.

toString

public String toString()
Overrides:
toString in class Object

hashCode

public int hashCode()
We assume the data has enough randomness in it, so use the first 4 bytes for speed. If this is not the case, override in the extending class.

Overrides:
hashCode in class Object

equals

public boolean equals(Object obj)
Warning - this returns true for two different classes with the same size and same data, e.g. SessionKey and SessionTag, but you wouldn't put them in the same Set, would you?

Overrides:
equals in class Object