Source Code Cross Referenced for RecordInputStream.java in  » Collaboration » poi-3.0.2-beta2 » org » apache » poi » hssf » record » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Collaboration » poi 3.0.2 beta2 » org.apache.poi.hssf.record 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* ====================================================================
002:         Licensed to the Apache Software Foundation (ASF) under one or more
003:         contributor license agreements.  See the NOTICE file distributed with
004:         this work for additional information regarding copyright ownership.
005:         The ASF licenses this file to You under the Apache License, Version 2.0
006:         (the "License"); you may not use this file except in compliance with
007:         the License.  You may obtain a copy of the License at
008:
009:         http://www.apache.org/licenses/LICENSE-2.0
010:
011:         Unless required by applicable law or agreed to in writing, software
012:         distributed under the License is distributed on an "AS IS" BASIS,
013:         WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         See the License for the specific language governing permissions and
015:         limitations under the License.
016:         ==================================================================== */
017:
018:        package org.apache.poi.hssf.record;
019:
020:        import org.apache.poi.util.LittleEndian;
021:
022:        import java.io.IOException;
023:        import java.io.InputStream;
024:        import java.io.ByteArrayOutputStream;
025:
026:        /**
027:         * Title:  Record Input Stream<P>
028:         * Description:  Wraps a stream and provides helper methods for the construction of records.<P>
029:         *
030:         * @author Jason Height (jheight @ apache dot org)
031:         */
032:
033:        public class RecordInputStream extends InputStream {
034:            /** Maximum size of a single record (minus the 4 byte header) without a continue*/
035:            public final static short MAX_RECORD_DATA_SIZE = 8224;
036:
037:            private InputStream in;
038:            protected short currentSid;
039:            protected short currentLength = -1;
040:            protected short nextSid = -1;
041:
042:            protected byte[] data = new byte[MAX_RECORD_DATA_SIZE];
043:            protected short recordOffset;
044:            protected long pos;
045:
046:            private boolean autoContinue = true;
047:
048:            public RecordInputStream(InputStream in)
049:                    throws RecordFormatException {
050:                this .in = in;
051:                try {
052:                    nextSid = LittleEndian.readShort(in);
053:                    //Dont increment the pos just yet (technically we are at the start of
054:                    //the record stream until nextRecord is called).      
055:                } catch (IOException ex) {
056:                    throw new RecordFormatException("Error reading bytes", ex);
057:                }
058:            }
059:
060:            /** This method will read a byte from the current record*/
061:            public int read() throws IOException {
062:                checkRecordPosition();
063:
064:                byte result = data[recordOffset];
065:                recordOffset += 1;
066:                pos += 1;
067:                return result;
068:            }
069:
070:            public short getSid() {
071:                return currentSid;
072:            }
073:
074:            public short getLength() {
075:                return currentLength;
076:            }
077:
078:            public short getRecordOffset() {
079:                return recordOffset;
080:            }
081:
082:            public long getPos() {
083:                return pos;
084:            }
085:
086:            public boolean hasNextRecord() {
087:                return (nextSid != 0);
088:            }
089:
090:            /** Moves to the next record in the stream.
091:             * 
092:             * <i>Note: The auto continue flag is reset to true</i>
093:             */
094:
095:            public void nextRecord() throws RecordFormatException {
096:                if ((currentLength != -1) && (currentLength != recordOffset)) {
097:                    System.out.println("WARN. Unread " + remaining()
098:                            + " bytes of record 0x"
099:                            + Integer.toHexString(currentSid));
100:                }
101:                currentSid = nextSid;
102:                pos += LittleEndian.SHORT_SIZE;
103:                autoContinue = true;
104:                try {
105:                    recordOffset = 0;
106:                    currentLength = LittleEndian.readShort(in);
107:                    if (currentLength > MAX_RECORD_DATA_SIZE)
108:                        throw new RecordFormatException(
109:                                "The content of an excel record cannot exceed "
110:                                        + MAX_RECORD_DATA_SIZE + " bytes");
111:                    pos += LittleEndian.SHORT_SIZE;
112:                    in.read(data, 0, currentLength);
113:
114:                    //Read the Sid of the next record
115:                    nextSid = LittleEndian.readShort(in);
116:                } catch (IOException ex) {
117:                    throw new RecordFormatException("Error reading bytes", ex);
118:                }
119:            }
120:
121:            public void setAutoContinue(boolean enable) {
122:                this .autoContinue = enable;
123:            }
124:
125:            public boolean getAutoContinue() {
126:                return autoContinue;
127:            }
128:
129:            protected void checkRecordPosition() {
130:                if (remaining() <= 0) {
131:                    if (isContinueNext() && autoContinue) {
132:                        nextRecord();
133:                    } else
134:                        throw new ArrayIndexOutOfBoundsException();
135:                }
136:            }
137:
138:            public byte readByte() {
139:                checkRecordPosition();
140:
141:                byte result = data[recordOffset];
142:                recordOffset += 1;
143:                pos += 1;
144:                return result;
145:            }
146:
147:            public short readShort() {
148:                checkRecordPosition();
149:
150:                short result = LittleEndian.getShort(data, recordOffset);
151:                recordOffset += LittleEndian.SHORT_SIZE;
152:                pos += LittleEndian.SHORT_SIZE;
153:                return result;
154:            }
155:
156:            public int readInt() {
157:                checkRecordPosition();
158:
159:                int result = LittleEndian.getInt(data, recordOffset);
160:                recordOffset += LittleEndian.INT_SIZE;
161:                pos += LittleEndian.INT_SIZE;
162:                return result;
163:            }
164:
165:            public long readLong() {
166:                checkRecordPosition();
167:
168:                long result = LittleEndian.getLong(data, recordOffset);
169:                recordOffset += LittleEndian.LONG_SIZE;
170:                pos += LittleEndian.LONG_SIZE;
171:                return result;
172:            }
173:
174:            public int readUShort() {
175:                checkRecordPosition();
176:
177:                int result = LittleEndian.getUShort(data, recordOffset);
178:                recordOffset += LittleEndian.SHORT_SIZE;
179:                pos += LittleEndian.SHORT_SIZE;
180:                return result;
181:            }
182:
183:            byte[] NAN_data = null;
184:
185:            public double readDouble() {
186:                checkRecordPosition();
187:                //Reset NAN data
188:                NAN_data = null;
189:                double result = LittleEndian.getDouble(data, recordOffset);
190:                //Excel represents NAN in several ways, at this point in time we do not often
191:                //know the sequence of bytes, so as a hack we store the NAN byte sequence
192:                //so that it is not corrupted.
193:                if (Double.isNaN(result)) {
194:                    NAN_data = new byte[8];
195:                    System.arraycopy(data, recordOffset, NAN_data, 0, 8);
196:                }
197:
198:                recordOffset += LittleEndian.DOUBLE_SIZE;
199:                pos += LittleEndian.DOUBLE_SIZE;
200:                return result;
201:            }
202:
203:            public byte[] getNANData() {
204:                if (NAN_data == null)
205:                    throw new RecordFormatException(
206:                            "Do NOT call getNANData without calling readDouble that returns NaN");
207:                return NAN_data;
208:            }
209:
210:            public short[] readShortArray() {
211:                checkRecordPosition();
212:
213:                short[] arr = LittleEndian.getShortArray(data, recordOffset);
214:                final int size = (2 * (arr.length + 1));
215:                recordOffset += size;
216:                pos += size;
217:
218:                return arr;
219:            }
220:
221:            /**     
222:             *  given a byte array of 16-bit unicode characters, compress to 8-bit and     
223:             *  return a string     
224:             *     
225:             * { 0x16, 0x00 } -0x16     
226:             *      
227:             * @param length the length of the final string
228:             * @return                                     the converted string
229:             * @exception  IllegalArgumentException        if len is too large (i.e.,
230:             *      there is not enough data in string to create a String of that     
231:             *      length)     
232:             */
233:            public String readUnicodeLEString(int length) {
234:                if ((length < 0)
235:                        || (((remaining() / 2) < length) && !isContinueNext())) {
236:                    throw new IllegalArgumentException("Illegal length");
237:                }
238:
239:                StringBuffer buf = new StringBuffer(length);
240:                for (int i = 0; i < length; i++) {
241:                    if ((remaining() == 0) && (isContinueNext())) {
242:                        nextRecord();
243:                        int compressByte = readByte();
244:                        if (compressByte != 1)
245:                            throw new IllegalArgumentException(
246:                                    "compressByte in continue records must be 1 while reading unicode LE string");
247:                    }
248:                    char ch = (char) readShort();
249:                    buf.append(ch);
250:                }
251:                return buf.toString();
252:            }
253:
254:            public String readCompressedUnicode(int length) {
255:                if ((length < 0)
256:                        || ((remaining() < length) && !isContinueNext())) {
257:                    throw new IllegalArgumentException("Illegal length");
258:                }
259:
260:                StringBuffer buf = new StringBuffer(length);
261:                for (int i = 0; i < length; i++) {
262:                    if ((remaining() == 0) && (isContinueNext())) {
263:                        nextRecord();
264:                        int compressByte = readByte();
265:                        if (compressByte != 0)
266:                            throw new IllegalArgumentException(
267:                                    "compressByte in continue records must be 0 while reading compressed unicode");
268:                    }
269:                    byte b = readByte();
270:                    //Typecast direct to char from byte with high bit set causes all ones
271:                    //in the high byte of the char (which is of course incorrect)
272:                    char ch = (char) ((short) 0xff & (short) b);
273:                    buf.append(ch);
274:                }
275:                return buf.toString();
276:            }
277:
278:            /** Returns an excel style unicode string from the bytes reminaing in the record.
279:             * <i>Note:</i> Unicode strings differ from <b>normal</b> strings due to the addition of
280:             * formatting information.
281:             * 
282:             * @return The unicode string representation of the remaining bytes.
283:             */
284:            public UnicodeString readUnicodeString() {
285:                return new UnicodeString(this );
286:            }
287:
288:            /** Returns the remaining bytes for the current record.
289:             * 
290:             * @return The remaining bytes of the current record.
291:             */
292:            public byte[] readRemainder() {
293:                int size = remaining();
294:                byte[] result = new byte[size];
295:                System.arraycopy(data, recordOffset, result, 0, size);
296:                recordOffset += size;
297:                pos += size;
298:                return result;
299:            }
300:
301:            /** Reads all byte data for the current record, including any
302:             *  that overlaps into any following continue records.
303:             * 
304:             *  @deprecated Best to write a input stream that wraps this one where there is
305:             *  special sub record that may overlap continue records.
306:             */
307:            public byte[] readAllContinuedRemainder() {
308:                //Using a ByteArrayOutputStream is just an easy way to get a
309:                //growable array of the data.
310:                ByteArrayOutputStream out = new ByteArrayOutputStream(
311:                        2 * MAX_RECORD_DATA_SIZE);
312:
313:                while (isContinueNext()) {
314:                    byte[] b = readRemainder();
315:                    out.write(b, 0, b.length);
316:                    nextRecord();
317:                }
318:                byte[] b = readRemainder();
319:                out.write(b, 0, b.length);
320:
321:                return out.toByteArray();
322:            }
323:
324:            /** The remaining number of bytes in the <i>current</i> record.
325:             * 
326:             * @return The number of bytes remaining in the current record
327:             */
328:            public int remaining() {
329:                return (currentLength - recordOffset);
330:            }
331:
332:            /** Returns true iif a Continue record is next in the excel stream 
333:             * 
334:             * @return True when a ContinueRecord is next.
335:             */
336:            public boolean isContinueNext() {
337:                return (nextSid == ContinueRecord.sid);
338:            }
339:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.