/// <summary> /// 增加一个键值对 /// </summary> public void Add(int key, LPCValue value) { confirm_map_int(); // 重置数据 _mapInt[key] = value; }
/// <summary> /// 在array中查询指定元素的所在处索引 /// </summary> public int IndexOf(LPCValue val) { // 都是null返回-1 if (_list == null || val == null) { return(-1); } // int类型 if (val.IsInt) { return(IndexOf(val.AsInt)); } // float类型 else if (val.IsFloat) { return(IndexOf(val.AsFloat)); } // string类型 else if (val.IsString) { return(IndexOf(val.AsString)); } // 返回数据 return(_list.IndexOf(val)); }
/// <summary> /// 增加一个键值对 /// </summary> public void Add(string key, LPCValue value) { confirm_map_str(); // 重置数据 _mapStr[key] = value; }
private static LPCValue RestoreString(ref string content, ref int offset) { int len = content.Length; int start_offset = offset; int count = 0; while (offset < len) { char c = content [offset]; if (c == '"') { offset++; break; } if (c == '\\') { offset += 2; count += 2; continue; } offset++; count++; } string str = content.Substring(start_offset, count); str.Replace("\\\"", "\""); str.Replace("\\\\", "\\"); str.Replace("\r", "\n"); LPCValue v = LPCValue.Create(str); return(v); }
// Duplicate an lpcvalue object public static LPCValue Duplicate(LPCValue val) { if (val.IsInt) { return(Create(val.AsInt)); } else if (val.IsFloat) { return(Create(val.AsFloat)); } else if (val.IsString) { return(Create(val.AsString)); } else if (val.IsBuffer) { return(Create((byte[])val.AsBuffer.Clone())); } else if (val.IsArray) { LPCArray dupVal = LPCArray.Empty; foreach (LPCValue element in val.AsArray.Values) { dupVal.Add(Duplicate(element)); } return(LPCValue.Create(dupVal)); } else if (val.IsMapping) { LPCMapping dupVal = LPCMapping.Empty; LPCMapping valMap = val.AsMapping; foreach (object key in valMap.Keys) { if (key is int) { int keyInt = (int)key; dupVal.Add(keyInt, Duplicate(valMap[keyInt])); continue; } else if (key is string) { string keyStr = (string)key; dupVal.Add(keyStr, Duplicate(valMap[keyStr])); continue; } throw new Exception("Unexpected key type."); } return(LPCValue.Create(dupVal)); } else { throw new Exception("Unexpected duplicated."); } }
public LPCArray Copy() { LPCValue dst = LPCValue.CreateArray(); foreach (LPCValue v in this.Values) { dst.AsArray.Add(v); } return(dst.AsArray); }
/// <summary> /// 测试是否含有指定的value值 /// </summary> public bool ContainsValue(LPCValue val) { if ((_mapStr != null) && _mapStr.ContainsValue(val)) { return(true); } if ((_mapInt != null) && _mapInt.ContainsValue(val)) { return(true); } return(false); }
/// <summary> /// 将一个数据插入到列表尾部 /// </summary> /// <param name="val"></param> public void Add(object val) { confirm_list(); if (!(val is LPCValue)) { _list.Add(LPCValue.Create(val)); } else { _list.Add((val as LPCValue)); } }
private static LPCValue RestoreBuffer(ref string content, ref int offset) { List <byte> bytes = new List <byte>(); int len = content.Length; bool ending_flag = false; while (offset < len) { switch (content [offset]) { case ':': offset++; ending_flag = true; break; default: { int v1 = content [offset]; offset++; int v2 = content [offset]; offset++; if (v1 >= '0' && v1 <= '9') { v1 = v1 - '0'; } if (v1 >= 'A' && v1 <= 'F') { v1 = v1 - 'A' + 10; } if (v2 >= '0' && v2 <= '9') { v2 = v2 - '0'; } if (v2 >= 'A' && v2 <= 'F') { v2 = v2 - 'A' + 10; } int val = v1 * 16 + v2; bytes.Add((byte)val); } break; } if (ending_flag) { break; } } return(LPCValue.Create(bytes.ToArray())); }
/// <summary> /// 增加一个键值对 /// </summary> public void Add(int key, object value) { confirm_map_int(); // 重置数据 if (!(value is LPCValue)) { _mapInt[key] = LPCValue.Create(value); } else { _mapInt[key] = value as LPCValue; } }
/// <summary> /// 增加一个键值对 /// </summary> public void Add(string key, object value) { confirm_map_str(); // 重置数据 if (!(value is LPCValue)) { _mapStr[key] = LPCValue.Create(value); } else { _mapStr[key] = value as LPCValue; } }
/// <summary> /// 移除索引处的值 /// </summary> /// <param name="idx"></param> public void Remove(LPCValue value) { // 都是null返回-1 if (_list == null || value == null) { return; } // int类型 if (value.IsInt) { IndexOf(value.AsInt); } // float类型 else if (value.IsFloat) { IndexOf(value.AsFloat); } // string类型 else if (value.IsString) { IndexOf(value.AsString); } { // 删除指定数据 int idx = 0; while (true) { // 已经到达了数组边界 if (idx >= _list.Count) { break; } // 不相等 if (_list [idx] != value) { idx++; continue; } // 移除数据 _list.RemoveAt(idx); } } }
// "1000", "100.38","0.98","-1000", "-100.38", "-0.98" private static LPCValue RestoreNumber(ref string content, ref int offset) { int len = content.Length; int start_offset = offset; bool is_float = false; int count = 0; while (offset < len) { char c = content [offset]; if (c == '.') { is_float = true; } if ((c == '-') || (c == '.') || ((c >= '0') && (c <= '9'))) { offset++; count++; continue; } break; } string numberstr = content.Substring(start_offset, count); if (is_float) { float fval = (float)System.Convert.ToDouble(numberstr); return(LPCValue.Create(fval)); } int ival = System.Convert.ToInt32(numberstr); return(LPCValue.Create(ival)); }
/// 创建 public static LPCValue Create(object val) { LPCValue v = new LPCValue(); Type valType = val.GetType(); if (valType == typeof(int)) { v.AsInt = (int)val; } else if (valType == typeof(float)) { v.AsFloat = (float)val; } else if (valType == typeof(string)) { v.AsString = (string)val; } else if (valType == typeof(byte[])) { v.AsBuffer = (byte[])val; } else if (valType == typeof(LPCArray)) { v.AsArray = (LPCArray)val; } else if (valType == typeof(LPCMapping)) { v.AsMapping = (LPCMapping)val; } else { throw new Exception("不识别的类型"); } return(v); }
// Duplicate an lpcvalue object public static LPCValue Duplicate(LPCMapping val) { LPCMapping dupVal = new LPCMapping(); foreach (object key in val.Keys) { if (key is int) { int keyInt = (int)key; dupVal.Add(keyInt, Duplicate(val[keyInt])); continue; } else if (key is string) { string keyStr = (string)key; dupVal.Add(keyStr, Duplicate(val[keyStr])); continue; } throw new Exception("Unexpected key type."); } // 返回数据 return(LPCValue.Create(dupVal)); }
private static LPCValue RestoreArray(ref string content, ref int offset) { int len = content.Length; LPCValue arr = LPCValue.CreateArray(); while (offset < len) { switch (content [offset]) { case '"': { offset++; LPCValue v = RestoreString(ref content, ref offset); arr.AsArray.Add(v); } break; case ':': { offset++; LPCValue v = RestoreBuffer(ref content, ref offset); arr.AsArray.Add(v); } break; case '(': offset++; if (content [offset] == '{') { offset++; LPCValue v = RestoreArray(ref content, ref offset); arr.AsArray.Add(v); } else if (content [offset] == '[') { offset++; LPCValue v = RestoreMapping(ref content, ref offset); arr.AsArray.Add(v); } break; case '}': { offset++; if (content [offset] == ')') { offset++; return(arr); } } break; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { LPCValue v = RestoreNumber(ref content, ref offset); arr.AsArray.Add(v); } break; case '@': { // alias offset++; LPCValue v = RestoreAlias(ref content, ref offset); arr.AsArray.Add(v); } break; default: offset++; break; } } return(arr); }
/// <summary> /// 设置索引处的值 /// </summary> public void Set(int idx, object val) { confirm_list(); _list [idx] = LPCValue.Create(val); }
/// <summary> /// 设置索引处的值 /// </summary> public void Set(int idx, LPCValue val) { confirm_list(); _list [idx] = val; }
private static LPCValue RestoreMapping(ref string content, ref int offset) { int len = content.Length; LPCValue m = LPCValue.CreateMapping(); LPCValue map_key = LPCValue.Create(); while (offset < len) { switch (content [offset]) { case '@': { offset++; LPCValue v = RestoreAlias(ref content, ref offset); SkipSpaceChar(ref content, ref offset); if (CheckKeyCompleted(ref content, ref offset)) { map_key = v; } else if (CheckValueCompleted(ref content, ref offset)) { if (map_key.IsInt) { m.AsMapping.Add(map_key.AsInt, v); } else if (map_key.IsString) { m.AsMapping.Add(map_key.AsString, v); } else { throw new Exception("Bad mapping key(int && string only)"); } } } break; case '"': { offset++; LPCValue v = RestoreString(ref content, ref offset); SkipSpaceChar(ref content, ref offset); if (CheckKeyCompleted(ref content, ref offset)) { map_key = v; } else if (CheckValueCompleted(ref content, ref offset)) { if (map_key.IsInt) { m.AsMapping.Add(map_key.AsInt, v); } else if (map_key.IsString) { m.AsMapping.Add(map_key.AsString, v); } else { throw new Exception("Bad mapping key(int && string only)"); } } } break; case ':': { offset++; LPCValue v = RestoreBuffer(ref content, ref offset); SkipSpaceChar(ref content, ref offset); if (CheckKeyCompleted(ref content, ref offset)) { map_key = v; } else if (CheckValueCompleted(ref content, ref offset)) { if (map_key.IsInt) { m.AsMapping.Add(map_key.AsInt, v); } else if (map_key.IsString) { m.AsMapping.Add(map_key.AsString, v); } else { throw new Exception("Bad mapping key(int && string only)"); } } } break; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { LPCValue v = RestoreNumber(ref content, ref offset); SkipSpaceChar(ref content, ref offset); if (CheckKeyCompleted(ref content, ref offset)) { map_key = v; } else if (CheckValueCompleted(ref content, ref offset)) { if (map_key.IsInt) { m.AsMapping.Add(map_key.AsInt, v); } else if (map_key.IsString) { m.AsMapping.Add(map_key.AsString, v); } else { throw new Exception("Bad mapping key(int && string only)"); } } } break; case '(': offset++; if (content [offset] == '{') { LPCValue v = RestoreArray(ref content, ref offset); SkipSpaceChar(ref content, ref offset); if (CheckKeyCompleted(ref content, ref offset)) { map_key = v; } else if (CheckValueCompleted(ref content, ref offset)) { if (map_key.IsInt) { m.AsMapping.Add(map_key.AsInt, v); } else if (map_key.IsString) { m.AsMapping.Add(map_key.AsString, v); } else { throw new Exception("Bad mapping key(int && string only)"); } } } else if (content [offset] == '[') { offset++; LPCValue v = RestoreMapping(ref content, ref offset); SkipSpaceChar(ref content, ref offset); if (CheckKeyCompleted(ref content, ref offset)) { map_key = v; } else if (CheckValueCompleted(ref content, ref offset)) { if (map_key.IsInt) { m.AsMapping.Add(map_key.AsInt, v); } else if (map_key.IsString) { m.AsMapping.Add(map_key.AsString, v); } else { throw new Exception("Bad mapping key(int && string only)"); } } } break; case ']': { offset++; if (content [offset] == ')') { offset++; return(m); } } break; default: offset++; break; } } return(m); }
/// <summary> /// 仅供内部调用的递归版本 /// </summary> private static int _RestoreFromBuffer(byte[] buf, int offset, out LPCValue value) { // 匹配到了多少个 int matchCnt = 0; // 获取 类型 和 数据大小 int _type = buf [offset++]; int dataSize = _type & 0x0F; ValueType type = (ValueType)(_type >> 4); matchCnt++; // 看是否需要获得额外的数据 int data = 0; if (dataSize > 0) { /* Set 0 for positive, 0xFFFF.... for negative */ data = (buf [offset] & 0x80) != 0 ? -1 : 0; /* Get low n bytes of integer */ for (int i = 0; i < dataSize; i++) { data <<= 8; data |= buf [offset + i]; } offset += dataSize; matchCnt += dataSize; } // 根据是否为各种类型,来恢复数据 switch (type) { case ValueType.UNDEFINED: { value = LPCValue.Create(); return(matchCnt); } case ValueType.STRING: { string val = System.Text.Encoding.UTF8.GetString(buf, offset, data); value = LPCValue.Create(val); matchCnt += data; return(matchCnt); } case ValueType.BUFFER: { byte[] _buf = new byte[data]; System.Buffer.BlockCopy(buf, offset, _buf, 0, data); value = LPCValue.Create(_buf); matchCnt += data; return(matchCnt); } case ValueType.INT: { value = LPCValue.Create(data); return(matchCnt); } case ValueType.FLOAT: { Debug.Assert(data == sizeof(float) || data == sizeof(double)); float val = 0; if (data == sizeof(float)) { val = BitConverter.ToSingle(buf, offset); } else if (data == sizeof(double)) { val = (float)BitConverter.ToDouble(buf, offset); } value = LPCValue.Create(val); matchCnt += data; return(matchCnt); } case ValueType.ARRAY: { LPCValue val = LPCValue.CreateArray(); for (int i = 0; i < data; i++) { LPCValue subVal; int cnt = _RestoreFromBuffer(buf, offset, out subVal); offset += cnt; matchCnt += cnt; val.AsArray.Add(subVal); } value = val; return(matchCnt); } case ValueType.MAPPING: { LPCValue val = LPCValue.CreateMapping(); for (int i = 0; i < data; i++) { LPCValue keyVal, valVal; int cnt1 = _RestoreFromBuffer(buf, offset, out keyVal); offset += cnt1; matchCnt += cnt1; int cnt2 = _RestoreFromBuffer(buf, offset, out valVal); offset += cnt2; matchCnt += cnt2; // 我们只支持key类型为int和string的 if (keyVal.IsInt) { val.AsMapping.Add(keyVal.AsInt, valVal); } else if (keyVal.IsString) { val.AsMapping.Add(keyVal.AsString, valVal); } else { throw new Exception("不支持的key类型。"); } } value = val; return(matchCnt); } default: { throw new Exception("不支持的Value类型。"); } } // switch case 结束 }
/// <summary> /// 通过缓冲区还原回值信息。失败了会抛出异常。 /// </summary> /// <returns>返回有多少字节数被成功解析了。</returns> public static int RestoreFromBuffer(byte[] buf, int offset, out LPCValue value) { int matchCnt = _RestoreFromBuffer(buf, offset, out value); return(matchCnt); }
/// <summary> /// 将指定的对象序列化到缓冲区中缓冲区。如果缓冲不够,会抛出异常。 /// </summary> /// <returns>成功保存了多少字节到缓冲区中。</returns> public static int SaveToBuffer(byte[] buf, int offset, LPCValue value) { if (value.IsString) { byte[] utf8Data = System.Text.Encoding.UTF8.GetBytes(value.AsString); int skip = _SaveTypeDataTo((int)value.type, utf8Data.Length, buf, offset); offset += skip; System.Buffer.BlockCopy(utf8Data, 0, buf, offset, utf8Data.Length); return(skip + utf8Data.Length); } else if (value.IsBuffer) { int skip = _SaveTypeDataTo((int)value.type, value.AsBuffer.Length, buf, offset); offset += skip; System.Buffer.BlockCopy(value.AsBuffer, 0, buf, offset, value.AsBuffer.Length); return(skip + value.AsBuffer.Length); } else if (value.IsInt) { int skip = _SaveTypeDataTo((int)value.type, value.AsInt, buf, offset); offset += skip; return(skip); } else if (value.IsFloat) { int skip = _SaveTypeDataTo((int)value.type, sizeof(float), buf, offset); offset += skip; byte[] arr = BitConverter.GetBytes(value.AsFloat); Debug.Assert(arr.Length == sizeof(float)); System.Buffer.BlockCopy(arr, 0, buf, offset, sizeof(float)); return(skip + sizeof(float)); } else if (value.IsUndefined) { int skip = _SaveTypeDataTo((int)value.type, 0, buf, offset); offset += skip; return(skip); } else if (value.IsArray) { int skip = _SaveTypeDataTo((int)value.type, value.AsArray.Count, buf, offset); offset += skip; for (int i = 0; i < value.AsArray.Count; i++) { int _skip = SaveToBuffer(buf, offset, value.AsArray [i]); skip += _skip; offset += _skip; } return(skip); } else if (value.IsMapping) { int skip = _SaveTypeDataTo((int)value.type, value.AsMapping.Count, buf, offset); offset += skip; foreach (object key in value.AsMapping.Keys) { LPCValue keyValue = null, valValue = null; Debug.Assert((key is int) || (key is string), "不支持非string和int的key值类型。"); if (key is int) { keyValue = LPCValue.Create((int)key); valValue = value.AsMapping [(int)key]; } else if (key is string) { keyValue = LPCValue.Create((string)key); valValue = value.AsMapping [(string)key]; } // 打包key值 int _skip = SaveToBuffer(buf, offset, keyValue); skip += _skip; offset += _skip; // 打包value值 _skip = SaveToBuffer(buf, offset, valValue); skip += _skip; offset += _skip; } return(skip); } else { throw new Exception("不识别的类型"); } }
public static string SaveToString(LPCValue val) { string result = ""; if (val.IsString) { return(SaveToString(val.AsString)); } else if (val.IsBuffer) { result = ":"; byte[] bytes = val.AsBuffer; for (int i = 0; i < bytes.Length; i++) { result += string.Format("{0:X}", bytes [i]); } return(result + ":"); } else if (val.IsInt) { return(Convert.ToString(val.AsInt)); } else if (val.IsArray) { result = "({"; foreach (LPCValue v in val.AsArray.Values) { result += SaveToString(v) + ","; } return(result + "})"); } else if (val.IsMapping) { result = "(["; foreach (object k in val.AsMapping.Keys) { if (k is int) { result += SaveToString((int)k) + ":"; result += SaveToString(val.AsMapping [(int)k]) + ","; continue; } if (k is string) { result += SaveToString((string)k) + ":"; result += SaveToString(val.AsMapping [(string)k]) + ","; continue; } } return(result + "])"); } else if (val.IsFloat) { return(SaveToString(val.AsFloat)); } else if (val.IsUndefined) { return("(undefined)"); } else { throw new Exception("未知LPC类型"); } }
/// <summary> /// 将一个数据插入到列表尾部 /// </summary> /// <param name="val"></param> public void Add(LPCValue val) { confirm_list(); _list.Add(val); }
public static LPCValue SafeRestoreFromString(string content) { if (string.IsNullOrEmpty(content)) { return(LPCValue.Create("")); } int offset = 0; switch (content [offset]) { case '"': { offset++; return(RestoreString(ref content, ref offset)); } case '(': { offset++; if (content [offset] == '{') { offset++; return(RestoreArray(ref content, ref offset)); } if (content [offset] == '[') { offset++; return(RestoreMapping(ref content, ref offset)); } } break; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { return(RestoreNumber(ref content, ref offset)); } case ':': { offset++; return(RestoreBuffer(ref content, ref offset)); } default: { // 其他情况直接返回content return(LPCValue.Create(content)); } } return(null); }