org.vishia.byteData
Class ByteDataAccess

java.lang.Object
  extended by org.vishia.byteData.ByteDataAccess
Direct Known Subclasses:
ByteDataAccessDbg, DateValues_Jc, Field_Jc, InspcDataExchangeAccess.Datagram, InspcDataExchangeAccess.Info, InspcDataExchangeAccess.SetValue, MemUnit, OamVariables.OamVariablesByteAccess, Object_Jc, RawDataAccess

public abstract class ByteDataAccess
extends java.lang.Object

This class is a base class to control the access to binary data. The binary data may typically used or produced from a part of software written in C or C++. There the binary data are struct-constructs.
It is able to support several kinds of struct constructs:

This application possibilities show a capable of development system to access binary data. The other, hand made way was calculate with indices of the byte[idx] specially user programmed. This class helps to make such complex index calculation needlessly. One struct at C level corresponds with one derivated class of ByteDataAccess. But last also a generation of the java code from C/C++-header files containing the structs is able to. So the definition of byte positions are made only on one source. The C/C++ is primary thereby.

children, currentChild, addChild

Children are used to evaluate or write different data structures after a known structure. The children may be from several derivated types of this class. With children and children inside children a tree of different data can be built or evaluated. If no child is added yet, the indices have the following values: A call of next() sets the indices to a possible but not yet defined current child: A call of addChild() or its adequate addChildXY() sets the indices to the given current child: The length of the current Child may be set while evaluating the child's data. The user should be call setLengthElement(int) with the child or setLengthCurrentChildElement(int) with the parent, respectively with this. If this methods are not called, but next() or addChild...() is called however, without a known length but this (the parent) knows the rules to determine the length of its possible children, it is possible to do that. The method specifyLengthCurrentChildElement() supplied the number of bytes. But if this method is not overwritten in the inherited class, an exception is thrown.
The UML structure of such an class in a environment may be shown with the followed object model diagram,
<+>---> is a composition, <>---> is a aggregation, <|---- is a inherition.
                      +-------------------------------+                 +----------+
                      | ByteDataAccess                |----data-------->| byte[]   |
                      |-------------------------------|                 +----------+
                      |idxBegin:int                   |
                      |idxChild:int                   |<---------------+ a known parent
  +-------------+     |idxEnd:int                     |---parent-------+ setted in addChild()
  | derivated   |     |-------------------------------|
  | user        |---|>|specifyLengthElement()         |
  | classes     |     |specifyLengthElementHead()     |--currentChild--+ the actual child element
  +-------------+     |specifyLengthCurrentChild()    |<---------------+
                      +-------------------------------+
 


Field Summary
static int _version_
          The version.
static byte kEndOfElements
          Definition of the code of end of information, return from next()
static byte kNothing
          Definition of the code of no information, return from next()
static byte kText
          Aussage: es ist ein String (XML: text()), kein Tag im String
static byte kUndefined
          coding: the value is undefined
 
Constructor Summary
ByteDataAccess()
          Constructs a new empty instance.
 
