예제 #1
0
        public static MobipocketRecord FromBinary(byte[] data, bool isTextRecord, TrailingEntryParser parser)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (isTextRecord && parser == null)
            {
                throw new ArgumentException("parser cannot be null if isTextRecord is true");
            }

            var record = new MobipocketRecord {
                Data = data, IsTextRecord = isTextRecord
            };

            if (isTextRecord)
            {
                try
                {
                    record.TrailingEntries = parser.Parse(data);
                }
                catch (Exception e)
                {
                    throw new Exception("cannot parse trailing entries for record", e);
                }
            }

            return(record);
        }
예제 #2
0
        /// <summary>
        /// Parses all text record
        /// </summary>
        private IEnumerable <MobipocketRecord> ParseTextMobipocketRecords()
        {
            int bytesUsed = 0;

            var parser = new TrailingEntryParser(Header.TrailingEntries);
            int previousOverlapSize = 0;

            //skip first record as header, and process all text records
            for (int recordIndex = 0; recordIndex < Header.TextRecordCount; recordIndex++)
            {
                //get current record
                var record = _pdb.Records[recordIndex + 1];

                //read record
                var mobiRecord = MobipocketRecord.FromBinary(record.Data, true, parser);

                //uncompress text
                mobiRecord.Text = GetRecordText(mobiRecord, previousOverlapSize, ref bytesUsed);

                //yield record
                yield return(mobiRecord);

                //save trailing entries
                previousOverlapSize = mobiRecord.TrailingEntries.IsMultibyteCharacterOverlapping ?
                                      mobiRecord.TrailingEntries.MultibyteCharacterOverlap.Length : 0;
            }

            if (bytesUsed != Header.TotalTextLength)
            {
                throw new Exception("text length doesn't match used characters");
            }
        }
예제 #3
0
        //---------------------------------------------
        //
        // Private methods
        //
        //---------------------------------------------

        #region Private methods

        private IEnumerable <MobipocketRecord> ParseMobipocketRecords()
        {
            foreach (var record in ParseTextMobipocketRecords())
            {
                AddResource(MobipocketResourceTypes.Text, record.Text);
                yield return(record);
            }

            for (int index = (int)Header.FirstNonTextRecord; index < _pdb.Records.Count; index++)
            {
                var data   = _pdb.Records[index].Data;
                var record = MobipocketRecord.FromBinary(data);

                yield return(record);

                if (record.IsFLISRecord)
                {
                    AddResource(MobipocketResourceTypes.FLIS, data);
                }
                else if (record.IsFCISRecord)
                {
                    AddResource(MobipocketResourceTypes.FCIS, data);
                }
                else if (record.IsEOFRecord)
                {
                    AddResource(MobipocketResourceTypes.EOF, data);
                }
                else
                {
                    try
                    {
                        using (var stream = new MemoryStream(record.Data))
                            using (var image = Image.FromStream(stream))
                            {
                                var format = image.RawFormat;

                                if (format.Equals(ImageFormat.Jpeg) ||
                                    format.Equals(ImageFormat.Gif) ||
                                    format.Equals(ImageFormat.Bmp))
                                {
                                    AddResource(MobipocketResourceTypes.Image, data);
                                }

                                else
                                {
                                    throw new NotSupportedException("image not supported");
                                }
                            }
                    }
                    catch
                    {
                        AddResource(MobipocketResourceTypes.Binary, data);
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Gets string value associated with palm database record using given compression schemes.
        /// </summary>
        /// <param name="record"></param>
        /// <returns></returns>
        private string GetRecordText(MobipocketRecord record, int previousOverlapSize, ref int bytesUsed)
        {
            if (record == null)
            {
                throw new ArgumentException("record");
            }

            //resulting data
            byte[] resultData;

            //decompress the text
            switch (Compression)
            {
            case MobipocketCompression.NoCompression:
            {
                var segment = record.GetDataWithoutTrailingEntries();
                resultData = new byte[segment.Count];

                Array.Copy(segment.Array, segment.Offset, resultData, 0, segment.Count);
                break;
            }

            case MobipocketCompression.LZ77:
                resultData = GetLZ77DecodedText(record.GetDataWithoutTrailingEntries());
                break;

            case MobipocketCompression.Huffdic:
                throw new NotSupportedException("huffdic compression not supported yet");

            default:
                throw new NotSupportedException();
            }

            //adjust bytes used
            bytesUsed += resultData.Length;

            //add Multibyte character overlap entry to text
            if (record.TrailingEntries.IsMultibyteCharacterOverlapping)
            {
                //may be not the most proficient method
                resultData = resultData.Concat(record.TrailingEntries.MultibyteCharacterOverlap).ToArray();
            }

            return(GetSystemEncoding().GetString(resultData, previousOverlapSize, resultData.Length - previousOverlapSize));
        }
예제 #5
0
        public static MobipocketRecord FromBinary(byte[] data, bool isTextRecord, TrailingEntryParser parser)
        {
            if (data == null)
                throw new ArgumentNullException("data");

            if (isTextRecord && parser == null)
                throw new ArgumentException("parser cannot be null if isTextRecord is true");

            var record = new MobipocketRecord { Data = data, IsTextRecord = isTextRecord };

            if (isTextRecord)
            {
                try
                {
                    record.TrailingEntries = parser.Parse(data);
                }
                catch (Exception e)
                {
                    throw new Exception("cannot parse trailing entries for record", e);
                }
            }

            return record;
        }