예제 #1
0
        private bool Write(ref uint pos, byte[] buf, int oldSize)
        {
            oldSize = ((oldSize + 7) & 0x7FFFFFF8);
            uint oldPos = pos;

            CopyBytes(Crc16.ComputeChecksum(buf, buf.Length - 2), buf, buf.Length - 2);
            if (((buf.Length + 7) & 0x00FFFFF8) != oldSize)
            {
                if (pos > 0)
                {
                    AddFree(pos, oldSize);
                }
                pos = FindFree(buf.Length);
            }
            ToSave((long)pos << 3, buf);
            return(pos != oldPos);
        }
예제 #2
0
        private void AddTopic(Topic t, Record r)
        {
            if (r.saved != 0)
            {
                t[Topic.MaskType.saved] = true;
                if (r.saved == FL_SAVED_E)
                {
                    byte[] lBuf = new byte[4];
                    _file.Position = (long)r.data_pos << 3;
                    _file.Read(lBuf, 0, 4);
                    int data_size = BitConverter.ToInt32(lBuf, 0);
                    if ((data_size & (FL_REMOVED | FL_RECORD)) == 0)
                    {
                        r.data_size = data_size - 6;
                        byte[] buf = new byte[data_size];
                        lBuf.CopyTo(buf, 0);
                        _file.Read(buf, 4, buf.Length - 4);
                        ushort crc1 = BitConverter.ToUInt16(buf, buf.Length - 2);
                        ushort crc2 = Crc16.ComputeChecksum(buf, buf.Length - 2);
                        if (crc1 != crc2)
                        {
                            throw new ApplicationException("CRC Error Data@0x" + ((long)r.pos << 3).ToString("X8"));
                        }
                        r.data = Encoding.UTF8.GetString(buf, 4, (int)r.data_size);
                    }
                }
                t.SetJson(r.data);
            }
            Console.WriteLine("{0}={1} [0x{2:X4}]", t.path, t.value, r.pos);
            _tr[t] = r;
            int idx = indexPPos(_refitParent, r.pos);

            while (idx >= 0 && idx < _refitParent.Count && _refitParent[idx].parent == r.pos)
            {
                Record nextR = _refitParent[idx];
                _refitParent.RemoveAt(idx);
                AddTopic(t.Get(nextR.name, null), nextR);
                idx = indexPPos(_refitParent, r.pos);
            }
        }
예제 #3
0
        public void Open()
        {
            if (!Directory.Exists("../data"))
            {
                Directory.CreateDirectory("../data");
            }
            _file = new FileStream("../data/persist.xdb", FileMode.OpenOrCreate, FileAccess.ReadWrite);
            if (_file.Length < 0x40)
            {
                _file.Write(new byte[0x40], 0, 0x40);
            }
            else
            {
                _file.Position = 0x40;
                long   curPos;
                byte[] lBuf = new byte[4];
                _refitParent = new List <Record>();
                Topic t;

                do
                {
                    curPos = _file.Position;
                    _file.Read(lBuf, 0, 4);
                    uint fl_size = BitConverter.ToUInt32(lBuf, 0);
                    int  len     = (int)fl_size & (((fl_size & FL_RECORD) != 0)?FL_REC_LEN:FL_DATA_LEN);

                    if ((fl_size & FL_REMOVED) != 0)
                    {
                        AddFree((uint)(curPos >> 3), (int)fl_size);
                    }
                    else if ((fl_size & FL_RECORD) != 0)
                    {
                        byte[] buf = new byte[len];
                        lBuf.CopyTo(buf, 0);
                        _file.Read(buf, 4, len - 4);
                        ushort crc1 = BitConverter.ToUInt16(buf, len - 2);
                        ushort crc2 = Crc16.ComputeChecksum(buf, len - 2);
                        if (crc1 != crc2)
                        {
                            throw new ApplicationException("CRC Error Record@0x" + curPos.ToString("X8"));
                        }
                        var r = new Record((uint)(curPos >> 3), buf);

                        if (r.parent == 0)
                        {
                            if (r.name == "/")
                            {
                                t = Topic.root;
                            }
                            else
                            {
                                t = null;
                            }
                        }
                        else if (r.parent < r.pos)
                        {
                            t = _tr.FirstOrDefault(z => z.Value.pos == r.parent).Key;
                            if (t != null)
                            {
                                t = t.Get(r.name, null);
                            }
                        }
                        else
                        {
                            t = null;
                        }
                        if (t != null)
                        {
                            AddTopic(t, r);
                        }
                        else
                        {
                            int idx = indexPPos(_refitParent, r.parent);
                            _refitParent.Insert(idx + 1, r);
                        }
                    }
                    _file.Position = curPos + ((len + 7) & 0x7FFFFFF8);
                } while(_file.Position < _file.Length);
                _refitParent = null;
            }
            _fileLength = _file.Length;
            Backup();
            ThreadPool.QueueUserWorkItem(FileOperations);
            Topic.root.all.changed += TopicChanged;
        }