Beispiel #1
0
            /// <summary> Constructs a property set
            ///
            /// </summary>
            /// <param name="d">the bytes
            /// </param>
            public PropertyStorage(BaseCompoundFile enclosingInstance, sbyte[] d)
            {
                InitBlock(enclosingInstance);
                data = d;
                int nameSize = IntegerHelper.getInt(data[NExcel.Biff.BaseCompoundFile.SIZE_OF_NAME_POS], data[NExcel.Biff.BaseCompoundFile.SIZE_OF_NAME_POS + 1]);

                type = data[NExcel.Biff.BaseCompoundFile.TYPE_POS];

                startBlock = IntegerHelper.getInt(data[NExcel.Biff.BaseCompoundFile.START_BLOCK_POS], data[NExcel.Biff.BaseCompoundFile.START_BLOCK_POS + 1], data[NExcel.Biff.BaseCompoundFile.START_BLOCK_POS + 2], data[NExcel.Biff.BaseCompoundFile.START_BLOCK_POS + 3]);
                size       = IntegerHelper.getInt(data[NExcel.Biff.BaseCompoundFile.SIZE_POS], data[NExcel.Biff.BaseCompoundFile.SIZE_POS + 1], data[NExcel.Biff.BaseCompoundFile.SIZE_POS + 2], data[NExcel.Biff.BaseCompoundFile.SIZE_POS + 3]);

                int chars = 0;

                if (nameSize > 2)
                {
                    chars = (nameSize - 1) / 2;
                }

                System.Text.StringBuilder n = new System.Text.StringBuilder("");
                for (int i = 0; i < chars; i++)
                {
                    n.Append((char)data[i * 2]);
                }

                name = n.ToString();
            }
Beispiel #2
0
        /// <summary> Accessor for the binary data - used when copying
        ///
        /// </summary>
        /// <returns> the binary data
        /// </returns>
        public override sbyte[] getData()
        {
            // Palette was read in, but has not been changed
            if (read && !dirty)
            {
                return(getRecord().Data);
            }

            sbyte[] data = new sbyte[numColours * 4 + 2];
            int     pos  = 0;

            // Set the number of records
            IntegerHelper.getTwoBytes(numColours, data, pos);

            // Set the rgb content
            for (int i = 0; i < numColours; i++)
            {
                pos           = i * 4 + 2;
                data[pos]     = (sbyte)rgbColours[i].red;
                data[pos + 1] = (sbyte)rgbColours[i].green;
                data[pos + 2] = (sbyte)rgbColours[i].blue;
            }

            return(data);
        }
Beispiel #3
0
        /// <summary> Used when writing out records.  This portion of the method handles the
        /// biff code and the .Length of the record and appends on the data retrieved
        /// from the subclasses
        ///
        /// </summary>
        /// <returns> the full record data to be written out to the compound file
        /// </returns>
        public sbyte[] getBytes()
        {
            sbyte[] data = getData();

            int dataLength = data.Length;

            // Don't the call the automatic continuation code for now
            //    Assert.verify(dataLength <= maxRecordLength - 4);
            // If the bytes .Length is greater than the max record .Length
            // then split out the data set into continue records
            if (data.Length > maxRecordLength - 4)
            {
                dataLength = maxRecordLength - 4;
                data       = handleContinueRecords(data);
            }

            sbyte[] bytes = new sbyte[data.Length + 4];

            Array.Copy(data, 0, bytes, 4, data.Length);

            IntegerHelper.getTwoBytes(Code, bytes, 0);
            IntegerHelper.getTwoBytes(dataLength, bytes, 2);

            return(bytes);
        }
