X-Git-Url: http://source.jalview.org/gitweb/?p=jalviewjs.git;a=blobdiff_plain;f=src%2Fjavajs%2Futil%2FCompoundDocument.java;fp=src%2Fjavajs%2Futil%2FCompoundDocument.java;h=15168a5f2c33c436e8ffad6cb16feeba54dbce8d;hp=60662db2753746fa63826fd770526511f3fdb8bf;hb=b9b7a352eee79b7764c3b09c9d19663075061d8c;hpb=7301a2415adab88038b291fc54caeeb3a5a47a44 diff --git a/src/javajs/util/CompoundDocument.java b/src/javajs/util/CompoundDocument.java index 60662db..15168a5 100644 --- a/src/javajs/util/CompoundDocument.java +++ b/src/javajs/util/CompoundDocument.java @@ -1,395 +1,395 @@ -/* $RCSfile$ - * $Author: egonw $ - * $Date: 2006-03-18 15:59:33 -0600 (Sat, 18 Mar 2006) $ - * $Revision: 4652 $ - * - * Copyright (C) 2003-2005 Miguel, Jmol Development, www.jmol.org - * - * Contact: hansonr@stolaf.edu - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - */ -package javajs.util; - - -import java.io.DataInputStream; -import java.io.BufferedInputStream; - - -import java.util.Map; - -import javajs.api.GenericZipTools; - - - -/* a simple compound document reader. - * See http://sc.openoffice.org/compdocfileformat.pdf - * - * random access file info: - * http://java.sun.com/docs/books/tutorial/essential/io/rafs.html - * - * SHOOT! random access is only for applications, not applets! - * - * With a bit more work, this could be set up to deliver binary files, but - * right now I've only implemented it for string-based data. All Jmol is using - * is getAllData(). - * - */ - -public class CompoundDocument extends BinaryDocument{ - -// RandomAccessFile file; - CompoundDocHeader header = new CompoundDocHeader(this); - Lst directory = new Lst(); - CompoundDocDirEntry rootEntry; - - int[] SAT; - int[] SSAT; - int sectorSize; - int shortSectorSize; - int nShortSectorsPerStandardSector; - int nIntPerSector; - int nDirEntriesperSector; - - // called by reflection - - public CompoundDocument(){ - super(); - this.isBigEndian = true; - } - - @Override - public void setStream(GenericZipTools jzt, BufferedInputStream bis, boolean isBigEndian) { - // isBigEndian is ignored here; it must be true - /* try { - file = new RandomAccessFile(fileName, "r"); - isRandom = true; - } catch (Exception e) { - // probably an applet - } - */ - this.jzt = jzt; - if (!isRandom) { - stream = new DataInputStream(bis); - } - stream.mark(Integer.MAX_VALUE); - if (!readHeader()) - return; - getSectorAllocationTable(); - getShortSectorAllocationTable(); - getDirectoryTable(); - } - - public Lst getDirectory() { - return directory; - } - - public String getDirectoryListing(String separator) { - String str = ""; - for (int i = 0; i < directory.size(); i++) { - CompoundDocDirEntry thisEntry = directory.get(i); - if (!thisEntry.isEmpty) - str += separator - + thisEntry.entryName - + "\tlen=" - + thisEntry.lenStream - + "\tSID=" - + thisEntry.SIDfirstSector - + (thisEntry.isStandard ? "\tfileOffset=" - + getOffset(thisEntry.SIDfirstSector) : ""); - } - return str; - } - - SB data; - - public SB getAllData() { - return getAllDataFiles(null, null); - } - - /** - * reads a compound document directory and saves all data in a Hashtable - * so that the files may be organized later in a different order. Also adds - * a #Directory_Listing entry. - * - * Files are bracketed by BEGIN Directory Entry and END Directory Entry lines, - * similar to ZipUtil.getAllData. - * - * @param prefix - * @param binaryFileList |-separated list of files that should be saved - * as xx xx xx hex byte strings. The directory listing - * is appended with ":asBinaryString" - * @param fileData - */ - @Override - public void getAllDataMapped(String prefix, - String binaryFileList, Map fileData) { - fileData.put("#Directory_Listing", getDirectoryListing("|")); - binaryFileList = "|" + binaryFileList + "|"; - for (int i = 0; i < directory.size(); i++) { - CompoundDocDirEntry thisEntry = directory.get(i); - if (!thisEntry.isEmpty && thisEntry.entryType != 5) { - String name = thisEntry.entryName; - System.out.println("CompoundDocument file " + name); - boolean isBinary = (binaryFileList.indexOf("|" + name + "|") >= 0); - if (isBinary) - name += ":asBinaryString"; - SB data = new SB(); - data.append("BEGIN Directory Entry ").append(name).append("\n"); - data.appendSB(getEntryAsString(thisEntry, isBinary)); - data.append("\nEND Directory Entry ").append(name).append("\n"); - fileData.put(prefix + "/" + name, data.toString()); - } - } - close(); - } - - @Override - public SB getAllDataFiles(String binaryFileList, String firstFile) { - if (firstFile != null) { - for (int i = 0; i < directory.size(); i++) { - CompoundDocDirEntry thisEntry = directory.get(i); - if (thisEntry.entryName.equals(firstFile)) { - directory.remove(i); - directory.add(1, thisEntry); // after ROOT_ENTRY - break; - } - } - } - data = new SB(); - data.append("Compound Document File Directory: "); - data.append(getDirectoryListing("|")); - data.append("\n"); - binaryFileList = "|" + binaryFileList + "|"; - for (int i = 0; i < directory.size(); i++) { - CompoundDocDirEntry thisEntry = directory.get(i); - //System.out.println("CompoundDocument reading " + thisEntry.entryName); - if (!thisEntry.isEmpty && thisEntry.entryType != 5) { - String name = thisEntry.entryName; - if (name.endsWith(".gz")) - name = name.substring(0, name.length() - 3); - data.append("BEGIN Directory Entry ").append(name).append("\n"); - data.appendSB(getEntryAsString(thisEntry, binaryFileList.indexOf("|" + thisEntry.entryName + "|") >= 0)); - data.append("\n"); - data.append("END Directory Entry ").append(thisEntry.entryName).append("\n"); - } - } - close(); - return data; - } - - public SB getFileAsString(String entryName) { - for (int i = 0; i < directory.size(); i++) { - CompoundDocDirEntry thisEntry = directory.get(i); - if (thisEntry.entryName.equals(entryName)) - return getEntryAsString(thisEntry, false); - } - return new SB(); - } - - private long getOffset(int SID) { - return (SID + 1) * sectorSize; - } - - private void gotoSector(int SID) { - seek(getOffset(SID)); - } - - private boolean readHeader() { - if (!header.readData()) - return false; - sectorSize = 1 << header.sectorPower; - shortSectorSize = 1 << header.shortSectorPower; - nShortSectorsPerStandardSector = sectorSize / shortSectorSize; // e.g. 512 / 64 = 8 - nIntPerSector = sectorSize / 4; // e.g. 512 / 4 = 128 - nDirEntriesperSector = sectorSize / 128; // e.g. 512 / 128 = 4 -// System.out.println( -// "compound document: revNum=" + header.revNumber + -// " verNum=" + header.verNumber + " isBigEndian=" + isBigEndian + -// " bytes per standard/short sector=" + sectorSize + "/" + shortSectorSize); - return true; - } - - private void getSectorAllocationTable() { - int nSID = 0; - int thisSID; - SAT = new int[header.nSATsectors * nIntPerSector + 109]; - - try { - for (int i = 0; i < 109; i++) { - thisSID = header.MSAT0[i]; - if (thisSID < 0) - break; - gotoSector(thisSID); - for (int j = 0; j < nIntPerSector; j++) { - SAT[nSID++] = readInt(); - //Logger.debug(thisSID+"."+j + "/" + (nSID - 1) + " : " + SAT[nSID - 1]); - } - } - int nMaster = header.nAdditionalMATsectors; - thisSID = header.SID_MSAT_next; - int[] MSAT = new int[nIntPerSector]; - out: while (nMaster-- > 0 && thisSID >= 0) { - // read a page of sector identifiers pointing to SAT sectors - gotoSector(thisSID); - for (int i = 0; i < nIntPerSector; i++) - MSAT[i] = readInt(); - // read each page of SAT sector identifiers - // last entry is pointer to next master sector allocation table page - for (int i = 0; i < nIntPerSector - 1; i++) { - thisSID = MSAT[i]; - if (thisSID < 0) - break out; - gotoSector(thisSID); - for (int j = nIntPerSector; --j >= 0;) - SAT[nSID++] = readInt(); - } - thisSID = MSAT[nIntPerSector - 1]; - } - } catch (Exception e) { - System.out.println(e.toString()); - } - } - - private void getShortSectorAllocationTable() { - int nSSID = 0; - int thisSID = header.SID_SSAT_start; - int nMax = header.nSSATsectors * nIntPerSector; - SSAT = new int[nMax]; - try { - while (thisSID > 0 && nSSID < nMax) { - gotoSector(thisSID); - for (int j = 0; j < nIntPerSector; j++) { - SSAT[nSSID++] = readInt(); - //System.out.println("short: " + thisSID+"."+j+" SSID=" +(nSSID-1)+" "+SSAT[nSSID-1]); - } - thisSID = SAT[thisSID]; - } - } catch (Exception e) { - System.out.println(e.toString()); - } - } - - private void getDirectoryTable() { - int thisSID = header.SID_DIR_start; - CompoundDocDirEntry thisEntry; - rootEntry = null; - try { - while (thisSID > 0) { - gotoSector(thisSID); - for (int j = nDirEntriesperSector; --j >= 0;) { - thisEntry = new CompoundDocDirEntry(this); - thisEntry.readData(); - if (thisEntry.lenStream > 0) { - directory.addLast(thisEntry); - //System.out.println(thisEntry.entryName); - } - if (thisEntry.entryType == 5) - rootEntry = thisEntry; - } - thisSID = SAT[thisSID]; - } - } catch (Exception e) { - System.out.println(e.toString()); - } -// System.out.println("CompoundDocument directory entry: \n" -// + getDirectoryListing("\n")); - } - - private SB getEntryAsString(CompoundDocDirEntry thisEntry, boolean asBinaryString) { - if(thisEntry.isEmpty) - return new SB(); - //System.out.println(thisEntry.entryName + " " + thisEntry.entryType + " " + thisEntry.lenStream + " " + thisEntry.isStandard + " " + thisEntry.SIDfirstSector); - return (thisEntry.isStandard ? getStandardStringData( - thisEntry.SIDfirstSector, thisEntry.lenStream, asBinaryString) - : getShortStringData(thisEntry.SIDfirstSector, thisEntry.lenStream, asBinaryString)); - } - private SB getStandardStringData(int thisSID, int nBytes, - boolean asBinaryString) { - SB data = new SB(); - byte[] byteBuf = new byte[sectorSize]; - ZipData gzipData = new ZipData(nBytes); - try { - while (thisSID > 0 && nBytes > 0) { - gotoSector(thisSID); - nBytes = getSectorData(data, byteBuf, sectorSize, nBytes, asBinaryString, gzipData); - thisSID = SAT[thisSID]; - } - if (nBytes == -9999) - return new SB(); - } catch (Exception e) { - System.out.println(e.toString()); - } - if (gzipData.isEnabled) - gzipData.addTo(jzt, data); - return data; - } - - private int getSectorData(SB data, byte[] byteBuf, - int nSectorBytes, int nBytes, - boolean asBinaryString, ZipData gzipData) - throws Exception { - readByteArray(byteBuf, 0, byteBuf.length); - int n = gzipData.addBytes(byteBuf, nSectorBytes, nBytes); - if (n >= 0) - return n; - if (asBinaryString) { - for (int i = 0; i < nSectorBytes; i++) { - data.append(Integer.toHexString(byteBuf[i] & 0xFF)).appendC(' '); - if (--nBytes < 1) - break; - } - } else { - for (int i = 0; i < nSectorBytes; i++) { - if (byteBuf[i] == 0) - return -9999; // don't allow binary data - data.appendC((char) byteBuf[i]); - if (--nBytes < 1) - break; - } - } - return nBytes; - } - - private SB getShortStringData(int shortSID, int nBytes, boolean asBinaryString) { - SB data = new SB(); - if (rootEntry == null) - return data; - int thisSID = rootEntry.SIDfirstSector; - int ptShort = 0; - byte[] byteBuf = new byte[shortSectorSize]; - ZipData gzipData = new ZipData(nBytes); - try { - //System.out.println("CD shortSID=" + shortSID); - // point to correct short data sector, 512/64 = 4 per page - while (thisSID >= 0 && shortSID >= 0 && nBytes > 0) { - while (shortSID - ptShort >= nShortSectorsPerStandardSector) { - ptShort += nShortSectorsPerStandardSector; - thisSID = SAT[thisSID]; - } - seek(getOffset(thisSID) + (shortSID - ptShort) * shortSectorSize); - nBytes = getSectorData(data, byteBuf, shortSectorSize, nBytes, asBinaryString, gzipData); - shortSID = SSAT[shortSID]; - //System.out.println("CD shortSID=" + shortSID); - } - } catch (Exception e) { - System.out.println(data.toString()); - System.out.println("reader error in CompoundDocument " + e.toString()); - } - if (gzipData.isEnabled) - gzipData.addTo(jzt, data); - return data; - } -} +/* $RCSfile$ + * $Author: egonw $ + * $Date: 2006-03-18 15:59:33 -0600 (Sat, 18 Mar 2006) $ + * $Revision: 4652 $ + * + * Copyright (C) 2003-2005 Miguel, Jmol Development, www.jmol.org + * + * Contact: hansonr@stolaf.edu + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ +package javajs.util; + + +import java.io.DataInputStream; +import java.io.BufferedInputStream; + + +import java.util.Map; + +import javajs.api.GenericZipTools; + + + +/* a simple compound document reader. + * See http://sc.openoffice.org/compdocfileformat.pdf + * + * random access file info: + * http://java.sun.com/docs/books/tutorial/essential/io/rafs.html + * + * SHOOT! random access is only for applications, not applets! + * + * With a bit more work, this could be set up to deliver binary files, but + * right now I've only implemented it for string-based data. All Jmol is using + * is getAllData(). + * + */ + +public class CompoundDocument extends BinaryDocument{ + +// RandomAccessFile file; + CompoundDocHeader header = new CompoundDocHeader(this); + Lst directory = new Lst(); + CompoundDocDirEntry rootEntry; + + int[] SAT; + int[] SSAT; + int sectorSize; + int shortSectorSize; + int nShortSectorsPerStandardSector; + int nIntPerSector; + int nDirEntriesperSector; + + // called by reflection + + public CompoundDocument(){ + super(); + this.isBigEndian = true; + } + + @Override + public void setStream(GenericZipTools jzt, BufferedInputStream bis, boolean isBigEndian) { + // isBigEndian is ignored here; it must be true + /* try { + file = new RandomAccessFile(fileName, "r"); + isRandom = true; + } catch (Exception e) { + // probably an applet + } + */ + this.jzt = jzt; + if (!isRandom) { + stream = new DataInputStream(bis); + } + stream.mark(Integer.MAX_VALUE); + if (!readHeader()) + return; + getSectorAllocationTable(); + getShortSectorAllocationTable(); + getDirectoryTable(); + } + + public Lst getDirectory() { + return directory; + } + + public String getDirectoryListing(String separator) { + String str = ""; + for (int i = 0; i < directory.size(); i++) { + CompoundDocDirEntry thisEntry = directory.get(i); + if (!thisEntry.isEmpty) + str += separator + + thisEntry.entryName + + "\tlen=" + + thisEntry.lenStream + + "\tSID=" + + thisEntry.SIDfirstSector + + (thisEntry.isStandard ? "\tfileOffset=" + + getOffset(thisEntry.SIDfirstSector) : ""); + } + return str; + } + + SB data; + + public SB getAllData() { + return getAllDataFiles(null, null); + } + + /** + * reads a compound document directory and saves all data in a Hashtable + * so that the files may be organized later in a different order. Also adds + * a #Directory_Listing entry. + * + * Files are bracketed by BEGIN Directory Entry and END Directory Entry lines, + * similar to ZipUtil.getAllData. + * + * @param prefix + * @param binaryFileList |-separated list of files that should be saved + * as xx xx xx hex byte strings. The directory listing + * is appended with ":asBinaryString" + * @param fileData + */ + @Override + public void getAllDataMapped(String prefix, + String binaryFileList, Map fileData) { + fileData.put("#Directory_Listing", getDirectoryListing("|")); + binaryFileList = "|" + binaryFileList + "|"; + for (int i = 0; i < directory.size(); i++) { + CompoundDocDirEntry thisEntry = directory.get(i); + if (!thisEntry.isEmpty && thisEntry.entryType != 5) { + String name = thisEntry.entryName; + System.out.println("CompoundDocument file " + name); + boolean isBinary = (binaryFileList.indexOf("|" + name + "|") >= 0); + if (isBinary) + name += ":asBinaryString"; + SB data = new SB(); + data.append("BEGIN Directory Entry ").append(name).append("\n"); + data.appendSB(getEntryAsString(thisEntry, isBinary)); + data.append("\nEND Directory Entry ").append(name).append("\n"); + fileData.put(prefix + "/" + name, data.toString()); + } + } + close(); + } + + @Override + public SB getAllDataFiles(String binaryFileList, String firstFile) { + if (firstFile != null) { + for (int i = 0; i < directory.size(); i++) { + CompoundDocDirEntry thisEntry = directory.get(i); + if (thisEntry.entryName.equals(firstFile)) { + directory.remove(i); + directory.add(1, thisEntry); // after ROOT_ENTRY + break; + } + } + } + data = new SB(); + data.append("Compound Document File Directory: "); + data.append(getDirectoryListing("|")); + data.append("\n"); + binaryFileList = "|" + binaryFileList + "|"; + for (int i = 0; i < directory.size(); i++) { + CompoundDocDirEntry thisEntry = directory.get(i); + //System.out.println("CompoundDocument reading " + thisEntry.entryName); + if (!thisEntry.isEmpty && thisEntry.entryType != 5) { + String name = thisEntry.entryName; + if (name.endsWith(".gz")) + name = name.substring(0, name.length() - 3); + data.append("BEGIN Directory Entry ").append(name).append("\n"); + data.appendSB(getEntryAsString(thisEntry, binaryFileList.indexOf("|" + thisEntry.entryName + "|") >= 0)); + data.append("\n"); + data.append("END Directory Entry ").append(thisEntry.entryName).append("\n"); + } + } + close(); + return data; + } + + public SB getFileAsString(String entryName) { + for (int i = 0; i < directory.size(); i++) { + CompoundDocDirEntry thisEntry = directory.get(i); + if (thisEntry.entryName.equals(entryName)) + return getEntryAsString(thisEntry, false); + } + return new SB(); + } + + private long getOffset(int SID) { + return (SID + 1) * sectorSize; + } + + private void gotoSector(int SID) { + seek(getOffset(SID)); + } + + private boolean readHeader() { + if (!header.readData()) + return false; + sectorSize = 1 << header.sectorPower; + shortSectorSize = 1 << header.shortSectorPower; + nShortSectorsPerStandardSector = sectorSize / shortSectorSize; // e.g. 512 / 64 = 8 + nIntPerSector = sectorSize / 4; // e.g. 512 / 4 = 128 + nDirEntriesperSector = sectorSize / 128; // e.g. 512 / 128 = 4 +// System.out.println( +// "compound document: revNum=" + header.revNumber + +// " verNum=" + header.verNumber + " isBigEndian=" + isBigEndian + +// " bytes per standard/short sector=" + sectorSize + "/" + shortSectorSize); + return true; + } + + private void getSectorAllocationTable() { + int nSID = 0; + int thisSID; + SAT = new int[header.nSATsectors * nIntPerSector + 109]; + + try { + for (int i = 0; i < 109; i++) { + thisSID = header.MSAT0[i]; + if (thisSID < 0) + break; + gotoSector(thisSID); + for (int j = 0; j < nIntPerSector; j++) { + SAT[nSID++] = readInt(); + //Logger.debug(thisSID+"."+j + "/" + (nSID - 1) + " : " + SAT[nSID - 1]); + } + } + int nMaster = header.nAdditionalMATsectors; + thisSID = header.SID_MSAT_next; + int[] MSAT = new int[nIntPerSector]; + out: while (nMaster-- > 0 && thisSID >= 0) { + // read a page of sector identifiers pointing to SAT sectors + gotoSector(thisSID); + for (int i = 0; i < nIntPerSector; i++) + MSAT[i] = readInt(); + // read each page of SAT sector identifiers + // last entry is pointer to next master sector allocation table page + for (int i = 0; i < nIntPerSector - 1; i++) { + thisSID = MSAT[i]; + if (thisSID < 0) + break out; + gotoSector(thisSID); + for (int j = nIntPerSector; --j >= 0;) + SAT[nSID++] = readInt(); + } + thisSID = MSAT[nIntPerSector - 1]; + } + } catch (Exception e) { + System.out.println(e.toString()); + } + } + + private void getShortSectorAllocationTable() { + int nSSID = 0; + int thisSID = header.SID_SSAT_start; + int nMax = header.nSSATsectors * nIntPerSector; + SSAT = new int[nMax]; + try { + while (thisSID > 0 && nSSID < nMax) { + gotoSector(thisSID); + for (int j = 0; j < nIntPerSector; j++) { + SSAT[nSSID++] = readInt(); + //System.out.println("short: " + thisSID+"."+j+" SSID=" +(nSSID-1)+" "+SSAT[nSSID-1]); + } + thisSID = SAT[thisSID]; + } + } catch (Exception e) { + System.out.println(e.toString()); + } + } + + private void getDirectoryTable() { + int thisSID = header.SID_DIR_start; + CompoundDocDirEntry thisEntry; + rootEntry = null; + try { + while (thisSID > 0) { + gotoSector(thisSID); + for (int j = nDirEntriesperSector; --j >= 0;) { + thisEntry = new CompoundDocDirEntry(this); + thisEntry.readData(); + if (thisEntry.lenStream > 0) { + directory.addLast(thisEntry); + //System.out.println(thisEntry.entryName); + } + if (thisEntry.entryType == 5) + rootEntry = thisEntry; + } + thisSID = SAT[thisSID]; + } + } catch (Exception e) { + System.out.println(e.toString()); + } +// System.out.println("CompoundDocument directory entry: \n" +// + getDirectoryListing("\n")); + } + + private SB getEntryAsString(CompoundDocDirEntry thisEntry, boolean asBinaryString) { + if(thisEntry.isEmpty) + return new SB(); + //System.out.println(thisEntry.entryName + " " + thisEntry.entryType + " " + thisEntry.lenStream + " " + thisEntry.isStandard + " " + thisEntry.SIDfirstSector); + return (thisEntry.isStandard ? getStandardStringData( + thisEntry.SIDfirstSector, thisEntry.lenStream, asBinaryString) + : getShortStringData(thisEntry.SIDfirstSector, thisEntry.lenStream, asBinaryString)); + } + private SB getStandardStringData(int thisSID, int nBytes, + boolean asBinaryString) { + SB data = new SB(); + byte[] byteBuf = new byte[sectorSize]; + ZipData gzipData = new ZipData(nBytes); + try { + while (thisSID > 0 && nBytes > 0) { + gotoSector(thisSID); + nBytes = getSectorData(data, byteBuf, sectorSize, nBytes, asBinaryString, gzipData); + thisSID = SAT[thisSID]; + } + if (nBytes == -9999) + return new SB(); + } catch (Exception e) { + System.out.println(e.toString()); + } + if (gzipData.isEnabled) + gzipData.addTo(jzt, data); + return data; + } + + private int getSectorData(SB data, byte[] byteBuf, + int nSectorBytes, int nBytes, + boolean asBinaryString, ZipData gzipData) + throws Exception { + readByteArray(byteBuf, 0, byteBuf.length); + int n = gzipData.addBytes(byteBuf, nSectorBytes, nBytes); + if (n >= 0) + return n; + if (asBinaryString) { + for (int i = 0; i < nSectorBytes; i++) { + data.append(Integer.toHexString(byteBuf[i] & 0xFF)).appendC(' '); + if (--nBytes < 1) + break; + } + } else { + for (int i = 0; i < nSectorBytes; i++) { + if (byteBuf[i] == 0) + return -9999; // don't allow binary data + data.appendC((char) byteBuf[i]); + if (--nBytes < 1) + break; + } + } + return nBytes; + } + + private SB getShortStringData(int shortSID, int nBytes, boolean asBinaryString) { + SB data = new SB(); + if (rootEntry == null) + return data; + int thisSID = rootEntry.SIDfirstSector; + int ptShort = 0; + byte[] byteBuf = new byte[shortSectorSize]; + ZipData gzipData = new ZipData(nBytes); + try { + //System.out.println("CD shortSID=" + shortSID); + // point to correct short data sector, 512/64 = 4 per page + while (thisSID >= 0 && shortSID >= 0 && nBytes > 0) { + while (shortSID - ptShort >= nShortSectorsPerStandardSector) { + ptShort += nShortSectorsPerStandardSector; + thisSID = SAT[thisSID]; + } + seek(getOffset(thisSID) + (shortSID - ptShort) * shortSectorSize); + nBytes = getSectorData(data, byteBuf, shortSectorSize, nBytes, asBinaryString, gzipData); + shortSID = SSAT[shortSID]; + //System.out.println("CD shortSID=" + shortSID); + } + } catch (Exception e) { + System.out.println(data.toString()); + System.out.println("reader error in CompoundDocument " + e.toString()); + } + if (gzipData.isEnabled) + gzipData.addTo(jzt, data); + return data; + } +}