/* * Query if given packed file can be deccoded. * 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.Instance.IsSupported(key)) { try { DBFileHeader header = PackedFileDbCodec.readHeader(packedFile); int maxVersion = DBTypeMap.Instance.MaxVersion(key); if (maxVersion != 0 && header.Version > maxVersion) { display = string.Format("{0}: needs {1}, has {2}", key, header.Version, DBTypeMap.Instance.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); }
/* * Fills the given string collection with data from the field in the given packed file. */ public static void FillFromPacked(SortedSet <string> result, PackedFile packed, string fieldName) { DBFile dbFile = PackedFileDbCodec.Decode(packed); foreach (DBRow entry in dbFile.Entries) { string toAdd = entry[fieldName].Value; if (toAdd != null) { result.Add(toAdd); } } }
private void AddFromPacked(PackedFile packed) { if (packed.Size != 0) { string type = DBFile.Typename(packed.FullPath); DBFileHeader header = PackedFileDbCodec.readHeader(packed); int currentMaxVersion; if (!maxVersion.TryGetValue(type, out currentMaxVersion)) { currentMaxVersion = header.Version; } else { currentMaxVersion = Math.Max(header.Version, currentMaxVersion); } maxVersion[type] = currentMaxVersion; } }
// this could do with an update; since the transition to schema.xml, // we also know obsolete fields and can remove them, // and we can add fields in the middle instead of assuming they got appended. public void UpdatePackedFile(PackedFile packedFile) { string key = DBFile.Typename(packedFile.FullPath); if (DBTypeMap.Instance.IsSupported(key)) { PackedFileDbCodec codec = PackedFileDbCodec.FromFilename(packedFile.FullPath); int maxVersion = DBTypeMap.Instance.MaxVersion(key); DBFileHeader header = PackedFileDbCodec.readHeader(packedFile); if (header.Version < maxVersion) { // found a more recent db definition; read data from db file DBFile updatedFile = PackedFileDbCodec.Decode(packedFile); TypeInfo dbFileInfo = updatedFile.CurrentType; TypeInfo targetInfo = GetTargetTypeInfo(key, maxVersion); if (targetInfo == null) { throw new Exception(string.Format("Can't decide new structure for {0} version {1}.", key, maxVersion)); } // identify FieldInstances missing in db file for (int i = 0; i < targetInfo.Fields.Count; i++) { FieldInfo oldField = dbFileInfo[targetInfo.Fields[i].Name]; if (oldField == null) { foreach (List <FieldInstance> entry in updatedFile.Entries) { entry.Insert(i, targetInfo.Fields[i].CreateInstance()); } } } //updatedFile.Header.GUID = guid; updatedFile.Header.Version = maxVersion; packedFile.Data = codec.Encode(updatedFile); } } }
/* * Create DBFile from the given PackedFile. */ public static DBFile Decode(PackedFile file) { PackedFileDbCodec codec = FromFilename(file.FullPath); return(codec.Decode(file.Data)); }