コード例 #1
0
 private static bool IsSimple(PType tp)
 {
     if (tp.IsAtom || tp.Vid == PTypeEnumeration.sstring)
     {
         return(true);
     }
     if (tp.Vid == PTypeEnumeration.record)
     {
         PTypeRecord rec    = (PTypeRecord)tp;
         bool        simple = true;
         for (int i = 0; i < rec.Fields.Length; i++)
         {
             var t = rec.Fields[i].Type;
             if (!(t.IsAtom || t.Vid == PTypeEnumeration.sstring))
             {
                 simple = false; break;
             }
         }
         if (simple)
         {
             return(true);
         }
     }
     return(false);
 }
コード例 #2
0
ファイル: BinarySerialize.cs プロジェクト: agmarchuk/PolarDB
        public static object Deserialize(BinaryReader br, PType tp)
        {
            switch (tp.Vid)
            {
            case PTypeEnumeration.none: { return(null); }

            case PTypeEnumeration.boolean: { return(br.ReadBoolean()); }

            case PTypeEnumeration.@byte: { return(br.ReadByte()); }

            case PTypeEnumeration.character: { return(br.ReadChar()); }

            case PTypeEnumeration.integer: { return(br.ReadInt32()); }

            case PTypeEnumeration.longinteger: { return(br.ReadInt64()); }

            case PTypeEnumeration.real: { return(br.ReadDouble()); }

            case PTypeEnumeration.sstring: { return(br.ReadString()); }

            case PTypeEnumeration.record:
            {
                PTypeRecord tp_rec = (PTypeRecord)tp;
                object[]    rec    = new object[tp_rec.Fields.Length];
                for (int i = 0; i < rec.Length; i++)
                {
                    object v = Deserialize(br, tp_rec.Fields[i].Type);
                    rec[i] = v;
                }
                return(rec);
            }

            case PTypeEnumeration.sequence:
            {
                PType tp_element = ((PTypeSequence)tp).ElementType;
                long  nelements  = br.ReadInt64();
                if (nelements < 0 || nelements > Int32.MaxValue)
                {
                    throw new Exception($"Err in Deserialize: sequense has too many ({nelements}) elements");
                }
                object[] elements = new object[nelements];
                for (int i = 0; i < nelements; i++)
                {
                    elements[i] = Deserialize(br, tp_element);
                }
                return(elements);
            }

            case PTypeEnumeration.union:
            {
                PTypeUnion tp_uni = (PTypeUnion)tp;
                // тег - 1 байт
                int    tag    = br.ReadByte();
                object subval = Deserialize(br, tp_uni.Variants[tag].Type);
                return(new object[] { tag, subval });
            }

            default: { throw new Exception($"Err in Deserialize: unknown type variant {tp.Vid}"); }
            }
        }
コード例 #3
0
        public static PType FromPObject(object po)
        {
            object[] uni = (object[])po;
            int      tg  = (int)uni[0];

            switch (tg)
            {
            case 0: return(new PType(PTypeEnumeration.none));

            case 1: return(new PType(PTypeEnumeration.boolean));

            case 2: return(new PType(PTypeEnumeration.character));

            case 3: return(new PType(PTypeEnumeration.integer));

            case 4: return(new PType(PTypeEnumeration.longinteger));

            case 5: return(new PType(PTypeEnumeration.real));

            case 6: return(new PType(PTypeEnumeration.fstring));

            case 7: return(new PType(PTypeEnumeration.sstring));

            case 8:
            {
                object[] fields_def = (object[])uni[1];
                var      query      = fields_def.Select(fd =>
                    {
                        object[] f = (object[])fd;
                        return(new NamedType((string)f[0], FromPObject(f[1])));
                    });
                PTypeRecord rec = new PTypeRecord(query.ToArray());
                return(rec);
            }

            case 9:
            {
                object[] growing_type = (object[])uni[1];
                return(new PTypeSequence(FromPObject(growing_type[1]), (bool)growing_type[0]));
            }

            // case 10: не реализован вариант объединения
            case 11:
            {
                return(new PType(PTypeEnumeration.@byte));
            }

            // case 12: не реализован вариант объектной пары
            default:
            {
                throw new Exception("unknown tag for pobject");
            }
            }
        }
