void ReadObjectCore() { KV1BinaryNodeType type = ReadNextNodeType(); // Keep reading values, until we reach the terminator while (type != endMarker) { ReadValue(type); type = ReadNextNodeType(); } }
void ReadValue(KV1BinaryNodeType type) { var name = Encoding.UTF8.GetString(ReadNullTerminatedBytes()); KVValue value; switch (type) { case KV1BinaryNodeType.ChildObject: listener.OnObjectStart(name); ReadObjectCore(); listener.OnObjectEnd(); return; case KV1BinaryNodeType.String: // UTF8 encoding is used for string values value = new KVObjectValue <string>(Encoding.UTF8.GetString(ReadNullTerminatedBytes()), KVValueType.String); break; case KV1BinaryNodeType.WideString: throw new NotSupportedException("Wide String is not supported, please create an issue saying where you found it: https://github.com/SteamDatabase/ValveKeyValue/issues"); case KV1BinaryNodeType.Int32: case KV1BinaryNodeType.Color: case KV1BinaryNodeType.Pointer: value = new KVObjectValue <int>(reader.ReadInt32(), KVValueType.Int32); break; case KV1BinaryNodeType.UInt64: value = new KVObjectValue <ulong>(reader.ReadUInt64(), KVValueType.UInt64); break; case KV1BinaryNodeType.Float32: var floatValue = BitConverter.ToSingle(reader.ReadBytes(4), 0); value = new KVObjectValue <float>(floatValue, KVValueType.FloatingPoint); break; case KV1BinaryNodeType.ProbablyBinary: throw new NotSupportedException("Hit kv type 9, please create an issue saying where you found it: https://github.com/SteamDatabase/ValveKeyValue/issues"); case KV1BinaryNodeType.Int64: value = new KVObjectValue <long>(reader.ReadInt64(), KVValueType.Int64); break; default: throw new ArgumentOutOfRangeException(nameof(type), type, "Unhandled binary node type."); } listener.OnKeyValuePair(name, value); }
void ReadValue(string name, KV1BinaryNodeType type) { KVValue value; switch (type) { case KV1BinaryNodeType.ChildObject: { listener.OnObjectStart(name); do { ReadObjectCore(); }while (PeekNextNodeType() != KV1BinaryNodeType.End); listener.OnObjectEnd(); return; } case KV1BinaryNodeType.String: value = new KVObjectValue <string>(ReadNullTerminatedString(), KVValueType.String); break; case KV1BinaryNodeType.WideString: throw new NotSupportedException("Wide String is not supported."); case KV1BinaryNodeType.Int32: case KV1BinaryNodeType.Color: case KV1BinaryNodeType.Pointer: value = new KVObjectValue <int>(reader.ReadInt32(), KVValueType.Int32); break; case KV1BinaryNodeType.UInt64: value = new KVObjectValue <ulong>(reader.ReadUInt64(), KVValueType.UInt64); break; case KV1BinaryNodeType.Float32: var floatValue = BitConverter.ToSingle(reader.ReadBytes(4), 0); value = new KVObjectValue <float>(floatValue, KVValueType.FloatingPoint); break; case KV1BinaryNodeType.Int64: value = new KVObjectValue <long>(reader.ReadInt64(), KVValueType.Int64); break; default: throw new ArgumentOutOfRangeException(nameof(type)); } listener.OnKeyValuePair(name, value); }
void ReadValue(KV1BinaryNodeType type) { var name = Encoding.UTF8.GetString(ReadNullTerminatedBytes()); KVValue value; switch (type) { case KV1BinaryNodeType.ChildObject: listener.OnObjectStart(name); ReadObjectCore(); listener.OnObjectEnd(); return; case KV1BinaryNodeType.String: // UTF8 encoding is used for string values value = new KVObjectValue <string>(Encoding.UTF8.GetString(ReadNullTerminatedBytes()), KVValueType.String); break; case KV1BinaryNodeType.WideString: throw new NotSupportedException("Wide String is not supported."); case KV1BinaryNodeType.Int32: case KV1BinaryNodeType.Color: case KV1BinaryNodeType.Pointer: value = new KVObjectValue <int>(reader.ReadInt32(), KVValueType.Int32); break; case KV1BinaryNodeType.UInt64: value = new KVObjectValue <ulong>(reader.ReadUInt64(), KVValueType.UInt64); break; case KV1BinaryNodeType.Float32: var floatValue = BitConverter.ToSingle(reader.ReadBytes(4), 0); value = new KVObjectValue <float>(floatValue, KVValueType.FloatingPoint); break; case KV1BinaryNodeType.Int64: value = new KVObjectValue <long>(reader.ReadInt64(), KVValueType.Int64); break; default: throw new ArgumentOutOfRangeException(nameof(type)); } listener.OnKeyValuePair(name, value); }
void DetectMagicHeader() { if (stream.Length - stream.Position < 8) { return; } if (reader.ReadUInt32() == BinaryMagicHeader) { stream.Position += 4; // Skip crc32 // There is likely to reason to handle this separately // as the types do not conflict between Steam or Dota 2 endMarker = KV1BinaryNodeType.AlternateEnd; } else { stream.Position -= 4; // Go back as we did not detect the header } }
void Write(KV1BinaryNodeType nodeType) { writer.Write((byte)nodeType); }