/// <summary> /// Get the data in this storage /// </summary> /// <returns>The data in this storage</returns> public IEnumerator <T> GetEnumerator() { if (!_fileInfo.Exists) { yield break; } int elementsInTrunk = _trunkSize / _elementSize; if (elementsInTrunk <= 0) { elementsInTrunk = 1; } Byte[] buffer = new byte[_elementSize * elementsInTrunk]; using (FileStream stream = _fileInfo.OpenRead()) using (BufferedStream bufferStream = new BufferedStream(stream, _trunkSize)) using (PinnedArray <T> structures = new PinnedArray <T>(elementsInTrunk)) { IntPtr structAddr = structures.AddrOfPinnedObject(); int bytesRead; while ((bytesRead = bufferStream.Read(buffer, 0, buffer.Length)) > 0) { Marshal.Copy(buffer, 0, structAddr, bytesRead); int elementsRead = bytesRead / _elementSize; for (int i = 0; i < elementsRead; i++) { yield return(structures.Array[i]); } } } }
/// <summary> /// Get a copy of the first element in the storage. If the storage is empty, a default value will be returned /// </summary> /// <returns>A copy of the first element in the storage. If the storage is empty, a default value will be returned</returns> public T Peek() { using (FileStream stream = _fileInfo.OpenRead()) using (PinnedArray <Byte> buffer = new PinnedArray <byte>(_elementSize)) { return((stream.Read(buffer.Array, 0, _elementSize) > 0) ? (T)Marshal.PtrToStructure(buffer.AddrOfPinnedObject(), typeof(T)) : new T()); } }
/// <summary> /// Get the data in this storage /// </summary> /// <returns>The data in this storage</returns> public IEnumerator <T> GetEnumerator() { using (FileStream stream = _fileInfo.OpenRead()) { int elementSize = Marshal.SizeOf(typeof(T)); if (_trunkSize <= 1) { using (PinnedArray <Byte> buffer = new PinnedArray <byte>(elementSize)) using (PinnedArray <T> structure = new PinnedArray <T>(1)) { IntPtr structAddr = structure.AddrOfPinnedObject(); IntPtr addr = buffer.AddrOfPinnedObject(); while (stream.Read(buffer.Array, 0, elementSize) > 0) { Toolbox.memcpy(structAddr, addr, elementSize); yield return(structure.Array[0]); } } } else { int bufferSize = elementSize * _trunkSize; using (PinnedArray <Byte> buffer = new PinnedArray <byte>(bufferSize)) using (PinnedArray <T> structure = new PinnedArray <T>(_trunkSize)) { IntPtr structAddr = structure.AddrOfPinnedObject(); IntPtr addr = buffer.AddrOfPinnedObject(); for ( int count = stream.Read(buffer.Array, 0, bufferSize) / elementSize; count > 0; count = stream.Read(buffer.Array, 0, bufferSize) / elementSize) { Toolbox.memcpy(structAddr, addr, bufferSize); if (count == _trunkSize) { foreach (T e in structure.Array) { yield return(e); } } else { for (int i = 0; i < count; i++) { yield return(structure.Array[i]); } } } } } } }
void Append(IEnumerable <T> samples) { int elementsInTrunk = _trunkSize / _elementSize; if (elementsInTrunk <= 0) { elementsInTrunk = 1; } byte[] byteBuffer = new byte[elementsInTrunk * _elementSize]; int index = 0; #if NETFX_CORE StorageFile storageFile = await StorageFile.GetFileFromPathAsync(_fileInfo); using (PinnedArray <T> buffer = new PinnedArray <T>(elementsInTrunk)) using (Stream bufferStream = await storageFile.OpenStreamForWriteAsync()) { bufferStream.Seek(0, SeekOrigin.End); #else using (PinnedArray <T> buffer = new PinnedArray <T>(elementsInTrunk)) using (FileStream stream = _fileInfo.Open(FileMode.Append, FileAccess.Write)) using (BufferedStream bufferStream = new BufferedStream(stream, _trunkSize)) { #endif IntPtr ptr = buffer.AddrOfPinnedObject(); foreach (T s in samples) { buffer.Array[index++] = s; if (index == buffer.Array.Length) { int writeCount = index * _elementSize; Marshal.Copy(ptr, byteBuffer, 0, writeCount); bufferStream.Write(byteBuffer, 0, writeCount); index = 0; } } if (index != 0) { int writeCount = index * _elementSize; Marshal.Copy(ptr, byteBuffer, 0, writeCount); bufferStream.Write(byteBuffer, 0, writeCount); index = 0; } } }
/// <summary> /// Get the data in this storage /// </summary> /// <returns>The data in this storage</returns> public IEnumerator <T> GetEnumerator() { int elementSize = Marshal.SizeOf(typeof(T)); using (FileStream stream = _fileInfo.OpenRead()) using (BufferedStream bufferStream = new BufferedStream(stream, _trunkSize <= 0 ? 4096 : _trunkSize)) using (PinnedArray <Byte> buffer = new PinnedArray <byte>(elementSize)) using (PinnedArray <T> structure = new PinnedArray <T>(1)) { IntPtr structAddr = structure.AddrOfPinnedObject(); IntPtr addr = buffer.AddrOfPinnedObject(); while (bufferStream.Read(buffer.Array, 0, elementSize) > 0) { Toolbox.memcpy(structAddr, addr, elementSize); yield return(structure.Array[0]); } } }
/// <summary> /// Get the subsampled data in this storage /// </summary> /// <param name="subsampleRate">The subsample rate</param> /// <returns>The subsampled data in this storage</returns> public IEnumerable <T> GetSubsamples(int subsampleRate) { using (FileStream stream = _fileInfo.OpenRead()) { int elementSize = Marshal.SizeOf(typeof(T)); int bufferSize = elementSize * subsampleRate; using (PinnedArray <Byte> buffer = new PinnedArray <byte>(bufferSize)) using (PinnedArray <T> structure = new PinnedArray <T>(subsampleRate)) { IntPtr structAddr = structure.AddrOfPinnedObject(); IntPtr addr = buffer.AddrOfPinnedObject(); while (stream.Read(buffer.Array, 0, bufferSize) > 0) { Toolbox.memcpy(structAddr, addr, bufferSize); yield return(structure.Array[0]); } } } }
/// <summary> /// Create a binary File Storage with the specific data /// </summary> /// <param name="fileName">The file name of the storage</param> /// <param name="samples">The data which will be stored in the storage</param> public BinaryFileStorage(String fileName, IEnumerable <T> samples) { _fileInfo = new FileInfo(fileName); if (_fileInfo.Exists) { _fileInfo.Delete(); } int size = Marshal.SizeOf(typeof(T)); using (PinnedArray <Byte> buffer = new PinnedArray <byte>(size)) using (FileStream stream = _fileInfo.OpenWrite()) { IntPtr ptr = buffer.AddrOfPinnedObject(); foreach (T s in samples) { Marshal.StructureToPtr(s, ptr, false); stream.Write(buffer.Array, 0, size); } } }
/// <summary> /// Append the samples to the end of the storage /// </summary> /// <param name="samples">The samples to be appended to the storage</param> public void Append(IEnumerable <T> samples) { int elementsInTrunk = _trunkSize / _elementSize; if (elementsInTrunk <= 0) { elementsInTrunk = 1; } byte[] byteBuffer = new byte[elementsInTrunk * _elementSize]; int index = 0; using (PinnedArray <T> buffer = new PinnedArray <T>(elementsInTrunk)) using (FileStream stream = _fileInfo.Open(FileMode.Append, FileAccess.Write)) using (BufferedStream bufferStream = new BufferedStream(stream, _trunkSize)) { IntPtr ptr = buffer.AddrOfPinnedObject(); foreach (T s in samples) { buffer.Array[index++] = s; if (index == buffer.Array.Length) { int writeCount = index * _elementSize; Marshal.Copy(ptr, byteBuffer, 0, writeCount); bufferStream.Write(byteBuffer, 0, writeCount); index = 0; } } if (index != 0) { int writeCount = index * _elementSize; Marshal.Copy(ptr, byteBuffer, 0, writeCount); bufferStream.Write(byteBuffer, 0, writeCount); index = 0; } } }
/// <summary> /// Get the subsampled data in this storage /// </summary> /// <param name="subsampleRate">The subsample rate</param> /// <returns>The subsampled data in this storage</returns> public IEnumerable <T> GetSubsamples(int subsampleRate) { if (!_fileInfo.Exists) { yield break; } int bufferSize = _elementSize * subsampleRate; using (FileStream stream = _fileInfo.OpenRead()) using (BufferedStream bufferStream = new BufferedStream(stream, _trunkSize)) using (PinnedArray <Byte> buffer = new PinnedArray <byte>(bufferSize)) using (PinnedArray <T> structure = new PinnedArray <T>(subsampleRate)) { IntPtr structAddr = structure.AddrOfPinnedObject(); IntPtr addr = buffer.AddrOfPinnedObject(); while (bufferStream.Read(buffer.Array, 0, bufferSize) > 0) { Toolbox.memcpy(structAddr, addr, bufferSize); yield return(structure.Array[0]); } } }