KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jxl > read > biff > SupbookRecord


1 /*********************************************************************
2 *
3 * Copyright (C) 2002 Andrew Khan
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 ***************************************************************************/

19
20 package jxl.read.biff;
21
22 import common.Logger;
23
24 import jxl.WorkbookSettings;
25 import jxl.biff.IntegerHelper;
26 import jxl.biff.StringHelper;
27 import jxl.biff.RecordData;
28
29 /**
30  * A record containing the references to the various sheets (internal and
31  * external) referenced by formulas in this workbook
32  */

33 public class SupbookRecord extends RecordData
34 {
35   /**
36    * The logger
37    */

38   private static Logger logger = Logger.getLogger(SupbookRecord.class);
39
40   /**
41    * The type of this supbook record
42    */

43   private Type type;
44
45   /**
46    * The number of sheets - internal & external supbooks only
47    */

48   private int numSheets;
49
50   /**
51    * The name of the external file
52    */

53   private String JavaDoc fileName;
54
55   /**
56    * The names of the external sheets
57    */

58   private String JavaDoc[] sheetNames;
59
60   /**
61    * The type of supbook this refers to
62    */

63   private static class Type {};
64
65
66   public static final Type INTERNAL = new Type();
67   public static final Type EXTERNAL = new Type();
68   public static final Type ADDIN = new Type();
69   public static final Type LINK = new Type();
70   public static final Type UNKNOWN = new Type();
71
72   /**
73    * Constructs this object from the raw data
74    *
75    * @param t the raw data
76    * @param ws the workbook settings
77    */

78   SupbookRecord(Record t, WorkbookSettings ws)
79   {
80     super(t);
81     byte[] data = getRecord().getData();
82
83     // First deduce the type
84
if (data.length == 4)
85     {
86       if (data[2] == 0x01 && data[3] == 0x04)
87       {
88         type = INTERNAL;
89       }
90       else if (data[2] == 0x01 && data[3] == 0x3a)
91       {
92         type = ADDIN;
93       }
94       else
95       {
96         type = UNKNOWN;
97       }
98     }
99     else if (data[0] == 0 && data[1] == 0)
100     {
101       type = LINK;
102     }
103     else
104     {
105       type = EXTERNAL;
106     }
107
108     if (type == INTERNAL)
109     {
110       numSheets = IntegerHelper.getInt(data[0], data[1]);
111     }
112
113     if (type == EXTERNAL)
114     {
115       readExternal(data, ws);
116     }
117   }
118
119   /**
120    * Reads the external data records
121    *
122    * @param data the data
123    * @param ws the workbook settings
124    */

125   private void readExternal(byte[] data, WorkbookSettings ws)
126   {
127     numSheets = IntegerHelper.getInt(data[0], data[1]);
128
129     // subtract file name encoding from the length
130
int ln = IntegerHelper.getInt(data[2], data[3]) - 1;
131     int pos = 0;
132
133     if (data[4] == 0)
134     {
135       // non-unicode string
136
int encoding = data[5];
137       pos = 6;
138       if (encoding == 0)
139       {
140         fileName = StringHelper.getString(data, ln, pos, ws);
141         pos += ln;
142       }
143       else
144       {
145         fileName = getEncodedFilename(data, ln, pos);
146         pos += ln;
147       }
148     }
149     else
150     {
151       // unicode string
152
int encoding = IntegerHelper.getInt(data[5], data[6]);
153       pos = 7;
154       if (encoding == 0)
155       {
156         fileName = StringHelper.getUnicodeString(data, ln, pos);
157         pos += ln * 2;
158       }
159       else
160       {
161         fileName = getUnicodeEncodedFilename(data, ln, pos);
162         pos += ln * 2;
163       }
164     }
165
166     sheetNames = new String JavaDoc[numSheets];
167
168     for (int i = 0; i < sheetNames.length; i++)
169     {
170       ln = IntegerHelper.getInt(data[pos], data[pos + 1]);
171
172       if (data[pos + 2] == 0x0)
173       {
174         sheetNames[i] = StringHelper.getString(data, ln, pos + 3, ws);
175         pos += ln + 3;
176       }
177       else if (data[pos + 2] == 0x1)
178       {
179         sheetNames[i] = StringHelper.getUnicodeString(data, ln, pos + 3);
180         pos += ln * 2 + 3;
181       }
182     }
183   }
184
185   /**
186    * Gets the type of this supbook record
187    *
188    * @return the type of this supbook
189    */

190   public Type getType()
191   {
192     return type;
193   }
194
195   /**
196    * Gets the number of sheets. This will only be non-zero for internal
197    * and external supbooks
198    *
199    * @return the number of sheets
200    */

201   public int getNumberOfSheets()
202   {
203     return numSheets;
204   }
205
206   /**
207    * Gets the name of the external file
208    *
209    * @return the name of the external file
210    */

211   public String JavaDoc getFileName()
212   {
213     return fileName;
214   }
215
216   /**
217    * Gets the name of the external sheet
218    *
219    * @param i the index of the external sheet
220    * @return the name of the sheet
221    */

222   public String JavaDoc getSheetName(int i)
223   {
224     return sheetNames[i];
225   }
226
227   /**
228    * Gets the data - used when copying a spreadsheet
229    *
230    * @return the raw external sheet data
231    */

232   public byte[] getData()
233   {
234     return getRecord().getData();
235   }
236
237   /**
238    * Gets the encoded string from the data array
239    *
240    * @param data the data
241    * @param ln length of the string
242    * @param pos the position in the array
243    * @return the string
244    */

245   private String JavaDoc getEncodedFilename(byte[] data, int ln, int pos)
246   {
247     StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
248     int endpos = pos + ln;
249     while (pos < endpos)
250     {
251       char c = (char) data[pos];
252
253       if (c == '\u0001')
254       {
255         // next character is a volume letter
256
pos++;
257         c = (char) data[pos];
258         buf.append(c);
259         buf.append(":\\\\");
260       }
261       else if (c == '\u0002')
262       {
263         // file is on the same volume
264
buf.append('\\');
265       }
266       else if (c == '\u0003')
267       {
268         // down directory
269
buf.append('\\');
270       }
271       else if (c == '\u0004')
272       {
273         // up directory
274
buf.append("..\\");
275       }
276       else
277       {
278         // just add on the character
279
buf.append(c);
280       }
281
282       pos++;
283     }
284
285     return buf.toString();
286   }
287
288   /**
289    * Gets the encoded string from the data array
290    *
291    * @param data the data
292    * @param ln length of the string
293    * @param pos the position in the array
294    * @return the string
295    */

296   private String JavaDoc getUnicodeEncodedFilename(byte[] data, int ln, int pos)
297   {
298     StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
299     int endpos = pos + ln * 2;
300     while (pos < endpos)
301     {
302       char c = (char) IntegerHelper.getInt(data[pos], data[pos + 1]);
303
304       if (c == '\u0001')
305       {
306         // next character is a volume letter
307
pos += 2;
308         c = (char) IntegerHelper.getInt(data[pos], data[pos + 1]);
309         buf.append(c);
310         buf.append(":\\\\");
311       }
312       else if (c == '\u0002')
313       {
314         // file is on the same volume
315
buf.append('\\');
316       }
317       else if (c == '\u0003')
318       {
319         // down directory
320
buf.append('\\');
321       }
322       else if (c == '\u0004')
323       {
324         // up directory
325
buf.append("..\\");
326       }
327       else
328       {
329         // just add on the character
330
buf.append(c);
331       }
332
333       pos += 2;
334     }
335
336     return buf.toString();
337   }
338 }
339
Popular Tags