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.write.biff;
21
22 import jxl.biff.IntegerHelper;
23 import jxl.biff.Type;
24 import jxl.biff.WritableRecordData;
25
26 /**
27 * Indicates an extension to the Shared String Table. Currently this
28 * contains blank records
29 *
30 * Thanks to Guenther for contributing a proper implementation of the EXTSST
31 * record, replacing my previous dummy version
32 */
33 class ExtendedSSTRecord extends WritableRecordData
34 {
35 private static final int infoRecordSize = 8;
36 private int numberOfStrings;
37 private int[] absoluteStreamPositions;
38 private int[] relativeStreamPositions;
39 private int currentStringIndex = 0;
40
41 /**
42 * Constructor
43 *
44 * @param numstrings the number of strings per bucket
45 * @param streampos the absolute stream position of the beginning of
46 * the SST record
47 */
48 public ExtendedSSTRecord(int newNumberOfStrings)
49 {
50 super(Type.EXTSST);
51 numberOfStrings = newNumberOfStrings;
52 int numberOfBuckets = getNumberOfBuckets();
53 absoluteStreamPositions = new int[numberOfBuckets];
54 relativeStreamPositions = new int[numberOfBuckets];
55 currentStringIndex = 0;
56 }
57
58 public int getNumberOfBuckets()
59 {
60 int numberOfStringsPerBucket = getNumberOfStringsPerBucket();
61 return numberOfStringsPerBucket != 0 ?
62 (numberOfStrings + numberOfStringsPerBucket - 1) /
63 numberOfStringsPerBucket : 0;
64 }
65
66 public int getNumberOfStringsPerBucket()
67 {
68 // XXX
69 // should come up with a more clever calculation
70 // bucket limit should not be bigger than 1024, otherwise we end
71 // up with too many buckets and would have to write continue records
72 // for the EXTSST record which we want to avoid for now.
73 final int bucketLimit = 128;
74 return (numberOfStrings + bucketLimit - 1) / bucketLimit;
75 }
76
77 public void addString(int absoluteStreamPosition,
78 int relativeStreamPosition)
79 {
80 absoluteStreamPositions[currentStringIndex] =
81 absoluteStreamPosition + relativeStreamPosition;
82 relativeStreamPositions[currentStringIndex] = relativeStreamPosition;
83 currentStringIndex++;
84 }
85
86 /**
87 * Gets the binary data to be written out
88 *
89 * @return the binary data
90 */
91 public byte[] getData()
92 {
93 int numberOfBuckets = getNumberOfBuckets();
94 byte[] data = new byte[2 + (8 * numberOfBuckets)];
95 // number of strings per bucket
96 IntegerHelper.getTwoBytes(getNumberOfStringsPerBucket(), data, 0);
97
98 for (int i = 0; i < numberOfBuckets; i++)
99 {
100 // absolute stream position
101 IntegerHelper.getFourBytes(absoluteStreamPositions[i],
102 data,
103 2 + (i * infoRecordSize));
104 // relative offset
105 IntegerHelper.getTwoBytes(relativeStreamPositions[i],
106 data,
107 6 + (i * infoRecordSize));
108 // reserved
109 // IntegerHelper.getTwoBytes(0x0, data, 8 + (i * infoRecordSize));
110 }
111
112 return data;
113 }
114 }
115