private RecordInfo RequestRecord(string id, string subId, byte recordType, byte[] recordData, long minimumLength, long extraBuffer) { RecordInfo result = null; if (!_emptyRecordListSorted) { _emptyRecords.Sort(delegate(RecordInfo x, RecordInfo y) { return x.Length.CompareTo(y.Length); }); _emptyRecordListSorted = true; } result = (from a in _emptyRecords where a.Length >= minimumLength select a).FirstOrDefault(); if (result == null) { result = new RecordInfo(); result.Length = minimumLength + extraBuffer; result.Offset = FileStream.Length; result.ID = id; result.SubID = subId; result.FieldType = recordType; result.Database = this; FileStream.SetLength(result.Offset + result.Length); //add index if (_fileStreamIdx != null) { _fileStreamIdx.Position = _fileStreamIdx.Length; byte[] buffer = new byte[117]; using (MemoryStream ms = new MemoryStream(buffer)) using (BinaryWriter bw = new BinaryWriter(ms)) { result.OffsetIdx = _fileStreamIdx.Position; ms.Position = 0; bw.Write(result.Offset); bw.Write(result.Length); bw.Write(result.FieldType); bw.Write(result.ID); bw.Write(result.SubID); _fileStreamIdx.Write(buffer, 0, 117); } } } else { //re-use of an empty record result.ID = id; result.SubID = subId; _emptyRecords.Remove(result); result.FieldType = recordType; //change index _fileStreamIdx.Position = result.OffsetIdx; byte[] buffer = new byte[117]; using (MemoryStream ms = new MemoryStream(buffer)) using (BinaryWriter bw = new BinaryWriter(ms)) { result.OffsetIdx = _fileStreamIdx.Position; ms.Position = 0; bw.Write(result.Offset); bw.Write(result.Length); bw.Write(result.FieldType); bw.Write(result.ID); bw.Write(result.SubID); _fileStreamIdx.Write(buffer, 0, 117); } } //write record header data FileStream.Position = result.Offset + RECORD_POS_LENGTH; BinaryWriter.Write(result.Length); FileStream.Position = result.Offset + RECORD_POS_FIELDTYPE; FileStream.WriteByte(recordType); FileStream.Position = result.Offset + RECORD_POS_ID; BinaryWriter.Write(result.ID); BinaryWriter.Write(result.SubID); //write data FileStream.Position = result.Offset + 150; FileStream.Write(recordData, 150, (int)minimumLength - 150); //Flush(); return result; }
public void DeleteRecord(RecordInfo ri) { FileStream.Position = ri.Offset + RECORD_POS_FIELDTYPE; BinaryWriter.Write(RECORD_EMPTY); _emptyRecords.Add(ri); _emptyRecordListSorted = false; if (_fileStreamIdx!=null) { _fileStreamIdx.Position = ri.OffsetIdx + 16; _fileStreamIdx.WriteByte(RECORD_EMPTY); } }
private bool LoadDatabaseFile() { //index file not available //create one //this is an exception. (should be anyway) //first create it in a temporary file and copy to target if finished bool result = false; bool cancelled = false; try { string fn = string.Concat(FileName, ".gsx"); if (File.Exists(fn)) { File.Delete(fn); } byte[] buffer = new byte[117]; using (TemporaryFile tf = new TemporaryFile()) using (FileStream fsIdx = File.Open(tf.Path, FileMode.OpenOrCreate, FileAccess.Write)) using (MemoryStream ms = new MemoryStream(buffer)) using (BinaryWriter bw = new BinaryWriter(ms)) { long max = this.FileStream.Length; DateTime nextUpdate = DateTime.Now.AddSeconds(1); using (Utils.ProgressBlock prog = new ProgressBlock("LoadingDatabase", "Loading", 100, 0, true)) { this.FileStream.Position = DATABASE_CONTENT_OFFSET; long eof = this.FileStream.Length; while (this.FileStream.Position < eof) { RecordInfo ri = new RecordInfo(); ri.Database = this; ri.Offset = this.FileStream.Position; this.FileStream.Position = ri.Offset + RECORD_POS_LENGTH; ri.Length = BinaryReader.ReadInt64(); this.FileStream.Position = ri.Offset + RECORD_POS_FIELDTYPE; ri.FieldType = BinaryReader.ReadByte(); if (ri.FieldType == RECORD_EMPTY) { _emptyRecords.Add(ri); _emptyRecordListSorted = false; } else { this.FileStream.Position = ri.Offset + RECORD_POS_ID; ri.ID = BinaryReader.ReadString(); ri.SubID = BinaryReader.ReadString(); switch (ri.FieldType) { case RECORD_GEOCACHE: this.GeocacheCollection.Add(new Data.Geocache(ri)); break; case RECORD_LOG: this.LogCollection.Add(new Data.Log(ri)); break; case RECORD_WAYPOINT: this.WaypointCollection.Add(new Data.Waypoint(ri)); break; case RECORD_USERWAYPOINT: this.UserWaypointCollection.Add(new Data.UserWaypoint(ri)); break; case RECORD_LOGIMAGE: this.LogImageCollection.Add(new Data.LogImage(ri)); break; case RECORD_GEOCACHEIMAGE: this.GeocacheImageCollection.Add(new Data.GeocacheImage(ri)); break; } } this.FileStream.Position = ri.Offset + ri.Length; ri.OffsetIdx = fsIdx.Position; ms.Position = 0; bw.Write(ri.Offset); bw.Write(ri.Length); bw.Write(ri.FieldType); if (ri.FieldType != RECORD_EMPTY) { bw.Write(ri.ID); bw.Write(ri.SubID); } else { bw.Write(""); bw.Write(""); } fsIdx.Write(buffer, 0, 117); if (DateTime.Now >= nextUpdate) { if (!prog.Update("Loading", 100, (int)(100.0 * (double)this.FileStream.Position / (double)max))) { cancelled = true; break; } nextUpdate = DateTime.Now.AddSeconds(1); } } //if all OK and not canceled fsIdx.Close(); if (!cancelled) { File.Copy(tf.Path, fn); _fileStreamIdx = File.Open(fn, FileMode.OpenOrCreate, FileAccess.ReadWrite); Utils.Calculus.SetDistanceAndAngleGeocacheFromLocation(this.GeocacheCollection, ApplicationData.Instance.CenterLocation); result = true; } } } } catch(Exception e) { Core.ApplicationData.Instance.Logger.AddLog(this, e); } return result; }
private bool LoadIndexFile(ref bool cancelled) { bool result = false; string fn = string.Concat(FileName, ".gsx"); try { //check if file exists //if not, it will be created during loading of database file if (File.Exists(fn)) { _fileStreamIdx = File.Open(fn, FileMode.OpenOrCreate, FileAccess.ReadWrite); long max = _fileStreamIdx.Length; DateTime nextUpdate = DateTime.Now.AddSeconds(1); using (Utils.ProgressBlock prog = new ProgressBlock("LoadingDatabase", "Loading", 100, 0, true)) { int maxChunks = 1000; int chunkSize = 117; byte[] buffer = new byte[maxChunks * chunkSize]; using (MemoryStream ms = new MemoryStream(buffer)) using (BinaryReader br = new BinaryReader(ms)) { while (_fileStreamIdx.Position < max) { long startPos = _fileStreamIdx.Position; int chunksRead = _fileStreamIdx.Read(buffer, 0, maxChunks * chunkSize) / chunkSize; for (int i = 0; i < chunksRead; i++) { RecordInfo ri = new RecordInfo(); ri.Database = this; ri.OffsetIdx = startPos + i * chunkSize; ms.Position = i * chunkSize; ri.Offset = br.ReadInt64(); ri.Length = br.ReadInt64(); ri.FieldType = br.ReadByte(); if (ri.FieldType != RECORD_EMPTY) { ri.ID = br.ReadString(); ri.SubID = br.ReadString(); } switch (ri.FieldType) { case RECORD_EMPTY: //empty _emptyRecords.Add(ri); _emptyRecordListSorted = false; break; case RECORD_GEOCACHE: this.GeocacheCollection.Add(new Data.Geocache(ri)); break; case RECORD_LOG: this.LogCollection.Add(new Data.Log(ri)); break; case RECORD_WAYPOINT: this.WaypointCollection.Add(new Data.Waypoint(ri)); break; case RECORD_USERWAYPOINT: this.UserWaypointCollection.Add(new Data.UserWaypoint(ri)); break; case RECORD_LOGIMAGE: this.LogImageCollection.Add(new Data.LogImage(ri)); break; case RECORD_GEOCACHEIMAGE: this.GeocacheImageCollection.Add(new Data.GeocacheImage(ri)); break; } if (DateTime.Now >= nextUpdate) { if (!prog.Update("Loading", 100, (int)(100.0 * (double)_fileStreamIdx.Position / (double)max))) { cancelled = true; break; } nextUpdate = DateTime.Now.AddSeconds(1); } } } if (!cancelled) { Utils.Calculus.SetDistanceAndAngleGeocacheFromLocation(GeocacheCollection, Core.ApplicationData.Instance.CenterLocation); result = true; } } } } } catch(Exception e) { Core.ApplicationData.Instance.Logger.AddLog(this, e); try { if (_fileStreamIdx!=null) { _fileStreamIdx.Dispose(); _fileStreamIdx = null; } File.Delete(fn); } catch { } } return result; }
private bool LoadDatabaseFile() { bool result = false; try { long max = FileStream.Length; DateTime nextUpdate = DateTime.Now.AddSeconds(1); using (Utils.ProgressBlock prog = new ProgressBlock("Loading database","Loading...",100,0)) { byte[] memBuffer = new byte[200]; using (MemoryStream ms = new MemoryStream(memBuffer)) using (BinaryReader br = new BinaryReader(ms)) { FileStream fs = FileStream; fs.Position = 0; long eof = fs.Length; while (fs.Position < eof) { RecordInfo ri = new RecordInfo(); ri.Database = this; ri.Offset = fs.Position; fs.Read(memBuffer, 0, 150); ms.Position = RECORD_POS_LENGTH; ri.Length = br.ReadInt64(); ms.Position = RECORD_POS_FIELDTYPE; byte ft = br.ReadByte(); switch (ft) { case RECORD_EMPTY: //empty _emptyRecords.Add(ri); _emptyRecordListSorted = false; break; case RECORD_GEOCACHE: ms.Position = RECORD_POS_ID; ri.ID = br.ReadString(); this.GeocacheCollection.Add(new Data.Geocache(ri)); break; case RECORD_LOG: ms.Position = RECORD_POS_ID; ri.ID = br.ReadString(); this.LogCollection.Add(new Data.Log(ri)); break; case RECORD_WAYPOINT: ms.Position = RECORD_POS_ID; ri.ID = br.ReadString(); this.WaypointCollection.Add(new Data.Waypoint(ri)); break; case RECORD_USERWAYPOINT: ms.Position = RECORD_POS_ID; ri.ID = br.ReadString(); this.UserWaypointCollection.Add(new Data.UserWaypoint(ri)); break; case RECORD_LOGIMAGE: ms.Position = RECORD_POS_ID; ri.ID = br.ReadString(); this.LogImageCollection.Add(new Data.LogImage(ri)); break; case RECORD_GEOCACHEIMAGE: ms.Position = RECORD_POS_ID; ri.ID = br.ReadString(); this.GeocacheImageCollection.Add(new Data.GeocacheImage(ri)); break; } fs.Position = ri.Offset + ri.Length; if (DateTime.Now>=nextUpdate) { prog.Update("Loading...", 100, (int)(100.0 * (double)fs.Position / (double)max)); nextUpdate = DateTime.Now.AddSeconds(1); } } } } Utils.Calculus.SetDistanceAndAngleGeocacheFromLocation(this.GeocacheCollection, ApplicationData.Instance.CenterLocation); result = true; } catch { } return result; }
private RecordInfo RequestRecord(string id, byte recordType, byte[] recordData, long minimumLength, long extraBuffer) { RecordInfo result = null; if (!_emptyRecordListSorted) { _emptyRecords.Sort(delegate(RecordInfo x, RecordInfo y) { return x.Length.CompareTo(y.Length); }); _emptyRecordListSorted = true; } result = (from a in _emptyRecords where a.Length >= minimumLength select a).FirstOrDefault(); if (result == null) { result = new RecordInfo(); result.Length = minimumLength + extraBuffer; result.Offset = FileStream.Length; result.ID = id; result.Database = this; FileStream.SetLength(result.Offset + result.Length); } else { //re-use of an empty record result.ID = id; _emptyRecords.Remove(result); } if (result != null) { //write record header data FileStream.Position = result.Offset + RECORD_POS_LENGTH; BinaryWriter.Write(result.Length); FileStream.Position = result.Offset + RECORD_POS_FIELDTYPE; FileStream.WriteByte(recordType); FileStream.Position = result.Offset + RECORD_POS_ID; BinaryWriter.Write(result.ID); //write data FileStream.Position = result.Offset + 150; FileStream.Write(recordData, 150, (int)minimumLength - 150); } return result; }