Exemplo n.º 1
0
        /// <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 结束
        }
Exemplo n.º 2
0
        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);
        }