Esempio n. 1
0
        private void FixupHeaderForWriting(BBeB book)
        {
            if (book.MetaData == null)
            {
                // TODO - This is just because we don't have any metadata yet
                Debug.WriteLineIf(s_bDebugMode, "Book has no metadata - Mocking some up for testing");

                MemoryStream  metaStream    = new MemoryStream();
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(BookMetaData));
                BookMetaData  md            = new BookMetaData();
                xmlSerializer.Serialize(metaStream, md);
                metaStream.Seek(0, SeekOrigin.Begin);
                book.MetaData = md;                 //.Load(metaStream);
            }

            if (book.Header.wVersion >= 800)
            {
                if (book.ThumbnailData == null)
                {
                    throw new InvalidBookException("Don't have a thumbnail image");
                }

                book.Header.dwThumbSize = (uint)book.ThumbnailData.Length;
            }

            book.Header.NumberOfObjects = (ulong)book.Objects.Count;
        }
Esempio n. 2
0
        private void ConnectPageTree(BBeB book)
        {
            Debug.WriteLineIf(s_bDebugMode, "Connecting page tree");

            PageTreeObject pageTree = (PageTreeObject)book.FindFirstObject(typeof(PageTreeObject));

            if (pageTree == null)
            {
                throw new InvalidBookException("Couldn't find the required PageTree object");
            }

            UInt32ArrayTag pageListTag = (UInt32ArrayTag)pageTree.FindFirstTag(TagId.PageList);

            if (pageListTag == null)
            {
                throw new InvalidBookException("Couldn't find the required PageList tag");
            }

            foreach (uint id in pageListTag.Value)
            {
                PageObject page = (PageObject)book.FindObject((ushort)id);
                if (page == null)
                {
                    throw new InvalidBookException("Can't find page id " + id);
                }
                pageTree.Pages.Add(page);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Resolve the object ID's that are used to specify references to
        /// the actual references.
        /// </summary>
        private void ConnectObjects(BBeB book)
        {
            Debug.WriteLineIf(s_bDebugMode, "Connecting objects");

            ConnectPageTree(book);
            ConnectPages(book);
            ConnectBlocks(book);
            ConnectTexts(book);
        }
Esempio n. 4
0
 private void ConnectTexts(BBeB book)
 {
     foreach (BBeBObject obj in book.Objects)
     {
         if (obj.GetType() == typeof(TextObject))
         {
             ConnectText((TextObject)obj, book);
         }
     }
 }
Esempio n. 5
0
 private void ConnectBlocks(BBeB book)
 {
     foreach (BBeBObject obj in book.Objects)
     {
         if (obj.GetType() == typeof(BlockObject))
         {
             ConnectBlock((BlockObject)obj, book);
         }
     }
 }
Esempio n. 6
0
 private void ConnectPages(BBeB book)
 {
     foreach (BBeBObject obj in book.Objects)
     {
         if (obj.GetType() == typeof(PageObject))
         {
             ConnectPage((PageObject)obj, book);
         }
     }
 }
Esempio n. 7
0
        private void ConnectPage(PageObject page, BBeB book)
        {
            Debug.WriteLineIf(s_bDebugMode, "Connecting page: " + page.ID);

            UInt32ArrayTag childIDs = (UInt32ArrayTag)page.FindFirstTag(TagId.PageObjectIds);

            if (childIDs != null)
            {
                foreach (uint id in childIDs.Value)
                {
                    BBeBObject child = book.FindObject((ushort)id);
                    if (child == null)
                    {
                        throw new InvalidBookException("Can't find object id " + id);
                    }

                    Debug.Assert(child.ID == id);

                    Debug.WriteLineIf(s_bDebugMode, "   Child: " + child.GetType().ToString() + " - id:" + child.ID);
                    page.Children.Add(child);
                }
            }

            UInt32Tag objInfoTag = (UInt32Tag)page.FindFirstTag(TagId.ObjectInfoLink);

            if (objInfoTag != null)
            {
                page.InfoObj = book.FindObject((ushort)objInfoTag.Value);
                if (page.InfoObj == null)
                {
                    throw new InvalidBookException("Can't find info object id " + objInfoTag.Value);
                }
            }

            StreamTagGroup stream = (StreamTagGroup)page.FindFirstTag(TagId.StreamGroup);

            if (stream != null)
            {
                BBeBObject tempObj = new BBeBObject(0x0);

                page.StreamTags = BBeBTagFactory.ParseAllTags(tempObj, stream.Data);
            }

            UInt32Tag linkTag = (UInt32Tag)page.FindFirstTag(TagId.Link);

            if (linkTag != null)
            {
                BBeBObject linkedObj = book.FindObject((ushort)linkTag.Value);
                if (linkedObj == null)
                {
                    throw new InvalidBookException("Can't find object id " + linkTag.Value);
                }
                page.LinkObj = linkedObj;
            }
        }
Esempio n. 8
0
        public BBeB ParseHTML(HtmlDocument doc, BindingParams bindingParams, TocEntry tocEntries)
        {
            m_Book = new BBeB();

            byte[] thumb = File.ReadAllBytes(bindingParams.IconFile);
            setHeaderValues(thumb.Length);
            m_Book.MetaData      = bindingParams.MetaData;
            m_Book.ThumbnailData = thumb;

            // Create our default Attribute objects
            createDefaultAttributeObjects(BBeB.ReaderPageWidth, BBeB.ReaderPageHeight);

            // cover page works, but it's ugly
            createCoverPage();

            m_CurrentPage = createPage();

            PageObject firstBookPage = m_CurrentPage;

            m_StartReadingBlock = null;
            m_StartReadingPage  = null;

            addBookPage(m_CurrentPage);

            IHTMLDocument2             dom      = (IHTMLDocument2)doc.DomDocument;
            IHTMLDOMNode               domNode  = (IHTMLDOMNode)dom.body;
            IHTMLDOMChildrenCollection children = (IHTMLDOMChildrenCollection)domNode.childNodes;

            TextBlockBuilder tbBuilder = new TextBlockBuilder(GetNextObjId(), m_CharMapper);

            foreach (IHTMLDOMNode child in children)
            {
                tbBuilder = ParseDomNode(child, tbBuilder);
            }

            PrintHTMLElementChildren(children);

            // If we have any text left then add it
            FlushTextToBlock(m_CurrentPage, tbBuilder, m_MainBodyTextAttr);

            finalizePage(m_CurrentPage);

            // Create the table of contents
            createTocPage(firstBookPage, tocEntries);

            m_TocObject.AddEntry(m_StartReadingPage.ID, m_StartReadingBlock.ID, "Start Reading");

            // Also serialize the table of contents object
            m_TocObject.Serialize();

            finalizeBook();

            return(m_Book);
        }
Esempio n. 9
0
        private void SerializeHeader(BBeB book, BBeBinaryWriter writer)
        {
            BBeBHeader header = book.Header;

            TocObject tocObject = (TocObject)book.FindObject((ushort)header.dwTocObjectId);

            if (tocObject == null)
            {
                throw new InvalidBookException("Can't find the TOC object");
            }

            writer.Write(header.signature);
            writer.Write(header.wVersion);
            writer.Write(header.wPseudoEncByte);
            writer.Write(header.dwRootObjectId);
            writer.Write(header.NumberOfObjects);
            m_dwIndexOffsetVal = writer.Position;
            writer.Write(header.ObjectIndexOffset);
            writer.Write(header.dwUnknown1);
            writer.Write(header.byBindingDir);
            writer.Write(header.byPadding1);
            writer.Write(header.wDPI);
            writer.Write(header.wPadding2);
            writer.Write(header.wScreenWidth);
            writer.Write(header.wScreenHeight);
            writer.Write(header.byColorDepth);
            writer.Write(header.byPadding3);
            writer.Write(header.byUnkonwn2);
            writer.Write(header.dwTocObjectId);
            writer.WriteStreamOffsetReference(tocObject);

            // This may seem a little wasteful as we actually serialize the MetaData object twice
            // Once here and onces when we actualy write it to the stream, however we need to set
            // the compressed size in the header and we can only do it by compressing it first.

            // Really we should store the compressed byte stream and just save that out
            // but its not very big so the overhead is quite small
            {
                MemoryStream mem = new MemoryStream();
                BinaryWriter sw  = new BinaryWriter(mem);
                header.wDocInfoCompSize = (ushort)(SerializeMetaData(book.MetaData, sw) + 4);
            }
            writer.Write(header.wDocInfoCompSize);

            Debug.Assert(writer.Position == 0x4E);

            if (header.wVersion >= 800)
            {
                writer.Write(header.wThumbnailFlags);
                writer.Write(header.dwThumbSize);
                Debug.Assert(writer.Position == 0x54);
            }
        }
Esempio n. 10
0
        private void ConnectBlock(BlockObject block, BBeB book)
        {
            UInt32Tag linkTag = (UInt32Tag)block.FindFirstTag(TagId.Link);

            if (linkTag == null)
            {
                throw new InvalidBookException("Can't find link for block " + block.ID);
            }

            block.LinkObj = book.FindObject((ushort)linkTag.Value);
            if (block.LinkObj == null)
            {
                throw new InvalidBookException("Can't find object id " + linkTag.Value);
            }
        }
Esempio n. 11
0
        private void ConnectText(TextObject text, BBeB book)
        {
            UInt32Tag linkTag = (UInt32Tag)text.FindFirstTag(TagId.Link);

            if (linkTag == null)
            {
                throw new InvalidBookException("Can't find link for block " + text.ID);
            }

            BBeBObject LinkObj = book.FindObject((ushort)linkTag.Value);

            if (LinkObj == null)
            {
                throw new InvalidBookException("Can't find object id " + linkTag.Value);
            }
        }
Esempio n. 12
0
        public BBeB Deserialize(Stream bbebStream)
        {
            BinaryReader reader = new BinaryReader(bbebStream, Encoding.Unicode);

            BBeB       book   = new BBeB();
            BBeBHeader header = DeserializeHeader(reader);

            header.Validate();

            book.Header = header;

            book.MetaData = DeserializeMetaData(reader, header.wDocInfoCompSize);

            if (header.wVersion >= 800)
            {
                book.ThumbnailData = reader.ReadBytes((int)header.dwThumbSize);
            }

            // See http://www.sven.de/librie/Librie/LrfFormat for more information on this table.
            const ulong k_dwObjTableElementSize = 4 * sizeof(uint);

            ulong nTotalSize = 0;

            BBeBObjectFactory objFactory = new BBeBObjectFactory();

            Debug.WriteLineIf(s_bDebugMode, "File contains " + header.NumberOfObjects + " objects");
            for (ulong idxObj = 0; idxObj < header.NumberOfObjects; idxObj++)
            {
                reader.BaseStream.Seek((long)(header.ObjectIndexOffset + idxObj * k_dwObjTableElementSize),
                                       SeekOrigin.Begin);

                uint id     = reader.ReadUInt32();
                uint offset = reader.ReadUInt32();
                uint size   = reader.ReadUInt32();

                nTotalSize += size;

                reader.BaseStream.Seek(offset, SeekOrigin.Begin);
                book.Objects.Add(objFactory.CreateObject(reader, id, size));
            }

            Debug.WriteLineIf(s_bDebugMode, "Total size: " + nTotalSize);

            ConnectObjects(book);

            return(book);
        }
Esempio n. 13
0
        public bool SaveDocument(BindingParams bindingParameters, TocEntry tocEntries,
                                 BBeBLib.Serializer.CharacterMapper charMapper,
                                 HtmlDocument document)
        {
            bool ret = false;

            string filename = bindingParameters.MetaData.BookInfo.Author + " - " + bindingParameters.MetaData.BookInfo.Title;

            SaveFileDialog dialog = new SaveFileDialog();

            dialog.FileName = filename;
            dialog.Filter   = "BBeB/LRF Files (*.lrf)|*.lrf";
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                Host.Status("Converting....");
                Application.DoEvents();
                HTMLToBbebTransform transformer = new HTMLToBbebTransform(charMapper);
                BBeB book = transformer.ParseHTML(document, bindingParameters, tocEntries);

                Host.Status("Saving....");
                Application.DoEvents();

                // Save book now
                File.Delete(dialog.FileName);
                BBeBLib.Serializer.BBeBSerializer serializer = new BBeBLib.Serializer.BBeBSerializer();
                FileStream newLrfStream = File.OpenWrite(dialog.FileName);
                try
                {
                    serializer.Serialize(newLrfStream, book);
                }
                catch (Exception ex)
                {
                    // TODO Need to get these strings from a resource for localization purposes
                    string msg = string.Format("Couldn't save file {0}\n{1}", dialog.FileName, ex.ToString());
                    MessageBox.Show(msg, "Error saving file!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    newLrfStream.Close();
                }
                Host.Status("Finished.");
            }
            return(ret);
        }
Esempio n. 14
0
        /// <summary>
        /// Serialize the object to the supplied stream.
        /// </summary>
        /// <param name="stream">Write the serialized bytes of the book to this stream.</param>
        /// <param name="book">The book to serialize</param>
        public void Serialize(Stream stream, BBeB book)
        {
            m_dwIndexOffsetVal = 0;

            FixupHeaderForWriting(book);

            BBeBinaryWriter writer = new BBeBinaryWriter(stream);

            book.Header.Validate();
            SerializeHeader(book, writer);
            SerializeMetaData(book.MetaData, writer);

            if (book.Header.wVersion >= 800)
            {
                writer.Write(book.ThumbnailData);
            }

            // Now go back and update the position of the object index now that we
            // know where its offset in the stream.
            long dwObjIdxStartOffset = writer.Position;

            writer.Position = m_dwIndexOffsetVal;
            writer.Write((ulong)dwObjIdxStartOffset);
            writer.Position = dwObjIdxStartOffset;

            // Write the object offset index table
            foreach (BBeBObject obj in book.Objects)
            {
                writer.Write((uint)obj.ID);
                writer.WriteStreamOffsetReference(obj);                 // Will be fixed up later
                writer.WriteStreamSizeReference(obj);                   // Will be fixed up later
                writer.Write((uint)0x0);                                // Unused and reserved
            }

            // Now write out all the objects
            foreach (BBeBObject obj in book.Objects)
            {
                SerializeObject(obj, writer);
            }

            writer.Flush();
            writer.ResolveReferences();
        }
Esempio n. 15
0
        public BBeBWriter(BBeB book)
        {
            this.book = book;

            writePages();
        }
Esempio n. 16
0
 public HTMLWriter(BBeB book) :
     base(book)
 {
 }