*/
public final class BoolErrRecord extends CellRecord {
public final static short sid = 0x0205;
- private byte field_4_bBoolErr;
- private byte field_5_fError;
+ private int _value;
+ /**
+ * If <code>true</code>, this record represents an error cell value, otherwise this record represents a boolean cell value
+ */
+ private boolean _isError;
/** Creates new BoolErrRecord */
public BoolErrRecord() {
- // fields uninitialised
+ // fields uninitialised
}
/**
*/
public BoolErrRecord(RecordInputStream in) {
super(in);
- field_4_bBoolErr = in.readByte();
- field_5_fError = in.readByte();
+ switch (in.remaining()) {
+ case 2:
+ _value = in.readByte();
+ break;
+ case 3:
+ _value = in.readUShort();
+ break;
+ default:
+ throw new RecordFormatException("Unexpected size ("
+ + in.remaining() + ") for BOOLERR record.");
+ }
+ int flag = in.readUByte();
+ switch (flag) {
+ case 0:
+ _isError = false;
+ break;
+ case 1:
+ _isError = true;
+ break;
+ default:
+ throw new RecordFormatException("Unexpected isError flag ("
+ + flag + ") for BOOLERR record.");
+ }
}
/**
* @param value representing the boolean value
*/
public void setValue(boolean value) {
- field_4_bBoolErr = value ? ( byte ) 1 : ( byte ) 0;
- field_5_fError = ( byte ) 0;
+ _value = value ? 1 : 0;
+ _isError = false;
}
/**
case ErrorConstants.ERROR_NAME:
case ErrorConstants.ERROR_NUM:
case ErrorConstants.ERROR_NA:
- field_4_bBoolErr = value;
- field_5_fError = ( byte ) 1;
+ _value = value;
+ _isError = true;
return;
}
throw new IllegalArgumentException("Error Value can only be 0,7,15,23,29,36 or 42. It cannot be "+value);
* @return boolean representing the boolean value
*/
public boolean getBooleanValue() {
- return (field_4_bBoolErr != 0);
+ return _value != 0;
}
/**
* @return byte representing the error value
*/
public byte getErrorValue() {
- return field_4_bBoolErr;
+ return (byte)_value;
}
/**
* @return boolean true if the cell holds a boolean value
*/
public boolean isBoolean() {
- return (field_5_fError == ( byte ) 0);
- }
-
- /**
- * manually indicate this is an error rather than a boolean
- */
- public void setError(boolean val) {
- field_5_fError = (byte) (val == false ? 0 : 1);
+ return !_isError;
}
/**
*
* @return boolean true if the cell holds an error value
*/
-
public boolean isError() {
- return field_5_fError != 0;
+ return _isError;
}
@Override
}
@Override
protected void serializeValue(LittleEndianOutput out) {
- out.writeByte(field_4_bBoolErr);
- out.writeByte(field_5_fError);
+ out.writeByte(_value);
+ out.writeByte(_isError ? 1 : 0);
}
@Override
public Object clone() {
BoolErrRecord rec = new BoolErrRecord();
copyBaseFields(rec);
- rec.field_4_bBoolErr = field_4_bBoolErr;
- rec.field_5_fError = field_5_fError;
+ rec._value = _value;
+ rec._isError = _isError;
return rec;
}
}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record;
+
+import java.util.Arrays;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import org.apache.poi.hssf.record.RecordInputStream.LeftoverDataException;
+import org.apache.poi.util.HexRead;
+/**
+ * Tests for {@link BoolErrRecord}
+ */
+public final class TestBoolErrRecord extends TestCase {
+
+ public void testError() {
+ byte[] data = HexRead.readFromString(
+ "00 00 00 00 0F 00 " + // row, col, xfIndex
+ "07 01 " // #DIV/0!, isError
+ );
+
+ RecordInputStream in = TestcaseRecordInputStream.create(BoolErrRecord.sid, data);
+ BoolErrRecord ber = new BoolErrRecord(in);
+ assertTrue(ber.isError());
+ assertEquals(7, ber.getErrorValue());
+
+ TestcaseRecordInputStream.confirmRecordEncoding(BoolErrRecord.sid, data, ber.serialize());
+ }
+
+ /**
+ * Bugzilla 47479 was due to an apparent error in OOO which (as of version 3.0.1)
+ * writes the <i>value</i> field of BOOLERR records as 2 bytes instead of 1.<br/>
+ * Coincidentally, the extra byte written is zero, which is exactly the value
+ * required by the <i>isError</i> field. This probably why Excel seems to have
+ * no problem. OOO does not have the same bug for error values (which wouldn't
+ * work by the same coincidence).
+ */
+ public void testOooBadFormat_bug47479() {
+ byte[] data = HexRead.readFromString(
+ "05 02 09 00 " + // sid, size
+ "00 00 00 00 0F 00 " + // row, col, xfIndex
+ "01 00 00 " // extra 00 byte here
+ );
+
+ RecordInputStream in = TestcaseRecordInputStream.create(data);
+ BoolErrRecord ber = new BoolErrRecord(in);
+ boolean hasMore;
+ try {
+ hasMore = in.hasNextRecord();
+ } catch (LeftoverDataException e) {
+ if ("Initialisation of record 0x205 left 1 bytes remaining still to be read.".equals(e.getMessage())) {
+ throw new AssertionFailedError("Identified bug 47479");
+ }
+ throw e;
+ }
+ assertFalse(hasMore);
+ assertTrue(ber.isBoolean());
+ assertEquals(true, ber.getBooleanValue());
+
+ // Check that the record re-serializes correctly
+ byte[] outData = ber.serialize();
+ byte[] expData = HexRead.readFromString(
+ "05 02 08 00 " +
+ "00 00 00 00 0F 00 " +
+ "01 00 " // normal number of data bytes
+ );
+ assertTrue(Arrays.equals(expData, outData));
+ }
+}