Пример #1
0
 public MobiFile(PalmFile pf)
     : base()
 {
     this.m_AppInfoID          = pf.AppInfoID;
     this.m_Attributes         = pf.m_Attributes;
     this.m_Compression        = pf.Compression;
     this.m_CreationDate       = pf.CreationDate;
     this.m_Creator            = pf.Creator;
     this.m_CurrentPosition    = pf.CurrentPosition;
     this.m_FileName           = pf.FileName;
     this.m_LastBackupDate     = pf.LastBackupDate;
     this.m_ModificationDate   = pf.ModificationDate;
     this.m_ModificationNumber = pf.ModificationNumber;
     this.m_Name             = pf.Name;
     this.m_NextRecordListID = pf.NextRecordListID;
     this.m_NumberOfRecords  = pf.NumberOfRecords;
     this.m_RecordList       = pf.RecordList;
     this.m_SortInfoID       = pf.SortInfoID;
     this.m_TextLength       = pf.TextLength;
     this.m_TextRecordCount  = pf.TextRecordCount;
     this.m_TextRecordSize   = pf.TextRecordSize;
     this.m_Type             = pf.Type;
     this.m_UniqueIDSeed     = pf.UniqueIDSeed;
     this.m_Version          = pf.Version;
     this.m_RecordInfoList   = pf.m_RecordInfoList;
 }
Пример #2
0
        public new static MobiFile LoadFile(String fileName)
        {
            MobiFile    retval = new MobiFile(PalmFile.LoadFile(fileName));
            List <Byte> empty2 = new List <Byte> ();
            List <Byte> temp   = new List <Byte> ();

            empty2.Add(0);
            empty2.Add(0);
            List <Byte> headerdata = new List <Byte> ();

            headerdata.AddRange(retval.m_RecordList [0].Data);

            temp.AddRange(empty2);
            temp.AddRange(headerdata.GetRange(12, 2));
            retval.m_EncryptionType = BytesToUint(temp.ToArray());

            if (retval.Compression == 2)
            {
                StringBuilder sb       = new StringBuilder();
                Int32         pos      = 0;
                Int32         a        = 1;
                List <Byte>   datatemp = null;
                while (a < retval.m_TextRecordCount + 1)
                {
                    List <Byte> blockbuilder = new List <Byte> ();
                    datatemp = new List <byte> (retval.m_RecordList [a++].Data);
                    datatemp.Add(0);
                    pos = 0;
                    List <Byte> temps = new List <Byte> ();

                    while (pos < datatemp.Count && blockbuilder.Count < 4096)
                    {
                        Byte ab = (byte)(datatemp[pos++]);
                        if (ab == 0x00 || (ab > 0x08 && ab <= 0x7f))
                        {
                            blockbuilder.Add(ab);
                            //blockbuilder.Add (0);
                        }
                        else if (ab > 0x00 && ab <= 0x08)
                        {
                            temps.Clear();
                            temps.Add(0);
                            temps.Add(0);
                            temps.Add(0);
                            temps.Add(ab);
                            UInt32 value = BytesToUint(temps.ToArray());
                            for (uint i = 0; i < value; i++)
                            {
                                blockbuilder.Add((byte)(datatemp [pos++]));
                                //	blockbuilder.Add (0);
                            }
                        }
                        else if (ab > 0x7f && ab <= 0xbf)
                        {
                            temps.Clear();
                            temps.Add(0);
                            temps.Add(0);
                            Byte bb = (Byte)((ab & 63));                              // do this to drop the first 2 bits
                            temps.Add(bb);
                            if (pos < datatemp.Count)
                            {
                                temps.Add((byte)(datatemp [pos++]));
                            }
                            else
                            {
                                temps.Add(0);
                            }

                            UInt32 b               = BytesToUint(temps.ToArray());
                            UInt32 dist            = (b >> 3) * 1;
                            UInt32 len             = ((b << 29) >> 29);
                            Int32  uncompressedpos = blockbuilder.Count - ((Int32)dist);
                            for (int i = 0; i < (len + 3) * 1; i++)
                            {
                                try {
                                    blockbuilder.Add(blockbuilder[uncompressedpos + i]);
                                } catch (Exception) {
                                }
                            }
                        }
                        else if (ab > 0xbf && ab <= 0xff)
                        {
                            blockbuilder.Add(32);
                            //blockbuilder.Add (0);
                            blockbuilder.Add((byte)(ab ^ 0x80));
                            //blockbuilder.Add (0);
                        }
                    }

                    sb.Append(Encoding.UTF8.GetString(blockbuilder.ToArray()));
                }
                retval.m_BookText = sb.ToString();
            }
            else if (retval.Compression == 17480)
            {
                temp.Clear();
                temp.AddRange(headerdata.GetRange(112, 4));
                retval.m_HuffOffset = BytesToUint(temp.ToArray());

                temp.Clear();
                temp.AddRange(headerdata.GetRange(116, 4));
                retval.m_HuffCount = BytesToUint(temp.ToArray());

                if (headerdata.Count >= 244)
                {
                    temp.Clear();
                    temp.AddRange(headerdata.GetRange(240, 4));
                    retval.m_Extra_flags = BytesToUint(temp.ToArray());
                }

                UInt32      off1;
                UInt32      off2;
                UInt32      entrybits;
                List <Byte> huffdata = new List <Byte> ();
                List <Byte> cdicdata = new List <Byte> ();
                huffdata.AddRange(retval.m_RecordList [retval.m_HuffOffset].Data);
                cdicdata.AddRange(retval.m_RecordList [retval.m_HuffOffset + 1].Data);

                temp.Clear();
                temp.AddRange(huffdata.GetRange(16, 4));
                off1 = BytesToUint(temp.ToArray());

                temp.Clear();
                temp.AddRange(huffdata.GetRange(20, 4));
                off2 = BytesToUint(temp.ToArray());

                temp.Clear();
                temp.AddRange(cdicdata.GetRange(12, 4));
                entrybits = BytesToUint(temp.ToArray());

                List <UInt32>       huffdict1 = new List <UInt32> ();
                List <UInt32>       huffdict2 = new List <UInt32> ();
                List <List <Byte> > huffdicts = new List <List <Byte> > ();

                for (int i = 0; i < 256; i++)
                {
                    temp.Clear();
                    temp.AddRange(huffdata.GetRange((int)(off1 + (i * 4)), 4));
                    huffdict1.Add(BitConverter.ToUInt32(temp.ToArray(), 0));
                }
                for (int i = 0; i < 64; i++)
                {
                    temp.Clear();
                    temp.AddRange(huffdata.GetRange((int)(off2 + (i * 4)), 4));
                    huffdict2.Add(BitConverter.ToUInt32(temp.ToArray(), 0));
                }

                for (int i = 1; i < retval.m_HuffCount; i++)
                {
                    huffdicts.Add(new List <byte> (retval.m_RecordList [retval.m_HuffOffset + i].Data));
                }

                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < retval.m_TextRecordCount; i++)
                {
                    // Remove Trailing Entries
                    List <Byte> datatemp = new List <byte> (retval.m_RecordList [1 + i].Data);
                    Int32       size     = getSizeOfTrailingDataEntries(datatemp.ToArray(), datatemp.Count, retval.m_Extra_flags);

                    sb.Append(unpack(new BitReader(datatemp.GetRange(0, datatemp.Count - size).ToArray()), huffdict1.ToArray(), huffdict2.ToArray(), huffdicts, (int)((long)entrybits)));
                }

                retval.m_BookText = sb.ToString();
            }
            else
            {
                throw new Exception("Compression format is unsupported");
            }
            return(retval);
        }
