public LPCArray Copy() { LPCValue dst = LPCValue.CreateArray(); foreach (LPCValue v in this.Values) { dst.AsArray.Add(v); } return(dst.AsArray); }
/// <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 结束 }
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); }