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); }