package jxl.read.biff; import common.Logger; import jxl.WorkbookSettings; import jxl.biff.IntegerHelper; import jxl.biff.RecordData; import jxl.biff.StringHelper; public class SupbookRecord extends RecordData { private static Logger logger = Logger.getLogger(SupbookRecord.class); private Type type; private int numSheets; private String fileName; private String[] sheetNames; private static class Type { private Type() {} } public static final Type INTERNAL = new Type(); public static final Type EXTERNAL = new Type(); public static final Type ADDIN = new Type(); public static final Type LINK = new Type(); public static final Type UNKNOWN = new Type(); SupbookRecord(Record t, WorkbookSettings ws) { super(t); byte[] data = getRecord().getData(); if (data.length == 4) { if (data[2] == 1 && data[3] == 4) { this.type = INTERNAL; } else if (data[2] == 1 && data[3] == 58) { this.type = ADDIN; } else { this.type = UNKNOWN; } } else if (data[0] == 0 && data[1] == 0) { this.type = LINK; } else { this.type = EXTERNAL; } if (this.type == INTERNAL) this.numSheets = IntegerHelper.getInt(data[0], data[1]); if (this.type == EXTERNAL) readExternal(data, ws); } private void readExternal(byte[] data, WorkbookSettings ws) { this.numSheets = IntegerHelper.getInt(data[0], data[1]); int ln = IntegerHelper.getInt(data[2], data[3]) - 1; int pos = 0; if (data[4] == 0) { int encoding = data[5]; pos = 6; if (encoding == 0) { this.fileName = StringHelper.getString(data, ln, pos, ws); pos += ln; } else { this.fileName = getEncodedFilename(data, ln, pos); pos += ln; } } else { int encoding = IntegerHelper.getInt(data[5], data[6]); pos = 7; if (encoding == 0) { this.fileName = StringHelper.getUnicodeString(data, ln, pos); pos += ln * 2; } else { this.fileName = getUnicodeEncodedFilename(data, ln, pos); pos += ln * 2; } } this.sheetNames = new String[this.numSheets]; for (int i = 0; i < this.sheetNames.length; i++) { ln = IntegerHelper.getInt(data[pos], data[pos + 1]); if (data[pos + 2] == 0) { this.sheetNames[i] = StringHelper.getString(data, ln, pos + 3, ws); pos += ln + 3; } else if (data[pos + 2] == 1) { this.sheetNames[i] = StringHelper.getUnicodeString(data, ln, pos + 3); pos += ln * 2 + 3; } } } public Type getType() { return this.type; } public int getNumberOfSheets() { return this.numSheets; } public String getFileName() { return this.fileName; } public String getSheetName(int i) { return this.sheetNames[i]; } public byte[] getData() { return getRecord().getData(); } private String getEncodedFilename(byte[] data, int ln, int pos) { StringBuffer buf = new StringBuffer(); int endpos = pos + ln; while (pos < endpos) { char c = (char)data[pos]; if (c == '\001') { pos++; c = (char)data[pos]; buf.append(c); buf.append(":\\\\"); } else if (c == '\002') { buf.append('\\'); } else if (c == '\003') { buf.append('\\'); } else if (c == '\004') { buf.append("..\\"); } else { buf.append(c); } pos++; } return buf.toString(); } private String getUnicodeEncodedFilename(byte[] data, int ln, int pos) { StringBuffer buf = new StringBuffer(); int endpos = pos + ln * 2; while (pos < endpos) { char c = (char)IntegerHelper.getInt(data[pos], data[pos + 1]); if (c == '\001') { pos += 2; c = (char)IntegerHelper.getInt(data[pos], data[pos + 1]); buf.append(c); buf.append(":\\\\"); } else if (c == '\002') { buf.append('\\'); } else if (c == '\003') { buf.append('\\'); } else if (c == '\004') { buf.append("..\\"); } else { buf.append(c); } pos += 2; } return buf.toString(); } }