Method Summary
 boolean addChild(ByteDataAccess child)
          adds an child Element after the current child or as first child after head.
 void addChildEmpty(ByteDataAccess child)
          Adds a child Element at current end of data to write data.
 void addChildFloat(float value)
          Adds a child for 1 integer value without a child instance, and sets the value as integer.
 void addChildInteger(int nrofBytes, long value)
          Adds a child for 1 integer value without a child instance, and sets the value as integer.
 void addChildString(java.lang.CharSequence value)
          Adds a child with String value.
 void addChildString(java.lang.CharSequence value, java.lang.String sEncoding)
          Adds a child with String value.
 void addChildString(java.lang.String value)
          Adds a child with String value.
 void addChildString(java.lang.String value, java.lang.String sEncoding, boolean preventCtrlChars)
          Adds a child with String value.
 int addText(java.lang.String ss)
          Deprecated.  
 void assignAsChild(ByteDataAccess parent)
          Deprecated. use addChild()
 void assignAtIndex(int idxChildInParent, ByteDataAccess parent)
          assigns the element to the given position of the parents data to present a child of the parent.
 void assignAtIndex(int idxChildInParent, int lengthChild, ByteDataAccess parent)
          assigns the element to the given position of the parents data to present a child of the parent with a defined length.
 void assignData(byte[] data, int length)
          Assigns new data to this element.
 void assignData(byte[] data, int lengthData, int index)
          Assigns new data to this element at given index in data.
 void assignEmpty(byte[] data)
          Initializes a top level, the data are considered as non initalized.
 void copyData(int[] dst)
          copies some data to a int[], primarily to debug a content.
 void copyDataFrom(ByteDataAccess src)
          Copies the data into a byte[]
 void detach()
          Remove all connections.
 void elementAt(int indexObjectArray)
          Counts the idxChild by given index, idxChild is ByteCount from idxBegin
 void expandParent()
          Expands the end index of the parent, it means the management of the expanse of the data.
 double getChildDouble()
          Adds a child for 1 double value without a child instance, but returns the value as integer.
 float getChildFloat()
          Adds a child for 1 float value without a child instance, but returns the value as integer.
 long getChildInteger(int nrofBytes)
          Adds a child for 1 integer value without a child instance, but returns the value as integer.
 java.lang.String getChildString(int nrofBytes)
          Adds a child for a String value without a child instance, but returns the value as String.
 ByteDataAccess getCurrentChild()
           
 byte[] getData()
          Returns the data buffer itself.
 int getInt32(int idx)
          Returns the content of 4 bytes inside the actual element as a integer number between -2147483648 and 2147483647, big- or little-endian depending on setBigEndian().
 int getLength()
          Returns the length of the existing actual element.
 int getLengthCurrentChildElement()
          Returns the length of the current child element.
 int getLengthHead()
          returns the length of the head.
 int getLengthTotal()
          Returns the length of the data.
 int getMaxNrofBytes()
          returns the number number of bytes there are max available from position of the current child
 int getMaxNrofBytesForNextChild()
          returns the number number of bytes there are max available from position of a next current child
 int getPositionInBuffer()
          Returns the position of the Element data in the assigned buffer.
 int getPositionNextChildInBuffer()
          Returns the position of the current child in the assigned buffer.
 java.lang.String getText()
          Returns the current string or null on end
 int getUint32(int idx)
           
 boolean isTextByte(byte nn)
          Returns true if the current child element represents a TEXT(), direct ASCII chars, false if the element is a complex element.
 int next()
          Sets the data index to the position after the current child element and returns its code.
 void removeChild()
          remove the current child to assign another current child instead of the first one.
 void removeChildren()
          Remove all children.
 void rewind()
          starts the calling loop of next().
 void setBigEndian(boolean val)
          Sets the big or little endian mode.
 void setLengthCurrentChildElement(int lengthOfCurrentChild)
          Sets the length of the current child element after calling next().
 void setLengthElement(int length)
          Sets the length of the current element, considering all children.
abstract  int specifyLengthElementHead()
          Specifies the length of the head data.
 boolean sufficingBytesForNextChild(int nrofBytes)
          returns true if the given number of bytes is sufficing in the data from position of next child.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

_version_

public static final int _version_
The version.

See Also:
Constant Field Values

kEndOfElements

public static final byte kEndOfElements
Definition of the code of end of information, return from next()

See Also:
Constant Field Values

kNothing

public static final byte kNothing
Definition of the code of no information, return from next()

See Also:
Constant Field Values

kText

public static final byte kText
Aussage: es ist ein String (XML: text()), kein Tag im String

See Also:
Constant Field Values

kUndefined

public static final byte kUndefined
coding: the value is undefined

See Also:
Constant Field Values
Constructor Detail

ByteDataAccess

public ByteDataAccess()
Constructs a new empty instance. Use assign() to work with it.

Method Detail

getLengthHead

public final int getLengthHead()
returns the length of the head. It is specified by specifyLengthElementHead() of the derivated class.


specifyLengthElementHead

public abstract int specifyLengthElementHead()
Specifies the length of the head data. This is the index of the first child relative to the start position of the element. This method is called inside this base class itself inside some methods. Outside the method may be called at example to calculate the size of data.
Only the derivated class knows the position of the first child element. It must specify that like the followed sample:
protected void specifyLengthElementHead()
{ return kIdxFirstChild;  //kIdxFistChild should be defined as static final int.
}

