概要
ゲームプログラミングをしていたら思いついたコードです
C#とJson.netで、ゲームデータを読み書きするのにJsonを使うのは、なんか面倒くさかったので、
こういうコードを書いてました
(こういうコードを一から書くのも面倒っていうか)
注意点
使用したC#のバージョンは、7.3で、unsafeによるポインタ操作をしています。
更に、Newtonsoft.Json.dllというライブラリも使用してます
コード
using Newtonsoft.Json.Linq;
using System;
namespace Utility.Json {
public abstract class JsonData {
protected JToken Json { get; set; }
internal JsonData() { }
public override string ToString() => Json.ToString();
public JsonData this[string name] {
get {
if (Json[name] == null) Json[name] = new JObject();
return In(name);
}
}
JsonData In(string name) {
var nested = CreateObj();
nested.Json = Json[name];
return nested;
}
protected abstract JsonData CreateObj();
public abstract sbyte? Target(string name, sbyte? value);
public abstract short? Target(string name, short? value);
public abstract int? Target(string name, int? value);
public abstract long? Target(string name, long? value);
public abstract byte? Target(string name, byte? value);
public abstract ushort? Target(string name, ushort? value);
public abstract uint? Target(string name, uint? value);
public abstract ulong? Target(string name, ulong? value);
public abstract float? Target(string name, float? value);
public abstract double? Target(string name, double? value);
public abstract decimal? Target(string name, decimal? value);
public abstract bool? Target(string name, bool? value);
public abstract char? Target(string name, char? value);
public abstract string Target(string name, string value);
protected unsafe void SizeError<TNum, TEnum>()
where TNum : unmanaged
where TEnum : unmanaged, Enum {
var numSize = sizeof(TNum);
var enumSize = sizeof(TEnum);
if (numSize == enumSize) return;
var mes = "列挙型 " + default(TEnum).GetType().FullName + " の型サイズが、";
mes += default(TNum).GetType().FullName + " の型サイズ一致しません\n\n";
mes += "列挙型の型サイズ : " + numSize + "\n";
mes += "数値型の型サイズ : " + enumSize + "\n";
throw new Exception(mes);
}
public abstract T? TargetEnum_sbyte<T>(string name, T? value) where T : unmanaged, Enum;
public abstract T? TargetEnum_short<T>(string name, T? value) where T : unmanaged, Enum;
public abstract T? TargetEnum_int<T>(string name, T? value) where T : unmanaged, Enum;
public abstract T? TargetEnum_long<T>(string name, T? value) where T : unmanaged, Enum;
public abstract T? TargetEnum_byte<T>(string name, T? value) where T : unmanaged, Enum;
public abstract T? TargetEnum_ushort<T>(string name, T? value) where T : unmanaged, Enum;
public abstract T? TargetEnum_uint<T>(string name, T? value) where T : unmanaged, Enum;
public abstract T? TargetEnum_ulong<T>(string name, T? value) where T : unmanaged, Enum;
public T? TargetEnum_sbyte<T>(string name, T value) where T : unmanaged, Enum {
return TargetEnum_sbyte(name, (T?)value);
}
public T? TargetEnum_short<T>(string name, T value) where T : unmanaged, Enum {
return TargetEnum_short(name, (T?)value);
}
public T? TargetEnum_int<T>(string name, T value) where T : unmanaged, Enum {
return TargetEnum_int(name, (T?)value);
}
public T? TargetEnum_long<T>(string name, T value) where T : unmanaged, Enum {
return TargetEnum_long(name, (T?)value);
}
public T? TargetEnum_byte<T>(string name, T value) where T : unmanaged, Enum {
return TargetEnum_byte(name, (T?)value);
}
public T? TargetEnum_ushort<T>(string name, T value) where T : unmanaged, Enum {
return TargetEnum_ushort(name, (T?)value);
}
public T? TargetEnum_uint<T>(string name, T value) where T : unmanaged, Enum {
return TargetEnum_uint(name, (T?)value);
}
public T? TargetEnum_ulong<T>(string name, T value) where T : unmanaged, Enum {
return TargetEnum_ulong(name, (T?)value);
}
public unsafe T? TargetEnum_signed<T>(string name, T? value) where T : unmanaged, Enum {
var enumSize = sizeof(T);
if (enumSize == sizeof(sbyte)) return TargetEnum_sbyte(name, value);
else if (enumSize == sizeof(short)) return TargetEnum_short(name, value);
else if (enumSize == sizeof(int)) return TargetEnum_int(name, value);
else if (enumSize == sizeof(long)) return TargetEnum_long(name, value);
throw new Exception("出ないと思われるエラー");
}
public T? TargetEnum_signed<T>(string name, T value) where T : unmanaged, Enum {
return TargetEnum_signed(name, (T?)value);
}
public unsafe T? TargetEnum_unsigned<T>(string name, T? value) where T : unmanaged, Enum {
var enumSize = sizeof(T);
if (enumSize == sizeof(byte)) return TargetEnum_byte(name, value);
else if (enumSize == sizeof(ushort)) return TargetEnum_ushort(name, value);
else if (enumSize == sizeof(uint)) return TargetEnum_uint(name, value);
else if (enumSize == sizeof(ulong)) return TargetEnum_ulong(name, value);
throw new Exception("出ないと思われるエラー");
}
public T? TargetEnum_unsigned<T>(string name, T value) where T : unmanaged, Enum {
return TargetEnum_unsigned(name, (T?)value);
}
}
public sealed class JsonDataLoader : JsonData {
public static JsonDataLoader LoadFromText(string jsonStr) {
return new JsonDataLoader { Json = JToken.Parse(jsonStr) };
}
JsonDataLoader() { }
protected override JsonData CreateObj() => new JsonDataLoader();
public override sbyte? Target(string name, sbyte? value) {
return (sbyte?)Json[name];
}
public override short? Target(string name, short? value) {
return (short?)Json[name];
}
public override int? Target(string name, int? value) {
return (int?)Json[name];
}
public override long? Target(string name, long? value) {
return (long?)Json[name];
}
public override byte? Target(string name, byte? value) {
return (byte?)Json[name];
}
public override ushort? Target(string name, ushort? value) {
return (ushort?)Json[name];
}
public override uint? Target(string name, uint? value) {
return (uint?)Json[name];
}
public override ulong? Target(string name, ulong? value) {
return (ulong?)Json[name];
}
public override float? Target(string name, float? value) {
return (float?)Json[name];
}
public override double? Target(string name, double? value) {
return (double?)Json[name];
}
public override decimal? Target(string name, decimal? value) {
return (decimal?)Json[name];
}
public override bool? Target(string name, bool? value) {
return (bool?)Json[name];
}
public override char? Target(string name, char? value) {
return (char?)Json[name];
}
public override string Target(string name, string value) {
return (string)Json[name];
}
unsafe TEnum FromNum<TNum, TEnum>(TNum value)
where TNum : unmanaged
where TEnum : unmanaged, Enum {
SizeError<TNum, TEnum>();
return *(TEnum*)&value;
}
unsafe TEnum? FromNum<TNum, TEnum>(TNum? value)
where TNum : unmanaged
where TEnum : unmanaged, Enum {
SizeError<TNum, TEnum>();
return value.HasValue ?
(TEnum?)FromNum<TNum, TEnum>(value.Value) :
null;
}
TEnum? FromNum<TNum, TEnum>(TNum? value, TEnum enumType)
where TNum : unmanaged
where TEnum : unmanaged, Enum {
SizeError<TNum, TEnum>();
return FromNum<TNum, TEnum>(value);
}
public override T? TargetEnum_sbyte<T>(string name, T? value) {
return FromNum(Target(name, default(sbyte?)), default(T));
}
public override T? TargetEnum_short<T>(string name, T? value) {
return FromNum(Target(name, default(short?)), default(T));
}
public override T? TargetEnum_int<T>(string name, T? value) {
return FromNum(Target(name, default(int?)), default(T));
}
public override T? TargetEnum_long<T>(string name, T? value) {
return FromNum(Target(name, default(long?)), default(T));
}
public override T? TargetEnum_byte<T>(string name, T? value) {
return FromNum(Target(name, default(byte?)), default(T));
}
public override T? TargetEnum_ushort<T>(string name, T? value) {
return FromNum(Target(name, default(ushort?)), default(T));
}
public override T? TargetEnum_uint<T>(string name, T? value) {
return FromNum(Target(name, default(uint?)), default(T));
}
public override T? TargetEnum_ulong<T>(string name, T? value) {
return FromNum(Target(name, default(ulong?)), default(T));
}
}
public unsafe sealed class JsonDataSaver : JsonData {
public static JsonDataSaver CreateRoot() {
return new JsonDataSaver { Json = new JObject() };
}
JsonDataSaver() { }
protected override JsonData CreateObj() => new JsonDataSaver();
public override sbyte? Target(string name, sbyte? value) {
Json[name] = value;
return value;
}
public override short? Target(string name, short? value) {
Json[name] = value;
return value;
}
public override int? Target(string name, int? value) {
Json[name] = value;
return value;
}
public override long? Target(string name, long? value) {
Json[name] = value;
return value;
}
public override byte? Target(string name, byte? value) {
Json[name] = value;
return value;
}
public override ushort? Target(string name, ushort? value) {
Json[name] = value;
return value;
}
public override uint? Target(string name, uint? value) {
Json[name] = value;
return value;
}
public override ulong? Target(string name, ulong? value) {
Json[name] = value;
return value;
}
public override float? Target(string name, float? value) {
Json[name] = value;
return value;
}
public override double? Target(string name, double? value) {
Json[name] = value;
return value;
}
public override decimal? Target(string name, decimal? value) {
Json[name] = value;
return value;
}
public override bool? Target(string name, bool? value) {
Json[name] = value;
return value;
}
public override char? Target(string name, char? value) {
Json[name] = value;
return value;
}
public override string Target(string name, string value) {
Json[name] = value;
return value;
}
unsafe TNum FromEnum<TNum, TEnum>(TEnum @enum)
where TNum : unmanaged
where TEnum : unmanaged, Enum {
SizeError<TNum, TEnum>();
return *(TNum*)&@enum;
}
unsafe TNum? FromEnum<TNum, TEnum>(TEnum? @enum)
where TNum : unmanaged
where TEnum : unmanaged, Enum {
SizeError<TNum, TEnum>();
return @enum.HasValue ? (TNum?)FromEnum<TNum, TEnum>(@enum.Value) : null;
}
public override T? TargetEnum_sbyte<T>(string name, T? value) {
Target(name, FromEnum<sbyte, T>(value));
return value;
}
public override T? TargetEnum_short<T>(string name, T? value) {
Target(name, FromEnum<short, T>(value));
return value;
}
public override T? TargetEnum_int<T>(string name, T? value) {
Target(name, FromEnum<int, T>(value));
return value;
}
public override T? TargetEnum_long<T>(string name, T? value) {
Target(name, FromEnum<long, T>(value));
return value;
}
public override T? TargetEnum_byte<T>(string name, T? value) {
Target(name, FromEnum<byte, T>(value));
return value;
}
public override T? TargetEnum_ushort<T>(string name, T? value) {
Target(name, FromEnum<ushort, T>(value));
return value;
}
public override T? TargetEnum_uint<T>(string name, T? value) {
Target(name, FromEnum<uint, T>(value));
return value;
}
public override T? TargetEnum_ulong<T>(string name, T? value) {
Target(name, FromEnum<ulong, T>(value));
return value;
}
}
}
コードのダウンロード
・ソースのzip(ホームページに移動します)
http://mini09.web.fc2.com/codes/top.html