jxl.biff.drawing.DrawingData Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jxl Show documentation
Show all versions of jxl Show documentation
JExcelApi is a java library which provides the ability to read, write, and modify Microsoft Excel spreadsheets.
The newest version!
/*********************************************************************
*
* Copyright (C) 2004 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 java.util.ArrayList;
import jxl.common.Assert;
import jxl.common.Logger;
/**
* Class used to concatenate all the data for the various drawing objects
* into one continuous stream
*/
public class DrawingData implements EscherStream
{
/**
* The logger
*/
private static Logger logger = Logger.getLogger(DrawingData.class);
/**
* The drawing data
*/
private byte[] drawingData;
/**
* The number of drawings
*/
private int numDrawings;
/**
* Initialized flag
*/
private boolean initialized;
/**
* The spgr container. The contains the SpContainer for each drawing
*/
private EscherRecord[] spContainers;
/**
* Constructor
*/
public DrawingData()
{
numDrawings = 0;
drawingData = null;
initialized = false;
}
/**
* Initialization
*/
private void initialize()
{
EscherRecordData er = new EscherRecordData(this, 0);
Assert.verify(er.isContainer());
EscherContainer dgContainer = new EscherContainer(er);
EscherRecord[] children = dgContainer.getChildren();
children = dgContainer.getChildren();
// Dg dg = (Dg) children[0];
EscherContainer spgrContainer = null;
for (int i = 0; i < children.length && spgrContainer == null; i++)
{
EscherRecord child = children[i];
if (child.getType() == EscherRecordType.SPGR_CONTAINER)
{
spgrContainer = (EscherContainer) child;
}
}
Assert.verify(spgrContainer != null);
EscherRecord[] spgrChildren = spgrContainer.getChildren();
// See if any of the spgrChildren are SpgrContainer
boolean nestedContainers = false;
for (int i = 0; i < spgrChildren.length && !nestedContainers; i++)
{
if (spgrChildren[i].getType() == EscherRecordType.SPGR_CONTAINER)
{
nestedContainers = true;
}
}
// If there are no nested containers, simply set the spContainer list
// to be the list of children
if (!nestedContainers)
{
spContainers = spgrChildren;
}
else
{
// Go through the hierarchy and dig out all the Sp containers
ArrayList sps = new ArrayList();
getSpContainers(spgrContainer, sps);
spContainers = new EscherRecord[sps.size()];
spContainers = (EscherRecord[]) sps.toArray(spContainers);
}
initialized = true;
}
/**
* Gets the sp container from the internal data
*
* @param spgrContainer the spgr container
* @param sps the list of sp records
*/
private void getSpContainers(EscherContainer spgrContainer, ArrayList sps)
{
EscherRecord[] spgrChildren = spgrContainer.getChildren();
for (int i = 0; i < spgrChildren.length; i++)
{
if (spgrChildren[i].getType() == EscherRecordType.SP_CONTAINER)
{
sps.add(spgrChildren[i]);
}
else if (spgrChildren[i].getType() == EscherRecordType.SPGR_CONTAINER)
{
getSpContainers((EscherContainer) spgrChildren[i], sps);
}
else
{
logger.warn("Spgr Containers contains a record other than Sp/Spgr " +
"containers");
}
}
}
/**
* Adds the byte stream to the drawing data
*
* @param data the data to add
*/
public void addData(byte[] data)
{
addRawData(data);
numDrawings++;
}
/**
* Adds the data to the array without incrementing the drawing number.
* This is used by comments, which for some bizarre and inexplicable
* reason split out the data
*
* @param data the data to add
*/
public void addRawData(byte[] data)
{
if (drawingData == null)
{
drawingData = data;
return;
}
// Resize the array
byte[] newArray = new byte[drawingData.length + data.length];
System.arraycopy(drawingData, 0, newArray, 0, drawingData.length);
System.arraycopy(data, 0, newArray, drawingData.length, data.length);
drawingData = newArray;
// Dirty up this object
initialized = false;
}
/**
* Accessor for the number of drawings
*
* @return the current count of drawings
*/
final int getNumDrawings()
{
return numDrawings;
}
/**
* Gets the sp container for the specified drawing number
*
* @param drawingNum the drawing number for which to return the spContainer
* @return the spcontainer
*/
EscherContainer getSpContainer(int drawingNum)
{
if (!initialized)
{
initialize();
}
if ( (drawingNum + 1) >= spContainers.length)
{
throw new DrawingDataException();
}
EscherContainer spContainer =
(EscherContainer) spContainers[drawingNum + 1];
Assert.verify(spContainer != null);
return spContainer;
}
/**
* Gets the data which was read in for the drawings
*
* @return the drawing data
*/
public byte[] getData()
{
return drawingData;
}
}