/// <summary> /// Main Program procedure /// </summary> /// <param name="args">Command line arguments</param> static void Main(string[] args) { MobiFile mf = null; try { mf = MobiFile.LoadFile(args [0]); } catch (Exception e) { Console.Out.WriteLine("Error reading file"); Console.Out.WriteLine(e.Message); return; } Console.OutputEncoding = System.Text.Encoding.UTF8; ConsoleReader cr = new ConsoleReader(mf); Console.Out.Write(cr.GetLines()); ConsoleKeyInfo cki = Console.ReadKey(); while (cki.Key != ConsoleKey.Escape) { if ((cki.Key == ConsoleKey.LeftArrow) || (cki.Key == ConsoleKey.UpArrow) || (cki.Key == ConsoleKey.PageUp)) { cr.PageBack(); ClearConsole(); Console.Out.Write(cr.GetLines()); } else if ((cki.Key == ConsoleKey.RightArrow) || (cki.Key == ConsoleKey.DownArrow) || (cki.Key == ConsoleKey.PageDown)) { cr.PageForward(); ClearConsole(); Console.Out.Write(cr.GetLines()); } else if (cki.Key == ConsoleKey.F && cki.Modifiers == ConsoleModifiers.Control) { Console.Out.WriteLine("Enter Search String: "); String searchstring = Console.ReadLine(); if (cr.Find(searchstring)) { Console.Out.Write("Couldn't Find Value"); } ClearConsole(); Console.Out.Write(cr.GetLines()); } cki = Console.ReadKey(); } cr.SavePosition(); }
public ConsoleReader(MobiFile mf) { m_File = mf; m_BookLines = new List <String> (); String filetext = m_File.BookText; filetext = filetext.Substring(filetext.IndexOf("<body>")); filetext = filetext.Replace("</html>", ""); filetext = filetext.Replace("<mbp:", "<"); filetext = filetext.Replace("svg:svg", "svg"); filetext = filetext.Replace("svg:image", "image"); filetext = filetext.Replace("xlink:href", "href"); Int32 pos = 0; while (pos != -1) { pos = filetext.IndexOf("filepos=", pos + 1); if (pos != -1) { Int32 pos2 = filetext.IndexOf(">", pos + 1); if (pos2 != -1) { filetext = filetext.Insert(pos2, "\""); } } } filetext = filetext.Replace("filepos=", "filepos=\""); MemoryStream ms = new MemoryStream(); StreamWriter sw = new StreamWriter(ms); sw.Write(filetext); sw.Flush(); ms.Seek(0, SeekOrigin.Begin); XmlReaderSettings settings = new XmlReaderSettings(); settings.ValidationType = ValidationType.None; settings.ValidationFlags = System.Xml.Schema.XmlSchemaValidationFlags.None; settings.IgnoreComments = true; settings.IgnoreProcessingInstructions = true; settings.DtdProcessing = DtdProcessing.Prohibit; settings.ConformanceLevel = ConformanceLevel.Fragment; XmlReader xtr = XmlTextReader.Create(ms, settings); StringBuilder sb = new StringBuilder(); Boolean foundBody = false; Boolean r = xtr.Read(); while (r) { if (xtr.Name.ToLower() == "head" || xtr.Name.ToLower() == "svg" || xtr.Name.ToLower() == "image") { xtr.Skip(); } if (xtr.Name.ToLower() == "body") { foundBody = true; } if (xtr.Name.ToLower() == "p") { sb.AppendLine(); sb.AppendLine(); } if (foundBody) { try { String tempstring = xtr.ReadContentAsString(); if (tempstring.Trim().Length > 0) { sb.Append(tempstring); } } catch (Exception) { } } try { r = xtr.Read(); } catch (Exception) { } } xtr.Close(); sw.Close(); sw.Dispose(); ms.Close(); ms.Dispose(); String[] delim = new String[1]; delim [0] = "\r\n"; String[] lines = sb.ToString().Split(delim, StringSplitOptions.None); foreach (string str in lines) { if (str.Length <= LineMax) { m_BookLines.Add(str.Trim()); } else { String temp = str; Int32 ppos = 0; while (temp.Length > LineMax) { ppos = temp.LastIndexOf(' ', LineMax); if (ppos != -1) { m_BookLines.Add(temp.Substring(0, ppos).Trim()); temp = temp.Substring(ppos + 1); } else { m_BookLines.Add(temp.Substring(0, LineMax) + "-".Trim()); temp = temp.Substring(LineMax + 1); } } m_BookLines.Add(temp.Trim()); } } LoadPosition(); }
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); }