/*********************************************************************
*
* Copyright (C) 2003 Andrew Khan
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***************************************************************************/
package jxl.biff.drawing;
import jxl.common.Logger;
import jxl.biff.IntegerHelper;
/**
* A single record from an Escher stream. Basically this a container for
* the header data for each Escher record
*/
final class EscherRecordData
{
/**
* The logger
*/
private static Logger logger = Logger.getLogger(EscherRecordData.class);
/**
* The byte position of this record in the escher stream
*/
private int pos;
/**
* The instance value
*/
private int instance;
/**
* The version value
*/
private int version;
/**
* The record id
*/
private int recordId;
/**
* The length of the record, excluding the 8 byte header
*/
private int length;
/**
* The length of the stream
*/
private int streamLength;
/**
* Indicates whether this record is a container
*/
private boolean container;
/**
* The type of this record
*/
private EscherRecordType type;
/**
* A handle back to the drawing group, which contains the entire escher
* stream byte data
*/
private EscherStream escherStream;
/**
* Constructor
*
* @param dg the escher stream data
* @param p the current position in the stream
*/
public EscherRecordData(EscherStream dg, int p)
{
escherStream = dg;
pos = p;
byte[] data = escherStream.getData();
streamLength = data.length;
// First two bytes contain instance and version
int value = IntegerHelper.getInt(data[pos], data[pos + 1]);
// Instance value is the first 12 bits
instance = (value & 0xfff0) >> 4;
// Version is the last four bits
version = value & 0xf;
// Bytes 2 and 3 are the record id
recordId = IntegerHelper.getInt(data[pos + 2], data[pos + 3]);
// Length is bytes 4,5,6 and 7
length = IntegerHelper.getInt(data[pos + 4], data[pos + 5],
data[pos + 6], data[pos + 7]);
if (version == 0x0f)
{
container = true;
}
else
{
container = false;
}
}
/**
* Constructor
*
* @param t the type of the escher record
*/
public EscherRecordData(EscherRecordType t)
{
type = t;
recordId = type.getValue();
}
/**
* Determines whether this record is a container
*
* @return TRUE if this is a container, FALSE otherwise
*/
public boolean isContainer()
{
return container;
}
/**
* Accessor for the length, excluding the 8 byte header
*
* @return the length excluding the 8 byte header
*/
public int getLength()
{
return length;
}
/**
* Accessor for the record id
*
* @return the record id
*/
public int getRecordId()
{
return recordId;
}
/**
* Accessor for the drawing group stream
*
* @return the drawing group stream
*/
EscherStream getDrawingGroup()
{
return escherStream;
}
/**
* Gets the position in the stream
*
* @return the position in the stream
*/
int getPos()
{
return pos;
}
/**
* Gets the escher type of this record
*
* @return the escher type
*/
EscherRecordType getType()
{
if (type == null)
{
type = EscherRecordType.getType(recordId);
}
return type;
}
/**
* Gets the instance value
*
* @return the instance value
*/
int getInstance()
{
return instance;
}
/**
* Sets whether or not this is a container - called when writing
* out an escher stream
*
* @param c TRUE if this is a container, FALSE otherwise
*/
void setContainer(boolean c)
{
container = c;
}
/**
* Called from the subclass when writing to set the instance value
*
* @param inst the instance
*/
void setInstance(int inst)
{
instance = inst;
}
/**
* Called when writing to set the length of this record
*
* @param l the length
*/
void setLength(int l)
{
length = l;
}
/**
* Called when writing to set the version of this record
*
* @param v the version
*/
void setVersion(int v)
{
version = v;
}
/**
* Adds the 8 byte header data on the value data passed in, returning
* the modified data
*
* @param d the value data
* @return the value data with the header information
*/
byte[] setHeaderData(byte[] d)
{
byte[] data = new byte[d.length + 8];
System.arraycopy(d, 0, data, 8, d.length);
if (container)
{
version = 0x0f;
}
// First two bytes contain instance and version
int value = instance << 4;
value |= version;
IntegerHelper.getTwoBytes(value, data, 0);
// Bytes 2 and 3 are the record id
IntegerHelper.getTwoBytes(recordId, data, 2);
// Length is bytes 4,5,6 and 7
IntegerHelper.getFourBytes(d.length, data, 4);
return data;
}
/**
* Accessor for the header stream
*
* @return the escher stream
*/
EscherStream getEscherStream()
{
return escherStream;
}
/**
* Gets the data that was read in, excluding the header data
*
* @return the value data that was read in
*/
byte[] getBytes()
{
byte[] d = new byte[length];
System.arraycopy(escherStream.getData(), pos + 8, d, 0, length);
return d;
}
/**
* Accessor for the stream length
*
* @return the stream length
*/
int getStreamLength()
{
return streamLength;
}
}
|