private NodeAttribute ReadAttribute(JsonReader reader)
{
string key = "", handle = null;
List <TranslatedFSStringArgument> fsStringArguments = null;
NodeAttribute attribute = null;
while (reader.Read())
{
if (reader.TokenType == JsonToken.EndObject)
{
break;
}
else if (reader.TokenType == JsonToken.PropertyName)
{
key = reader.Value.ToString();
}
else if (reader.TokenType == JsonToken.String ||
reader.TokenType == JsonToken.Integer ||
reader.TokenType == JsonToken.Float ||
reader.TokenType == JsonToken.Boolean)
{
if (key == "type")
{
var type = (NodeAttribute.DataType)Convert.ToUInt32(reader.Value);
attribute = new NodeAttribute(type);
}
else if (key == "value")
{
switch (attribute.Type)
{
case NodeAttribute.DataType.DT_Byte:
attribute.Value = Convert.ToByte(reader.Value);
break;
case NodeAttribute.DataType.DT_Short:
attribute.Value = Convert.ToInt16(reader.Value);
break;
case NodeAttribute.DataType.DT_UShort:
attribute.Value = Convert.ToUInt16(reader.Value);
break;
case NodeAttribute.DataType.DT_Int:
attribute.Value = Convert.ToInt32(reader.Value);
break;
case NodeAttribute.DataType.DT_UInt:
attribute.Value = Convert.ToUInt32(reader.Value);
break;
case NodeAttribute.DataType.DT_Float:
attribute.Value = Convert.ToSingle(reader.Value);
break;
case NodeAttribute.DataType.DT_Double:
attribute.Value = Convert.ToDouble(reader.Value);
break;
case NodeAttribute.DataType.DT_Bool:
attribute.Value = Convert.ToBoolean(reader.Value);
break;
case NodeAttribute.DataType.DT_String:
case NodeAttribute.DataType.DT_Path:
case NodeAttribute.DataType.DT_FixedString:
case NodeAttribute.DataType.DT_LSString:
case NodeAttribute.DataType.DT_WString:
case NodeAttribute.DataType.DT_LSWString:
attribute.Value = reader.Value.ToString();
break;
case NodeAttribute.DataType.DT_ULongLong:
if (reader.Value.GetType() == typeof(System.Int64))
{
attribute.Value = Convert.ToUInt64((long)reader.Value);
}
else if (reader.Value.GetType() == typeof(BigInteger))
{
attribute.Value = (ulong)((BigInteger)reader.Value);
}
else
{
attribute.Value = (ulong)reader.Value;
}
break;
// TODO: Not sure if this is the correct format
case NodeAttribute.DataType.DT_ScratchBuffer:
attribute.Value = Convert.FromBase64String(reader.Value.ToString());
break;
case NodeAttribute.DataType.DT_Long:
case NodeAttribute.DataType.DT_Int64:
attribute.Value = Convert.ToInt64(reader.Value);
break;
case NodeAttribute.DataType.DT_Int8:
attribute.Value = Convert.ToSByte(reader.Value);
break;
case NodeAttribute.DataType.DT_TranslatedString:
{
if (attribute.Value == null)
{
attribute.Value = new TranslatedString();
}
var ts = (TranslatedString)attribute.Value;
ts.Value = reader.Value.ToString();
ts.Handle = handle;
break;
}
case NodeAttribute.DataType.DT_TranslatedFSString:
{
var fsString = new TranslatedFSString();
fsString.Value = reader.Value.ToString();
fsString.Handle = handle;
fsString.Arguments = fsStringArguments;
attribute.Value = fsString;
break;
}
case NodeAttribute.DataType.DT_UUID:
attribute.Value = new Guid(reader.Value.ToString());
break;
case NodeAttribute.DataType.DT_IVec2:
case NodeAttribute.DataType.DT_IVec3:
case NodeAttribute.DataType.DT_IVec4:
{
string[] nums = reader.Value.ToString().Split(' ');
int length = attribute.GetColumns();
if (length != nums.Length)
{
throw new FormatException(String.Format("A vector of length {0} was expected, got {1}", length, nums.Length));
}
int[] vec = new int[length];
for (int i = 0; i < length; i++)
{
vec[i] = int.Parse(nums[i]);
}
attribute.Value = vec;
break;
}
case NodeAttribute.DataType.DT_Vec2:
case NodeAttribute.DataType.DT_Vec3:
case NodeAttribute.DataType.DT_Vec4:
{
string[] nums = reader.Value.ToString().Split(' ');
int length = attribute.GetColumns();
if (length != nums.Length)
{
throw new FormatException(String.Format("A vector of length {0} was expected, got {1}", length, nums.Length));
}
float[] vec = new float[length];
for (int i = 0; i < length; i++)
{
vec[i] = float.Parse(nums[i]);
}
attribute.Value = vec;
break;
}
case NodeAttribute.DataType.DT_Mat2:
case NodeAttribute.DataType.DT_Mat3:
case NodeAttribute.DataType.DT_Mat3x4:
case NodeAttribute.DataType.DT_Mat4x3:
case NodeAttribute.DataType.DT_Mat4:
var mat = Matrix.Parse(reader.Value.ToString());
if (mat.cols != attribute.GetColumns() || mat.rows != attribute.GetRows())
{
throw new FormatException("Invalid column/row count for matrix");
}
attribute.Value = mat;
break;
case NodeAttribute.DataType.DT_None:
default:
throw new NotImplementedException("Don't know how to unserialize type " + attribute.Type.ToString());
}
}
else if (key == "handle")
{
if (attribute != null && attribute.Type == NodeAttribute.DataType.DT_TranslatedString)
{
if (attribute.Value == null)
{
attribute.Value = new TranslatedString();
}
var ts = (TranslatedString)attribute.Value;
ts.Handle = reader.Value.ToString();
}
else
{
handle = reader.Value.ToString();
}
}
else if (key == "version")
{
if (attribute.Value == null)
{
attribute.Value = new TranslatedString();
}
var ts = (TranslatedString)attribute.Value;
ts.Version = UInt16.Parse(reader.Value.ToString());
}
else
{
throw new InvalidDataException("Unknown property encountered during attribute parsing: " + key);
}
}
else if (reader.TokenType == JsonToken.StartArray && key == "arguments")
{
var args = ReadFSStringArguments(reader);
if (attribute.Value != null)
{
var fs = ((TranslatedFSString)attribute.Value);
fs.Arguments = args;
}
else
{
fsStringArguments = args;
}
}
else
{
throw new InvalidDataException("Unexpected JSON token during parsing of attribute: " + reader.TokenType);
}
}
return(attribute);
}