コード例 #4
0
        //TODO: Добавление уровня - неправильный путь борьбы с рекурсивными типами, но пока ...
        //TODO: А еще я похоже "напортачил" с вариантом (растущих) последовательностей ...
        public object ToPObject(int level)
        {
            if (level < 0)
            {
                return(null);
            }
            switch (this.vid)
            {
            case PTypeEnumeration.fstring:
            {
                return(new object[] { PType.ToInt(this.vid), ((PTypeFString)this).Size });
            }

            case PTypeEnumeration.record:
            {
                PTypeRecord ptr   = (PTypeRecord)this;
                var         query = ptr.Fields.Select(pair => new object[] { pair.Name, pair.Type.ToPObject(level - 1) }).ToArray();
                return(new object[] { PType.ToInt(this.vid), query });
            }

            case PTypeEnumeration.sequence:
            {
                PTypeSequence pts = (PTypeSequence)this;
                return(new object[] { PType.ToInt(this.vid),
                                      new object[] {
                                          new object[] { "growing", new object[] { PType.ToInt(PTypeEnumeration.boolean), null } },
                                          new object[] { "Type", pts.ElementType.ToPObject(level - 1) }
                                      } });
            }

            case PTypeEnumeration.union:
            {
                PTypeUnion ptu   = (PTypeUnion)this;
                var        query = ptu.Variants.Select(pair => new object[] { pair.Name, pair.Type.ToPObject(level - 1) }).ToArray();
                return(new object[] { PType.ToInt(this.vid), query });
            }

            default: return(new object[] { PType.ToInt(this.vid), null });
            }
        }
コード例 #5
0
        public string Interpret(object v, bool withfieldnames = false)
        {
            switch (this.vid)
            {
            case PTypeEnumeration.none: return("");

            case PTypeEnumeration.boolean: return(((bool)v).ToString());

            case PTypeEnumeration.character: return("'" + ((char)v).ToString() + "'");    // Нужно учесть специальные символы

            case PTypeEnumeration.integer: return(((int)v).ToString());

            case PTypeEnumeration.longinteger: return(((long)v).ToString());

            case PTypeEnumeration.real: return(((double)v).ToString("G", CultureInfo.InvariantCulture));

            case PTypeEnumeration.fstring: return("\"" + ((string)v).Replace("\"", "\\\"") + "\"");

            case PTypeEnumeration.sstring: return("\"" + ((string)v).Replace("\"", "\\\"") + "\"");

            case PTypeEnumeration.record:
            {
                PTypeRecord   ptr = (PTypeRecord)this;
                object[]      arr = (object[])v;
                StringBuilder sb  = new StringBuilder();
                sb.Append('{');
                for (int i = 0; i < ptr.Fields.Length; i++)
                {
                    if (i > 0)
                    {
                        sb.Append(',');
                    }
                    if (withfieldnames)
                    {
                        sb.Append(ptr.Fields[i].Name);
                        sb.Append(':');
                    }

                    sb.Append(ptr.Fields[i].Type.Interpret(arr[i]));
                }
                sb.Append('}');
                return(sb.ToString());
            }

            case PTypeEnumeration.sequence:
            {
                PTypeSequence pts = (PTypeSequence)this;
                PType         tel = pts.ElementType;
                object[]      arr = (object[])v;
                StringBuilder sb  = new StringBuilder();
                sb.Append('[');
                for (int i = 0; i < arr.Length; i++)
                {
                    if (i > 0)
                    {
                        sb.Append(',');
                    }
                    sb.Append(tel.Interpret(arr[i]));
                }
                sb.Append(']');
                return(sb.ToString());
            }

            case PTypeEnumeration.union:
            {
                PTypeUnion ptu = (PTypeUnion)this;
                object[]   arr = (object[])v;
                if (arr.Length != 2)
                {
                    throw new Exception("incorrect data for union");
                }
                int tag = (int)arr[0];
                if (tag < 0 || tag >= ptu.Variants.Length)
                {
                    throw new Exception("incorrect data for union");
                }
                NamedType nt = ptu.Variants[tag];
                return(nt.Name + "^" + nt.Type.Interpret(arr[1]));
            }

            case PTypeEnumeration.@byte:
                return(((byte)v).ToString());

            // не реализован вариант объектной парыЫ
            default: throw new Exception("Can't interpret value by type");
            }
        }
