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); }
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); } }
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; }