Returns:
Position of the first child element relative to the start position or -1.

assignData

public void assignData(byte[] data,
                       int length)
                throws java.lang.IllegalArgumentException
Assigns new data to this element.
The user may overwrite this method and call super.assignData(data, length) inside if some additional actions should be done.
This method is also usefull to deassign a current data buffer, call assign(null, 0);.
If the element are using before, its connection to an other parent is dissolved.

Parameters:
data - The data. The length of data may be greater as the number of the significant bytes.
length - Number of significant bytes in data. If length is > data.length, an exception may be thrown in any state of the evaluation.
Throws:
java.lang.IllegalArgumentException - if the length is > data.length

assignData

public void assignData(byte[] data,
                       int lengthData,
                       int index)
                throws java.lang.IllegalArgumentException
Assigns new data to this element at given index in data.
The user may overwrite this method and call super.assignData(data, length) inside if some additional actions should be done.
This method is also usefull to deassign a current data buffer, call assign(null, 0);.
If the element are using before, its connection to an other parent is dissolved.

Parameters:
data - The data. The length of data may be greater as the number of the significant bytes.
lengthData - absolute Number of significant bytes in data from idx=0. If length is > data.length, an exception is thrown. If the length is <0 (especially -1), it means, it is not known outside. Than the element is initialized with its known head length. The length mustn't not ==0, it is tested. Use -1 also if the head length is 0.
index - Start position in data
Throws:
java.lang.IllegalArgumentException

assignEmpty

public final void assignEmpty(byte[] data)
Initializes a top level, the data are considered as non initalized. The length of the head should be a constant value, given from method call specifyLengthElementHead(). The child Positions are set to the end of head, no childs are presumed. The head should be filled with data after that calling some methods like setInt32(int, int).
The children should be added by calling addChild(ByteDataAccess) and filled with data after that.
If the element are using before, its connection to an other parent is dissolved.
Example to shown the principle:
   ...........the data undefined with defined length.........
   +++++                   Head, the length should be known.
        ####****#####****  Space for children,
 

Parameters:
data - The data. The reference should be initialized, it means the data have a defined maximum of length. But it is not tested here.
Throws:
java.lang.IllegalArgumentException

removeChildren

public final void removeChildren()
Remove all children. Let the head unchanged.

Since:
2010-11-16

detach

public final void detach()
Remove all connections. Especially for children.


assignAsChild

public final void assignAsChild(ByteDataAccess parent)
                         throws java.lang.IllegalArgumentException
Deprecated. use addChild()

assigns the element to the current child position of parent, to represent the current child of the parent. This method should be used by reading out byte[] data if it is detected, that the content of data matches of this derivated type of ByteDataAccess. next() should be called before. The pattern of using is:
 
    int nWhat;    //code of the element
    while( (nWhat = dataElement.next()) != ByteDataAccess.kEndOfElements )
    { switch(nWhat)  //test the first byte of the current element
      { case ByteDataAccess.kText:
        { sText = dataElement.getText();
        } break;
        case code1:
        { code1Element.assignAsChild(dataElement);
          evaluateValue(code1Element);
        } break:
        case code2:
        { code1Element.assignAsChild(dataElement);
          evaluateValue(code1Element);
        } break:
        default: throw new IllegalArgumentException("unknown Element", dataElement);
      }
    }
    
The difference to addChild(ByteDataAccess) is: addChild() is used to writeout to data, addChild() appends the child always after idxEnd, but this method is used to read from data and appends the child at position of the current child.
The data reference is copied, the idxBegin of this element is set to the idxChild of parent, it is the current child position. All other indices are setted calling specifyLengthElementHead(): idxChild and specifyLengthElement(): idxEnd. The idxChildEnd of parent is setted, so calling next() after this operation increments in data after this new child.
If the element are using before, its connection to an other parent is dissolved.

Parameters:
parent - The parent. It should reference data, and a current child position should be set by calling next() before. See sample at next().
Throws:
java.lang.IllegalArgumentException - If the data are wrong. The exception is thrown orginal from specifyLengthElement().

assignAtIndex

public final void assignAtIndex(int idxChildInParent,
                                int lengthChild,
                                ByteDataAccess parent)
                         throws java.lang.IllegalArgumentException
