コード例 #1
0
        public unsafe DeserializeResult Deserialize(byte[] mass)
        {
            Table[]  tables;
            uint     userID;
            DateTime synchDT;
            int      SPos = Encoding.GetByteCount(Mark);

            {
                fixed(void *numPtr = &mass[mass.Length - 4])
                {
                    userID = *(uint *)numPtr;
                }

                fixed(void *numPtr = &mass[mass.Length - 8 - 4])
                {
                    synchDT = new DateTime(*(long *)numPtr);
                }
            }

            {
                int TableCount;
                fixed(void *numPtr = &mass[SPos])
                {
                    TableCount = *(int *)numPtr;
                }                               //количество таблиц

                SPos  += 4;
                tables = new Table[TableCount];
            }

            //гружу записи
            for (int i = 0; i < tables.Length; i++)
            {
                DataBase.ISTable Table;
                DataBase.ITable  Tbl;
                {
                    string TableName;
                    int    TableNameLength;
                    fixed(void *numPtr = &mass[SPos])
                    {
                        TableNameLength = *(int *)numPtr;
                    }                                    //длина имени таблицы

                    SPos     += sizeof(int);
                    TableName = Encoding.GetString(mass, SPos, TableNameLength);  //имя таблицы
                    SPos     += TableNameLength;

                    Tbl = _dataBase.Tables[TableName];
                    if (Tbl == null)
                    {
                        throw new Exception($"Таблица не найдена: \"{TableName}\"");
                    }

                    Table = Tbl.CreateSubTable(false);
                }

                int RowCount;
                fixed(void *numPtr = &mass[SPos])
                {
                    RowCount = *(int *)numPtr;
                }

                SPos += sizeof(int);

                int RowsDataLength, CheckRowsDataLength = 0;
                fixed(void *numPtr = &mass[SPos])
                {
                    RowsDataLength = *(int *)numPtr;
                }                                   //длина данных

                SPos += sizeof(int);

                var rows = new Row[RowCount];

                for (int j = 0; j < RowCount; j++)
                {
                    CheckRowsDataLength += sizeof(uint) + sizeof(int) + sizeof(DataBase.State);    //id+метка об удалении + длина записи
                    int RowDataLength, CheckRowDataLength = sizeof(uint) + sizeof(DataBase.State); //id+метка об удалении

                    fixed(void *numPtr = &mass[SPos])
                    {
                        RowDataLength = *(int *)numPtr;
                    }                                   //длина следующей записи

                    SPos += sizeof(int);

                    uint ID;
                    fixed(void *numPtr = &mass[SPos])
                    {
                        ID = *(uint *)numPtr;
                    }                         //идентификатор

                    SPos += sizeof(uint);

                    DataBase.State InUse;
                    fixed(void *numPtr = &mass[SPos])
                    {
                        InUse = *(DataBase.State *)numPtr;
                    }                                      //метка об удалении

                    SPos += sizeof(DataBase.State);

                    object[] Values;
                    int      ColumnIndex = 0;

                    Values = new object[Tbl.Columns.Count];
                    //Values[Values.Length - 1] = SPoolID;

                    rows[j] = new Row(ID, InUse, Values);

                    //тут важно, чтобы у всех таблиц были колонки relation spool и располагались в конце
                    for (int k = 0; k < Tbl.Columns.Count - 1; k++)
                    {
                        var column = Tbl.GetColumn(k);

                        if (!column.Protect)
                        {
                            switch (column.TypeCol)
                            {
                            case DataBase.Types.Bool:
                                fixed(void *numPtr = &mass[SPos])
                                {
                                    Values[k] = *(bool *)numPtr;
                                }

                                SPos += sizeof(bool);
                                CheckRowDataLength  += sizeof(bool);
                                CheckRowsDataLength += sizeof(bool);
                                break;

                            case DataBase.Types.AutoStatus:
                                fixed(void *numPtr = &mass[SPos])
                                {
                                    Values[k] = (*(bool *)numPtr ? DataBase.AutoStatus.Used : DataBase.AutoStatus.UnUse);
                                }

                                SPos += sizeof(bool);
                                CheckRowDataLength  += sizeof(bool);
                                CheckRowsDataLength += sizeof(bool);
                                break;

                            case DataBase.Types.Byte:
                                Values[k]            = mass[SPos];
                                SPos                += sizeof(byte);
                                CheckRowDataLength  += sizeof(byte);
                                CheckRowsDataLength += sizeof(byte);
                                break;

                            case DataBase.Types.DateTime:
                                fixed(void *numPtr = &mass[SPos])
                                {
                                    Values[k] = new DateTime(*(long *)numPtr);
                                }

                                SPos += sizeof(long);
                                CheckRowDataLength  += sizeof(long);
                                CheckRowsDataLength += sizeof(long);
                                break;

                            case DataBase.Types.Double:
                                fixed(void *numPtr = &mass[SPos])
                                {
                                    Values[k] = *(double *)numPtr;
                                }

                                SPos += sizeof(double);
                                CheckRowDataLength  += sizeof(double);
                                CheckRowsDataLength += sizeof(double);
                                break;

                            case DataBase.Types.Decimal:
                                fixed(void *numPtr = &mass[SPos])
                                {
                                    Values[k] = *(decimal *)numPtr;
                                }

                                SPos += sizeof(decimal);
                                CheckRowDataLength  += sizeof(decimal);
                                CheckRowsDataLength += sizeof(decimal);
                                break;

                            case DataBase.Types.Int64:
                                fixed(void *numPtr = &mass[SPos])
                                {
                                    Values[k] = *(long *)numPtr;
                                }

                                SPos += sizeof(long);
                                CheckRowDataLength  += sizeof(long);
                                CheckRowsDataLength += sizeof(long);
                                break;

                            case DataBase.Types.Int32:
                                fixed(void *numPtr = &mass[SPos])
                                {
                                    Values[k] = *(int *)numPtr;
                                }

                                SPos += sizeof(int);
                                CheckRowDataLength  += sizeof(int);
                                CheckRowsDataLength += sizeof(int);
                                break;

                            case DataBase.Types.RIU32:
                                fixed(void *numPtr = &mass[SPos])
                                {
                                    Values[k] = new RIU32(*(uint *)numPtr);
                                }

                                SPos += sizeof(uint);
                                CheckRowDataLength  += sizeof(uint);
                                CheckRowsDataLength += sizeof(uint);
                                break;

                            case DataBase.Types.String:    //тут надо бдительничать!
                                int StrLength;
                                fixed(void *numPtr = &mass[SPos])
                                {
                                    StrLength = *(int *)numPtr;
                                }

                                SPos += sizeof(int);
                                CheckRowDataLength  += sizeof(int);
                                CheckRowsDataLength += sizeof(int);

                                Values[k]            = Encoding.GetString(mass, SPos, StrLength);
                                SPos                += StrLength;
                                CheckRowDataLength  += StrLength;
                                CheckRowsDataLength += StrLength;
                                break;

                            default: throw new Exception("не поддерживаемый тип");
                            }
                            ColumnIndex++;
                        }
                    }

                    if (CheckRowDataLength != RowDataLength)
                    {
                        throw new Exception($"Сообщение повреждено: {tables[i].STable.Name} {(j + 1).ToString()}-{ID} CheckRowDataLength != RowDataLength({CheckRowDataLength}!={RowDataLength})");
                    }
                }

                tables[i] = new Table()
                {
                    STable = Table, Rows = rows
                };

                if (CheckRowsDataLength != RowsDataLength)
                {
                    throw new Exception($"Сообщение повреждено: {tables[i].STable.Name} CheckRowsDataLength != RowsDataLength({CheckRowsDataLength}!={RowsDataLength})");
                }
            }

            return(new DeserializeResult()
            {
                Tables = tables, SynchDate = synchDT, UserID = userID
            });
        }