コード例 #6
0
        private object Des(PType tp)
        {
            switch (tp.Vid)
            {
            case PTypeEnumeration.none: { return(null); }

            case PTypeEnumeration.boolean: { return(ReadBoolean()); }

            case PTypeEnumeration.@byte: { return(ReadByte()); }

            case PTypeEnumeration.character: { return(ReadChar()); }

            case PTypeEnumeration.integer: { return(ReadInt32()); }

            case PTypeEnumeration.longinteger: { return(ReadInt64()); }

            case PTypeEnumeration.real: { return(ReadDouble()); }

            case PTypeEnumeration.sstring: { return(ReadString()); }

            case PTypeEnumeration.record:
            {
                PTypeRecord tp_rec = (PTypeRecord)tp;
                object[]    rec    = new object[tp_rec.Fields.Length];
                char        c      = (char)tr.Read();
                if (c != '{')
                {
                    throw new Exception("Polar syntax error 19327");
                }
                for (int i = 0; i < rec.Length; i++)
                {
                    Skip();
                    object v = Des(tp_rec.Fields[i].Type);
                    rec[i] = v;
                    if (i < rec.Length - 1)
                    {
                        Skip();
                        c = (char)tr.Read();
                        if (c != ',')
                        {
                            throw new Exception("Polar syntax error 19329");
                        }
                    }
                    Skip();
                }
                c = (char)tr.Read();
                if (c != '}')
                {
                    throw new Exception("Polar syntax error 19328");
                }
                return(rec);
            }

            case PTypeEnumeration.sequence:
            {
                PType         tp_element = ((PTypeSequence)tp).ElementType;
                List <object> lsequ      = new List <object>();
                char          c          = (char)tr.Read();
                if (c != '[')
                {
                    throw new Exception("Polar syntax error 19331");
                }
                bool firsttime = true;
                while (true)
                {
                    Skip();
                    //TODO: неудачно, что дважды проверяю и выхожу по закрывающей скобке
                    if (firsttime && tr.Peek() == ']')
                    {
                        c = (char)tr.Read(); break;
                    }
                    firsttime = false;
                    lsequ.Add(Des(tp_element));
                    Skip();
                    c = (char)tr.Read();
                    if (c == ']')
                    {
                        break;
                    }
                    else if (c == ',')
                    {
                        continue;
                    }
                    throw new Exception("Polar syntax error 19333");
                }
                if (c != ']')
                {
                    throw new Exception("Polar syntax error 19332");
                }
                object[] elements = lsequ.ToArray();
                return(elements);
            }

            case PTypeEnumeration.union:
            {
                PTypeUnion tp_uni = (PTypeUnion)tp;
                // тег - 1 байт
                int         tag = ReadInt32();
                Skip(); int c   = tr.Read(); if (c != '^')
                {
                    throw new Exception("Polar syntax error 19335");
                }
                Skip();
                object subval = Des(tp_uni.Variants[tag].Type);
                return(new object[] { tag, subval });
            }

            default: { throw new Exception($"Err in Deserialize: unknown type variant {tp.Vid}"); }
            }
        }