Beispiel #4
0
        /// <summary> Constructs this object from the raw data.  Used when reading in a
        /// format record
        ///
        /// </summary>
        /// <param name="t">the raw data
        /// </param>
        /// <param name="ws">the workbook settings
        /// </param>
        /// <param name="dummy">dummy overload
        /// </param>
        public FontRecord(Record t, WorkbookSettings ws, Biff7 dummy) : base(t)
        {
            sbyte[] data = getRecord().Data;

            pointHeight    = IntegerHelper.getInt(data[0], data[1]) / EXCEL_UNITS_PER_POINT;
            colourIndex    = IntegerHelper.getInt(data[4], data[5]);
            boldWeight     = IntegerHelper.getInt(data[6], data[7]);
            scriptStyle    = IntegerHelper.getInt(data[8], data[9]);
            underlineStyle = data[10];
            fontFamily     = data[11];
            initialized    = false;

            if ((data[2] & 0x02) != 0)
            {
                italic = true;
            }

            if ((data[2] & 0x08) != 0)
            {
                struckout = true;
            }

            int numChars = data[14];

            name = StringHelper.getString(data, numChars, 15, ws);
        }
Beispiel #5
0
        /// <summary> Gets the binary data for output to file
        ///
        /// </summary>
        /// <returns> the binary data
        /// </returns>
        public override sbyte[] getData()
        {
            sbyte[] data = new sbyte[2];

            // Hard code in the information for now
            IntegerHelper.getTwoBytes(wsoptions, data, 0);

            return(data);
        }
Beispiel #6
0
        /// <summary> Constructs this object from the raw data
        ///
        /// </summary>
        /// <param name="t">the raw data
        /// </param>
        /// <param name="bt">the biff type
        /// </param>
        public XFRecord(Record t, BiffType bt) : base(t)
        {
            biffType = bt;

            sbyte[] data = getRecord().Data;

            fontIndex   = IntegerHelper.getInt(data[0], data[1]);
            formatIndex = IntegerHelper.getInt(data[2], data[3]);
            date        = false;
            number      = false;

            // Compare against the date formats
            for (int i = 0; i < dateFormats.Length; i++)
            {
                if (formatIndex == dateFormats[i])
                {
                    date       = true;
                    dateFormat = langDateFormats[i];
                }
            }

            // Compare against the number formats
            for (int i = 0; i < numberFormats.Length; i++)
            {
                if (formatIndex == numberFormats[i])
                {
                    number       = true;
                    numberFormat = langNumberFormats[i];
                }
            }

            // Initialize the parent format and the type
            int cellAttributes = IntegerHelper.getInt(data[4], data[5]);

            parentFormat = (cellAttributes & 0xfff0) >> 4;

            int formatType = cellAttributes & 0x4;

            xfFormatType = formatType == 0?cell:style;
            locked       = ((cellAttributes & 0x1) != 0);
            hidden       = ((cellAttributes & 0x2) != 0);

            if (xfFormatType == cell && (parentFormat & 0xfff) == 0xfff)
            {
                // Something is screwy with the parent format - set to zero
                parentFormat = 0;
                logger.warn("Invalid parent format found - ignoring");
            }

            initialized           = false;
            read                  = true;
            formatInfoInitialized = false;
            copied                = false;
        }
Beispiel #7
0
        /// <summary> Used to get the data when writing out the format record
        ///
        /// </summary>
        /// <returns> the raw data
        /// </returns>
        public override sbyte[] getData()
        {
            data = new sbyte[formatString.Length * 2 + 3 + 2];

            IntegerHelper.getTwoBytes(indexCode, data, 0);
            IntegerHelper.getTwoBytes(formatString.Length, data, 2);
            data[4] = (sbyte)1;              // unicode indicator
            StringHelper.getUnicodeBytes(formatString, data, 5);

            return(data);
        }
