public DBFile ReadFile(BinaryReader reader, DBFileHeader header, TypeInfo info) { reader.BaseStream.Position = header.Length; DBFile file = new DBFile(header, info); int i = 0; while (reader.BaseStream.Position < reader.BaseStream.Length) { try { file.Entries.Add(ReadFields(reader, info)); i++; } catch (Exception x) { string message = string.Format("{2} at entry {0}, db version {1}", i, file.Header.Version, x.Message); throw new DBFileNotSupportedException(message, x); } } if (file.Entries.Count != header.EntryCount) { throw new DBFileNotSupportedException(string.Format("Expected {0} entries, got {1}", header.EntryCount, file.Entries.Count)); } else if (reader.BaseStream.Position != reader.BaseStream.Length) { throw new DBFileNotSupportedException(string.Format("Expected {0} bytes, read {1}", header.Length, reader.BaseStream.Position)); } return(file); }
/* * Reads a db file from stream, using the version information * contained in the header read from it. */ public DBFile Decode(Stream stream) { BinaryReader reader = new BinaryReader(stream); reader.BaseStream.Position = 0; DBFileHeader header = readHeader(reader); List <TypeInfo> infos = DBTypeMap.GetVersionedInfos(typeName, header.Version); if (infos.Count == 0) { infos.AddRange(DBTypeMap.GetAllInfos(typeName)); } foreach (TypeInfo realInfo in infos) { try { #if DEBUG Console.WriteLine("Parsing version {1} with info {0}", string.Join(",", realInfo.Fields), header.Version); #endif DBFile result = ReadFile(reader, header, realInfo); return(result); } catch (Exception) { } } return(null); // throw new DBFileNotSupportedException(string.Format("No applicable type definition found")); }
/* * Query if given packed file can be decoded. * Is not entirely reliable because it only reads the header and checks if a * type definition is available for the given GUID and/or type name and version. * The actual decode tries out all available type infos for that type name * but that is less efficient because it has to read the whole file at least once * if successful. */ public static bool CanDecode(PackedFile packedFile, out string display) { bool result = true; string key = DBFile.Typename(packedFile.FullPath); if (DBTypeMap.IsSupported(key)) { try { DBFileHeader header = PackedFileDbCodec.readHeader(packedFile); int maxVersion = DBTypeMap.MaxVersion(key); if (maxVersion != 0 && header.Version > maxVersion) { display = string.Format("{0}: needs {1}, has {2}", key, header.Version, DBTypeMap.MaxVersion(key)); result = false; } else { display = string.Format("Version: {0}", header.Version); } } catch (Exception x) { display = string.Format("{0}: {1}", key, x.Message); } } else { display = string.Format("{0}: no definition available", key); result = false; } return(result); }
public override bool Equals(object other) { bool result = false; if (other is DBFileHeader) { DBFileHeader header2 = (DBFileHeader)other; result = GUID.Equals(header2.GUID); result &= Version.Equals(header2.Version); result &= EntryCount.Equals(header2.EntryCount); } return(result); }
public static void WriteHeader(BinaryWriter writer, DBFileHeader header) { if (header.GUID != "") { writer.Write(GUID_MARKER); IOFunctions.WriteCAString(writer, header.GUID, Encoding.Unicode); } if (header.Version != 0) { writer.Write(VERSION_MARKER); writer.Write(header.Version); } writer.Write((byte)1); writer.Write(header.EntryCount); }
public static DBFileHeader readHeader(BinaryReader reader) { byte index = reader.ReadByte(); int version = 0; string guid = ""; bool hasMarker = false; uint entryCount = 0; try { if (index != 1) { // I don't think those can actually occur more than once per file while (index == 0xFC || index == 0xFD) { var bytes = new List <byte>(4); bytes.Add(index); bytes.AddRange(reader.ReadBytes(3)); UInt32 marker = BitConverter.ToUInt32(bytes.ToArray(), 0); if (marker == GUID_MARKER) { guid = IOFunctions.ReadCAString(reader, Encoding.Unicode); index = reader.ReadByte(); } else if (marker == VERSION_MARKER) { hasMarker = true; version = reader.ReadInt32(); index = reader.ReadByte(); // break; } else { throw new DBFileNotSupportedException(string.Format("could not interpret {0}", marker)); } } } entryCount = reader.ReadUInt32(); } catch { } DBFileHeader header = new DBFileHeader(guid, version, entryCount, hasMarker); return(header); }
/* * Add data contained in the given db file to this one. */ public void Import(DBFile file) { if (CurrentType.Name != file.CurrentType.Name) { throw new DBFileNotSupportedException ("File type of imported DB doesn't match that of the currently opened one", this); } // check field type compatibility for (int i = 0; i < file.CurrentType.Fields.Count; i++) { if (file.CurrentType.Fields [i].TypeCode != CurrentType.Fields [i].TypeCode) { throw new DBFileNotSupportedException ("Data structure of imported DB doesn't match that of currently opened one at field " + i, this); } } DBFileHeader h = file.Header; Header = new DBFileHeader(h.GUID, h.Version, h.EntryCount, h.HasVersionMarker); CurrentType = file.CurrentType; // this.entries = new List<List<FieldInstance>> (); entries.AddRange(file.entries); Header.EntryCount = (uint)entries.Count; }
/* * Create copy of given header. */ public DBFileHeader(DBFileHeader toCopy) : this(toCopy.GUID, toCopy.Version, 0, toCopy.HasVersionMarker) { }
/* * Create copy of the given db file. */ public DBFile(DBFile toCopy) : this(toCopy.Header, toCopy.CurrentType) { Header = new DBFileHeader(toCopy.Header.GUID, toCopy.Header.Version, toCopy.Header.EntryCount, toCopy.Header.HasVersionMarker); // we need to create a new instance for every field so we don't write through to the old data toCopy.entries.ForEach(entry => entries.Add(new DBRow(toCopy.CurrentType, entry))); }
/* * Create db file with the given header and the given type. */ public DBFile(DBFileHeader h, TypeInfo info) { Header = h; CurrentType = info; }