Open Source Repository

/*********************************************************************** Copyright (C) 2002 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;import jxl.common.Logger;import jxl.read.biff.Record;/*** Extension of the standard RecordData which is used to support those* records which, once read, may also be written*/public abstract class WritableRecordData extends RecordDataimplements ByteData{/*** The logger*/private static Logger logger = Logger.getLogger(WritableRecordData.class);/*** The maximum length allowed by Excel for any record length*/protected static final int maxRecordLength = 8228;/*** Constructor used by the writable records** @param t the biff type of this record*/protected WritableRecordData(Type t){super(t);}/*** Constructor used when reading a record** @param t the raw data read from the biff file*/protected WritableRecordData(Record t){super(t);}/*** Used when writing out records. This portion of the method handles the* biff code and the length of the record and appends on the data retrieved* from the subclasses** @return the full record data to be written out to the compound file*/public final byte[] getBytes(){byte[] data = getData();int dataLength = data.length;// Don't the call the automatic continuation code for now// Assert.verify(dataLength <= maxRecordLength - 4);// If the bytes length is greater than the max record length// then split out the data set into continue recordsif (data.length > maxRecordLength - 4){dataLength = maxRecordLength - 4;data = handleContinueRecords(data);}byte[] bytes = new byte[data.length + 4];System.arraycopy(data, 0, bytes, 4, data.length);IntegerHelper.getTwoBytes(getCode(), bytes, 0);IntegerHelper.getTwoBytes(dataLength, bytes, 2);return bytes;}/*** The number of bytes for this record exceeds the maximum record* length, so a continue is required* @param data the raw data* @return the continued data*/private byte[] handleContinueRecords(byte[] data){// Deduce the number of continue recordsint continuedData = data.length - (maxRecordLength - 4);int numContinueRecords = continuedData / (maxRecordLength - 4) + 1;// Create the new byte array, allowing for the continue records// code and lengthbyte[] newdata = new byte[data.length + numContinueRecords * 4];// Copy the bona fide record data into the beginning of the super// recordSystem.arraycopy(data, 0, newdata, 0, maxRecordLength - 4);int oldarraypos = maxRecordLength - 4;int newarraypos = maxRecordLength - 4;// Now handle all the continue recordsfor (int i = 0; i < numContinueRecords; i++){// The number of bytes to add into the new arrayint length = Math.min(data.length - oldarraypos, maxRecordLength - 4);// Add in the continue record codeIntegerHelper.getTwoBytes(Type.CONTINUE.value, newdata, newarraypos);IntegerHelper.getTwoBytes(length, newdata, newarraypos + 2);// Copy in as much of the new data as possibleSystem.arraycopy(data, oldarraypos, newdata, newarraypos + 4, length);// Update the position countersoldarraypos += length;newarraypos += length + 4;}return newdata;}/*** Abstract method called by the getBytes method. Subclasses implement* this method to incorporate their specific binary data - excluding the* biff code and record length, which is handled by this class** @return subclass specific biff data*/protected abstract byte[] getData();}