Beispiel #8
0
        /// <summary> Constructs this object from the raw data.  Used when reading in a
        /// format record
        ///
        /// </summary>
        /// <param name="t">the raw data
        /// </param>
        /// <param name="ws">the workbook settings
        /// </param>
        /// <param name="biffType">biff type dummy overload
        /// </param>
        public FormatRecord(Record t, WorkbookSettings ws, BiffType biffType) : base(t)
        {
            sbyte[] data = getRecord().Data;
            indexCode   = IntegerHelper.getInt(data[0], data[1]);
            initialized = true;

            if (biffType == biff8)
            {
                int numchars = IntegerHelper.getInt(data[2], data[3]);
                if (data[4] == 0)
                {
                    formatString = StringHelper.getString(data, numchars, 5, ws);
                }
                else
                {
                    formatString = StringHelper.getUnicodeString(data, numchars, 5);
                }
            }
            else
            {
                int     numchars = data[2];
                sbyte[] chars    = new sbyte[numchars];
                Array.Copy(data, 3, chars, 0, chars.Length);
                formatString = new string(NExcelUtils.Byte.ToCharArray(NExcelUtils.Byte.ToByteArray(chars)));
            }

            date   = false;
            number = false;

            // First see if this is a date format
            for (int i = 0; i < dateStrings.Length; i++)
            {
                string dateString = dateStrings[i];
                if (formatString.IndexOf(dateString) != -1 || formatString.IndexOf(dateString.ToUpper()) != -1)
                {
                    date = true;
                    break;
                }
            }

            // See if this is number format - look for the # or 0 characters
            if (!date)
            {
                if (formatString.IndexOf((System.Char) '#') != -1 || formatString.IndexOf((System.Char) '0') != -1)
                {
                    number = true;
                }
            }
        }
Beispiel #9
0
        /// <summary> Gets the byte data for writing out
        ///
        /// </summary>
        /// <returns> the raw data
        /// </returns>
        public override sbyte[] getData()
        {
            sbyte[] data = new sbyte[16 + name.Length * 2];

            // Excel expects font heights in 1/20ths of a point
            IntegerHelper.getTwoBytes(pointHeight * EXCEL_UNITS_PER_POINT, data, 0);

            // Set the font attributes to be zero for now
            if (italic)
            {
                data[2] |= 0x2;
            }

            if (struckout)
            {
                data[2] |= 0x08;
            }

            // Set the index to the colour palette
            IntegerHelper.getTwoBytes(colourIndex, data, 4);

            // Bold style
            IntegerHelper.getTwoBytes(boldWeight, data, 6);

            // Script style
            IntegerHelper.getTwoBytes(scriptStyle, data, 8);

            // Underline style
            data[10] = (sbyte)underlineStyle;

            // Set the font family to be 0
            data[11] = fontFamily;

            // Set the character set to be zero
            data[12] = characterSet;

            // Set the reserved bit to be zero
            data[13] = 0;

            // Set the .Length of the font name
            data[14] = (sbyte)name.Length;

            data[15] = (sbyte)1;

            // Copy in the string
            StringHelper.getUnicodeBytes(name, data, 16);

            return(data);
        }
Beispiel #10
0
            /// <summary> Constructs an empty property set.  Used when writing the file
            ///
            /// </summary>
            /// <param name="name">the property storage name
            /// </param>
            public PropertyStorage(BaseCompoundFile enclosingInstance, string name)
            {
                InitBlock(enclosingInstance);
                data = new sbyte[NExcel.Biff.BaseCompoundFile.PROPERTY_STORAGE_BLOCK_SIZE];

                Assert.verify(name.Length < 32);

                IntegerHelper.getTwoBytes((name.Length + 1) * 2, data, NExcel.Biff.BaseCompoundFile.SIZE_OF_NAME_POS);
                // add one to the name .Length to allow for the null character at
                // the end
                for (int i = 0; i < name.Length; i++)
                {
                    data[i * 2] = (sbyte)name[i];
                }
            }
Beispiel #11
0
        /// <summary> Abstract method implementation to get the raw byte data ready to write out
        ///
        /// </summary>
        /// <returns> The byte data
        /// </returns>
        public override sbyte[] getData()
        {
            sbyte[] data = new sbyte[4];

            IntegerHelper.getTwoBytes(xfIndex, data, 0);

            // Set the built in bit
            data[1] |= (sbyte)-0x80;

            data[2] = (sbyte)styleNumber;

            // Set the outline level
            data[3] = (sbyte)-0x01;

            return(data);
        }
