Skip to content

Commit

Permalink
KeyValues update
Browse files Browse the repository at this point in the history
  • Loading branch information
ntoxin66 committed Sep 10, 2016
1 parent 24c4347 commit b5500a4
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 18 deletions.
Binary file modified plugins/dynamic.smx
Binary file not shown.
1 change: 0 additions & 1 deletion scripting/dynamic.sp
Expand Up @@ -39,7 +39,6 @@ int g_iDynamic_MemberLookup_Offset;
#include "dynamic/system/datatypes/float.sp"
#include "dynamic/system/datatypes/handle.sp"
#include "dynamic/system/datatypes/int.sp"

#include "dynamic/system/datatypes/string.sp"
#include "dynamic/system/datatypes/vector.sp"

Expand Down
97 changes: 84 additions & 13 deletions scripting/dynamic/system/keyvalues.sp
Expand Up @@ -82,16 +82,22 @@ stock void IterateKeyValues(Handle plugin, KeyValues kv, DynamicObject dynamic,

if (result == Plugin_Continue)
{
DynamicObject child = _Dynamic_GetDynamic(dynamic, key);
if (!child.IsValid(false))
if (depth == 0)
{
child = DynamicObject();
child.Initialise(plugin);

_Dynamic_SetDynamic(dynamic, key, child);
IterateKeyValues(plugin, kv, dynamic, valuelength, callbackforward, depth+1);
}
else
{
DynamicObject child = _Dynamic_GetDynamic(dynamic, key);
if (!child.IsValid(false))
{
child = DynamicObject();
child.Initialise(plugin);

_Dynamic_SetDynamic(dynamic, key, child);
}
IterateKeyValues(plugin, kv, child, valuelength, callbackforward, depth+1);
}

IterateKeyValues(plugin, kv, child, valuelength, callbackforward, depth+1);
}
kv.GoBack();
}
Expand Down Expand Up @@ -136,7 +142,7 @@ stock void IterateKeyValues(Handle plugin, KeyValues kv, DynamicObject dynamic,
while (kv.GotoNextKey(false));
}

stock bool _Dynamic_WriteKeyValues(DynamicObject dynamic, const char[] path)
stock bool _Dynamic_WriteKeyValues(DynamicObject dynamic, const char[] path, const char[] basekey)
{
if (!dynamic.IsValid(true))
return false;
Expand All @@ -151,20 +157,24 @@ stock bool _Dynamic_WriteKeyValues(DynamicObject dynamic, const char[] path)
return false;
}

WriteObjectToKeyValues(stream, dynamic, 0);
stream.WriteLine("\"%s\"", basekey);
stream.WriteLine("{");
_Dynamic_KeyValues_WriteDynamic(stream, dynamic, 1);
stream.WriteLine("}");

delete stream;
return true;
}

stock void WriteObjectToKeyValues(File stream, DynamicObject dynamic, int indent)
stock void _Dynamic_KeyValues_WriteDynamic(File stream, DynamicObject dynamic, int indent)
{
// Create indent
char indextext[16];
for (int i = 0; i < indent; i++)
indextext[i] = 9;
indextext[indent] = 0;
int length = 1024;
char buffer[1024];

int count = dynamic.MemberCount;
int memberoffset;
Expand All @@ -177,17 +187,78 @@ stock void WriteObjectToKeyValues(File stream, DynamicObject dynamic, int indent

if (type == DynamicType_Dynamic)
{
stream.WriteLine("%s\"%s\"", indextext, membername);
if (StrEqual(membername, ""))
stream.WriteLine("%s\"%d\"", indextext, i);
else
{
_Dynamic_KeyValues_EscapeString(membername, buffer, sizeof(membername));
stream.WriteLine("%s\"%s\"", indextext, buffer);
}
stream.WriteLine("%s{", indextext);
WriteObjectToKeyValues(stream, _Dynamic_GetDynamicByOffset(dynamic, memberoffset), indent+1);
_Dynamic_KeyValues_WriteDynamic(stream, _Dynamic_GetDynamicByOffset(dynamic, memberoffset), indent+1);
stream.WriteLine("%s}", indextext);
}
else
{
//length = GetStringLengthByOffset(view_as<int>(dynamic), memberoffset);
char[] membervalue = new char[length];
_Dynamic_GetStringByOffset(dynamic, memberoffset, membervalue, length);
_Dynamic_KeyValues_EscapeString(membervalue, buffer, sizeof(buffer));
stream.WriteLine("%s\"%s\"\t\"%s\"", indextext, membername, membervalue);
}
}
}

