public void Deserialize(XmlAttribute xml) { var name = xml.Name; if (name[0] == '_') { Hash = int.Parse(name.Substring(1), NumberStyles.HexNumber); } else { // known attribute :) Name = name; } var type = AttributeTypes.GetType(Hash); // try resolving the full name, e.g. 'Class.bProperty' var fullHash = StringHasher.GetHash(FullName); if (fullHash != Hash) { if (AttributeTypes.IsTypeKnown(fullHash)) { type = AttributeTypes.GetType(fullHash); } } Data = new AttributeData(type, xml.Value); // looks to be part of the spec :/ //if (Data.Type != type) // Debug.WriteLine($"Attribute '{FullName}' was created as a '{type.ToString()}' but was actually a '{Data.Type.ToString()}'!"); }
public StringId(string name) { m_Length = name.Length; m_Hash = StringHasher.GetHash(name); m_Name = name; }
public static void RegisterType(string name, DataType type) { var hash = StringHasher.GetHash(name); if (!m_userTypes.ContainsKey(hash)) { m_userTypes.Add(hash, type); } }
public void Deserialize(BinaryStream stream, bool readHash) { if (readHash) { var hash = stream.ReadInt32(); var name = StringHasher.ResolveHash(hash); var type = AttributeTypes.GetType(hash); // cannot be null or contain spaces var nameResolved = ((name != null) && !name.Contains(" ")); if (nameResolved) { Name = name; } else { Hash = hash; } // try resolving the full name, e.g. 'Class.bProperty' var fullHash = StringHasher.GetHash(FullName); if (fullHash != hash) { if (AttributeTypes.IsTypeKnown(fullHash)) { type = AttributeTypes.GetType(fullHash); } } Data = new AttributeData(type); } else { Deserialize(stream); } }
public void Deserialize(NodeClass node) { if (node.Attributes.Count > 0) { foreach (var attr in node.Attributes) { if (attr.Hash == StringHasher.GetHash("Name")) { Name = attr.Data.ToString(); break; } } } var nChildren = node.Children.Count; Entries = new List <EntityReference>(nChildren); // _256A1FF9 nodes foreach (var group in node.Children) { if (group.Children.Count != 1) { throw new InvalidOperationException("Houston, we got a bit of a problem..."); } var entry = new EntityReference() { Use32Bit = Use32Bit, GroupNode = group, EntityNode = group.Children[0], }; Entries.Add(entry); } }
public static byte[] Parse(string s, ref DataType type) { if (s.Length == 0) { // the following MUST have a null terminator! switch (type) { case DataType.String: case DataType.RML: return(new byte[1] { 0 }); } switch (type) { case DataType.StringId: case DataType.PathId: type = DataType.BinHex; return(BitConverter.GetBytes(-1)); } // for others, the resulting buffer can be empty return(new byte[0]); } switch (type) { case DataType.Bool: case DataType.Byte: { var value = byte.Parse(s); return(new byte[1] { value }); } case DataType.Int16: { var value = short.Parse(s); return(BitConverter.GetBytes(value)); } case DataType.UInt16: { var value = ushort.Parse(s); return(BitConverter.GetBytes(value)); } case DataType.Int32: { var value = int.Parse(s); return(BitConverter.GetBytes(value)); } case DataType.UInt32: { var value = uint.Parse(s); return(BitConverter.GetBytes(value)); } case DataType.Float: { var value = float.Parse(s); return(BitConverter.GetBytes(value)); } case DataType.Vector2: case DataType.Vector3: case DataType.Vector4: { var vals = s.Split(','); if (vals.Length < 2) { throw new InvalidOperationException($"Invalid vector value '{s}'"); } var fVals = new float[4]; for (int i = 0; i < vals.Length; i++) { fVals[i] = float.Parse(vals[i]); } var nVals = 0; if (type == DataType.Vector2) { nVals = 2; } if (type == DataType.Vector3) { nVals = 3; } if (type == DataType.Vector4) { nVals = 4; } var buffer = new byte[nVals * 4]; for (int v = 0; v < nVals; v++) { var f = BitConverter.GetBytes(fVals[v]); System.Buffer.BlockCopy(f, 0, buffer, (v * 4), 4); } return(buffer); } case DataType.RML: return(Utils.GetStringBuffer(s)); } switch (s[0]) { // StringId case '$': var str = s.Substring(1); var hash = StringHasher.GetHash(str); StringHasher.AddToLookup(str); type = DataType.StringId; return(BitConverter.GetBytes(hash)); // BinHex case '#': { if (Utils.IsHexString(s)) { type = DataType.BinHex; return(Utils.HexString2Bytes(s)); } } break; // Array case '[': { // strip the braces var aryStr = s.Substring(1, s.Length - 2); var aryVals = aryStr.Split(','); var count = aryVals.Length; var offset = 0; var size = -1; byte[] buffer = null; for (int i = 0; i < count; i++) { var aryVal = aryVals[i]; var value = Utils.HexString2Bytes(aryVal); if (buffer == null) { size = value.Length; buffer = new byte[(count * size) + 4]; var cBuf = BitConverter.GetBytes(count); System.Buffer.BlockCopy(cBuf, 0, buffer, 0, 4); offset = 4; } else { if (value.Length != size) { throw new InvalidDataException("Array element size mismatch!"); } } System.Buffer.BlockCopy(value, 0, buffer, offset, size); offset += size; } return(buffer); } } if (Utils.IsHexString(s)) { return(Utils.HexString2Bytes(s)); } // return as string type = DataType.String; // if it's a StringId, require '$' prefix if (type == DataType.StringId) { throw new InvalidDataException("Malformed StringId -- string must have a prefix!"); } return(Utils.GetStringBuffer(s)); }
private static bool RegisterTypeToLookup(TypeLookup lookup, string name, int hash, DataType type) { if (name != null) { if (hash != -1) { // add manual lookup StringHasher.AddToLookup(hash, name); } else { hash = StringHasher.GetHash(name); // try adding this to the lookup if (!StringHasher.CanResolveHash(hash)) { Debug.WriteLine($"- Adding '{name}' to lookup"); StringHasher.AddToLookup(name); } } if (!lookup.ContainsKey(hash)) { lookup.Add(hash, type); } var id = name; var parentId = ""; var splitIdx = name.LastIndexOf('.'); if (splitIdx != -1) { parentId = name.Substring(0, splitIdx); id = name.Substring(splitIdx + 1); StringHasher.AddToLookup(parentId); StringHasher.AddToLookup(id); } // auto-register accompanying "text_*" string if ((type == DataType.StringId) || (type == DataType.PathId)) { id = $"text_{id}"; if (!String.IsNullOrEmpty(parentId)) { id = $"{parentId}.{id}"; } RegisterTypeToLookup(lookup, id, -1, DataType.String); } } else { // empty attribute!? if (hash == -1) { return(false); } //--var canResolve = StringHasher.CanResolveHash(hash); //-- //--name = (canResolve) //-- ? StringHasher.ResolveHash(hash) //-- : $"_{hash:X8}"; //-- //--if (canResolve) //--{ //-- if (IsTypeKnown(hash)) //-- { //-- var knownType = GetType(hash); //-- //-- //WriteUniqueHint($"<!-- Remove: --><Attribute Hash=\"{attrHash:X8}\" Type=\"{attrType.ToString()}\" /><!-- SameAs --><Attribute Name=\"{name}\" Type=\"{knownType.ToString()}\" />"); //-- } //-- else //-- { //-- //WriteUniqueHint($"<!-- Rename: --><Attribute Hash=\"{attrHash:X8}\" Type=\"{attrType.ToString()}\" /><!-- EqualTo --><Attribute Name=\"{name}\" Type=\"{attrType.ToString()}\" />"); //-- } //--} if (!lookup.ContainsKey(hash)) { lookup.Add(hash, type); } } return(true); }