Beispiel #12
0
        /// <summary> Initialize the record data</summary>
        private void  initialize()
        {
            sbyte[] data = getRecord().Data;

            int numrecords = IntegerHelper.getInt(data[0], data[1]);

            for (int i = 0; i < numrecords; i++)
            {
                int pos   = i * 4 + 2;
                int red   = IntegerHelper.getInt(data[pos], (sbyte)0);
                int green = IntegerHelper.getInt(data[pos + 1], (sbyte)0);
                int blue  = IntegerHelper.getInt(data[pos + 2], (sbyte)0);
                rgbColours[i] = new RGB(red, green, blue);
            }

            initialized = true;
        }
Beispiel #13
0
        /// <summary> Gets the IEEE value from the byte array passed in
        ///
        /// </summary>
        /// <param name="pos">the position in the data block which contains the double value
        /// </param>
        /// <param name="data">the data block containing the raw bytes
        /// </param>
        /// <returns> the double value converted from the raw data
        /// </returns>
        public static double getIEEEDouble(sbyte[] data, int pos)
        {
            int num1 = IntegerHelper.getInt(data[pos], data[pos + 1], data[pos + 2], data[pos + 3]);
            int num2 = IntegerHelper.getInt(data[pos + 4], data[pos + 5], data[pos + 6], data[pos + 7]);

            // Long.parseLong doesn't like the sign bit, so have to extract this
            // information and put it in at the end.  (Acknowledgment:  thanks
            // to Ruben for pointing this out)
            bool negative = ((((long)num2) & 0x80000000) != 0);

            // Thanks to Lyle for the following improved IEEE double processing
            long   val   = ((num2 & 0x7fffffff) * 0x100000000L) + (num1 < 0?0x100000000L + num1:num1);
            double Value = BitConverter.Int64BitsToDouble(val);

            if (negative)
            {
                Value = -Value;
            }
            return(Value);
        }
Beispiel #14
0
        /// <summary> Constructs this object from the raw data.  Used when reading in a
        /// format record
        ///
        /// </summary>
        /// <param name="t">the raw data
        /// </param>
        /// <param name="ws">the workbook settings
        /// </param>
        public FontRecord(Record t, WorkbookSettings ws) : base(t)
        {
            sbyte[] data = getRecord().Data;

            pointHeight    = IntegerHelper.getInt(data[0], data[1]) / EXCEL_UNITS_PER_POINT;
            colourIndex    = IntegerHelper.getInt(data[4], data[5]);
            boldWeight     = IntegerHelper.getInt(data[6], data[7]);
            scriptStyle    = IntegerHelper.getInt(data[8], data[9]);
            underlineStyle = data[10];
            fontFamily     = data[11];
            characterSet   = data[12];
            initialized    = false;

            if ((data[2] & 0x02) != 0)
            {
                italic = true;
            }

            if ((data[2] & 0x08) != 0)
            {
                struckout = true;
            }

            int numChars = data[14];

            if (data[15] == 0)
            {
                name = StringHelper.getString(data, numChars, 16, ws);
            }
            else if (data[15] == 1)
            {
                name = StringHelper.getUnicodeString(data, numChars, 16);
            }
            else
            {
                // Some font names don't have the unicode indicator
                name = StringHelper.getString(data, numChars, 15, ws);
            }
        }
