Пример #1
0
  /**
   * Read in the actual token (array) values. This occurs AFTER the last Ptg in the expression. See
   * page 304-305 of Excel97-2007BinaryFileFormat(xls)Specification.pdf
   */
  public void readTokenValues(LittleEndianInput in) {
    int nColumns = in.readUByte();
    short nRows = in.readShort();
    // The token_1_columns and token_2_rows do not follow the documentation.
    // The number of physical rows and columns is actually +1 of these values.
    // Which is not explicitly documented.
    nColumns++;
    nRows++;

    token_1_columns = nColumns;
    token_2_rows = nRows;

    int totalCount = nRows * nColumns;
    token_3_arrayValues = ConstantValueParser.parse(in, totalCount);
  }
 private static Ptg readRefPtg(byte[] formulaRawBytes) {
   LittleEndianInput in = new LittleEndianInputStream(new ByteArrayInputStream(formulaRawBytes));
   byte ptgSid = in.readByte();
   switch (ptgSid) {
     case AreaPtg.sid:
       return new AreaPtg(in);
     case Area3DPtg.sid:
       return new Area3DPtg(in);
     case RefPtg.sid:
       return new RefPtg(in);
     case Ref3DPtg.sid:
       return new Ref3DPtg(in);
   }
   return null;
 }
Пример #3
0
 public ArrayPtg(LittleEndianInput in) {
   field_1_reserved = new byte[RESERVED_FIELD_LEN];
   // TODO - add readFully method to RecordInputStream
   for (int i = 0; i < RESERVED_FIELD_LEN; i++) {
     field_1_reserved[i] = in.readByte();
   }
 }
Пример #4
0
 public AttrPtg(LittleEndianInput in) {
   _options = in.readByte();
   _data = in.readShort();
   if (isOptimizedChoose()) {
     int nCases = _data;
     int[] jumpTable = new int[nCases];
     for (int i = 0; i < jumpTable.length; i++) {
       jumpTable[i] = in.readUShort();
     }
     _jumpTable = jumpTable;
     _chooseFuncOffset = in.readUShort();
   } else {
     _jumpTable = null;
     _chooseFuncOffset = -1;
   }
 }
 private static byte[] readRawData(LittleEndianInput in, int size) {
   if (size < 0) {
     throw new IllegalArgumentException("Negative size (" + size + ")");
   }
   if (size == 0) {
     return EMPTY_BYTE_ARRAY;
   }
   byte[] result = new byte[size];
   in.readFully(result);
   return result;
 }
Пример #6
0
 private static byte[] readTail(byte[] expectedTail, LittleEndianInput in) {
   byte[] result = new byte[TAIL_SIZE];
   in.readFully(result);
   if (false) { // Quite a few examples in the unit tests which don't have the exact expected tail
     for (int i = 0; i < expectedTail.length; i++) {
       if (expectedTail[i] != result[i]) {
         System.err.println(
             "Mismatch in tail byte ["
                 + i
                 + "]"
                 + "expected "
                 + (expectedTail[i] & 0xFF)
                 + " but got "
                 + (result[i] & 0xFF));
       }
     }
   }
   return result;
 }
Пример #7
0
  public FormulaRecord(RecordInputStream ris) {
    super(ris);
    LittleEndianInput in = ris;
    long valueLongBits = in.readLong();
    field_5_options = in.readShort();
    specialCachedValue = SpecialCachedValue.create(valueLongBits);
    if (specialCachedValue == null) {
      field_4_value = Double.longBitsToDouble(valueLongBits);
    }

    field_6_zero = in.readInt();

    int field_7_expression_len =
        in.readShort(); // this length does not include any extra array data
    int nBytesAvailable = in.available();
    field_8_parsed_expr = Formula.read(field_7_expression_len, in, nBytesAvailable);
  }
Пример #8
0
 /**
  * When there are no array constants present, <tt>encodedTokenLen</tt>==<tt>totalEncodedLen</tt>
  *
  * @param encodedTokenLen number of bytes in the stream taken by the plain formula tokens
  * @param totalEncodedLen the total number of bytes in the formula (includes trailing encoding for
  *     array constants, but does not include 2 bytes for initial <tt>ushort encodedTokenLen</tt>
  *     field.
  * @return A new formula object as read from the stream. Possibly empty, never <code>null</code>.
  */
 public static Formula read(int encodedTokenLen, LittleEndianInput in, int totalEncodedLen) {
   byte[] byteEncoding = new byte[totalEncodedLen];
   in.readFully(byteEncoding);
   return new Formula(byteEncoding, encodedTokenLen);
 }
Пример #9
0
 public static BoolPtg read(LittleEndianInput in) {
   return valueOf(in.readByte() == 1);
 }
Пример #10
0
    protected ExtRst(LittleEndianInput in, int expectedLength) {
      reserved = in.readShort();

      // Old style detection (Reserved = 0xFF)
      if (reserved == -1) {
        populateEmpty();
        return;
      }

      // Spot corrupt records
      if (reserved != 1) {
        System.err.println(
            "Warning - ExtRst was has wrong magic marker, expecting 1 but found "
                + reserved
                + " - ignoring");
        // Grab all the remaining data, and ignore it
        for (int i = 0; i < expectedLength - 2; i++) {
          in.readByte();
        }
        // And make us be empty
        populateEmpty();
        return;
      }

      // Carry on reading in as normal
      short stringDataSize = in.readShort();

      formattingFontIndex = in.readShort();
      formattingOptions = in.readShort();

      // RPHSSub
      numberOfRuns = in.readUShort();
      short length1 = in.readShort();
      // No really. Someone clearly forgot to read
      //  the docs on their datastructure...
      short length2 = in.readShort();
      // And sometimes they write out garbage :(
      if (length1 == 0 && length2 > 0) {
        length2 = 0;
      }
      if (length1 != length2) {
        throw new IllegalStateException(
            "The two length fields of the Phonetic Text don't agree! "
                + length1
                + " vs "
                + length2);
      }
      phoneticText = StringUtil.readUnicodeLE(in, length1);

      int runData = stringDataSize - 4 - 6 - (2 * phoneticText.length());
      int numRuns = (runData / 6);
      phRuns = new PhRun[numRuns];
      for (int i = 0; i < phRuns.length; i++) {
        phRuns[i] = new PhRun(in);
      }

      int extraDataLength = runData - (numRuns * 6);
      if (extraDataLength < 0) {
        System.err.println("Warning - ExtRst overran by " + (0 - extraDataLength) + " bytes");
        extraDataLength = 0;
      }
      extraData = new byte[extraDataLength];
      for (int i = 0; i < extraData.length; i++) {
        extraData[i] = in.readByte();
      }
    }