stock void _Dynamic_KeyValues_EscapeString(const char[] input, char[] output, int length)
{
int pos_in=0;
int pos_out=0;
int x;
do
{
x = input[pos_in++];
switch (x)
{
case 34: // `"` -> `\"`
{
if (pos_out+1 >= length)
return;

output[pos_out++] = 92;
output[pos_out++] = 34;
}
case 92: // `\` -> `\\`
{
if (pos_out+1 >= length)
return;

output[pos_out++] = 92;
output[pos_out++] = 92;
}
case 10: // newline -> `\n`
{
if (pos_out+1 >= length)
return;

output[pos_out++] = 92;
output[pos_out++] = 110;
}
case 13: // linefeed -> `\r`
{
if (pos_out+1 >= length)
return;

output[pos_out++] = 92;
output[pos_out++] = 114;
}
default:
{
if (pos_out == length)
return;

output[pos_out++] = x;
}
}
}
while(x != 0);
}
5 changes: 4 additions & 1 deletion scripting/dynamic/system/natives.sp
Expand Up @@ -149,7 +149,10 @@ public int Native_Dynamic_WriteKeyValues(Handle plugin, int params)
GetNativeStringLength(2, length);
char[] path = new char[length];
GetNativeString(2, path, length+1);
return _Dynamic_WriteKeyValues(dynamic, path);
GetNativeStringLength(3, length);
char[] basekey = new char[length];
GetNativeString(3, basekey, length+1);
return _Dynamic_WriteKeyValues(dynamic, path, basekey);
}

// native int Dynamic_GetInt(Dynamic obj, const char[] membername, int defaultvalue=-1);
Expand Down
109 changes: 109 additions & 0 deletions scripting/dynamic/system/selftest.sp
Expand Up @@ -119,6 +119,15 @@ public void _Dynamic_SelfTest(any userid)
}
PrintToConsole(client, "> Dynamic_FindByMemberValue test completed");

// Dynamic_KeyValues Test
test.Reset();
if (!_Dynamic_KeyValuesTest(client, test))
{
test.Dispose();
return;
}
PrintToConsole(client, "> Dynamic_KeyValues test completed");

test.Dispose();
}

Expand Down Expand Up @@ -1058,6 +1067,96 @@ stock bool _Dynamic_FindByMemberValueTest(int client, Dynamic test)
return true;
}