Beispiel #15
0
        /// <summary> The number of bytes for this record exceeds the maximum record
        /// .Length, so a continue is required
        /// </summary>
        /// <param name="data">the raw data
        /// </param>
        /// <returns>  the continued data
        /// </returns>
        private sbyte[] handleContinueRecords(sbyte[] data)
        {
            // Deduce the number of continue records
            int continuedData      = data.Length - maxRecordLength - 4;
            int numContinueRecords = continuedData / (maxRecordLength - 4) + 1;

            // Create the new byte array, allowing for the continue records
            // code and .Length
            sbyte[] newdata = new sbyte[data.Length + numContinueRecords * 4];

            // Copy the bona fide record data into the beginning of the super
            // record
            Array.Copy(data, 0, newdata, 0, maxRecordLength - 4);
            int oldarraypos = maxRecordLength - 4;
            int newarraypos = maxRecordLength - 4;

            // Now handle all the continue records
            for (int i = 0; i < numContinueRecords; i++)
            {
                // The number of bytes to add into the new array
                int length = System.Math.Min(data.Length - oldarraypos, maxRecordLength - 4);

                // Add in the continue record code
                IntegerHelper.getTwoBytes(NExcel.Biff.Type.CONTINUE.Value, newdata, newarraypos);
                IntegerHelper.getTwoBytes(length, newdata, newarraypos + 2);

                // Copy in as much as the new data as possible
                Array.Copy(data, oldarraypos, newdata, newarraypos + 4, length);

                // Update the position counters
                oldarraypos += length;
                newarraypos += length + 4;
            }

            return(newdata);
        }
Beispiel #16
0
        /// <summary> Constructs this object from the raw data
        ///
        /// </summary>
        /// <param name="t">the raw data
        /// </param>
        public WorkspaceInformationRecord(Record t) : base(t)
        {
            sbyte[] data = getRecord().Data;

            wsoptions = IntegerHelper.getInt(data[0], data[1]);
        }
Beispiel #17
0
        /// <summary> Converts the various fields into binary data.  If this object has
        /// been read from an Excel file rather than being requested by a user (ie.
        /// if the read flag is TRUE) then
        /// no processing takes place and the raw data is simply returned.
        ///
        /// </summary>
        /// <returns> the raw data for writing
        /// </returns>
        public override sbyte[] getData()
        {
            // Format rationalization process means that we always want to
            // regenerate the format info - even if the spreadsheet was
            // read in
            if (!formatInfoInitialized)
            {
                initializeFormatInformation();
            }

            sbyte[] data = new sbyte[20];

            IntegerHelper.getTwoBytes(fontIndex, data, 0);
            IntegerHelper.getTwoBytes(formatIndex, data, 2);

            // Do the cell attributes
            int cellAttributes = 0;

            if (this.Locked)
            {
                cellAttributes |= 0x01;
            }

            if (Hidden)
            {
                cellAttributes |= 0x02;
            }

            if (xfFormatType == style)
            {
                cellAttributes |= 0x04;
                parentFormat    = 0xffff;
            }

            cellAttributes |= (parentFormat << 4);

            IntegerHelper.getTwoBytes(cellAttributes, data, 4);

            int alignMask = align.Value;

            if (wrap)
            {
                alignMask |= 0x08;
            }

            alignMask |= (valign.Value << 4);

            alignMask |= (orientation.Value << 8);

            IntegerHelper.getTwoBytes(alignMask, data, 6);

            // Set the borders
            int borderMask = leftBorder.Value;

            borderMask |= (rightBorder.Value << 4);
            borderMask |= (topBorder.Value << 8);
            borderMask |= (bottomBorder.Value << 12);

            IntegerHelper.getTwoBytes(borderMask, data, 10);

            // Set the border palette information if border mask is non zero
            // Hard code the colours to be black
            if (borderMask != 0)
            {
                sbyte lc = (sbyte)leftBorderColour.Value;
                sbyte rc = (sbyte)rightBorderColour.Value;
                sbyte tc = (sbyte)topBorderColour.Value;
                sbyte bc = (sbyte)bottomBorderColour.Value;

                data[12] = (sbyte)((lc & 0x7f) | ((rc & 0x01) << 7));
                data[13] = (sbyte)((rc & 0x7f) >> 1);
                data[14] = (sbyte)((tc & 0x7f) | ((bc & 0x01) << 7));
                data[15] = (sbyte)((bc & 0x7f) >> 1);
            }

            // Set the background pattern
            IntegerHelper.getTwoBytes(pattern.Value, data, 16);

            // Set the colour palette
            int colourPaletteMask = backgroundColour.Value;

            colourPaletteMask |= (0x40 << 7);
            IntegerHelper.getTwoBytes(colourPaletteMask, data, 18);

            // Set the cell options
            if (shrinkToFit)
            {
                options |= 0x10;
            }
            else
            {
                options &= 0xffef;
            }

            IntegerHelper.getTwoBytes(options, data, 8);

            return(data);
        }