Пример #3
0
        public static PalmFile LoadFile(String fileName)
        {
            PalmFile retval = new PalmFile();

            retval.m_FileName = fileName;
            FileStream   fs        = null;
            StreamReader sr        = null;
            UInt32       seconds   = 0;
            DateTime     startdate = new DateTime(1904, 1, 1);

            //startdate = new DateTime(1970, 1, 1);
            try {
                fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                sr = new StreamReader(fs);
                Char[] buffer = new char[32];
                sr.Read(buffer, 0, 32);
                fs.Seek(32, SeekOrigin.Begin);
                retval.m_Name = new String(buffer);
                Byte[] bytebuffer = new Byte[4];
                fs.Read(bytebuffer, 2, 2);
                retval.m_Attributes = BytesToUint(bytebuffer);
                bytebuffer          = new Byte[4];
                fs.Read(bytebuffer, 2, 2);
                retval.m_Version = BytesToUint(bytebuffer);
                bytebuffer       = new Byte[4];
                fs.Read(bytebuffer, 0, 4);
                seconds = BytesToUint(bytebuffer);
                TimeSpan ts = new TimeSpan(0, (int)(seconds / 60), 0);
                retval.m_CreationDate = startdate + ts;
                fs.Read(bytebuffer, 0, 4);
                seconds = BytesToUint(bytebuffer);
                ts      = new TimeSpan(0, (int)(seconds / 60), 0);
                retval.m_ModificationDate = startdate + ts;
                fs.Read(bytebuffer, 0, 4);
                seconds = BytesToUint(bytebuffer);
                ts      = new TimeSpan(0, (int)(seconds / 60), 0);
                retval.m_LastBackupDate = startdate + ts;
                fs.Read(bytebuffer, 0, 4);
                retval.m_ModificationNumber = BytesToUint(bytebuffer);
                fs.Read(bytebuffer, 0, 4);
                retval.m_AppInfoID = BytesToUint(bytebuffer);
                fs.Read(bytebuffer, 0, 4);
                retval.m_SortInfoID = BytesToUint(bytebuffer);
                buffer = new char[4];
                sr.DiscardBufferedData();
                sr.Read(buffer, 0, 4);
                retval.m_Type = new String(buffer);
                sr.Read(buffer, 0, 4);
                retval.m_Creator = new String(buffer);
                fs.Seek(68, SeekOrigin.Begin);
                fs.Read(bytebuffer, 0, 4);

                retval.m_UniqueIDSeed = BytesToUint(bytebuffer);
                fs.Read(bytebuffer, 0, 4);

                retval.m_NextRecordListID = BytesToUint(bytebuffer);
                bytebuffer = new Byte[4];
                fs.Read(bytebuffer, 2, 2);

                // Load RecordInfo

                retval.m_NumberOfRecords = BytesToUint(bytebuffer);
                retval.m_RecordInfoList  = new PalmRecordInfo[retval.m_NumberOfRecords];
                retval.m_RecordList      = new PalmRecord[retval.m_NumberOfRecords];
                for (int i = 0; i < retval.m_NumberOfRecords; i++)
                {
                    fs.Read(bytebuffer, 0, 4);
                    retval.m_RecordInfoList [i].DataOffset = BytesToUint(bytebuffer);

                    bytebuffer = new Byte[4];
                    fs.Read(bytebuffer, 3, 1);
                    retval.m_RecordInfoList [i].Attributes = BytesToUint(bytebuffer);

                    bytebuffer = new Byte[4];
                    fs.Read(bytebuffer, 1, 3);
                    retval.m_RecordInfoList [i].UniqueID = BytesToUint(bytebuffer);
                }

                //Load Records

                UInt32 StartOffset;
                UInt32 EndOffset;
                Int32  RecordLength;
                for (int i = 0; i < retval.m_NumberOfRecords - 1; i++)
                {
                    StartOffset  = retval.m_RecordInfoList [i].DataOffset;
                    EndOffset    = retval.m_RecordInfoList [i + 1].DataOffset;
                    RecordLength = ((Int32)((long)(EndOffset - StartOffset)));
                    fs.Seek(StartOffset, SeekOrigin.Begin);
                    retval.m_RecordList [i].Data = new Byte[RecordLength];
                    fs.Read(retval.m_RecordList [i].Data, 0, RecordLength);
                }

                StartOffset  = retval.m_RecordInfoList [retval.m_NumberOfRecords - 1].DataOffset;
                RecordLength = (int)(fs.Length - ((Int32)((long)StartOffset)));
                fs.Seek(StartOffset, SeekOrigin.Begin);
                retval.m_RecordList [retval.m_NumberOfRecords - 1].Data = new Byte[RecordLength];
                fs.Read(retval.m_RecordList [retval.m_NumberOfRecords - 1].Data, 0, RecordLength);

                // LoadHeader
                List <Byte> empty2 = new List <Byte> ();
                List <Byte> temp   = new List <Byte> ();
                empty2.Add(0);
                empty2.Add(0);

                List <Byte> headerdata = new List <Byte> ();

                headerdata.AddRange(retval.m_RecordList [0].Data);

                temp.AddRange(empty2);
                temp.AddRange(headerdata.GetRange(0, 2));
                retval.m_Compression = BytesToUint(temp.ToArray());
                temp.Clear();
                temp.AddRange(headerdata.GetRange(4, 4));
                retval.m_TextLength = BytesToUint(temp.ToArray());

                temp.Clear();
                temp.AddRange(empty2);
                temp.AddRange(headerdata.GetRange(8, 2));
                retval.m_TextRecordCount = BytesToUint(temp.ToArray());

                temp.Clear();
                temp.AddRange(empty2);
                temp.AddRange(headerdata.GetRange(10, 2));
                retval.m_TextRecordSize = BytesToUint(temp.ToArray());

                temp.Clear();
                temp.AddRange(headerdata.GetRange(12, 4));
                retval.m_CurrentPosition = BytesToUint(temp.ToArray());
                ;
            } finally {
                if (sr != null)
                {
                    sr.Close();
                    sr.Dispose();
                }
                if (fs != null)
                {
                    fs.Close();
                    fs.Dispose();
                }
            }
            return(retval);
        }