stock bool _Dynamic_KeyValuesTest(int client, Dynamic test)
{
// Build structure for testing
Dynamic child; Dynamic grandchild;
for (int i=0; i<3; i++)
{
child = Dynamic();
child.SetString("String", "abcd");
child.SetInt("Int", i);

grandchild = Dynamic();
grandchild.SetVector("Vector", NULL_VECTOR);
grandchild.SetFloat("Float", 66.66);
child.SetDynamic("granny", grandchild);

if (i == 1)
test.SetDynamic("SomeValue", child);
else
test.PushDynamic(child);
}

// Write test structure to disk
test.WriteKeyValues("test.txt", "BaseKeyName");

// Read test structure from disk
test.Reset();
test.ReadKeyValues("test.txt");

// Really basic tests
if (test.GetDynamicByIndex(0).GetInt("Int") != 0)
{
PrintToConsole(client, "Dynamic_KeyValuesTest test failed: ErrorCode 9x1");
PrintToConsole(client, "> %d should equal %d", test.GetDynamicByIndex(0).GetInt("Int"), 0);
return false;
}
if (test.GetDynamic("SomeValue").GetInt("Int") != 1)
{
PrintToConsole(client, "Dynamic_KeyValuesTest test failed: ErrorCode 9x2");
PrintToConsole(client, "> %d should equal %d", test.GetDynamic("SomeValue").GetInt("Int"), 1);
return false;
}
if (test.GetDynamicByIndex(2).GetInt("Int") != 2)
{
PrintToConsole(client, "Dynamic_KeyValuesTest test failed: ErrorCode 9x3");
PrintToConsole(client, "> %d should equal %d", test.GetDynamicByIndex(2).GetInt("Int"), 2);
return false;
}

// Ensure file contents match after an additional write
test.Reset();
test.ReadKeyValues("test.txt");
test.WriteKeyValues("test1.txt", "BaseKeyName");
File stream1 = OpenFile("test.txt", "r");
File stream2 = OpenFile("test1.txt", "r");
char buffer1[1024];
char buffer2[1024];
while(stream1.ReadLine(buffer1, sizeof(buffer1)))
{
if (!stream2.ReadLine(buffer2, sizeof(buffer2)))
{
PrintToConsole(client, "Dynamic_KeyValuesTest test failed: ErrorCode 9x4");
PrintToConsole(client, "> 0 should equal 1");
delete stream1; delete stream2;
return false;
}
else if (!StrEqual(buffer1, buffer2))
{
PrintToConsole(client, "Dynamic_KeyValuesTest test failed: ErrorCode 9x5");
PrintToConsole(client, "> '%s' should equal '%s'", buffer1, buffer2);
delete stream1; delete stream2;
return false;
}
}
if (stream2.ReadLine(buffer2, sizeof(buffer2)))
{
PrintToConsole(client, "Dynamic_KeyValuesTest test failed: ErrorCode 9x6");
PrintToConsole(client, "> 1 should equal 0");
delete stream1; delete stream2;
return false;
}

delete stream1;
delete stream2;

DeleteFile("test.txt");
DeleteFile("test1.txt");

return true;
}

stock bool _Dynamic_CompareVectors(const float value1[3], const float value2[3])
{
if (value1[0] != value2[0])
Expand All @@ -1067,4 +1166,14 @@ stock bool _Dynamic_CompareVectors(const float value1[3], const float value2[3])
if (value1[2] != value2[2])
return false;
return true;
}

stock int _Dynamic_HashFile(const char[] path)
{
File stream = OpenFile(path, "r");




delete stream;
}
6 changes: 3 additions & 3 deletions scripting/include/dynamic.inc
Expand Up @@ -79,7 +79,7 @@ native bool Dynamic_ReadConfig(Dynamic obj, const char[] path, bool use_valve_fs
native bool Dynamic_WriteConfig(Dynamic obj, const char[] path);

native bool Dynamic_ReadKeyValues(Dynamic obj, const char[] path, int valuelength, Dynamic_HookType callback=INVALID_FUNCTION);
native bool Dynamic_WriteKeyValues(Dynamic obj, const char[] path);
native bool Dynamic_WriteKeyValues(Dynamic obj, const char[] path, const char[] basekey);

native int Dynamic_GetMemberCount(Dynamic obj);
native int Dynamic_GetMemberOffset(Dynamic obj, const char[] membername);
Expand Down Expand Up @@ -262,9 +262,9 @@ methodmap Dynamic
return Dynamic_ReadKeyValues(this, path, valuelength, callback);
}

public bool WriteKeyValues(const char[] path)
public bool WriteKeyValues(const char[] path, const char[] basekey="")
{
return Dynamic_WriteKeyValues(this, path);
return Dynamic_WriteKeyValues(this, path, basekey);
}

public static Dynamic GetSettings()
Expand Down

0 comments on commit b5500a4

Please sign in to comment.