Beispiel #18
0
        /// <summary> Initializes the internal format information from the data read in</summary>
        private void  initializeFormatInformation()
        {
            // Initialize the cell format string
            if (formatIndex < BuiltInFormat.builtIns.Length && BuiltInFormat.builtIns[formatIndex] != null)
            {
                excelFormat = BuiltInFormat.builtIns[formatIndex];
            }
            else
            {
                excelFormat = formattingRecords.getFormatRecord(formatIndex);
            }

            // Initialize the font
            font = formattingRecords.Fonts.getFont(fontIndex);

            // Initialize the cell format data from the binary record
            sbyte[] data = getRecord().Data;

            // Get the parent record
            int cellAttributes = IntegerHelper.getInt(data[4], data[5]);

            parentFormat = (cellAttributes & 0xfff0) >> 4;
            int formatType = cellAttributes & 0x4;

            xfFormatType = formatType == 0?cell:style;
            locked       = ((cellAttributes & 0x1) != 0);
            hidden       = ((cellAttributes & 0x2) != 0);

            if (xfFormatType == cell && (parentFormat & 0xfff) == 0xfff)
            {
                // Something is screwy with the parent format - set to zero
                parentFormat = 0;
                logger.warn("Invalid parent format found - ignoring");
            }


            int alignMask = IntegerHelper.getInt(data[6], data[7]);

            // Get the wrap
            if ((alignMask & 0x08) != 0)
            {
                wrap = true;
            }

            // Get the horizontal alignment
            align = Alignment.getAlignment(alignMask & 0x7);

            // Get the vertical alignment
            valign = VerticalAlignment.getAlignment((alignMask >> 4) & 0x7);

            // Get the orientation
            orientation = Orientation.getOrientation((alignMask >> 8) & 0xff);

            int attr = IntegerHelper.getInt(data[8], data[9]);

            // Get the shrink to fit flag
            shrinkToFit = (attr & 0x10) != 0;

            // Get the used attribute
            if (biffType == biff8)
            {
                usedAttributes = data[9];
            }

            // Get the borders
            int borderMask = IntegerHelper.getInt(data[10], data[11]);

            leftBorder   = BorderLineStyle.getStyle(borderMask & 0x7);
            rightBorder  = BorderLineStyle.getStyle((borderMask >> 4) & 0x7);
            topBorder    = BorderLineStyle.getStyle((borderMask >> 8) & 0x7);
            bottomBorder = BorderLineStyle.getStyle((borderMask >> 12) & 0x7);

            int borderColourMask = IntegerHelper.getInt(data[12], data[13]);

            leftBorderColour  = Colour.getInternalColour(borderColourMask & 0x7f);
            rightBorderColour = Colour.getInternalColour((borderColourMask & 0x3f80) >> 7);

            borderColourMask   = IntegerHelper.getInt(data[14], data[15]);
            topBorderColour    = Colour.getInternalColour(borderColourMask & 0x7f);
            bottomBorderColour = Colour.getInternalColour((borderColourMask & 0x3f80) >> 7);

            if (biffType == biff8)
            {
                // Get the background pattern
                int patternVal = IntegerHelper.getInt(data[16], data[17]);
                pattern = Pattern.getPattern(patternVal);

                // Get the background colour
                int colourPaletteMask = IntegerHelper.getInt(data[18], data[19]);
                backgroundColour = Colour.getInternalColour(colourPaletteMask & 0x3f);


                if (backgroundColour == Colour.UNKNOWN || backgroundColour == Colour.DEFAULT_BACKGROUND1)
                {
                    backgroundColour = Colour.DEFAULT_BACKGROUND;
                }
            }
            else
            {
                pattern          = Pattern.NONE;
                backgroundColour = Colour.DEFAULT_BACKGROUND;
            }

            // Set the lazy initialization flag
            formatInfoInitialized = true;
        }