using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.IO; using System.Linq; using Logger; namespace CSVReader { public class UnitCSVReader : AbstractUnitCSVReader, ICSVReader { public UnitCSVReader(string filename) { try { string fileName = Path.Combine(".", "Assets", "CSVInput", filename); Reader = new BinaryReader(File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); CityLogger.Log("Opened file with " + Reader.BaseStream.Length / ROWLENGTHINBYTES + " rows of data", LogLevel.INFO); Defined = true; } catch (Exception e) { CityLogger.LogError("Datei nicht gefunden, " + e.Message); Defined = false; } } #region exposed public double JumpToEntry(double time, bool forward) { if (double.IsNaN(time) || !TestBinaryReader() || !IsInBounds(time)) return -1; long skip; double currTime = GetTimeAtRelativeOffset(0); int jumpDirection = (currTime < time) ? 1 : -1; skip = jumpDirection * ROWLENGTHINBYTES; lock (LockObject) { while (true) { if (!TestNewPosition(Reader.BaseStream.Position + skip)) return -1; double test = GetTimeAtRelativeOffset(jumpDirection); bool step = IsStep(test, time, jumpDirection, forward); if (step) Reader.BaseStream.Position += skip; else { if (forward && jumpDirection == 1 || !forward && jumpDirection == -1) Reader.BaseStream.Position += skip; break; } } } return GetTimeAtRelativeOffset((forward) ? 0 : -1); } public InputObject ReadNextEntry(bool forward) { if (!TestBinaryReader()) return null; long skip; if (forward) skip = 0; else skip = (-1 * ROWLENGTHINBYTES); lock (LockObject) { if (!TestNewPosition(Reader.BaseStream.Position + skip)) return null; Reader.BaseStream.Position += skip; InputObject o = ParseObject(); if (!forward)//compensate the streams natural behaviour of striving forward ;) Reader.BaseStream.Position += skip; return o; } } public bool IsInBounds(double time) { if (!TestBinaryReader()) return false; double startTime = !double.IsNaN(ChunkStartTimestamp) ? ChunkStartTimestamp : GetTimeAtAbsolutPosition(0); double endTime = !double.IsNaN(ChunkEndTimestamp) ? ChunkEndTimestamp : GetTimeAtAbsolutPosition((Reader.BaseStream.Length / ROWLENGTHINBYTES) - 1); if (startTime <= time && time <= endTime) return true; return false; } public double Peek(bool forward) { if (!TestBinaryReader()) return -1.0; //return GetTimeAtRelativOffset(0); if (forward) return GetTimeAtRelativeOffset(0); else return GetTimeAtRelativeOffset(-1); } public double GetLastTimestamp() { return GetTimeAtAbsolutPosition((Reader.BaseStream.Length / ROWLENGTHINBYTES) - 1); } public double GetFirstTimestamp() { return GetTimeAtAbsolutPosition(0); } public double GetChunkStarttimestamp() { return ChunkStartTimestamp; } public double GetChunkEndtimestamp() { return ChunkEndTimestamp; } public void SetChunkStarttimestamp(double time) { double firstFileTimestamp = GetFirstTimestamp(); double lastFileTimestamp = GetLastTimestamp(); if (time < firstFileTimestamp || time > lastFileTimestamp) { ChunkStartTimestamp = double.NaN; } else { double currTime = GetTimeAtRelativeOffset(0); if (currTime < time) { currTime = JumpToEntry(time, true); if (currTime > -1) { ChunkStartTimestamp = currTime; return; } } ChunkStartTimestamp = time; } } public void SetChunkEndtimestamp(double time) { double firstFileTimestamp = GetFirstTimestamp(); double lastFileTimestamp = GetLastTimestamp(); if (time > lastFileTimestamp || time < firstFileTimestamp) { ChunkEndTimestamp = double.NaN; } else { double currTime = GetTimeAtRelativeOffset(0); Debug.Log("currTime" + currTime.ToString()); if (currTime > time) { currTime = JumpToEntry(time, false); Debug.Log("currTime" + currTime.ToString()); if (currTime > -1) { ChunkEndTimestamp = currTime; return; } } ChunkEndTimestamp = time; } } public void TearDown() { if (TestBinaryReader()) Reader.Close(); Defined = true; } #endregion #region internal protected override InputObject ParseObject() { try { float[] posRot = new float[9]; int id = BitConverter.ToInt32(Reader.ReadBytes(sizeof(int)), 0); double time = BitConverter.ToDouble(Reader.ReadBytes(sizeof(double)), 0); for (int i = 0; i < posRot.Length; i++) posRot[i] = BitConverter.ToSingle(Reader.ReadBytes(sizeof(float)), 0); uint toC = BitConverter.ToUInt32(Reader.ReadBytes(sizeof(uint)), 0); uint boC = BitConverter.ToUInt32(Reader.ReadBytes(sizeof(uint)), 0); int type = BitConverter.ToInt32(Reader.ReadBytes(sizeof(int)), 0); int sensorID = BitConverter.ToInt32(Reader.ReadBytes(sizeof(int)), 0); return new InputObject(id, time, posRot[0], posRot[1], posRot[2], posRot[3], posRot[4], posRot[5], posRot[6], posRot[7], posRot[8], toC, boC, (EntityType)type, sensorID); } catch { CityLogger.LogWarning("Unable to read From File"); } return null; } protected override double GetTimeAtRelativeOffset(long shift) { double curTime = -1; long skip = (shift * ROWLENGTHINBYTES) + sizeof(int); lock (LockObject) { if (!TestNewPosition(Reader.BaseStream.Position + skip)) if (skip < 0) return GetFirstTimestamp(); else return GetLastTimestamp(); Reader.BaseStream.Position += skip; curTime = BitConverter.ToDouble(Reader.ReadBytes(sizeof(double)), 0); Reader.BaseStream.Position -= (skip + sizeof(double)); //try //{ // curTime = BitConverter.ToDouble(Reader.ReadBytes(sizeof(double)), 0); //} //finally //{ // Reader.BaseStream.Position -= (skip + sizeof(double)); //} } return curTime; } protected override double GetTimeAtAbsolutPosition(long offset) { double curTime = -1; long newPos = (offset * ROWLENGTHINBYTES) + sizeof(int); if (!TestNewPosition(newPos)) return curTime; lock (LockObject) { long oldPos = Reader.BaseStream.Position; Reader.BaseStream.Position = newPos; try { curTime = BitConverter.ToDouble(Reader.ReadBytes(sizeof(double)), 0); } finally { Reader.BaseStream.Position = oldPos; } } return curTime; } protected override bool TestNewPosition(long newPos) { if (newPos >= Reader.BaseStream.Length || newPos < 0) { CityLogger.LogWarning("Tried to move filepointer out of bounds"); return false; } return true; } protected override bool TestBinaryReader() { if (!Defined) { CityLogger.LogError("Reader is not opened on File. unable to procced"); return false; } return true; } protected override bool IsStep(double newTime, double targetTime, int jumpdirection, bool forward) { if (forward) return jumpdirection == 1 ? newTime < targetTime : newTime >= targetTime; else return jumpdirection == 1 ? newTime <= targetTime : newTime > targetTime; } #endregion } }