Skip to content

Commit

Permalink
Implement binary blobs
Browse files Browse the repository at this point in the history
  • Loading branch information
xPaw committed Dec 2, 2022
1 parent ff6bbe7 commit a157a15
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@
"2" "3"
"3" "7"
}
"7" "hello.world"
"8" "multiline
"7" "11 FF"
"8" "hello.world"
"9" "multiline
string"
"9" "-69.42"
"10" "-69.42"
}
"test" "success"
}
14 changes: 12 additions & 2 deletions ValveKeyValue/ValveKeyValue.Test/TextKV3/BasicKV3TestCases.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,12 @@ public void DeserializesArray()
using var stream = TestDataHelper.OpenResource("TextKV3.array.kv3");
var data = KVSerializer.Create(KVSerializationFormat.KeyValues3Text).Deserialize(stream);

Assert.True(false);
Assert.That(data["arrayValue"].ValueType, Is.EqualTo(KVValueType.Array));
Assert.That(data["arrayOnSingleLine"].ValueType, Is.EqualTo(KVValueType.Array));
Assert.That(data["arrayNoSpace"].ValueType, Is.EqualTo(KVValueType.Array));
Assert.That(data["arrayMixedTypes"].ValueType, Is.EqualTo(KVValueType.Array));

// TODO: Test all the children values
}

[Test]
Expand All @@ -99,7 +104,12 @@ public void DeserializesBinaryBlob()
using var stream = TestDataHelper.OpenResource("TextKV3.binary_blob.kv3");
var data = KVSerializer.Create(KVSerializationFormat.KeyValues3Text).Deserialize(stream);

Assert.True(false);
Assert.That(data["array"].ValueType, Is.EqualTo(KVValueType.BinaryBlob));
Assert.That(((KVBinaryBlob)data["array"]).Bytes, Is.EqualTo(new byte[]
{
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xFF
}));
}

[Test]
Expand Down
5 changes: 1 addition & 4 deletions ValveKeyValue/ValveKeyValue/Abstraction/KVObjectVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,13 @@ void VisitObject(string name, KVValue value, bool isArray)
listener.OnObjectEnd();
break;

case KVValueType.BinaryBlob:
// TODO: write binary blobs
break;

case KVValueType.Array:
listener.OnArrayStart(name, value.Flag);
VisitArray((IEnumerable<KVValue>)value);
listener.OnArrayEnd();
break;

case KVValueType.BinaryBlob: // TODO: Should binary blobs have their own method?
case KVValueType.FloatingPoint:
case KVValueType.Int32:
case KVValueType.Pointer:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,11 @@ void ReadText(string text)

void ReadBinaryBlob(string text)
{
var bytes = Utils.ParseHexStringAsByteArray(text);
//var value = new KVObjectValue<byte[]>(bytes, KVValueType.BinaryBlob);
var value = new KVObjectValue<byte>(0x00, KVValueType.BinaryBlob); // TODO: wrong
value.Flag = stateMachine.GetAndResetFlag();
var bytes = Utils.ParseHexStringAsByteArrayNoReverse(text);
var value = new KVBinaryBlob(bytes)
{
Flag = stateMachine.GetAndResetFlag()
};

switch (stateMachine.Current)
{
Expand Down
123 changes: 123 additions & 0 deletions ValveKeyValue/ValveKeyValue/KVBinaryBlob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
using System;
using System.Text;

namespace ValveKeyValue
{
public class KVBinaryBlob : KVValue
{
public byte[] Bytes { get; }

public override KVValueType ValueType => KVValueType.BinaryBlob;

public KVBinaryBlob(byte[] value)
{
Bytes = value;
}

#region IConvertible

public override TypeCode GetTypeCode()
{
throw new NotSupportedException();
}

public override bool ToBoolean(IFormatProvider provider)
{
throw new NotSupportedException();
}

public override byte ToByte(IFormatProvider provider)
{
throw new NotSupportedException();
}

public override char ToChar(IFormatProvider provider)
{
throw new NotSupportedException();
}

public override DateTime ToDateTime(IFormatProvider provider)
{
throw new NotSupportedException();
}

public override decimal ToDecimal(IFormatProvider provider)
{
throw new NotSupportedException();
}

public override double ToDouble(IFormatProvider provider)
{
throw new NotSupportedException();
}

public override short ToInt16(IFormatProvider provider)
{
throw new NotSupportedException();
}

public override int ToInt32(IFormatProvider provider)
{
throw new NotSupportedException();
}

public override long ToInt64(IFormatProvider provider)
{
throw new NotSupportedException();
}

public override sbyte ToSByte(IFormatProvider provider)
{
throw new NotSupportedException();
}

public override float ToSingle(IFormatProvider provider)
{
throw new NotSupportedException();
}

public override string ToString(IFormatProvider provider)
=> ToString();

public override object ToType(Type conversionType, IFormatProvider provider)
{
throw new NotSupportedException();
}

public override ushort ToUInt16(IFormatProvider provider)
{
throw new NotSupportedException();
}

public override uint ToUInt32(IFormatProvider provider)
{
throw new NotSupportedException();
}

public override ulong ToUInt64(IFormatProvider provider)
{
throw new NotSupportedException();
}

#endregion

public override string ToString()
{
var builder = new StringBuilder();

foreach (var oneByte in Bytes)
{
builder.Append(oneByte.ToString("X2"));
builder.Append(' ');
}

// Remove final space
if (builder.Length > 1)
{
builder.Length -= 1;
}

return builder.ToString();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
using ValveKeyValue.Abstraction;
Expand Down Expand Up @@ -142,6 +144,9 @@ void WriteValue(KVValue value)

switch (value.ValueType)
{
case KVValueType.BinaryBlob:
WriteBinaryBlob((KVBinaryBlob)value);
break;
case KVValueType.Boolean:
if ((bool)value)
{
Expand All @@ -166,6 +171,49 @@ void WriteValue(KVValue value)
}
}

void WriteBinaryBlob(KVBinaryBlob value)
{
// TODO: Verify this against Valve
if (value.Bytes.Length > 32)
{
writer.WriteLine();
WriteIndentation();
}

writer.Write('#');
writer.Write('[');
writer.WriteLine();
indentation++;
WriteIndentation();

var count = 0;

foreach (var oneByte in value.Bytes)
{
writer.Write(oneByte.ToString("X2"));

if (++count % 32 == 0)
{
writer.WriteLine();
WriteIndentation();
}
else if (count != value.Bytes.Length)
{
writer.Write(' ');
}
}

indentation--;

if (count % 32 != 0)
{
writer.WriteLine();
WriteIndentation();
}

writer.Write(']');
}

void WriteIndentation()
{
if (indentation == 0)
Expand Down
15 changes: 15 additions & 0 deletions ValveKeyValue/ValveKeyValue/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ namespace ValveKeyValue
{
internal class Utils
{
// TODO: Need to figure out whether Array.Reverse is actually correct for kv1
public static byte[] ParseHexStringAsByteArrayNoReverse(string hexadecimalRepresentation)
{
Require.NotNull(hexadecimalRepresentation, nameof(hexadecimalRepresentation));

var data = new byte[hexadecimalRepresentation.Length / 2];
for (var i = 0; i < data.Length; i++)
{
var currentByteText = hexadecimalRepresentation.Substring(i * 2, 2);
data[i] = byte.Parse(currentByteText, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}

return data;
}

public static byte[] ParseHexStringAsByteArray(string hexadecimalRepresentation)
{
Require.NotNull(hexadecimalRepresentation, nameof(hexadecimalRepresentation));
Expand Down

0 comments on commit a157a15

Please sign in to comment.