Beispiel #1
0
 private static RecordInputStream ConvertToInputStream(DrawingRecord r)
 {
     byte[] data = r.Serialize();
     using (MemoryStream ms = new MemoryStream(data))
     {
         RecordInputStream rinp = new RecordInputStream(ms);
         rinp.NextRecord();
         return(rinp);
     }
 }
Beispiel #2
0
        public override Object Clone()
        {
            DrawingRecord rec = new DrawingRecord();

            rec.recordData = (byte[])recordData.Clone();// new byte[recordData.Length];
            if (contd != null)
            {
                rec.contd = (byte[])contd.Clone();
            }

            return(rec);
        }
Beispiel #3
0
        /**
         * @return the next available record, or <code>null</code> if
         * this pass didn't return a record that's
         * suitable for returning (eg was a continue record).
         */
        private Record ReadNextRecord()
        {
            Record record = RecordFactory.CreateSingleRecord(_recStream);

            _lastRecordWasEOFLevelZero = false;

            if (record is BOFRecord)
            {
                _bofDepth++;
                return(record);
            }

            if (record is EOFRecord)
            {
                _bofDepth--;
                if (_bofDepth < 1)
                {
                    _lastRecordWasEOFLevelZero = true;
                }

                return(record);
            }

            if (record is DBCellRecord)
            {
                // Not needed by POI.  Regenerated from scratch by POI when spreadsheet is written
                return(null);
            }

            if (record is RKRecord)
            {
                return(RecordFactory.ConvertToNumberRecord((RKRecord)record));
            }

            if (record is MulRKRecord)
            {
                Record[] records = RecordFactory.ConvertRKRecords((MulRKRecord)record);

                _unreadRecordBuffer = records;
                _unreadRecordIndex  = 1;
                return(records[0]);
            }

            if (record.Sid == DrawingGroupRecord.sid &&
                _lastRecord is DrawingGroupRecord)
            {
                DrawingGroupRecord lastDGRecord = (DrawingGroupRecord)_lastRecord;
                lastDGRecord.Join((AbstractEscherHolderRecord)record);
                return(null);
            }
            if (record.Sid == ContinueRecord.sid)
            {
                ContinueRecord contRec = (ContinueRecord)record;

                if (_lastRecord is ObjRecord || _lastRecord is TextObjectRecord)
                {
                    // Drawing records have a very strange continue behaviour.
                    //There can actually be OBJ records mixed between the continues.
                    _lastDrawingRecord.ProcessContinueRecord(contRec.Data);
                    //we must remember the position of the continue record.
                    //in the serialization procedure the original structure of records must be preserved
                    if (_shouldIncludeContinueRecords)
                    {
                        return(record);
                    }
                    return(null);
                }
                if (_lastRecord is DrawingGroupRecord)
                {
                    ((DrawingGroupRecord)_lastRecord).ProcessContinueRecord(contRec.Data);
                    return(null);
                }
                if (_lastRecord is DrawingRecord)
                {
                    ((DrawingRecord)_lastRecord).ProcessContinueRecord(contRec.Data);
                    return(null);
                }
                if (_lastRecord is UnknownRecord)
                {
                    //Gracefully handle records that we don't know about,
                    //that happen to be continued
                    return(record);
                }
                if (_lastRecord is EOFRecord)
                {
                    // This is really odd, but excel still sometimes
                    //  outPuts a file like this all the same
                    return(record);
                }
                //if (_lastRecord is StringRecord)
                //{
                //    ((StringRecord)_lastRecord).ProcessContinueRecord(contRec.Data);
                //    return null;
                //}
                throw new RecordFormatException("Unhandled Continue Record");
            }
            _lastRecord = record;
            if (record is DrawingRecord)
            {
                _lastDrawingRecord = (DrawingRecord)record;
            }
            return(record);
        }
Beispiel #4
0
 public DrawingRecordForBiffViewer(DrawingRecord r)
     : base(ConvertToInputStream(r))
 {
     ConvertRawBytesToEscherRecords();
 }