assigns the element to the given position of the parents data to present a child of the parent with a defined length. The difference to addChild(ByteDataAccess) is: The position is given here directly, it should not be the current child but a free child.
The data reference is copied, the idxBegin of this element is set to the idxChild given as parameter. All other indices are set calling specifyLengthElementHead(): idxChild and specifyLengthElement(): idxEnd.
If the element are using before, its connection to an other parent is dissolved.

Parameters:
parent - The parent. It should reference data.
lengthChild - Number of the bytes of the free child.
idxChildInParent - The index of the free child in the data.
Throws:
java.lang.IllegalArgumentException - If the indices are wrong in respect to the data.

assignAtIndex

public final void assignAtIndex(int idxChildInParent,
                                ByteDataAccess parent)
                         throws java.lang.IllegalArgumentException
assigns the element to the given position of the parents data to present a child of the parent. The length of the child is limited to TODO the length of head - or not limited.

Parameters:
parent - The parent. It should reference data.
idxChildInParent - The index of the free child in the data.
Throws:
java.lang.IllegalArgumentException - If the indices are wrong in respect to the data.

addChild

public final boolean addChild(ByteDataAccess child)
                       throws java.lang.IllegalArgumentException
adds an child Element after the current child or as first child after head. With the aid of the child Element the data can be read or write structured.
Some children can be added after a parent like following sample:
 ByteAccessDerivation child = new ByteAccessDerivation();  //empty and unassigned.
 parent.addChild(child);        //The byte[] data of parent are assigned, index after current child index of parent.
 child.addChild(grandchild);    //By adding a child to this child, also the parent's index is corrected.
 

Parameters:
child - The child will be assigned with the data of this at index after the current child's end-index.
Throws:
java.lang.IllegalArgumentException - if the length of the old current child is not determined yet. Either the method specifyLengthElement() should be overwritten or the method setLengthElement(int) for the child or setLengthCurrentChildElement(int) should be called to prevent this exception.
java.lang.IllegalArgumentException - if the length of the head of the new current child is to far for the data. It means, child.idxEnd > data.length.

removeChild

public final void removeChild()
                       throws java.lang.IllegalArgumentException
remove the current child to assign another current child instead of the first one. This method is usefull if data are tested with several structures. It mustn't be called in expand mode. In expand mode you have to be consider about your children.

Parameters:
child -
Throws:
java.lang.IllegalArgumentException

addChildEmpty

public final void addChildEmpty(ByteDataAccess child)
                         throws java.lang.IllegalArgumentException
Adds a child Element at current end of data to write data. The child's data are initialized with call of child.specifyEmptyDefaultData().

Parameters:
child - The child will associated to this and should be used to add some content.
Throws:
java.lang.IllegalArgumentException

expandParent

public final void expandParent()
                        throws java.lang.IllegalArgumentException
Expands the end index of the parent, it means the management of the expanse of the data.

Throws:
java.lang.IllegalArgumentException

getChildInteger

public final long getChildInteger(int nrofBytes)
                           throws java.lang.IllegalArgumentException
Adds a child for 1 integer value without a child instance, but returns the value as integer.

Parameters:
nrofBytes - of the integer
Returns:
value in long format, cast it to (int) if you read only 4 bytes etc.
Throws:
java.lang.IllegalArgumentException - if not data has not enaught bytes.

getChildFloat

public final float getChildFloat()
                          throws java.lang.IllegalArgumentException
Adds a child for 1 float value without a child instance, but returns the value as integer.

Returns:
value in float format
Throws:
java.lang.IllegalArgumentException - if not data has not enaught bytes.

getChildDouble

public final double getChildDouble()
                            throws java.lang.IllegalArgumentException
Adds a child for 1 double value without a child instance, but returns the value as integer.

Returns:
value in float format
Throws:
java.lang.IllegalArgumentException - if not data has not enaught bytes.

addChildInteger

public final void addChildInteger(int nrofBytes,
                                  long value)
                           throws java.lang.IllegalArgumentException
Adds a child for 1 integer value without a child instance, and sets the value as integer.

Parameters:
nrofBytes - of the integer
Throws:
java.lang.IllegalArgumentException

addChildFloat

