public string GetPath(bool excludeEntry = true) { string path = ""; if (this.Property == 0 && this.Parent is BINContainer) { path += string.Format("{0}/[{1}]", this.Parent.GetPath(excludeEntry), (this.Parent as BINContainer).Values.IndexOf(this)); } else if (this.Property == 0 && this.Parent is BINMap) { BINMap map = this.Parent as BINMap; if (map.Values.ContainsValue(this)) { path += map.Values.First(x => x.Value == this).Key.GetPath(excludeEntry); } else { if (map.KeyType == BINValueType.Byte) { path += string.Format("{0}/{1}", this.Parent.GetPath(excludeEntry), (byte)this.Value); } else if (map.KeyType == BINValueType.UInt16) { path += string.Format("{0}/{1}", this.Parent.GetPath(excludeEntry), (ushort)this.Value); } else if (map.KeyType == BINValueType.UInt32) { path += string.Format("{0}/{1}", this.Parent.GetPath(excludeEntry), (uint)this.Value); } else if (map.KeyType == BINValueType.UInt64) { path += string.Format("{0}/{1}", this.Parent.GetPath(excludeEntry), (ulong)this.Value); } else if (map.KeyType == BINValueType.String) { path += string.Format("{0}/{1}", this.Parent.GetPath(excludeEntry), (string)this.Value); } else if (map.KeyType == BINValueType.Hash) { path += string.Format("{0}/{1}", this.Parent.GetPath(excludeEntry), (uint)this.Value); } else { throw new Exception(); } } } else if (this.Property == 0 && this.Parent is BINOptional) { path += this.Parent.GetPath(excludeEntry); } else if (this.Parent is BINStructure) { path += string.Format("{0}.{1}", this.Parent.GetPath(excludeEntry), BINGlobal.GetField(this.Property)); } else if (this.Parent is BINEntry) { path += string.Format("{0}/{1}", this.Parent.GetPath(excludeEntry), BINGlobal.GetField(this.Property)); } else { path += string.Format("{0}/{1}", this.Parent.GetPath(excludeEntry), BINGlobal.GetClass(this.Property)); } return(excludeEntry ? path.Remove(0, path.IndexOf('/') + 1) : path); }
public BINValue this[string path] { get { string[] properties = path.Split('/'); string property = properties[0]; //Build next recursive property path string nextPath = string.Empty; if (properties.Length != 1) { for (int i = 1; i < properties.Length; i++) { nextPath += properties[i]; if (i + 1 != properties.Length) { nextPath += '/'; } } } //Determine the property type if (Regex.IsMatch(property, @"^\[\d+\]")) { int valueIndex = int.Parse(property.Substring(1, property.IndexOf(']') - 1)); return((this.Value as BINContainer).Values[valueIndex]); } else if (property.Contains('[') && !property.Contains('.')) { int startIndex = property.IndexOf('['); int valueIndex = int.Parse(property.Substring(startIndex + 1, property.IndexOf(']') - startIndex - 1)); if (this.Type == BINValueType.Container && (this.Value as BINContainer).EntryType == BINValueType.Embedded || (this.Value as BINContainer).EntryType == BINValueType.Structure) { BINContainer container = this.Value as BINContainer; return(container.Values[valueIndex]); } } else if (property.Contains('.')) { string[] structureProperties = property.Split('.'); string structureProperty = structureProperties[0]; string fieldProperty = structureProperties[1]; int? structureIndex = null; //Check if structure property has an array index if (structureProperty.Contains('[')) { int startIndex = structureProperty.IndexOf('['); structureIndex = int.Parse(structureProperty.Substring(startIndex + 1, structureProperty.IndexOf(']') - startIndex - 1)); structureProperty = structureProperty.Remove(structureProperty.IndexOf('[')); } uint structureHash = 0; uint fieldHash; if (structureIndex == null && !uint.TryParse(structureProperty, out structureHash)) { structureHash = Cryptography.FNV32Hash(structureProperty); } if (!uint.TryParse(fieldProperty, out fieldHash)) { fieldHash = Cryptography.FNV32Hash(fieldProperty); } BINStructure structure = (structureIndex == null) ? this.Value as BINStructure : (this.Value as BINContainer).Values[(int)structureIndex].Value as BINStructure; BINValue fieldValue = structure[fieldHash]; if (nextPath != string.Empty) { return(structure[fieldHash][nextPath]); } else { return(structure[fieldHash]); } } else if (this.Type == BINValueType.Map) { BINMap map = this.Value as BINMap; if (map.KeyType == BINValueType.Byte) { return(map[map.Values.Keys.Where(x => byte.Parse(property).Equals(x.Value)).First()]); } else if (map.KeyType == BINValueType.UInt16) { return(map[map.Values.Keys.Where(x => ushort.Parse(property).Equals(x.Value)).First()]); } else if (map.KeyType == BINValueType.UInt32) { return(map[map.Values.Keys.Where(x => uint.Parse(property).Equals(x.Value)).First()]); } else if (map.KeyType == BINValueType.UInt64) { return(map[map.Values.Keys.Where(x => ulong.Parse(property).Equals(x.Value)).First()]); } else if (map.KeyType == BINValueType.String) { return(map[map.Values.Keys.Where(x => string.Equals(property, x.Value)).First()]); } else if (map.KeyType == BINValueType.Hash) { return(map[map.Values.Keys.Where(x => uint.Parse(property).Equals(x.Value)).First()]); } else { throw new Exception("Unsupported Map Key Type: " + map.KeyType); } } return(null); } }