コード例 #2
0
ファイル: TXTSerializeProvider.cs プロジェクト: jlovenpk1/LOJ
        private object ParseField(DataBase.IColumn column, string txt)
        {
            object result = null;

            switch (column.TypeCol)
            {
            case DataBase.Types.Bool:
                result = bool.Parse(txt);
                break;

            case DataBase.Types.AutoStatus:
            {
                bool boolResult;
                if (bool.TryParse(txt, out boolResult))
                {
                    result = (boolResult ? DataBase.AutoStatus.Used : DataBase.AutoStatus.UnUse);
                }
                else
                {
                    result = Enum.Parse(typeof(DataBase.AutoStatus), txt, true);
                }
            }
            break;

            case DataBase.Types.Byte:
                result = byte.Parse(txt);
                break;

            case DataBase.Types.DateTime:
                result = DateTime.ParseExact(txt, "dd-MM-yyyy HH.mm.ss.fffffff", CultureInfo.InvariantCulture);
                break;

            case DataBase.Types.Double:
            {
                var str = ReplaceBackward(txt);
                result = Double.Parse(str);
            }
            break;

            case DataBase.Types.Decimal:
            {
                var str = ReplaceBackward(txt);
                result = Decimal.Parse(str);
            }
            break;

            case DataBase.Types.Int64:
                result = Int64.Parse(txt);
                break;

            case DataBase.Types.Int32:
                result = Int32.Parse(txt);
                break;

            case DataBase.Types.RIU32:
                result = new RIU32(UInt32.Parse(txt));
                break;

            case DataBase.Types.String:
                result = ReplaceBackward(txt);
                break;

            default: throw new Exception("не поддерживаемый тип");
            }

            return(result);
        }