Пример #11
0
 public MemAreaPtg(LittleEndianInput in) {
   field_1_reserved = in.readInt();
   field_2_subex_len = in.readShort();
 }
Пример #12
0
 public GUID(LittleEndianInput in) {
   this(in.readInt(), in.readUShort(), in.readUShort(), in.readLong());
 }
Пример #13
0
 protected final void readCoordinates(LittleEndianInput in) {
   field_1_first_row = in.readUShort();
   field_2_last_row = in.readUShort();
   field_3_first_column = in.readUShort();
   field_4_last_column = in.readUShort();
 }
Пример #14
0
 public FormatRun(LittleEndianInput in) {
   this(in.readShort(), in.readShort());
 }
Пример #15
0
 private PhRun(LittleEndianInput in) {
   phoneticTextFirstCharacterOffset = in.readUShort();
   realTextFirstCharacterOffset = in.readUShort();
   realTextLength = in.readUShort();
 }
  public EmbeddedObjectRefSubRecord(LittleEndianInput in, int size) {

    // Much guess-work going on here due to lack of any documentation.
    // See similar source code in OOO:
    // http://svn.services.openoffice.org/ooo/trunk/sc/source/filter/excel/xiescher.cxx
    // 1223 void XclImpOleObj::ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nRecSize )

    int streamIdOffset = in.readShort(); // OOO calls this 'nFmlaLen'
    int remaining = size - LittleEndian.SHORT_SIZE;

    int dataLenAfterFormula = remaining - streamIdOffset;
    int formulaSize = in.readUShort();
    remaining -= LittleEndian.SHORT_SIZE;
    field_1_unknown_int = in.readInt();
    remaining -= LittleEndian.INT_SIZE;
    byte[] formulaRawBytes = readRawData(in, formulaSize);
    remaining -= formulaSize;
    field_2_refPtg = readRefPtg(formulaRawBytes);
    if (field_2_refPtg == null) {
      // common case
      // field_2_n16 seems to be 5 here
      // The formula almost looks like tTbl but the row/column values seem like garbage.
      field_2_unknownFormulaData = formulaRawBytes;
    } else {
      field_2_unknownFormulaData = null;
    }

    int stringByteCount;
    if (remaining >= dataLenAfterFormula + 3) {
      int tag = in.readByte();
      stringByteCount = LittleEndian.BYTE_SIZE;
      if (tag != 0x03) {
        throw new RecordFormatException("Expected byte 0x03 here");
      }
      int nChars = in.readUShort();
      stringByteCount += LittleEndian.SHORT_SIZE;
      if (nChars > 0) {
        // OOO: the 4th way Xcl stores a unicode string: not even a Grbit byte present if length 0
        field_3_unicode_flag = (in.readByte() & 0x01) != 0;
        stringByteCount += LittleEndian.BYTE_SIZE;
        if (field_3_unicode_flag) {
          field_4_ole_classname = StringUtil.readUnicodeLE(in, nChars);
          stringByteCount += nChars * 2;
        } else {
          field_4_ole_classname = StringUtil.readCompressedUnicode(in, nChars);
          stringByteCount += nChars;
        }
      } else {
        field_4_ole_classname = "";
      }
    } else {
      field_4_ole_classname = null;
      stringByteCount = 0;
    }
    remaining -= stringByteCount;
    // Pad to next 2-byte boundary
    if (((stringByteCount + formulaSize) % 2) != 0) {
      int b = in.readByte();
      remaining -= LittleEndian.BYTE_SIZE;
      if (field_2_refPtg != null && field_4_ole_classname == null) {
        field_4_unknownByte = Byte.valueOf((byte) b);
      }
    }
    int nUnexpectedPadding = remaining - dataLenAfterFormula;

    if (nUnexpectedPadding > 0) {
      logger.log(
          POILogger.ERROR, "Discarding " + nUnexpectedPadding + " unexpected padding bytes ");
      readRawData(in, nUnexpectedPadding);
      remaining -= nUnexpectedPadding;
    }

    // Fetch the stream ID
    if (dataLenAfterFormula >= 4) {
      field_5_stream_id = Integer.valueOf(in.readInt());
      remaining -= LittleEndian.INT_SIZE;
    } else {
      field_5_stream_id = null;
    }
    field_6_unknown = readRawData(in, remaining);
  }
 public GroupMarkerSubRecord(LittleEndianInput in, int size) {
   byte[] buf = new byte[size];
   in.readFully(buf);
   reserved = buf;
 }
Пример #18
0
 public NumberPtg(LittleEndianInput in) {
   this(in.readDouble());
 }
Пример #19
0
 /** Creates new DeletedRef3DPtg */
 public DeletedRef3DPtg(LittleEndianInput in) {
   field_1_index_extern_sheet = in.readUShort();
   unused1 = in.readInt();
 }