View | Details | Raw Unified | Return to bug 38607
Collapse All | Expand All

(-)src/java/org/apache/poi/hssf/record/RecordInputStream.java (-8 / +30 lines)
Lines 18-28 Link Here
18
18
19
package org.apache.poi.hssf.record;
19
package org.apache.poi.hssf.record;
20
20
21
import org.apache.poi.util.LittleEndian;
21
import java.io.ByteArrayOutputStream;
22
23
import java.io.IOException;
22
import java.io.IOException;
24
import java.io.InputStream;
23
import java.io.InputStream;
25
import java.io.ByteArrayOutputStream;
24
25
import org.apache.poi.util.LittleEndian;
26
26
27
/**
27
/**
28
 * Title:  Record Input Stream<P>
28
 * Title:  Record Input Stream<P>
Lines 37-45 Link Here
37
  public final static short MAX_RECORD_DATA_SIZE = 8224;
37
  public final static short MAX_RECORD_DATA_SIZE = 8224;
38
38
39
  private InputStream in;
39
  private InputStream in;
40
  protected short currentSid;
40
  protected short currentSid = -1;
41
  protected short currentLength = -1;
41
  protected short currentLength = -1;
42
  protected short nextSid = -1;
42
  protected short nextSid;
43
43
44
  protected byte[] data = new byte[MAX_RECORD_DATA_SIZE];
44
  protected byte[] data = new byte[MAX_RECORD_DATA_SIZE];
45
  protected short recordOffset;
45
  protected short recordOffset;
Lines 47-56 Link Here
47
  
47
  
48
  private boolean autoContinue = true;
48
  private boolean autoContinue = true;
49
49
50
  /** currentSid with this value indicates EOF. */
51
  private final short eof;
52
50
  public RecordInputStream(InputStream in) throws RecordFormatException  {
53
  public RecordInputStream(InputStream in) throws RecordFormatException  {
54
    this(in, (short) 0);
55
  }
56
57
  /**
58
   * Constructs.
59
   * @param in The input stream.
60
   * @param eof The sid that indicates end of stream.
61
   */
62
  public RecordInputStream(InputStream in, short eof) throws RecordFormatException  {
51
    this.in = in;
63
    this.in = in;
64
    this.eof = eof;
52
    try {
65
    try {
53
      nextSid = LittleEndian.readShort(in);
66
      nextSid = readLEShortOrEOF();
54
      //Dont increment the pos just yet (technically we are at the start of
67
      //Dont increment the pos just yet (technically we are at the start of
55
      //the record stream until nextRecord is called).      
68
      //the record stream until nextRecord is called).      
56
    } catch (IOException ex) {
69
    } catch (IOException ex) {
Lines 85-91 Link Here
85
  }
98
  }
86
99
87
  public boolean hasNextRecord() {
100
  public boolean hasNextRecord() {
88
    return (nextSid != 0);
101
    return nextSid != eof;
89
  }
102
  }
90
  
103
  
91
  /** Moves to the next record in the stream.
104
  /** Moves to the next record in the stream.
Lines 109-120 Link Here
109
      in.read(data, 0, currentLength);
122
      in.read(data, 0, currentLength);
110
123
111
      //Read the Sid of the next record
124
      //Read the Sid of the next record
112
      nextSid = LittleEndian.readShort(in);
125
      nextSid = readLEShortOrEOF();
113
    } catch (IOException ex) {
126
    } catch (IOException ex) {
114
      throw new RecordFormatException("Error reading bytes");
127
      throw new RecordFormatException("Error reading bytes");
115
    }
128
    }
116
  }
129
  }
117
  
130
  
131
  private short readLEShortOrEOF() throws IOException {
132
    int firstByte = in.read();
133
    if (-1 == firstByte) {
134
      return eof;
135
    }
136
    int secondByte = in.read();
137
    return (short) ((secondByte << 8) | firstByte);
138
  }
139
118
  public void setAutoContinue(boolean enable) {
140
  public void setAutoContinue(boolean enable) {
119
    this.autoContinue = enable;    
141
    this.autoContinue = enable;    
120
  }
142
  }
(-)src/java/org/apache/poi/hssf/record/ObjRecord.java (-1 / +2 lines)
Lines 81-87 Link Here
81
        //Check if this can be continued, if so then the
81
        //Check if this can be continued, if so then the
82
        //following wont work properly
82
        //following wont work properly
83
        byte[] subRecordData = in.readRemainder();
83
        byte[] subRecordData = in.readRemainder();
84
        RecordInputStream subRecStream = new RecordInputStream(new ByteArrayInputStream(subRecordData));
84
        // We stop when the stream runs out of data.
85
        RecordInputStream subRecStream = new RecordInputStream(new ByteArrayInputStream(subRecordData), (short) -1);
85
        while(subRecStream.hasNextRecord()) {
86
        while(subRecStream.hasNextRecord()) {
86
          subRecStream.nextRecord();
87
          subRecStream.nextRecord();
87
          Record subRecord = SubRecord.createSubRecord(subRecStream);
88
          Record subRecord = SubRecord.createSubRecord(subRecStream);
(-)src/testcases/org/apache/poi/hssf/record/TestRecordInputStream.java (+60 lines)
Line 0 Link Here
1
2
/* ====================================================================
3
   Copyright 2002-2004   Apache Software Foundation
4
5
   Licensed under the Apache License, Version 2.0 (the "License");
6
   you may not use this file except in compliance with the License.
7
   You may obtain a copy of the License at
8
9
       http://www.apache.org/licenses/LICENSE-2.0
10
11
   Unless required by applicable law or agreed to in writing, software
12
   distributed under the License is distributed on an "AS IS" BASIS,
13
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
   See the License for the specific language governing permissions and
15
   limitations under the License.
16
==================================================================== */
17
18
package org.apache.poi.hssf.record;
19
20
import java.io.ByteArrayInputStream;
21
22
import junit.framework.TestCase;
23
24
/**
25
 * Tests for {@link org.apache.poi.hssf.record.RecordInputStream}.
26
 *
27
 * @author Andrzej Cichocki (arc at decisionsoft.com)
28
 * @author Matt Hillsdon (mth at decisionsoft.com)
29
 */
30
public class TestRecordInputStream extends TestCase {
31
32
  public TestRecordInputStream(String name) {
33
    super(name);
34
  }
35
36
  public void testEmptyStreamHasNoRecords() {
37
    assertFalse(new RecordInputStream(new ByteArrayInputStream(new byte[0])).hasNextRecord());
38
    assertFalse(new RecordInputStream(new ByteArrayInputStream(new byte[0]), (short) -1).hasNextRecord());
39
  }
40
41
  public void testRecordWithZeroSidIsNotIgnored() {
42
    byte[] data = new byte[] {
43
        0x15, 0, 18, 0, // CommonObjectDataSubRecord
44
        1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18, // 18 bytes record data
45
        0,0,0,0 // EndSubRecord has a zero sid and size.
46
    };
47
    RecordInputStream ris = new RecordInputStream(new ByteArrayInputStream(data), (short) -1);
48
    assertTrue(ris.hasNextRecord());
49
    ris.nextRecord();
50
    assertEquals(0x15, ris.getSid());
51
    assertEquals(18, ris.readRemainder().length);
52
    assertTrue(ris.hasNextRecord());
53
    ris.nextRecord();
54
    assertEquals(0, ris.getSid());
55
    assertEquals(0, ris.readRemainder().length);
56
    assertFalse(ris.hasNextRecord());
57
  }
58
59
}
60

Return to bug 38607