public final void addChildFloat(float value)
                         throws java.lang.IllegalArgumentException
Adds a child for 1 integer value without a child instance, and sets the value as integer.

Parameters:
nrofBytes - of the integer
Throws:
java.lang.IllegalArgumentException

getChildString

public final java.lang.String getChildString(int nrofBytes)
                                      throws java.lang.IllegalArgumentException,
                                             java.io.UnsupportedEncodingException
Adds a child for a String value without a child instance, but returns the value as String.

Parameters:
nrofBytes - of the integer
Returns:
value in long format, cast it to (int) if you read only 4 bytes etc.
Throws:
java.lang.IllegalArgumentException - if not data has not enaught bytes.
java.io.UnsupportedEncodingException

addChildString

public final void addChildString(java.lang.String value,
                                 java.lang.String sEncoding,
                                 boolean preventCtrlChars)
                          throws java.lang.IllegalArgumentException,
                                 java.io.UnsupportedEncodingException
Adds a child with String value.

Parameters:
value - String to add
sEncoding - If null then use the standard encoding of the system-environment.
preventCtrlChars - true then values < 0x20 are not set. If the String value contain a control character with code < 0x20, a '?' is written. This behavior guarantees, that byte-values < 0x20 can use to detect no-String elements, see getByteNextChild().
Throws:
java.lang.IllegalArgumentException
java.io.UnsupportedEncodingException

addChildString

public final void addChildString(java.lang.String value)
                          throws java.lang.IllegalArgumentException
Adds a child with String value.

Parameters:
value - String to add
Throws:
java.lang.IllegalArgumentException

addChildString

public final void addChildString(java.lang.CharSequence value,
                                 java.lang.String sEncoding)
                          throws java.lang.IllegalArgumentException,
                                 java.io.UnsupportedEncodingException
Adds a child with String value.

Parameters:
value - String to add, @pjava2c=nonPersistent.
Throws:
java.lang.IllegalArgumentException
java.io.UnsupportedEncodingException

addChildString

public final void addChildString(java.lang.CharSequence value)
                          throws java.lang.IllegalArgumentException
Adds a child with String value.

Parameters:
value - String to add, @pjava2c=nonPersistent.
Throws:
java.lang.IllegalArgumentException

addText

public final int addText(java.lang.String ss)
                  throws java.lang.IllegalArgumentException
Deprecated. 

Writes a String into data with given color. The user can overwrite this method and call super.addText(ss) inside if some additional actions should be done.

Parameters:
ss - The String to write
color - The color
Throws:
java.lang.IllegalArgumentException

rewind

public final void rewind()
starts the calling loop of next(). The calling of next() after them supplies the first child element.


next

public final int next()
               throws java.lang.IllegalArgumentException
Sets the data index to the position after the current child element and returns its code.
If more than 1 byte determines the code, the user should call getInt32(idxChild) to get the code. Usage:
 while( (eElement = code.next()) != kEndOfElements)
 { switch(eElement) { ... }
 } 

Returns:
The first byte, that may be the code of the child element.
If this code is between 0x20 to 0xbf, it is assumed that is an character, kText is returned than.
If no more childs are available, kEndOfElements is returned.
Throws:
java.lang.IllegalArgumentException

sufficingBytesForNextChild

public final boolean sufficingBytesForNextChild(int nrofBytes)
                                         throws java.lang.IllegalArgumentException
returns true if the given number of bytes is sufficing in the data from position of next child.

Parameters:
nrofBytes - that should fitting in the given data range from current child position to the end of data determines by calling assingData(...) or by calling addChild() with a known size of child or setLengthElement() .
Returns:
true if it is okay, false if the nrofBytes are negative or to large.
Throws:
java.lang.IllegalArgumentException - see getMaxNrofBytesForNextChild()

getMaxNrofBytesForNextChild

public final int getMaxNrofBytesForNextChild()
                                      throws java.lang.IllegalArgumentException
returns the number number of bytes there are max available from position of a next current child. , the number of bytes to the end of buffer is returned.

Returns:
nrofBytes that should fitting in the given data range from current child position to the end of data determines by calling assingData(...) or by calling addChild() with a known size of child or setLengthElement() .
Throws:
java.lang.IllegalArgumentException - if the length of the current child is not determined yet. Either the method specifyLengthElement() should be overwritten or the method setLengthElement(int) for the child or setLengthCurrentChildElement(int) should be called to prevent this exception.

