FileDocCategorySizeDatePackage
RKRecord.javaAPI DocApache Poi 3.0.18883Mon Jan 01 12:39:40 GMT 2007org.apache.poi.hssf.record

RKRecord

public class RKRecord extends Record implements CellValueRecordInterface
Title: RK Record Description: An internal 32 bit number with the two most significant bits storing the type. This is part of a bizarre scheme to save disk space and memory (gee look at all the other whole records that are in the file just "cause"..,far better to waste processor cycles on this then leave on of those "valuable" records out).

We support this in READ-ONLY mode. HSSF converts these to NUMBER records

REFERENCE: PG 376 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

author
Andrew C. Oliver (acoliver at apache dot org)
author
Jason Height (jheight at chariot dot net dot au)
version
2.0-pre
see
org.apache.poi.hssf.record.NumberRecord

Fields Summary
public static final short
sid
public static final short
RK_IEEE_NUMBER
public static final short
RK_IEEE_NUMBER_TIMES_100
public static final short
RK_INTEGER
public static final short
RK_INTEGER_TIMES_100
private int
field_1_row
private short
field_2_col
private short
field_3_xf_index
private int
field_4_rk_number
Constructors Summary
public RKRecord()


     
    
    
public RKRecord(RecordInputStream in)
Constructs a RK record and sets its fields appropriately.

param
id id must be 0x27e or an exception will be throw upon validation
param
size the size of the data area of the record
param
data data of the record (should not contain sid/len)

        super(in);
    
Methods Summary
public java.lang.Objectclone()

      RKRecord rec = new RKRecord();
      rec.field_1_row = field_1_row;
      rec.field_2_col = field_2_col;
      rec.field_3_xf_index = field_3_xf_index;
      rec.field_4_rk_number = field_4_rk_number;
      return rec;
    
protected voidfillFields(org.apache.poi.hssf.record.RecordInputStream in)

        //field_1_row       = LittleEndian.getShort(data, 0 + offset);
        field_1_row       = in.readUShort();
        field_2_col       = in.readShort();
        field_3_xf_index  = in.readShort();
        field_4_rk_number = in.readInt();
    
public shortgetColumn()

        return field_2_col;
    
public intgetRKField()

        return field_4_rk_number;
    
public doublegetRKNumber()
Extract the value of the number

The mechanism for determining the value is dependent on the two low order bits of the raw number. If bit 1 is set, the number is an integer and can be cast directly as a double, otherwise, it's apparently the exponent and mantissa of a double (and the remaining low-order bits of the double's mantissa are 0's).

If bit 0 is set, the result of the conversion to a double is divided by 100; otherwise, the value is left alone.

[insert picture of Screwy Squirrel in full Napoleonic regalia]

return
the value as a proper double (hey, it could happen)

        return RKUtil.decodeNumber(field_4_rk_number);
    
public shortgetRKType()
Get the type of the number

return
one of these values:
  1. RK_IEEE_NUMBER
  2. RK_IEEE_NUMBER_TIMES_100
  3. RK_INTEGER
  4. RK_INTEGER_TIMES_100

        return ( short ) (field_4_rk_number & 3);
    
public intgetRow()

        return field_1_row;
    
public shortgetSid()

        return sid;
    
public shortgetXFIndex()

        return field_3_xf_index;
    
public booleanisAfter(org.apache.poi.hssf.record.CellValueRecordInterface i)

        if (this.getRow() < i.getRow())
        {
            return false;
        }
        if ((this.getRow() == i.getRow())
                && (this.getColumn() < i.getColumn()))
        {
            return false;
        }
        if ((this.getRow() == i.getRow())
                && (this.getColumn() == i.getColumn()))
        {
            return false;
        }
        return true;
    
public booleanisBefore(org.apache.poi.hssf.record.CellValueRecordInterface i)

        if (this.getRow() > i.getRow())
        {
            return false;
        }
        if ((this.getRow() == i.getRow())
                && (this.getColumn() > i.getColumn()))
        {
            return false;
        }
        if ((this.getRow() == i.getRow())
                && (this.getColumn() == i.getColumn()))
        {
            return false;
        }
        return true;
    
public booleanisEqual(org.apache.poi.hssf.record.CellValueRecordInterface i)

        return ((this.getRow() == i.getRow())
                && (this.getColumn() == i.getColumn()));
    
public booleanisInValueSection()

        return true;
    
public booleanisValue()

        return true;
    
public static voidmain(java.lang.String[] ignored_args)
Debugging main()

Normally I'd do this in a junit test, but let's face it -- once this algorithm has been tested and it works, we are never ever going to change it. This is driven by the Faceless Enemy's minions, who dare not change the algorithm out from under us.

param
ignored_args command line arguments, which we blithely ignore

        int[]    values  =
        {
            0x3FF00000, 0x405EC001, 0x02F1853A, 0x02F1853B, 0xFCDD699A
        };
        double[] rvalues =
        {
            1, 1.23, 12345678, 123456.78, -13149594
        };

        for (int j = 0; j < values.length; j++)
        {
            System.out.println("input = " + Integer.toHexString(values[ j ])
                               + " -> " + rvalues[ j ] + ": "
                               + RKUtil.decodeNumber(values[ j ]));
        }
    
public intserialize(int offset, byte[] data)

        NumberRecord rec = new NumberRecord();

        rec.setColumn(getColumn());
        rec.setRow(getRow());
        rec.setValue(getRKNumber());
        rec.setXFIndex(getXFIndex());
        return rec.serialize(offset, data);
    
public voidsetColumn(short col)

    
public voidsetRow(int row)

    
public voidsetXFIndex(short xf)
NO OP!

    
public java.lang.StringtoString()

        StringBuffer buffer = new StringBuffer();

        buffer.append("[RK]\n");
        buffer.append("    .row            = ")
            .append(Integer.toHexString(getRow())).append("\n");
        buffer.append("    .col            = ")
            .append(Integer.toHexString(getColumn())).append("\n");
        buffer.append("    .xfindex        = ")
            .append(Integer.toHexString(getXFIndex())).append("\n");
        buffer.append("    .rknumber       = ")
            .append(Integer.toHexString(getRKField())).append("\n");
        buffer.append("        .rktype     = ")
            .append(Integer.toHexString(getRKType())).append("\n");
        buffer.append("        .rknumber   = ").append(getRKNumber())
            .append("\n");
        buffer.append("[/RK]\n");
        return buffer.toString();
    
protected voidvalidateSid(short id)

        if (id != sid)
        {
            throw new RecordFormatException("NOT A valid RK RECORD");
        }