Beispiel #5
0
        /**
         * Serializes this aggregate to a byte array.  Since this Is an aggregate
         * record it will effectively Serialize the aggregated records.
         *
         * @param offset    The offset into the start of the array.
         * @param data      The byte array to Serialize to.
         * @return          The number of bytes Serialized.
         */
        public override int Serialize(int offset, byte [] data)
        {
            ConvertUserModelToRecords();

            // Determine buffer size
            IList records = EscherRecords;
            int   size    = GetEscherRecordSize(records);

            byte[] buffer = new byte[size];


            // Serialize escher records into one big data structure and keep note of ending offsets.
            spEndingOffsets = new ArrayList();
            shapes          = new ArrayList();
            int pos = 0;

            for (IEnumerator iterator = records.GetEnumerator(); iterator.MoveNext();)
            {
                EscherRecord e = (EscherRecord)iterator.Current;
                pos += e.Serialize(pos, buffer, new SerializationListener(ref spEndingOffsets, ref shapes));
            }
            // todo: fix this
            shapes.Insert(0, null);
            spEndingOffsets.Insert(0, null);

            // Split escher records into Separate MSODRAWING and OBJ, TXO records.  (We don't break on
            // the first one because it's the patriach).
            pos = offset;
            for (int i = 1; i < shapes.Count; i++)
            {
                int endOffset = (int)spEndingOffsets[i] - 1;
                int startOffset;
                if (i == 1)
                {
                    startOffset = 0;
                }
                else
                {
                    startOffset = (int)spEndingOffsets[i - 1];
                }

                // Create and Write a new MSODRAWING record
                DrawingRecord drawing     = new DrawingRecord();
                byte[]        drawingData = new byte[endOffset - startOffset + 1];
                Array.Copy(buffer, startOffset, drawingData, 0, drawingData.Length);
                drawing.Data = drawingData;
                int temp = drawing.Serialize(pos, data);
                pos += temp;

                // Write the matching OBJ record
                Record obj = (Record)shapeToObj[shapes[i]];
                temp = obj.Serialize(pos, data);
                pos += temp;
            }

            // Write records that need to be Serialized after all drawing Group records
            for (int i = 0; i < tailRec.Count; i++)
            {
                Record rec = (Record)tailRec[i];
                pos += rec.Serialize(pos, data);
            }

            int bytesWritten = pos - offset;

            if (bytesWritten != RecordSize)
            {
                throw new RecordFormatException(bytesWritten + " bytes written but RecordSize reports " + RecordSize);
            }
            return(bytesWritten);
        }
Beispiel #6
0
        /**
         * Collapses the drawing records into an aggregate.
         */
        public static EscherAggregate CreateAggregate(IList records, int locFirstDrawingRecord, DrawingManager2 drawingManager)
        {
            // Keep track of any shape records Created so we can match them back to the object id's.
            // Textbox objects are also treated as shape objects.
            IList shapeRecords = new ArrayList();
            EscherRecordFactory recordFactory = new CustomEscherRecordFactory(ref shapeRecords);

            // Calculate the size of the buffer
            EscherAggregate agg      = new EscherAggregate(drawingManager);
            int             loc      = locFirstDrawingRecord;
            int             dataSize = 0;

            while (loc + 1 < records.Count &&
                   GetSid(records, loc) == DrawingRecord.sid &&
                   IsObjectRecord(records, loc + 1))
            {
                dataSize += ((DrawingRecord)records[loc]).Data.Length;
                loc      += 2;
            }

            // Create one big buffer
            byte[] buffer = new byte[dataSize];
            int    offset = 0;

            loc = locFirstDrawingRecord;
            while (loc + 1 < records.Count &&
                   GetSid(records, loc) == DrawingRecord.sid &&
                   IsObjectRecord(records, loc + 1))
            {
                DrawingRecord drawingRecord = (DrawingRecord)records[loc];
                Array.Copy(drawingRecord.Data, 0, buffer, offset, drawingRecord.Data.Length);
                offset += drawingRecord.Data.Length;
                loc    += 2;
            }

            // Decode the shapes
            //        agg.escherRecords = new ArrayList();
            int pos = 0;

            while (pos < dataSize)
            {
                EscherRecord r         = recordFactory.CreateRecord(buffer, pos);
                int          bytesRead = r.FillFields(buffer, pos, recordFactory);
                agg.AddEscherRecord(r);
                pos += bytesRead;
            }

            // Associate the object records with the shapes
            loc = locFirstDrawingRecord;
            int shapeIndex = 0;

            agg.shapeToObj = new Hashtable();
            while (loc + 1 < records.Count &&
                   GetSid(records, loc) == DrawingRecord.sid &&
                   IsObjectRecord(records, loc + 1))
            {
                Record objRecord = (Record)records[loc + 1];
                agg.shapeToObj[shapeRecords[shapeIndex++]] = objRecord;
                loc += 2;
            }

            return(agg);
        }