Monday, December 13, 2010

How to read memo block from FPT file.

Recently, I came across a situation where I need to extract the memo field data from an FPT file. After lot of googling I found this documentation which describes the FPT structure and then I decided to write my own code to parse the FPT file and extract the data stored in it.
A memo file (FPT) file contains one header and any number of block structures. The header part is 512 bytes long but the useful information is stored in 7th and 8th byte which is the size of the block structure.
 Following the header is the first memo block. A memo block consists of a memo block header and memo text. Memo block is 8 bytes long and stores the type of memo data and the length of the memo data.

A memo block can span over multiple blocks structures but a single block can’t have data of more than one memo block. It means if block is larger than the memo size then remaining block will be unused.
Here is the code to extract memo data.
public class MemoBlock
    {
        public MemoDataType MemoDataType { get; private set; }
        public Byte[] Memo { get; private set; }

        public MemoBlock(MemoDataType type, Byte[] data)
        {
            this.MemoDataType = type;
            this.Memo = data;
        }
    }

    public enum MemoDataType
    {
        Picture = 0
        , Text = 1
    }

    public class MemoCollection : IEnumerable<MemoBlock>
    {
        private System.IO.Stream Stream = null;
        private int blockSize = 0;

        public MemoCollection(System.IO.Stream memoStream)
        {
            this.Stream = memoStream;
        }

        #region IEnumerable<MemoBlock> Members

        public IEnumerator<MemoBlock> GetEnumerator()
        {
            return GetCollection();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        private IEnumerator<MemoBlock> GetCollection()
        {
            Stream.Seek(0, SeekOrigin.Begin);
            GetBlockSize();
            while (Stream.Position < Stream.Length)
            {
                var memo = ReadMemo();
                PositionToNextBlock();               
                yield return memo;
            }
        }

        private void PositionToNextBlock()
        {
            int unusedbytecount = (int)(Stream.Position % blockSize);
            if (unusedbytecount > 0)
                Stream.Seek(blockSize - unusedbytecount, SeekOrigin.Current);
        }

        private MemoBlock ReadMemo()
        {
            Byte[] header = new Byte[8];
            Stream.Read(header, 0, header.Length);
            MemoDataType type = (MemoDataType)ToInteger(header.Take(4).ToArray());
            int memoSize = ToInteger(header.Skip(4).Take(4).ToArray());
            Byte[] memoData = new Byte[memoSize];
            Stream.Read(memoData, 0, memoData.Length);
            return new MemoBlock(type, memoData);
            
        }

        private void GetBlockSize()
        {
            Byte[] buffer = new Byte[512];
            Stream.Read(buffer, 0, buffer.Length);
            blockSize = ToInteger(new Byte[] { 0,0,buffer[6],buffer[7]});

        }

        private int ToInteger(byte[] data)
        {
            if (BitConverter.IsLittleEndian)
                Array.Reverse(data);
            return BitConverter.ToInt32(data,0);
        }

        #endregion
    }

1 comment:


  1. شركة كشف تسربات المياه و
    شركة نظافه بالدمام
    و شركة عزل حراري بالدمام
    شركة وادي الرمال 0543578920
    كما نحرص ونهتم بالحفاظ على المبنى أو المنشأة
    شركة عزل التسربات بالدمام
    متخصصة لأعمال تسربات
    لجميع خدمات وادي الرمال
    شركة عزل مائي بالدمام و
    شركة عزل بالدمام
    www.wadielremal.com

    ReplyDelete