コード例 #7
0
        public static void SerializeFormatted(TextWriter tw, object v, PType tp, int level)
        {
            Intend(tw, level * intend);
            switch (tp.Vid)
            {
            case PTypeEnumeration.none: { return; }

            case PTypeEnumeration.boolean: { tw.Write((bool)v ? 't' : 'f'); return; }

            case PTypeEnumeration.@byte: { tw.Write(((byte)v).ToString()); return; }

            case PTypeEnumeration.character: { tw.Write((char)v); return; }

            case PTypeEnumeration.integer: { tw.Write((int)v); return; }

            case PTypeEnumeration.longinteger: { tw.Write((long)v); return; }

            case PTypeEnumeration.real: { tw.Write(((double)v).ToString("G", System.Globalization.CultureInfo.InvariantCulture)); return; }

            case PTypeEnumeration.sstring:
            {
                tw.Write('\"');
                tw.Write(((string)v).Replace("\\", "\\\\").Replace("\"", "\\\""));
                tw.Write('\"');
                return;
            }

            case PTypeEnumeration.record:
            {
                object[]    rec    = (object[])v;
                PTypeRecord tp_rec = (PTypeRecord)tp;
                if (rec.Length != tp_rec.Fields.Length)
                {
                    throw new Exception("Err in Serialize: wrong record field number");
                }
                bool simple = IsSimple(tp);
                if (simple)
                {
                    Serialize(tw, v, tp); return;
                }
                tw.Write('{');
                for (int i = 0; i < rec.Length; i++)
                {
                    if (i != 0)
                    {
                        tw.Write(',');
                    }
                    SerializeFormatted(tw, rec[i], tp_rec.Fields[i].Type, level + 1);
                }

                Intend(tw, level * intend);
                tw.Write('}');
                return;
            }

            case PTypeEnumeration.sequence:
            {
                PType    tp_element = ((PTypeSequence)tp).ElementType;
                object[] elements   = (object[])v;
                tw.Write('[');
                bool isfirst = true;
                foreach (object el in elements)
                {
                    if (!isfirst)
                    {
                        tw.Write(',');
                    }
                    isfirst = false;
                    SerializeFormatted(tw, el, tp_element, level + 1);
                }
                Intend(tw, level * intend);
                tw.Write(']');
                return;
            }

            case PTypeEnumeration.union:
            {
                PTypeUnion tp_uni = (PTypeUnion)tp;
                // тег - 1 байт
                int    tag    = (int)((object[])v)[0];
                object subval = ((object[])v)[1];
                if (tag < 0 || tag >= tp_uni.Variants.Length)
                {
                    throw new Exception("Err in Serialize: wrong union tag");
                }
                tw.Write(tag);
                tw.Write('^');
                if (IsSimple(tp_uni.Variants[tag].Type))
                {
                    Serialize(tw, subval, tp_uni.Variants[tag].Type);
                    return;
                }
                SerializeFormatted(tw, subval, tp_uni.Variants[tag].Type, level + 1);
                return;
            }
            }
        }
コード例 #8
0
ファイル: BinarySerialize.cs プロジェクト: agmarchuk/PolarDB
        public static void Serialize(BinaryWriter bw, object v, PType tp)
        {
            switch (tp.Vid)
            {
            case PTypeEnumeration.none: { return; }

            case PTypeEnumeration.boolean: { bw.Write((bool)v); return; }

            case PTypeEnumeration.@byte: { bw.Write((byte)v); return; }

            case PTypeEnumeration.character: { bw.Write((char)v); return; }

            case PTypeEnumeration.integer: { bw.Write((int)v); return; }

            case PTypeEnumeration.longinteger: { bw.Write((long)v); return; }

            case PTypeEnumeration.real: { bw.Write((double)v); return; }

            case PTypeEnumeration.sstring: { bw.Write((string)v); return; }

            case PTypeEnumeration.record:
            {
                object[]    rec    = (object[])v;
                PTypeRecord tp_rec = (PTypeRecord)tp;
                if (rec.Length != tp_rec.Fields.Length)
                {
                    throw new Exception("Err in Serialize: wrong record field number");
                }
                for (int i = 0; i < rec.Length; i++)
                {
                    Serialize(bw, rec[i], tp_rec.Fields[i].Type);
                }
                return;
            }

            case PTypeEnumeration.sequence:
            {
                PType    tp_element = ((PTypeSequence)tp).ElementType;
                object[] elements   = (object[])v;
                bw.Write((long)elements.Length);
                foreach (object el in elements)
                {
                    Serialize(bw, el, tp_element);
                }
                return;
            }

            case PTypeEnumeration.union:
            {
                PTypeUnion tp_uni = (PTypeUnion)tp;
                // тег - 1 байт
                int    tag    = (int)((object[])v)[0];
                object subval = ((object[])v)[1];
                if (tag < 0 || tag >= tp_uni.Variants.Length)
                {
                    throw new Exception("Err in Serialize: wrong union tag");
                }
                bw.Write((byte)tag);
                Serialize(bw, subval, tp_uni.Variants[tag].Type);
                return;
            }
            }
        }