Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fsEnumConverter will fail on ulong enums stored as strings #147

Open
lazlo-bonin opened this issue Oct 10, 2017 · 0 comments
Open

fsEnumConverter will fail on ulong enums stored as strings #147

lazlo-bonin opened this issue Oct 10, 2017 · 0 comments

Comments

@lazlo-bonin
Copy link
Contributor

lazlo-bonin commented Oct 10, 2017

If an enum is defined with a backing ulong field, fsEnumConverter will be unable to deserialize it.

For example:

public enum Test : ulong
{
    A, B, C
}

No time to make a diff or a pull request, but here's my fix for the TryDeserialize method:

public override fsResult TryDeserialize(fsData data, ref object instance, Type storageType)
{
	if (data.IsString)
	{
		var enumValues = data.AsString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

		for (var i = 0; i < enumValues.Length; ++i)
		{
			var enumValue = enumValues[i];

			// Verify that the enum name exists; Enum.TryParse is only
			// available in .NET 4.0 and above :(.
			if (ArrayContains(Enum.GetNames(storageType), enumValue) == false)
			{
				return fsResult.Fail("Cannot find enum name " + enumValue + " on type " + storageType);
			}
		}

		var underlyingType = Enum.GetUnderlyingType(storageType);

		if (underlyingType == typeof(ulong))
		{
			ulong instanceValue = 0;

			for (var i = 0; i < enumValues.Length; ++i)
			{
				var enumValue = enumValues[i];
				var flagValue = (ulong)Convert.ChangeType(Enum.Parse(storageType, enumValue), typeof(ulong));
				instanceValue |= flagValue;
			}

			instance = Enum.ToObject(storageType, (object)instanceValue);
		}
		else
		{
			long instanceValue = 0;

			for (var i = 0; i < enumValues.Length; ++i)
			{
				var enumValue = enumValues[i];
				var flagValue = (long)Convert.ChangeType(Enum.Parse(storageType, enumValue), typeof(long));
				instanceValue |= flagValue;
			}

			instance = Enum.ToObject(storageType, (object)instanceValue);
		}

		return fsResult.Success;

	}
	else if (data.IsInt64)
	{
		var enumValue = (int)data.AsInt64;

		// In .NET compact, Enum.ToObject(Type, Object) is defined but
		// the overloads like Enum.ToObject(Type, int) are not -- so we
		// get around this by boxing the value.
		instance = Enum.ToObject(storageType, (object)enumValue);

		return fsResult.Success;
	}

	return fsResult.Fail($"EnumConverter encountered an unknown JSON data type for {storageType}: {data.Type}")
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant