public static PalmDatabaseFormat FromBinary(BinaryReader reader) { try { //create new palm database var palm = new PalmDatabaseFormat(); //some buffer for reading data byte[] buffer = new byte[4096]; // Read database name reader.Read(buffer, 0, 32); palm.Name = Latin1.GetString(buffer.TakeWhile(data => !data.Equals(0)).ToArray()); // Read attributes palm.Attributes = (PalmDatabaseAttributes) Enum.ToObject(typeof(PalmDatabaseAttributes), reader.ReadInt16(Endian.BigEndian)); // Read version palm.Version = reader.ReadInt16(Endian.BigEndian); // Created time palm.CreationDate = DateTimeConverter.GetPDBTimeFromTimestamp(reader.ReadUInt32(Endian.BigEndian)); // Modified time palm.ModificationDate = DateTimeConverter.GetPDBTimeFromTimestamp(reader.ReadUInt32(Endian.BigEndian)); // Last backup time palm.LastBackupDate = DateTimeConverter.GetPDBTimeFromTimestamp(reader.ReadUInt32(Endian.BigEndian)); // Modification number palm.ModificationNumber = reader.ReadInt32(Endian.BigEndian); // Internal offsets palm._appInfoOffset = reader.ReadInt32(Endian.BigEndian); palm._sortInfoOffset = reader.ReadInt32(Endian.BigEndian); // read type and creator reader.Read(buffer, 0, 8); palm.Type = Latin1.GetString(buffer, 0, 4); palm.Creator = Latin1.GetString(buffer, 4, 4); // More internal data palm._uniqueIdSeed = reader.ReadInt32(Endian.BigEndian); palm._nextRecordListID = reader.ReadInt32(Endian.BigEndian); // Read number of records ushort numberOfRecords = reader.ReadUInt16(Endian.BigEndian); for (ushort i = 0; i < numberOfRecords; i++) { //create new record var record = new PalmDatabaseRecord(); //read offset of data record.Offset = reader.ReadUInt32(Endian.BigEndian); var category = reader.ReadByte(); record.Attributes = (PalmRecordAttributes) Enum.ToObject(typeof(PalmRecordAttributes), category >> 4); record.Category = category & 0xf; // uid reader.Read(buffer, 0, 3); record.Id = BitConverter.ToUInt32(new byte[] { buffer[2], buffer[1], buffer[0], 0 }, 0); // adjust size of previous record var last = palm.Records.LastOrDefault(); if (last != null) last.Size = record.Offset - last.Offset; // add record palm.Records.Add(record); } // set size of last record var lastRecord = palm.Records.LastOrDefault(); if (lastRecord != null) lastRecord.Size = (uint)reader.BaseStream.Length - lastRecord.Offset; foreach (var record in palm.Records) { reader.BaseStream.Seek(record.Offset, SeekOrigin.Begin); record.Data = new byte[record.Size]; reader.Read(record.Data, 0, (int)record.Size); } //return the result return palm; } catch (Exception e) { throw new Exception("cannot read palm database from binary reader", e); } }
/// <summary> /// Crates new instance of mobipocket header from provided palm database. /// </summary> /// <param name="pdb"></param> /// <returns></returns> internal static MobipocketHeader FromPalmDatabase(PalmDatabaseFormat pdb) { if (pdb == null) throw new ArgumentNullException("pdb"); if (pdb.Records.Count < 1) throw new ArgumentException("no records in palm database"); var bytes = pdb.Records.First().Data; if (bytes == null) throw new ArgumentException("first record in palm database is malformed"); return FromBinary(new ArraySegment<byte>(bytes, 0 ,bytes.Length)); }
public static PalmDatabaseFormat FromBinary(BinaryReader reader) { try { //create new palm database var palm = new PalmDatabaseFormat(); //some buffer for reading data byte[] buffer = new byte[4096]; // Read database name reader.Read(buffer, 0, 32); palm.Name = Latin1.GetString(buffer.TakeWhile(data => !data.Equals(0)).ToArray()); // Read attributes palm.Attributes = (PalmDatabaseAttributes)Enum.ToObject(typeof(PalmDatabaseAttributes), reader.ReadInt16(Endian.BigEndian)); // Read version palm.Version = reader.ReadInt16(Endian.BigEndian); // Created time palm.CreationDate = DateTimeConverter.GetPDBTimeFromTimestamp(reader.ReadUInt32(Endian.BigEndian)); // Modified time palm.ModificationDate = DateTimeConverter.GetPDBTimeFromTimestamp(reader.ReadUInt32(Endian.BigEndian)); // Last backup time palm.LastBackupDate = DateTimeConverter.GetPDBTimeFromTimestamp(reader.ReadUInt32(Endian.BigEndian)); // Modification number palm.ModificationNumber = reader.ReadInt32(Endian.BigEndian); // Internal offsets palm._appInfoOffset = reader.ReadInt32(Endian.BigEndian); palm._sortInfoOffset = reader.ReadInt32(Endian.BigEndian); // read type and creator reader.Read(buffer, 0, 8); palm.Type = Latin1.GetString(buffer, 0, 4); palm.Creator = Latin1.GetString(buffer, 4, 4); // More internal data palm._uniqueIdSeed = reader.ReadInt32(Endian.BigEndian); palm._nextRecordListID = reader.ReadInt32(Endian.BigEndian); // Read number of records ushort numberOfRecords = reader.ReadUInt16(Endian.BigEndian); for (ushort i = 0; i < numberOfRecords; i++) { //create new record var record = new PalmDatabaseRecord(); //read offset of data record.Offset = reader.ReadUInt32(Endian.BigEndian); var category = reader.ReadByte(); record.Attributes = (PalmRecordAttributes)Enum.ToObject(typeof(PalmRecordAttributes), category >> 4); record.Category = category & 0xf; // uid reader.Read(buffer, 0, 3); record.Id = BitConverter.ToUInt32(new byte[] { buffer[2], buffer[1], buffer[0], 0 }, 0); // adjust size of previous record var last = palm.Records.LastOrDefault(); if (last != null) { last.Size = record.Offset - last.Offset; } // add record palm.Records.Add(record); } // set size of last record var lastRecord = palm.Records.LastOrDefault(); if (lastRecord != null) { lastRecord.Size = (uint)reader.BaseStream.Length - lastRecord.Offset; } foreach (var record in palm.Records) { reader.BaseStream.Seek(record.Offset, SeekOrigin.Begin); record.Data = new byte[record.Size]; reader.Read(record.Data, 0, (int)record.Size); } //return the result return(palm); } catch (Exception e) { throw new Exception("cannot read palm database from binary reader", e); } }