getMaxNrofBytes

public final int getMaxNrofBytes()
returns the number number of bytes there are max available from position of the current child. , the number of bytes to the end of buffer is returned.

Returns:
nrofBytes that should fitting in the given data range from current child position to the end of data determines by calling assingData(...) or by calling addChild() with a known size of child or setLengthElement() .

getLength

public final int getLength()
Returns the length of the existing actual element.

Returns:
The number of bytes of the actual element in the buffer. It is (idxEnd - idxBegin).

getLengthTotal

public final int getLengthTotal()
Returns the length of the data.

Returns:
The number of bytes of data in the buffer. It is idxEnd.

getData

public final byte[] getData()
Returns the data buffer itself. The actual total length is getted with getLengthTotal().

Returns:
The number of bytes of the data in the buffer.

getPositionInBuffer

public final int getPositionInBuffer()
Returns the position of the Element data in the assigned buffer.

Returns:
index of this element in the data buffer.

getPositionNextChildInBuffer

public final int getPositionNextChildInBuffer()
Returns the position of the current child in the assigned buffer.

Returns:
index of the current child of this element in the data buffer.

getLengthCurrentChildElement

public final int getLengthCurrentChildElement()
                                       throws java.lang.IllegalArgumentException
Returns the length of the current child element. The length may be setted outside by calling setLengthCurrentChildElement() from user level after any calling of next() or after calling getText() if it is a text content. In this case this method returns this length in a simple way.
If the user don't have called setLengthCurrentChildElement() after the last next(), the users defined specifyLengthCurrentChildElement() is called.

Returns:
the length in bytes of the current child element.
Throws:
java.lang.IllegalArgumentException - if the user has not defined a overloaded methode specifyLengthCurrentChildElement() or this method has thrown the exception because the length is not determinable.

setLengthCurrentChildElement

public final void setLengthCurrentChildElement(int lengthOfCurrentChild)
Sets the length of the current child element after calling next(). The user may set the length due to the knowledge of the type and content of the actual child element. So the calling of specifyLengthCurrentChildElement() will be precluded. The idxChildEnd is setted.


setLengthElement

public final void setLengthElement(int length)
Sets the length of the current element, considering all children. If the element is the current child of its parent, the idxChildEnd of parent is set. Therefore a call of next() or addChild uses the idxChildEnd-position for a new child.

Parameters:
length - The length inclusive all children.

isTextByte

public final boolean isTextByte(byte nn)
Returns true if the current child element represents a TEXT(), direct ASCII chars, false if the element is a complex element. Text chararacters are coded with 0x20..0x7f, the standard ASCII code, and with 0x80 to 0xbf, special characters user defined.


getText

public final java.lang.String getText()
Returns the current string or null on end


setBigEndian

public void setBigEndian(boolean val)
Sets the big or little endian mode. This method is override-able, because a derived class may set the endian of embedded children too.

Parameters:
val - true if big endian, hi byte at lower adress, false if little endian.

copyData

public final void copyData(int[] dst)
copies some data to a int[], primarily to debug a content.

Parameters:
dst - This array is field, but only from data of the current element between idxBegin and idxEnd

getInt32

public final int getInt32(int idx)
Returns the content of 4 bytes inside the actual element as a integer number between -2147483648 and 2147483647, big- or little-endian depending on setBigEndian().

Parameters:
idx - the position of leading byte in the actual element, the data are raken from data[idxBegin+idx]. This is not the absolute position in data, idxBegin is added.
Returns:
the integer value in range from -2147483648 and 2147483647

getUint32

public final int getUint32(int idx)

copyDataFrom

public final void copyDataFrom(ByteDataAccess src)
                        throws java.lang.IllegalArgumentException
Copies the data into a byte[]

Throws:
java.lang.IllegalArgumentException

elementAt

public final void elementAt(int indexObjectArray)
Counts the idxChild by given index, idxChild is ByteCount from idxBegin

Parameters:
indexObjectArray - Index of Array

getCurrentChild

public final ByteDataAccess getCurrentChild()