Ver código fonte

删除不必要的文件

l2736 2 semanas atrás
pai
commit
dded419e85

+ 0 - 6
ShakerControl.sln

@@ -116,8 +116,6 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "NetMQ", "Communication\NetM
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeLibraryLoader", "NativeLibraryLoader\NativeLibraryLoader.csproj", "{1C9C9ED0-2215-43CC-8557-99CDFDD31219}"
 EndProject
-Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Data.Tdms", "Tdms\FSharp.Data.Tdms.fsproj", "{799900FA-5DB9-41ED-A4D1-74A984635718}"
-EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -244,10 +242,6 @@ Global
 		{1C9C9ED0-2215-43CC-8557-99CDFDD31219}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{1C9C9ED0-2215-43CC-8557-99CDFDD31219}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{1C9C9ED0-2215-43CC-8557-99CDFDD31219}.Release|Any CPU.Build.0 = Release|Any CPU
-		{799900FA-5DB9-41ED-A4D1-74A984635718}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{799900FA-5DB9-41ED-A4D1-74A984635718}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{799900FA-5DB9-41ED-A4D1-74A984635718}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{799900FA-5DB9-41ED-A4D1-74A984635718}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 0 - 16
ShakerFile/ShakerFile/FileConstant.cs

@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace ShakerFile
-{
-    public class FileConstant
-    {
-        public const UInt32 FILEID = 0x11223344;
-        public const UInt16 SHAKERINFOLENGTH = 1024 * 2;
-        public const UInt16 CHANNELNAMESLENGTH = 256;
-        public const UInt16 TESTCONFIGLEHGTH = 1024;
-        public const UInt16 SNLENGTH = 100;
-        public const UInt16 NAMELENGTH = 50;
-    }
-}

+ 0 - 29
ShakerFile/ShakerFile/FileHeader.cs

@@ -1,29 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace ShakerFile
-{
-    [StructLayout(LayoutKind.Sequential, Pack = 1)]
-    public struct FileHeader
-    {
-        public FileHeader()
-        {
-
-        }
-        public uint FileID = FileConstant.FILEID;
-        public FileVersion Version = FileVersion.Version1_0;
-        public long CreateTime = 0;
-        public long LastTime = 0;
-        public ushort ShakerInfoLength = 0;
-    }
-    [StructLayout(LayoutKind.Sequential, Pack = 1)]
-    public struct ShakerInfo
-    {
-        public ShakerInfo()
-        {
-
-        }
-        public uint SampleRate;
-        public uint ChannelCount;
-        public ulong FrameCount;
-    }
-}

+ 0 - 14
ShakerFile/ShakerFile/FileVersion.cs

@@ -1,14 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace ShakerFile
-{
-    public enum FileVersion : byte
-    {
-        /// <summary>
-        /// 1.0
-        /// </summary>
-        Version1_0,
-    }
-}

+ 0 - 10
ShakerFile/ShakerFile/IFileInfo.cs

@@ -1,10 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace ShakerFile
-{
-    public interface IFileInfo
-    {
-    }
-}

+ 0 - 18
ShakerFile/ShakerFile/IShakerFile.cs

@@ -1,18 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace ShakerFile
-{
-    public interface IShakerFile : IDisposable
-    {
-        public ReadOnlyMemory<byte> ShakerOtherConfig { get; }
-        public bool IsOpen { get; }
-        public string Path { get; }
-        public FileHeader FileHeader { get; }
-        public ShakerStringInfo ShakerStringInfo { get; }
-        public void WriteInfo(ShakerInfo shakerInfo, ShakerStringInfo stringInfo,ref byte shakerOtherConfig,ushort shakerInfoLength);
-        public void Close();
-        public void WriteData(ref float value, int count);
-    }
-}

+ 0 - 21
ShakerFile/ShakerFile/ShakerFile.projitems

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
-    <HasSharedItems>true</HasSharedItems>
-    <SharedGUID>1b007f83-8d00-4c26-ad5b-27634a5cccfc</SharedGUID>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration">
-    <Import_RootNamespace>ShakerFile</Import_RootNamespace>
-  </PropertyGroup>
-  <ItemGroup>
-    <Compile Include="$(MSBuildThisFileDirectory)FileConstant.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)FileHeader.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)FileVersion.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)IFileInfo.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)IShakerFile.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)ShakerStringInfo.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)V1_0\ShakerFile.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)WinFile.cs" />
-  </ItemGroup>
-</Project>

+ 0 - 13
ShakerFile/ShakerFile/ShakerFile.shproj

@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>1b007f83-8d00-4c26-ad5b-27634a5cccfc</ProjectGuid>
-    <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
-  </PropertyGroup>
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
-  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
-  <PropertyGroup />
-  <Import Project="ShakerFile.projitems" Label="Shared" />
-  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
-</Project>

+ 0 - 76
ShakerFile/ShakerFile/ShakerStringInfo.cs

@@ -1,76 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-using System.Text;
-
-namespace ShakerFile
-{
-    public class ShakerStringInfo
-    {
-        public string ShakerName = string.Empty;
-        public string ShakerSN = string.Empty;
-        public byte[] TestConfig = new byte[0];
-        public string ChannelNames = string.Empty;
-
-        public void Read(IntPtr file)
-        {
-            int count = 0;
-            int len = 0;
-            WinFile.ReadFile(file, ref Unsafe.As<int, byte>(ref len), 4, out _, 0);
-            count += 4;
-            if (len > 0)
-            {
-                byte[] temp = new byte[len];
-                WinFile.ReadFile(file, ref temp[0], (uint)len, out _, 0);
-                ShakerName = Encoding.Default.GetString(temp);
-            }
-            count += len;
-            len = 0;
-            WinFile.ReadFile(file, ref Unsafe.As<int, byte>(ref len), 4, out _, 0);
-            count += 4;
-            if (len > 0)
-            {
-                byte[] temp = new byte[len];
-                WinFile.ReadFile(file, ref temp[0], (uint)len, out _, 0);
-                ShakerSN = Encoding.Default.GetString(temp);
-            }
-            count += len;
-            len = 0;
-            WinFile.ReadFile(file, ref Unsafe.As<int, byte>(ref len), 4, out _, 0); if (len > 0)
-            {
-                TestConfig = new byte[len];
-                WinFile.ReadFile(file, ref TestConfig[0], (uint)len, out _, 0);
-            }
-            count += len;
-            len = 0;
-            WinFile.ReadFile(file, ref Unsafe.As<int, byte>(ref len), 4, out _, 0);
-            if (len > 0)
-            {
-                byte[] temp = new byte[len];
-                WinFile.ReadFile(file, ref temp[0], (uint)len, out _, 0);
-                ChannelNames = Encoding.Default.GetString(temp);
-            }
-            count += len;
-        }
-        public void Write(IntPtr file, ref int count)
-        {
-            List<byte[]> bytes = new List<byte[]>();
-            bytes.Add(Encoding.Default.GetBytes(ShakerName));
-            bytes.Add(Encoding.Default.GetBytes(ShakerSN));
-            bytes.Add(TestConfig);
-            bytes.Add(Encoding.Default.GetBytes(ChannelNames));
-            count = 0;
-            for (int i = 0; i < bytes.Count; i++)
-            {
-                int len = bytes[i].Length;
-                WinFile.WriteFile(file, ref Unsafe.As<int, byte>(ref len), 4, out _, 0);
-                count += 4;
-                if (len > 0)
-                {
-                    WinFile.WriteFile(file, ref bytes[i][0], (uint)len, out _, 0);
-                }
-                count += len;
-            }
-        }
-    }
-}

+ 0 - 149
ShakerFile/ShakerFile/V1_0/ShakerFile.cs

@@ -1,149 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace ShakerFile.V1_0
-{
-    internal class ShakerFile : IShakerFile
-    {
-        private ShakerFile()
-        {
-
-        }
-        private ShakerFile(string path)
-        {
-            Path = path;
-        }
-        private ShakerFile(ushort shakerInfoLength)
-        {
-            fileHeader.ShakerInfoLength = shakerInfoLength;
-        }
-        static ShakerFile()
-        {
-
-        }
-        public ReadOnlyMemory<byte> ShakerOtherConfig { get; private set; } = new ReadOnlyMemory<byte>();
-        public bool IsOpen => file > 0;
-        private nint file;
-        private FileHeader fileHeader = new FileHeader();
-        private ShakerInfo shakerInfo = new ShakerInfo();
-        private ShakerStringInfo shakerStringInfo = new ShakerStringInfo();
-        public string Path { get; private set; } = string.Empty;
-
-        public FileHeader FileHeader => fileHeader;
-        public ShakerStringInfo ShakerStringInfo => shakerStringInfo;
-
-        public ShakerInfo ShakerInfo => shakerInfo;
-
-        public void Close()
-        {
-            WinFile.CloseHandle(file);
-            file = 0;
-        }
-        private unsafe void CreateFile(string path)
-        {
-            if (fileHeader.ShakerInfoLength == 0) throw new ArgumentException("ShakerInfoLength can not be zero");
-            if (System.IO.File.Exists(path)) System.IO.File.Delete(path);
-            ShakerFile shakerFile = new ShakerFile();
-
-            file = WinFile.CreateFile(path, WinFile.DesiredAccess.ReadAndWrite, WinFile.ShareMode.None, 0, WinFile.CreationDisposition.CreateAlways, WinFile.FileAttributes.FILE_ATTRIBUTE_NORMAL, 0);
-            Path = path;
-            fileHeader.CreateTime = DateTime.Now.Ticks;
-            fileHeader.LastTime = fileHeader.CreateTime;
-            ShakerOtherConfig = new ReadOnlyMemory<byte>(new byte[fileHeader.ShakerInfoLength]);
-            uint count = 0;
-            WinFile.SetFilePointer(file, 0, 0, WinFile.MoveMethod.Begin);
-            WinFile.WriteFile(file, ref Unsafe.As<FileHeader, byte>(ref fileHeader), (uint)Marshal.SizeOf<FileHeader>(), out count, 0);
-            WinFile.WriteFile(file, ref Unsafe.As<ShakerInfo, byte>(ref shakerInfo), (uint)Marshal.SizeOf<ShakerInfo>(), out count, 0);
-            WinFile.WriteFile(file, ref Unsafe.AsRef<byte>(ShakerOtherConfig.Pin().Pointer), fileHeader.ShakerInfoLength, out count, 0);
-        }
-        public static unsafe ShakerFile CreateFile(string path,ushort shakerInfoLength)
-        {
-            if(shakerInfoLength ==0) throw new ArgumentException("ShakerInfoLength can not be zero");
-            if (System.IO.File.Exists(path)) System.IO.File.Delete(path);
-            ShakerFile shakerFile = new ShakerFile(shakerInfoLength);
-            shakerFile.CreateFile(path);
-            return shakerFile;
-        }
-        private unsafe void UpdateLastTime(DateTime time)
-        {
-            fileHeader.LastTime = time.Ticks;
-            int startaddr = (int)((ulong)(Unsafe.AsPointer(ref fileHeader.LastTime)) - (ulong)(Unsafe.AsPointer(ref fileHeader)));
-            WinFile.SetFilePointer(file, startaddr, 0, WinFile.MoveMethod.Begin);
-            uint count = 0;
-            WinFile.WriteFile(file, ref Unsafe.As<long, byte>(ref fileHeader.LastTime), (uint)Marshal.SizeOf(fileHeader.LastTime), out count, 0);
-        }
-        private unsafe void UpdateFrameCount()
-        {
-            UpdateLastTime(DateTime.Now);
-            uint count = 0;
-            int startaddr = (int)((ulong)(Unsafe.AsPointer(ref shakerInfo.FrameCount)) - (ulong)(Unsafe.AsPointer(ref shakerInfo))) + Marshal.SizeOf<FileHeader>();
-            shakerInfo.FrameCount++;
-            WinFile.SetFilePointer(file, startaddr, 0, WinFile.MoveMethod.Begin);
-            WinFile.WriteFile(file, ref Unsafe.As<ulong, byte>(ref shakerInfo.FrameCount), (uint)Unsafe.SizeOf<ulong>(), out count, 0);
-        }
-        public void Dispose()
-        {
-            WinFile.CloseHandle(file);
-            file = 0;
-        }
-
-        private unsafe void OpenFile()
-        {
-            file = WinFile.CreateFile(Path, WinFile.DesiredAccess.Read, WinFile.ShareMode.None, 0, WinFile.CreationDisposition.OpenExisting, WinFile.FileAttributes.FILE_ATTRIBUTE_NORMAL, 0);
-            uint count = 0;
-            WinFile.ReadFile(file, ref Unsafe.As<FileHeader, byte>(ref fileHeader), (uint)Marshal.SizeOf<FileHeader>(), out count, 0);
-            if (fileHeader.FileID != FileConstant.FILEID)
-            {
-                throw new Exception("File Format Error");
-            }
-            if (!Enum.GetValues<FileVersion>().Contains(fileHeader.Version))
-            {
-                throw new Exception("File Version Not Support");
-            }
-            WinFile.ReadFile(file, ref Unsafe.As<ShakerInfo, byte>(ref shakerInfo), (uint)Marshal.SizeOf<ShakerInfo>(), out count, 0);
-            WinFile.ReadFile(file, ref Unsafe.AsRef<byte>(ShakerOtherConfig.Pin().Pointer), fileHeader.ShakerInfoLength, out count, 0);
-            shakerStringInfo.Read(file);
-        }
-        public static ShakerFile OpenFile(string path)
-        {
-            ShakerFile file = new ShakerFile(path);
-            file.OpenFile();
-            return file;
-        }
-
-        public unsafe void WriteInfo(ShakerInfo shakerInfo, ShakerStringInfo info,ref byte shakerOtherConfig,ushort shakerInfoLength)
-        {
-            uint count = 0;
-            UpdateLastTime(DateTime.Now);
-            WinFile.SetFilePointer(file, Marshal.SizeOf<FileHeader>(), 0, WinFile.MoveMethod.Begin);
-            byte[] data = new byte[Marshal.SizeOf(shakerInfo)];
-            Unsafe.CopyBlock(ref data[0], ref Unsafe.As<ShakerInfo, byte>(ref shakerInfo), (uint)data.Length);
-            var d = Unsafe.As<byte, ShakerInfo>(ref data[0]);
-            WinFile.WriteFile(file, ref data[0], (uint)Marshal.SizeOf(shakerInfo), out count, 0);
-            if(shakerInfoLength>0)
-            {
-                WinFile.WriteFile(file, ref shakerOtherConfig,Math.Min(fileHeader.ShakerInfoLength, shakerInfoLength), out count, 0);
-            }
-            WinFile.SetFilePointer(file, Marshal.SizeOf<FileHeader>() +Marshal.SizeOf<ShakerInfo>()+fileHeader.ShakerInfoLength, 0, WinFile.MoveMethod.Begin);
-            this.shakerInfo = shakerInfo;
-            shakerStringInfo.ChannelNames = info.ChannelNames;
-            shakerStringInfo.ShakerName = info.ShakerName;
-            shakerStringInfo.ShakerSN = info.ShakerSN;
-            shakerStringInfo.TestConfig = info.TestConfig;
-            int cnt = 0;
-            shakerStringInfo.Write(file, ref cnt);
-
-        }
-        public void WriteData(ref float value, int count)
-        {
-            UpdateFrameCount();
-            WinFile.SetFilePointer(file, 0, 0, WinFile.MoveMethod.End);
-            uint cnt = 0;
-            WinFile.WriteFile(file, ref Unsafe.As<float, byte>(ref value), (uint)(Unsafe.SizeOf<float>() * count), out cnt, 0);
-        }
-    }
-}

+ 0 - 182
ShakerFile/ShakerFile/WinFile.cs

@@ -1,182 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace ShakerFile
-{
-    public static class WinFile
-    {
-        public enum DesiredAccess : uint
-        {
-            Read = 0x80000000,
-            Write = 0x40000000,
-            ReadAndWrite = Read | Write,
-        }
-        public enum ShareMode : uint
-        {
-            None=0,
-            Read = 0x00000001,
-            Write = 0x00000002,
-            Delete = 0x04,
-
-        }
-        public enum CreationDisposition : uint
-        {
-            CreateNew = 1,
-            CreateAlways = 2,
-            OpenExisting = 3,
-            OpenAlways = 4,
-            Truncate_Existing = 5,
-        }
-
-        [Flags]
-        public enum FileAttributes
-        {
-            /// <summary>
-            ///     A file or directory that is an archive file or directory. Applications typically use this attribute to mark
-            ///     files for backup or removal .
-            /// </summary>
-            FILE_ATTRIBUTE_ARCHIVE = 0x20,
-
-            /// <summary>
-            ///     A file or directory that is compressed. For a file, all of the data in the file is compressed. For a
-            ///     directory, compression is the default for newly created files and subdirectories.
-            /// </summary>
-            FILE_ATTRIBUTE_COMPRESSED = 0x800,
-
-            /// <summary>
-            ///     This value is reserved for system use.
-            /// </summary>
-            FILE_ATTRIBUTE_DEVICE = 0x40,
-
-            /// <summary>
-            ///     The handle that identifies a directory.
-            /// </summary>
-            FILE_ATTRIBUTE_DIRECTORY = 0x10,
-
-            /// <summary>
-            ///     A file or directory that is encrypted. For a file, all data streams in the file are encrypted. For a
-            ///     directory, encryption is the default for newly created files and subdirectories.
-            /// </summary>
-            FILE_ATTRIBUTE_ENCRYPTED = 0x4000,
-
-            /// <summary>
-            ///     The file or directory is hidden. It is not included in an ordinary directory listing.
-            /// </summary>
-            FILE_ATTRIBUTE_HIDDEN = 0x2,
-
-            /// <summary>
-            ///     The directory or user data stream is configured with integrity (only supported on ReFS volumes). It is not
-            ///     included in an ordinary directory listing. The integrity setting persists with the file if it's renamed. If a
-            ///     file is copied the destination file will have integrity set if either the source file or destination directory
-            ///     have integrity set.
-            ///     Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:  This
-            ///     flag is not supported until Windows Server 2012.
-            /// </summary>
-            FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x8000,
-
-            /// <summary>
-            ///     A file that does not have other attributes set. This attribute is valid only when used alone.
-            /// </summary>
-            FILE_ATTRIBUTE_NORMAL = 0x80,
-
-            /// <summary>
-            ///     The file or directory is not to be indexed by the content indexing service.
-            /// </summary>
-            FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000,
-
-            /// <summary>
-            ///     The user data stream not to be read by the background data integrity scanner (AKA scrubber). When set on a
-            ///     directory it only provides inheritance. This
-            ///     flag is only supported on Storage Spaces and ReFS volumes. It is not included in an ordinary directory
-            ///     listing.
-            ///     Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:  This
-            ///     flag is not supported until Windows 8 and Windows Server 2012.
-            /// </summary>
-            FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x20000,
-
-            /// <summary>
-            ///     The data of a file is not available immediately. This attribute indicates that the file data is physically
-            ///     moved to offline storage. This attribute is used by Remote Storage, which is the hierarchical storage management
-            ///     software. Applications should not arbitrarily change this attribute.
-            /// </summary>
-            FILE_ATTRIBUTE_OFFLINE = 0x1000,
-
-            /// <summary>
-            ///     A file that is read-only. Applications can read the file, but cannot write to it or delete it. This
-            ///     attribute is not honored on directories. For more information, see
-            ///     You cannot view or change the Read-only or the System attributes of folders in Windows Server 2003, in Windows XP,
-            ///     in Windows Vista or in Windows 7.
-            /// </summary>
-            FILE_ATTRIBUTE_READONLY = 0x1,
-
-            /// <summary>
-            ///     A file or directory that has an associated reparse point, or a file that is a symbolic link.
-            /// </summary>
-            FILE_ATTRIBUTE_REPARSE_POINT = 0x400,
-
-            /// <summary>
-            ///     A file that is a sparse file.
-            /// </summary>
-            FILE_ATTRIBUTE_SPARSE_FILE = 0x200,
-
-            /// <summary>
-            ///     A file or directory that the operating system uses a part of, or uses exclusively.
-            /// </summary>
-            FILE_ATTRIBUTE_SYSTEM = 0x4,
-
-            /// <summary>
-            ///     A file that is being used for temporary storage. File systems avoid writing data back to mass storage if
-            ///     sufficient cache memory is available, because typically, an application deletes a temporary file after the handle
-            ///     is closed. In that scenario, the system can entirely avoid writing the data. Otherwise, the data is written after
-            ///     the handle is closed.
-            /// </summary>
-            FILE_ATTRIBUTE_TEMPORARY = 0x100,
-
-            /// <summary>
-            ///     This value is reserved for system use.
-            /// </summary>
-            FILE_ATTRIBUTE_VIRTUAL = 0x10000
-        }
-        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
-        public static extern nint CreateFile(
-             string lpFileName,
-            DesiredAccess dwDesiredAccess,
-            ShareMode dwShareMode,
-            nint lpSecurityAttributes,
-            CreationDisposition dwCreationDisposition,
-            FileAttributes dwFlagsAndAttributes,
-            nint hTemplateFile);
-
-        [DllImport("kernel32.dll", SetLastError = true)]
-        public static extern bool ReadFile(
-            nint hFile,
-            ref byte lpBuffer,
-            uint nNumberOfBytesToRead,
-            out uint lpNumberOfBytesRead,
-            nint lpOverlapped);
-
-        [DllImport("kernel32.dll", SetLastError = true)]
-        public static extern bool WriteFile(
-            nint hFile,
-            ref byte lpBuffer,
-            uint nNumberOfBytesToWrite,
-            out uint lpNumberOfBytesWritten,
-            nint lpOverlapped);
-
-        public enum MoveMethod : uint
-        {
-            Begin = 0,
-            Current = 1,
-            End = 2,
-        }
-        [DllImport("kernel32.dll", SetLastError = true)]
-        public static extern bool CloseHandle(nint hObject);
-        [DllImport("kernel32.dll", EntryPoint = "SetFilePointer")]
-        public static extern uint SetFilePointer([In()] nint hFile, int lDistanceToMove, [In()] nint lpDistanceToMoveHigh, MoveMethod dwMoveMethod);
-
-        [DllImport("kernel32.dll", SetLastError = true)]
-        public static extern bool DeleteFile(string lpFileName);
-    }
-}

+ 0 - 166
Tdms/Buffer.fs

@@ -1,166 +0,0 @@
-namespace FSharp.Data.Tdms
-
-open System
-open System.Buffers.Binary
-open System.Numerics
-#if IS_DESIGNTIME
-open System.Runtime.InteropServices
-#endif
-open System.Text
-
-module Buffer =
-
-    let readInt16 (buffer: byte ReadOnlySpan byref) bigEndian =
-        let value =
-            if bigEndian then
-                BinaryPrimitives.ReadInt16BigEndian buffer
-            else
-                BinaryPrimitives.ReadInt16LittleEndian buffer
-
-        buffer <- buffer.Slice 2
-        value
-
-    let readInt (buffer: byte ReadOnlySpan byref) bigEndian =
-        let value =
-            if bigEndian then
-                BinaryPrimitives.ReadInt32BigEndian buffer
-            else
-                BinaryPrimitives.ReadInt32LittleEndian buffer
-
-        buffer <- buffer.Slice 4
-        value
-
-    let readInt64 (buffer: byte ReadOnlySpan byref) bigEndian =
-        let value =
-            if bigEndian then
-                BinaryPrimitives.ReadInt64BigEndian buffer
-            else
-                BinaryPrimitives.ReadInt64LittleEndian buffer
-
-        buffer <- buffer.Slice 8
-        value
-
-    let readUInt16 (buffer: byte ReadOnlySpan byref) bigEndian =
-        let value =
-            if bigEndian then
-                BinaryPrimitives.ReadUInt16BigEndian buffer
-            else
-                BinaryPrimitives.ReadUInt16LittleEndian buffer
-
-        buffer <- buffer.Slice 2
-        value
-
-    let readUInt (buffer: byte ReadOnlySpan byref) bigEndian =
-        let value =
-            if bigEndian then
-                BinaryPrimitives.ReadUInt32BigEndian buffer
-            else
-                BinaryPrimitives.ReadUInt32LittleEndian buffer
-
-        buffer <- buffer.Slice 4
-        value
-
-    let readUInt64 (buffer: byte ReadOnlySpan byref) bigEndian =
-        let value =
-            if bigEndian then
-                BinaryPrimitives.ReadUInt64BigEndian buffer
-            else
-                BinaryPrimitives.ReadUInt64LittleEndian buffer
-
-        buffer <- buffer.Slice 8
-        value
-
-    let readFloat32 (buffer: byte ReadOnlySpan byref) bigEndian =
-        let value =
-            if bigEndian then
-                #if IS_DESIGNTIME
-                if BitConverter.IsLittleEndian
-                then
-                   BitConverter.ToSingle(BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read<int> buffer)), 0)
-                else
-                    MemoryMarshal.Read<float32> buffer
-                #else
-                BinaryPrimitives.ReadSingleBigEndian buffer
-                #endif
-            else
-                #if IS_DESIGNTIME
-                if not BitConverter.IsLittleEndian
-                then
-                   BitConverter.ToSingle(BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read<int> buffer)), 0)
-                else
-                    MemoryMarshal.Read<float32> buffer
-                #else
-                BinaryPrimitives.ReadSingleLittleEndian buffer
-                #endif
-
-        buffer <- buffer.Slice 4
-        value
-
-    let readFloat (buffer: byte ReadOnlySpan byref) bigEndian =
-        let value =
-            if bigEndian then
-                #if IS_DESIGNTIME
-                if BitConverter.IsLittleEndian
-                then
-                   BitConverter.ToDouble(BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read<int64> buffer)), 0)
-                else
-                    MemoryMarshal.Read<float> buffer
-                #else
-                BinaryPrimitives.ReadDoubleBigEndian buffer
-                #endif
-            else
-                #if IS_DESIGNTIME
-                if not BitConverter.IsLittleEndian
-                then
-                   BitConverter.ToDouble(BitConverter.GetBytes(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read<int64> buffer)), 0)
-                else
-                    MemoryMarshal.Read<float> buffer
-                #else
-                BinaryPrimitives.ReadDoubleLittleEndian buffer
-                #endif
-
-        buffer <- buffer.Slice 8
-        value
-
-    let readFloat80 (buffer: byte ReadOnlySpan byref) bigEndian =
-        if bigEndian then
-            { RawSignificand = readUInt64 &buffer bigEndian
-              RawSignExponent = readUInt16 &buffer bigEndian }
-        else
-            { RawSignExponent = readUInt16 &buffer bigEndian
-              RawSignificand = readUInt64 &buffer bigEndian }
-
-    let readType (buffer: byte ReadOnlySpan byref) bigEndian =
-        readUInt &buffer bigEndian
-        |> function
-        | 0u -> typeof<unit>
-        | 0x21u -> typeof<bool>
-        | 1u -> typeof<int8>
-        | 2u -> typeof<int16>
-        | 3u -> typeof<int>
-        | 4u -> typeof<int64>
-        | 5u -> typeof<uint8>
-        | 6u -> typeof<uint16>
-        | 7u -> typeof<uint>
-        | 8u -> typeof<uint64>
-        | 9u
-        | 0x19u -> typeof<float32>
-        | 10u
-        | 0x1Au -> typeof<float>
-        | 0x08000Cu -> typeof<struct (float32 * float32)>
-        | 0x10000Du -> typeof<Complex>
-        | 11u
-        | 0x1Bu -> typeof<float80>
-        | 0x20u -> typeof<string>
-        | 0x44u -> typeof<Timestamp>
-        | value -> failwithf "Unknown type: %i" value
-
-    let readString (buffer: byte ReadOnlySpan byref) bigEndian =
-        let length = readUInt &buffer bigEndian |> int
-        let bytes = buffer.Slice(0, length)
-        buffer <- buffer.Slice length
-        #if IS_DESIGNTIME
-        Encoding.UTF8.GetString (bytes.ToArray())
-        #else
-        Encoding.UTF8.GetString bytes
-        #endif

+ 0 - 312
Tdms/Channel.fs

@@ -1,312 +0,0 @@
-namespace FSharp.Data.Tdms
-
-open System
-open System.IO
-open System.Numerics
-open System.Threading
-open System.Threading.Tasks
-
-type Channel = {
-    Name: string
-    FilePath: string
-    Properties: Property seq
-    RawDataBlocks: RawDataBlocks option
-    BigEndian: bool
-}
-
-module Channel =
-    
-    let tryGetPropertyValue<'t> propertyName { Properties = properties } =
-        properties
-        |> Seq.tryFind (fun { Name = propertyName' } -> propertyName' = propertyName)
-        |> Option.bind Property.tryGet<'t>
-
-    let getPropertyValue<'t> propertyName =
-        tryGetPropertyValue<'t> propertyName >> Option.get
-        
-    let tryGetRawData<'t>
-        { FilePath = path
-          RawDataBlocks = rawDataBlocks
-          BigEndian = bigEndian }
-        =
-        let bufferSize = 65_536
-        match rawDataBlocks with
-        | None -> None
-        | Some (PrimitiveRawDataBlocks (ty, rawDataBlockArray)) ->
-
-            if typeof<'t>.IsAssignableFrom ty then
-                use fileStream =
-                    new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.None)
-
-                if ty = typeof<bool> then
-                    Reader.readPrimitiveRawData<bool> fileStream rawDataBlockArray bigEndian
-                    |> box
-                    |> tryUnbox<'t []>
-                elif ty = typeof<sbyte> then
-                    Reader.readPrimitiveRawData<sbyte> fileStream rawDataBlockArray bigEndian
-                    |> box
-                    |> tryUnbox<'t []>
-                elif ty = typeof<int16> then
-                    Reader.readPrimitiveRawData<int16> fileStream rawDataBlockArray bigEndian
-                    |> box
-                    |> tryUnbox<'t []>
-                elif ty = typeof<int> then
-                    Reader.readPrimitiveRawData<int> fileStream rawDataBlockArray bigEndian
-                    |> box
-                    |> tryUnbox<'t []>
-                elif ty = typeof<int64> then
-                    Reader.readPrimitiveRawData<int64> fileStream rawDataBlockArray bigEndian
-                    |> box
-                    |> tryUnbox<'t []>
-                elif ty = typeof<byte> then
-                    Reader.readPrimitiveRawData<byte> fileStream rawDataBlockArray bigEndian
-                    |> box
-                    |> tryUnbox<'t []>
-                elif ty = typeof<uint16> then
-                    Reader.readPrimitiveRawData<uint16> fileStream rawDataBlockArray bigEndian
-                    |> box
-                    |> tryUnbox<'t []>
-                elif ty = typeof<uint> then
-                    Reader.readPrimitiveRawData<uint> fileStream rawDataBlockArray bigEndian
-                    |> box
-                    |> tryUnbox<'t []>
-                elif ty = typeof<uint64> then
-                    Reader.readPrimitiveRawData<uint64> fileStream rawDataBlockArray bigEndian
-                    |> box
-                    |> tryUnbox<'t []>
-                elif ty = typeof<float32> then
-                    Reader.readPrimitiveRawData<float32> fileStream rawDataBlockArray bigEndian
-                    |> box
-                    |> tryUnbox<'t []>
-                elif ty = typeof<float> then
-                    Reader.readPrimitiveRawData<float> fileStream rawDataBlockArray bigEndian
-                    |> box
-                    |> tryUnbox<'t []>
-                elif ty = typeof<Complex> then
-                    Reader.readComplexRawData fileStream rawDataBlockArray bigEndian
-                    |> box
-                    |> tryUnbox<'t []>
-                elif ty = typeof<Timestamp> then
-                    Reader.readTimestampRawData fileStream rawDataBlockArray bigEndian
-                    |> box
-                    |> tryUnbox<'t []>
-                elif ty = typeof<float80> then
-                    Reader.readFloat80RawData fileStream rawDataBlockArray bigEndian
-                    |> box
-                    |> tryUnbox<'t []>
-                else
-                    None
-            else if ty = typeof<Timestamp> then
-                if typeof<'t> = typeof<DateTime> then
-                    use fileStream =
-                        new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.None)
-
-                    Reader.readTimestampRawData fileStream rawDataBlockArray bigEndian
-                    |> Array.map Timestamp.toDateTime
-                    |> box
-                    |> tryUnbox<'t []>
-                else if typeof<'t> = typeof<DateTimeOffset> then
-                    use fileStream =
-                        new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.None)
-
-                    Reader.readTimestampRawData fileStream rawDataBlockArray bigEndian
-                    |> Array.map Timestamp.toDateTimeOffset
-                    |> box
-                    |> tryUnbox<'t []>
-                else if typeof<'t> = typeof<TimeSpan> then
-                    use fileStream =
-                        new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.None)
-
-                    Reader.readTimestampRawData fileStream rawDataBlockArray bigEndian
-                    |> Array.map Timestamp.toTimeSpan
-                    |> box
-                    |> tryUnbox<'t []>
-                else
-                    None
-            else
-                None
-        | Some (StringRawDataBlocks stringRawDataBlockArray) ->
-            if typeof<'t> = typeof<string> then
-                use fileStream =
-                    new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.None)
-
-                Reader.readStringRawData fileStream stringRawDataBlockArray bigEndian
-                |> box
-                |> tryUnbox<'t []>
-            else
-                None
-
-    #if !IS_DESIGNTIME
-    let tryGetRawDataAsyncCt<'t>
-        ct
-        { FilePath = path
-          RawDataBlocks = rawDataBlocks
-          BigEndian = bigEndian }
-        =
-        let bufferSize = 65_536
-        match rawDataBlocks with
-        | None -> Task.FromResult None
-        | Some (PrimitiveRawDataBlocks (ty, rawDataBlockArray)) ->
-
-            if ty = typeof<'t> then
-                if ty = typeof<bool> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readPrimitiveRawDataAsync<bool> ct fileStream rawDataBlockArray bigEndian
-                        return box result |> tryUnbox<'t []>
-                    }
-                else if ty = typeof<sbyte> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readPrimitiveRawDataAsync<sbyte> ct fileStream rawDataBlockArray bigEndian
-                        return box result |> tryUnbox<'t []>
-                    }
-                else if ty = typeof<int16> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readPrimitiveRawDataAsync<int16> ct fileStream rawDataBlockArray bigEndian
-                        return box result |> tryUnbox<'t []>
-                    }
-                else if ty = typeof<int> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readPrimitiveRawDataAsync<int> ct fileStream rawDataBlockArray bigEndian
-                        return box result |> tryUnbox<'t []>
-                    }
-                else if ty = typeof<int64> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readPrimitiveRawDataAsync<int64> ct fileStream rawDataBlockArray bigEndian
-                        return box result |> tryUnbox<'t []>
-                    }
-                else if ty = typeof<byte> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readPrimitiveRawDataAsync<byte> ct fileStream rawDataBlockArray bigEndian
-                        return box result |> tryUnbox<'t []>
-                    }
-                else if ty = typeof<uint16> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readPrimitiveRawDataAsync<uint16> ct fileStream rawDataBlockArray bigEndian
-                        return box result |> tryUnbox<'t []>
-                    }
-                else if ty = typeof<uint> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readPrimitiveRawDataAsync<uint> ct fileStream rawDataBlockArray bigEndian
-                        return box result |> tryUnbox<'t []>
-                    }
-                else if ty = typeof<uint64> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readPrimitiveRawDataAsync<uint64> ct fileStream rawDataBlockArray bigEndian
-                        return box result |> tryUnbox<'t []>
-                    }
-                else if ty = typeof<float32> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readPrimitiveRawDataAsync<float32> ct fileStream rawDataBlockArray bigEndian
-                        return box result |> tryUnbox<'t []>
-                    }
-                else if ty = typeof<float> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readPrimitiveRawDataAsync<float> ct fileStream rawDataBlockArray bigEndian
-                        return box result |> tryUnbox<'t []>
-                    }
-                else if ty = typeof<float80> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readFloat80RawDataAsync ct fileStream rawDataBlockArray bigEndian
-                        return box result |> tryUnbox<'t []>
-                    }
-                else if ty = typeof<Complex> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readComplexRawDataAsync ct fileStream rawDataBlockArray bigEndian
-                        return box result |> tryUnbox<'t []>
-                    }
-                else
-                    Task.FromResult None
-            else if ty = typeof<Timestamp> then
-                if typeof<'t> = typeof<DateTime> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readTimestampRawDataAsync ct fileStream rawDataBlockArray bigEndian
-
-                        return
-                            Array.map Timestamp.toDateTime result
-                            |> box
-                            |> tryUnbox<'t []>
-                    }
-                else if typeof<'t> = typeof<DateTimeOffset> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readTimestampRawDataAsync ct fileStream rawDataBlockArray bigEndian
-
-                        return
-                            Array.map Timestamp.toDateTimeOffset result
-                            |> box
-                            |> tryUnbox<'t []>
-                    }
-                else if typeof<'t> = typeof<TimeSpan> then
-                    backgroundTask {
-                        use fileStream =
-                            new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                        let! result = Reader.readTimestampRawDataAsync ct fileStream rawDataBlockArray bigEndian
-
-                        return
-                            Array.map Timestamp.toTimeSpan result
-                            |> box
-                            |> tryUnbox<'t []>
-                    }
-                else
-                    Task.FromResult None
-            else
-                Task.FromResult None
-        | Some (StringRawDataBlocks stringRawDataBlockArray) ->
-            if typeof<'t> = typeof<string> then
-                backgroundTask {
-                    use fileStream =
-                        new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.Asynchronous)
-
-                    let! result = Reader.readStringRawDataAsync ct fileStream stringRawDataBlockArray bigEndian
-                    return result |> box |> tryUnbox<'t []>
-                }
-            else
-                Task.FromResult None
-
-    let tryRawDataAsync<'t> = tryGetRawDataAsyncCt<'t> CancellationToken.None
-    #endif

+ 0 - 15
Tdms/Extended.fs

@@ -1,15 +0,0 @@
-namespace FSharp.Data.Tdms
-
-open System.Runtime.CompilerServices
-open System.Runtime.InteropServices
-
-#if !IS_DESIGNTIME
-[<Struct; IsReadOnly; StructLayout(LayoutKind.Sequential, Pack = 1)>]
-#else
-[<Struct; StructLayout(LayoutKind.Sequential, Pack = 1)>]
-#endif
-type Extended =
-    { RawSignExponent: uint16
-      RawSignificand: uint64 }
-
-type float80 = Extended

+ 0 - 28
Tdms/FSharp.Data.Tdms.Runtime.fs

@@ -1,28 +0,0 @@
-#if INTERACTIVE
-#load "../../src/ProvidedTypes.fsi" "../../src/ProvidedTypes.fs"
-#endif
-
-namespace FSharp.Data
-
-open FSharp.Data.Tdms
-
-module Helpers =
-
-    type RawDataHelper =
-
-        static member RawData<'T>(group, channel, index) =
-            File.tryGetRawData<'T> group channel index
-            |> Option.defaultValue [||]
-
-    let rawData ty group channel index =
-        let generic =
-            typeof<RawDataHelper>.GetMethod "RawData"
-
-        let concrete = generic.MakeGenericMethod [| ty |]
-        concrete.Invoke(null, [| group; channel; index |])
-
-#if !IS_DESIGNTIME
-// Put the TypeProviderAssemblyAttribute in the runtime DLL, pointing to the design-time DLL
-[<assembly:CompilerServices.TypeProviderAssembly("FSharp.Data.Tdms.DesignTime.dll")>]
-do ()
-#endif

+ 0 - 43
Tdms/FSharp.Data.Tdms.fsproj

@@ -1,43 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-  <PropertyGroup>
-    <OutputType>Library</OutputType>
-    <TargetFramework>net6.0</TargetFramework>
-    <Authors>Dylan Meysmans</Authors>
-    <Description>TDMS 2.0 support for F# and C#</Description>
-    <PackageLicenseExpression>MIT</PackageLicenseExpression>
-    <PackageProjectUrl>https://mettekou.github.io/FSharp.Data.Tdms</PackageProjectUrl>
-    <RepositoryUrl>https://github.com/mettekou/FSharp.Data.Tdms</RepositoryUrl>
-    <RepositoryType>git</RepositoryType>
-    <PublishRepositoryUrl>true</PublishRepositoryUrl>
-    <PackageReadmeFile>README.md</PackageReadmeFile>
-    <GenerateDocumentationFile>true</GenerateDocumentationFile>
-    <FSharpToolsDirectory>typeproviders</FSharpToolsDirectory>
-    <PackagePath>typeproviders</PackagePath>
-    <EmbedUntrackedSources>true</EmbedUntrackedSources>
-  </PropertyGroup>
-  <ItemGroup>
-    <Compile Include="Extended.fs" />
-    <Compile Include="Timestamp.fs" />
-    <Compile Include="Property.fs" />
-    <Compile Include="Buffer.fs" />
-    <Compile Include="RawDataBlock.fs" />
-    <Compile Include="Reader.fs" />
-    <Compile Include="Channel.fs" />
-    <Compile Include="Group.fs" />
-    <Compile Include="Object.fs" />
-    <Compile Include="Segment.fs" />
-    <Compile Include="File.fs" />
-    <Compile Include="FSharp.Data.Tdms.Runtime.fs" />
-  </ItemGroup>
-  <ItemGroup>
-
-    <PackageReference Include="MinVer" Version="4.2.0">
-      <PrivateAssets>all</PrivateAssets>
-      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
-    </PackageReference>
-    <PackageReference Update="FSharp.Core" Version="6.0.7" />
-  </ItemGroup>
-  <PropertyGroup>
-    <MinVerTagPrefix>v</MinVerTagPrefix>
-  </PropertyGroup>
-</Project>

+ 0 - 340
Tdms/File.fs

@@ -1,340 +0,0 @@
-namespace FSharp.Data.Tdms
-
-open System
-open System.Buffers
-open System.IO
-open System.Runtime.InteropServices
-open System.Text.RegularExpressions
-open System.Threading
-open System.Threading.Tasks
-open FSharp.Collections
-
-type File =
-    { Path: string
-      Properties: Property seq
-      Groups: FSharp.Data.Tdms.Group seq }
-
-module File =
-
-    [<Literal>]
-    let LeadInLength = 28
-
-    let ofObjects path objects =
-        let groups =
-            objects
-            |> Seq.choose
-                (fun ({ Name = groupName
-                        Properties = properties }: FSharp.Data.Tdms.Object) ->
-                    if Regex.IsMatch(groupName, @"^\/'[^\/']+'$") then
-                        Some
-                            { Name = groupName.Substring(2, String.length groupName - 3)
-                              Properties = properties
-                              Channels =
-                                  objects
-                                  |> Seq.filter
-                                      (fun { Name = channelName } ->
-                                          channelName.StartsWith groupName
-                                          && String.length channelName > String.length groupName)
-                                  |> Seq.map (Object.toChannel path) }
-                    else
-                        None)
-
-        { Path = path
-          Properties =
-              objects
-              |> Seq.tryFind (fun ({ Name = name }: FSharp.Data.Tdms.Object) -> name = "/")
-              |> Option.map (fun { Properties = properties } -> properties)
-              |> Option.toList
-              |> Seq.concat
-          Groups = groups }
-
-    /// <summary>
-    /// Opens a <see cref="File" />, reads the index from it, and closes it.
-    /// </summary>
-    /// <param name="path">the path to the <see cref="File" /> to read.</param>
-    /// <param name="writeIndex">Whether to write the TDMS index file if it does not exist.</param>
-    let read path writeIndex =
-        let indexPath =
-            Path.ChangeExtension(path, ".tdms_index")
-
-        let indexExists = File.Exists indexPath
-
-        use stream =
-            new FileStream(
-                (if indexExists then indexPath else path),
-                FileMode.Open,
-                FileAccess.Read,
-                FileShare.Read,
-                65_536,
-                if indexExists then
-                    FileOptions.SequentialScan
-                else
-                    FileOptions.None
-            )
-
-        use indexStream =
-            if not indexExists && writeIndex then
-                new FileStream(indexPath, FileMode.Create, FileAccess.Write, FileShare.None, 8_192, false)
-            else
-                null
-
-        let mutable buffer = ArrayPool<byte>.Shared.Rent LeadInLength
-        let objects = ResizeArray()
-        let mutable offset = 0uL
-
-        while stream.Position < stream.Length do
-            stream.Read(buffer, 0, LeadInLength)
-            |> ignore
-
-            if not indexExists && writeIndex then
-                indexStream.Write(Segment.tdsh, 0, 4)
-                indexStream.Write(buffer, 4, 24)
-
-            let mutable leadInSpan = ReadOnlySpan buffer
-
-            let { TableOfContents = tableOfContents
-                  NextSegmentOffset = nextSegmentOffset
-                  RawDataOffset = rawDataOffset } =
-                Segment.readLeadIn &leadInSpan
-
-            let metaDataStart = offset + 28uL
-
-            if tableOfContents.HasFlag(TableOfContents.ContainsMetaData) then
-                let remainingLength = int rawDataOffset
-
-                if remainingLength > buffer.Length then
-                    ArrayPool<byte>.Shared.Return (buffer, false)
-                    buffer <- ArrayPool<byte>.Shared.Rent remainingLength
-
-                stream.Read(buffer, 0, remainingLength) |> ignore
-
-                if not indexExists && writeIndex then
-                    indexStream.Write(buffer, 0, remainingLength)
-
-                let mutable metaDataSpan = ReadOnlySpan buffer
-
-                Segment.readMetaData
-                    objects
-                    (metaDataStart + rawDataOffset)
-                    (metaDataStart + min nextSegmentOffset (uint64 stream.Length - metaDataStart))
-                    &metaDataSpan
-                    (tableOfContents.HasFlag(TableOfContents.ContainsBigEndianData))
-                    (tableOfContents.HasFlag(TableOfContents.ContainsInterleavedData))
-
-            offset <- metaDataStart + nextSegmentOffset
-
-            if not indexExists then
-                stream.Seek(int64 offset, SeekOrigin.Begin)
-                |> ignore
-
-        ArrayPool<byte>.Shared.Return (buffer, false)
-        ofObjects path objects
-
-
-    let readAsyncCt ct path writeIndex =
-        task {
-            let indexPath =
-                Path.ChangeExtension(path, ".tdms_index")
-
-            let indexExists = File.Exists(indexPath)
-
-            use stream =
-                new FileStream(
-                    (if indexExists then indexPath else path),
-                    FileMode.Open,
-                    FileAccess.Read,
-                    FileShare.Read,
-                    65_536,
-                    if indexExists then
-                        FileOptions.SequentialScan
-                        ||| FileOptions.Asynchronous
-                    else
-                        FileOptions.Asynchronous
-                )
-
-            use indexStream =
-                if not indexExists && writeIndex then
-                    new FileStream(indexPath, FileMode.Create, FileAccess.Write, FileShare.None, 1_048_576, true)
-                else
-                    null
-
-            let mutable buffer = ArrayPool<byte>.Shared.Rent LeadInLength
-            let objects = ResizeArray()
-            let mutable offset = 0uL
-
-            while stream.Position < stream.Length do
-                let! _ = stream.ReadAsync(buffer, 0, LeadInLength, ct)
-
-                if not indexExists && writeIndex then
-                    do! indexStream.WriteAsync(Segment.tdsh, 0, 4, ct)
-                    do! indexStream.WriteAsync(buffer, 4, 24, ct)
-
-                let mutable leadInSpan = ReadOnlySpan buffer
-
-                let { TableOfContents = tableOfContents
-                      NextSegmentOffset = nextSegmentOffset
-                      RawDataOffset = rawDataOffset } =
-                    Segment.readLeadIn &leadInSpan
-
-                let metaDataStart = offset + 28uL
-
-                if tableOfContents.HasFlag(TableOfContents.ContainsMetaData) then
-                    let remainingLength = int rawDataOffset
-
-                    if remainingLength > buffer.Length then
-                        ArrayPool<byte>.Shared.Return (buffer, false)
-                        buffer <- ArrayPool<byte>.Shared.Rent remainingLength
-
-                    let! _ = stream.ReadAsync(buffer, 0, remainingLength, ct)
-
-                    if not indexExists && writeIndex then
-                        do! indexStream.WriteAsync(buffer, 0, remainingLength, ct)
-
-                    let mutable metaDataSpan = ReadOnlySpan buffer
-
-                    Segment.readMetaData
-                        objects
-                        (metaDataStart + rawDataOffset)
-                        (metaDataStart + nextSegmentOffset)
-                        &metaDataSpan
-                        (tableOfContents.HasFlag(TableOfContents.ContainsBigEndianData))
-                        (tableOfContents.HasFlag(TableOfContents.ContainsInterleavedData))
-
-                offset <- metaDataStart + nextSegmentOffset
-                
-                if not indexExists then
-                    stream.Seek(int64 offset, SeekOrigin.Begin)
-                    |> ignore
-
-            ArrayPool<byte>.Shared.Return (buffer, false)
-            return ofObjects path objects
-        }
-
-    /// <summary>
-    /// Asynchronously opens a <see cref="File" />, reads the index from it, and closes it.
-    /// </summary>
-    /// <param name="path">the path to the <see cref="File" /> to read.</param>
-    /// <param name="writeIndex">Whether to write the index file if it does not exist.</param>
-    let readAsync = readAsyncCt CancellationToken.None
-
-    let tryGetPropertyValue<'t> propertyName ({ Properties = properties }: File) =
-        properties
-        |> Seq.tryFind (fun { Name = propertyName' } -> propertyName' = propertyName)
-        |> Option.bind Property.tryGet<'t>
-
-    let getPropertyValue<'t> propertyName =
-        tryGetPropertyValue<'t> propertyName >> Option.get
-
-    /// <summary>Returns all groups within the <see cref="File" />.</summary>
-    let getGroups { Groups = groups } = groups
-    
-    /// <summary>Returns the <see cref="Group" /> with the given name within the <see cref="File" />. Returns None if it does not exist.</summary>
-    /// <param name="groupName">the name of the <see cref="Group" /> to find.</param>
-    let tryFindGroup groupName =
-        getGroups >> Seq.tryFind (fun { Name = groupName' } -> groupName' = groupName)
-
-    /// <summary>Returns the <see cref="Group" /> with the given name within the <see cref="File" />.</summary>
-    /// <param name="groupName">the name of the <see cref="Group" /> to find.</param>
-    let findGroup groupName = tryFindGroup groupName >> Option.get
-    
-    /// <summary>Returns the <see cref="Channel" /> with the given name within the <see cref="Group" /> with the given name within the <see cref="File" />. Returns None if it does not exist.</summary>
-    /// <param name="groupName">the name of the <see cref="Group" /> to find the <see cref="Channel" /> in.</param>
-    /// <param name="channelName">the name of the <see cref="Channel" /> to find.</param>
-    let tryFindChannel groupName channelName =
-        tryFindGroup groupName
-        >> Option.bind (Group.tryFindChannel channelName)
-
-    /// <summary>Returns the <see cref="Channel" /> with the given name within the <see cref="Group" /> with the given name.</summary>
-    /// <param name="groupName">the name of the <see cref="Group" /> to find the <see cref="Channel" /> in.</param>
-    /// <param name="channelName">the name of the <see cref="Channel" /> to find.</param>
-    let findChannel groupName channelName =
-        tryFindChannel groupName channelName >> Option.get
-
-    /// <summary>Returns the raw data for a <see cref="Channel" />. Returns None if the <see cref="Channel" /> does not exist, if it does not have any raw data, or if its raw data is not of the given type.</summary>
-    /// <param name="groupName">the name of the <see cref="Group" /> the <see cref="Channel" /> is in.</param>
-    /// <param name="channelName">the name of the <see cref="Channel" /> to get raw data for.</param>
-    /// <param name="file">the TDMS file to read from.</param>
-    let tryGetRawData<'t> groupName channelName file =
-        tryFindChannel groupName channelName file
-        |> Option.bind Channel.tryGetRawData<'t>
-    
-    #if !IS_DESIGNTIME
-    /// <summary>Asynchronously returns the raw data for a <see cref="Channel" />. Returns None if the <see cref="Channel" /> does not exist, if it does not have any raw data, or if its raw data is not of the given type.</summary>
-    /// <param name="groupName">the name of the <see cref="Group" /> the <see cref="Channel" /> is in.</param>
-    /// <param name="channelName">the name of the <see cref="Channel" /> to get raw data for.</param>
-    /// <param name="file">the TDMS file to read from.</param>
-    let tryGetRawDataAsyncCt<'t> ct groupName channelName file =
-        tryFindChannel groupName channelName file
-        |> Option.map (Channel.tryGetRawDataAsyncCt<'t> ct)
-        |> Option.defaultValue (Task.FromResult None)
-
-    let tryGetRawDataAsync<'t> = tryGetRawDataAsyncCt<'t> CancellationToken.None
-    #endif
-
-type File with
-
-    /// <summary>
-    /// Opens a TDMS file, reads the index from it, and closes it.
-    /// </summary>
-    /// <param name="path"> The path to the TDMS file to read.</param>
-    /// <param name="writeIndex"> Whether to write the TDMS index file.</param>
-    static member Read(path, writeIndex) = File.read path writeIndex
-
-    /// <summary>
-    /// Asynchronously opens a TDMS file, reads the index from it, and closes it.
-    /// </summary>
-    /// <param name="path"> The path to the TDMS file to read.</param>
-    /// <param name="writeIndex"> Whether to write the TDMS index file.</param>
-    static member ReadAsync(path, writeIndex, [<Optional; DefaultParameterValue(CancellationToken())>] ct) = File.readAsyncCt ct path writeIndex
-
-    /// <summary>
-    /// Tries to get the raw data for the given channel, belonging to the given group in the given TDMS file.
-    /// </summary>
-    member file.TryGetRawData<'T>(groupName, channelName, [<Out>] rawData: byref<'T []>) =
-        match File.tryGetRawData<'T> groupName channelName file with
-        | None -> false
-        | Some rd ->
-            rawData <- rd
-            true
-    #if !IS_DESIGNTIME
-    /// <summary>
-    /// Asynchronously gets the raw data for the given channel, belonging to the given group in the given TDMS file.
-    /// </summary>
-    member file.GetRawDataAsync<'t>(groupName, channelName, [<Optional; DefaultParameterValue(CancellationToken())>] ct) =
-        backgroundTask {
-            match! File.tryGetRawDataAsyncCt<'t> ct groupName channelName file with
-            | None -> return null
-            | Some rd -> return rd
-        }
-    #endif
-    
-    /// <summary>
-    /// Tries to get a property value for the given TDMS file.
-    /// </summary>
-    member file.TryGetPropertyValue<'T>(propertyName, [<Out>] propertyValue: byref<'T>) =
-        match File.tryGetPropertyValue<'T> propertyName file with
-        | None -> false
-        | Some pv ->
-            propertyValue <- pv
-            true
-
-    /// <summary>
-    /// Tries to get a property value for the given group in the given TDMS file.
-    /// </summary>
-    member file.TryGetPropertyValue<'T>(propertyName, groupName, [<Out>] propertyValue: byref<'T>) =
-        match File.tryFindGroup groupName file
-              |> Option.bind (Group.tryGetPropertyValue<'T> propertyName) with
-        | None -> false
-        | Some pv ->
-            propertyValue <- pv
-            true
-
-    /// <summary>
-    /// Tries to get a property value for the given channel, belonging to the given group in the given TDMS file.
-    /// </summary>
-    member file.TryGetPropertyValue<'T>(propertyName, groupName, channelName, [<Out>] propertyValue: byref<'T>) =
-        match File.tryGetPropertyValue<'T> ("/" + groupName + "/" + channelName) file with
-        | None -> false
-        | Some pv ->
-            propertyValue <- pv
-            true

+ 0 - 30
Tdms/Group.fs

@@ -1,30 +0,0 @@
-namespace FSharp.Data.Tdms
-
-type Group =
-    { Name: string
-      Properties: Property seq
-      Channels: Channel seq }
-
-module Group =
-
-    let tryGetPropertyValue<'t> propertyName ({ Properties = properties }: Group) =
-        properties
-        |> Seq.tryFind (fun { Name = propertyName' } -> propertyName' = propertyName)
-        |> Option.bind Property.tryGet<'t>
-
-    let getPropertyValue<'t> propertyName =
-        tryGetPropertyValue<'t> propertyName >> Option.get
-
-    /// <summary>Finds the <see cref="Channel" /> with the given name within the <see cref="Group" />. Returns None if it does not exist.</summary>
-    /// <param name="channelName">the name of the <see cref="Channel" /> to get.</param>
-    let tryFindChannel channelName { Channels = channels } =
-        channels
-        |> Seq.tryFind (fun { Name = channelName' } -> channelName = channelName')
-
-    /// <summary>Finds the <see cref="Channel" /> with the given name within the <see cref="Group" />.</summary>
-    /// <param name="channelName">the name of the <see cref="Channel" /> to get.</param>
-    let findChannel channelName =
-        tryFindChannel channelName >> Option.get
-
-    /// <summary>Returns all channels within the <see cref="Group" />.</summary>
-    let getChannels { Channels = channels } = channels

+ 0 - 167
Tdms/Object.fs

@@ -1,167 +0,0 @@
-namespace FSharp.Data.Tdms
-
-open System
-open System.IO
-open System.Numerics
-open System.Runtime.InteropServices
-open System.Threading.Tasks
-
-type Object =
-    { Name: string
-      BigEndian: bool
-      mutable RawDataBlocks: RawDataBlocks option
-      Properties: Property ResizeArray }
-
-module Object =
-
-    let addPrimitiveRawDataBlock ty primitiveRawDataBlock object =
-        match object.RawDataBlocks with
-        | None ->
-            let primitiveRawDataBlockArray = ResizeArray()
-            primitiveRawDataBlockArray.Add primitiveRawDataBlock
-            object.RawDataBlocks <- Some(PrimitiveRawDataBlocks(ty, primitiveRawDataBlockArray))
-        | Some (PrimitiveRawDataBlocks (ty', primitiveRawDataBlockArray)) ->
-            if ty <> ty' then
-                failwithf
-                    "Object %s already has type %A, cannot add a primitive data block of type %A to it; check whether the TDMS file is valid"
-                    object.Name
-                    ty'
-                    ty
-            else
-                primitiveRawDataBlockArray.Add primitiveRawDataBlock
-        | Some (StringRawDataBlocks _) ->
-            failwithf
-                "Object %s already has type string, cannot add a primitive data block of type %A to it; check whether the TDMS file is valid"
-                object.Name
-                ty
-
-    let addStringRawDataBlock stringRawDataBlock object =
-        match object.RawDataBlocks with
-        | None ->
-            let stringRawDataBlockArray = ResizeArray()
-            stringRawDataBlockArray.Add stringRawDataBlock
-            object.RawDataBlocks <- Some(StringRawDataBlocks stringRawDataBlockArray)
-        | Some (PrimitiveRawDataBlocks (ty', _)) ->
-            failwithf
-                "Object %s already has type %A, cannot add a string data block to it; check whether the TDMS file is valid"
-                object.Name
-                ty'
-        | Some (StringRawDataBlocks stringRawDataBlockArray) -> stringRawDataBlockArray.Add stringRawDataBlock
-
-    let readRawDataIndex
-        object
-        (rawDataPosition: uint64)
-        (buffer: byte ReadOnlySpan byref)
-        bigEndian
-        (interleaved: bool)
-        =
-        match Buffer.readUInt &buffer bigEndian with
-        | 0u ->
-            match object.RawDataBlocks with
-            | None -> failwithf "Missing raw data index for object %s; check whether the TDMS file is valid" object.Name
-            | Some (PrimitiveRawDataBlocks (ty, primitiveRawDataBlockArray)) ->
-                match Seq.tryLast primitiveRawDataBlockArray with
-                | None ->
-                    failwithf
-                        "Missing primitive raw data blocks for object %s; this is a bug in FSharp.Data.Tdms"
-                        object.Name
-                | Some (DecimatedPrimitiveRawDataBlock (_, bytes)) ->
-                    if interleaved then
-                        failwithf
-                            "Object %s raw data changes from decimated to interleaved without a new raw data index; check whether the TDMS file is valid"
-                            object.Name
-                    else
-                        primitiveRawDataBlockArray.Add(DecimatedPrimitiveRawDataBlock(rawDataPosition, bytes))
-                        bytes
-                | Some (InterleavedPrimitiveRawDataBlock _) ->
-                    if not interleaved then
-                        failwithf
-                            "Object %s raw data changes from interleaved to decimated without a new raw data index; check whether the TDMS file is valid"
-                            object.Name
-                    else
-                        uint64 (Marshal.SizeOf ty)
-            | Some (StringRawDataBlocks stringRawDataBlockArray) ->
-                match Seq.tryLast stringRawDataBlockArray with
-                | None ->
-                    failwithf
-                        "Missing string raw data blocks for object %s; this is a bug in FSharp.Data.Tdms"
-                        object.Name
-                | Some (_, length, bytes) ->
-                    stringRawDataBlockArray.Add(rawDataPosition, length, bytes)
-                    bytes
-        | 20u ->
-            let ty = Buffer.readType &buffer bigEndian
-            Buffer.readUInt &buffer bigEndian |> ignore
-            let length = Buffer.readUInt64 &buffer bigEndian
-            let size = Marshal.SizeOf ty
-
-            if not interleaved then
-                addPrimitiveRawDataBlock ty (DecimatedPrimitiveRawDataBlock(rawDataPosition, length)) object
-                length * uint64 size
-            else
-                addPrimitiveRawDataBlock
-                    ty
-                    (InterleavedPrimitiveRawDataBlock
-                        { Start = rawDataPosition
-                          Count = length
-                          Skip = 0uL })
-                    object
-
-                uint64 size
-        | 28u ->
-            Buffer.readType &buffer bigEndian |> ignore
-            Buffer.readUInt &buffer bigEndian |> ignore
-
-            let length = Buffer.readUInt64 &buffer bigEndian
-            let bytes = Buffer.readUInt64 &buffer bigEndian
-            addStringRawDataBlock (rawDataPosition, length, bytes) object
-            bytes
-        | 0xFFFFFFFFu -> 0uL
-        | 0x1269u
-        | 0x126Au ->
-            let ty = Buffer.readType &buffer bigEndian
-            let dimension = Buffer.readUInt &buffer bigEndian
-            let chunkSize = Buffer.readUInt64 &buffer bigEndian
-            let scalerCount = Buffer.readUInt &buffer bigEndian |> int
-
-            let scalers =
-                Array.zeroCreate<FormatChangingScaler> scalerCount
-
-            for scalerIndex = 0 to scalerCount - 1 do
-                scalers.[scalerIndex] <- RawDataBlock.readFormatChangingScaler &buffer bigEndian
-
-            let widthCount = Buffer.readUInt &buffer bigEndian |> int
-            let widths = Array.zeroCreate<uint> widthCount
-
-            for widthIndex = 0 to widthCount - 1 do
-                widths.[widthIndex] <- Buffer.readUInt &buffer bigEndian
-            //object.LastRawDataIndex <- Some (DaqMx (ty, dimension, chunkSize, scalers, widths))
-            0uL
-        | length -> failwithf "Invalid raw data index length: %i" length
-
-    let toChannel
-        filePath
-        ({ Name = name
-           Properties = properties
-           RawDataBlocks = rawDataBlocks
-           BigEndian = bigEndian }: Object)
-        =
-        { Name =
-              name.Split([| '/' |], StringSplitOptions.RemoveEmptyEntries).[1]
-                  .Trim('\'')
-          FilePath = filePath
-          Properties = properties
-          RawDataBlocks = rawDataBlocks
-          BigEndian = bigEndian }
-
-    let toGroup
-        filePath
-        channels
-        ({ Name = groupName
-           Properties = groupProperties }: Object)
-        =
-        { Name =
-              groupName.Split([| '/' |], StringSplitOptions.RemoveEmptyEntries).[0]
-                  .Trim('\'')
-          Properties = groupProperties
-          Channels = Seq.map (toChannel filePath) channels }

+ 0 - 24
Tdms/Property.fs

@@ -1,24 +0,0 @@
-namespace FSharp.Data.Tdms
-
-open System
-
-type Property = {
-  Name: string
-  Type : Type
-  Raw : obj
-}
-
-module Property =
-    
-    let tryGet<'t> { Type = ty; Raw = raw } =
-        let ty' = typeof<'t>
-        if ty'.IsAssignableFrom ty
-        then tryUnbox<'t> raw
-        else
-          if ty = typeof<Timestamp> then
-            let timestamp = raw :?> Timestamp
-            if ty' = typeof<DateTime> then tryUnbox<'t> (Timestamp.toDateTime timestamp)
-            else if ty' = typeof<DateTimeOffset> then tryUnbox<'t> (Timestamp.toDateTimeOffset timestamp)
-            else if ty' = typeof<TimeSpan> then tryUnbox<'t> (Timestamp.toTimeSpan timestamp)
-            else None
-          else None

+ 0 - 32
Tdms/RawDataBlock.fs

@@ -1,32 +0,0 @@
-namespace FSharp.Data.Tdms
-
-open System
-
-type FormatChangingScaler =
-    { DaqMxDataType: uint
-      RawBufferIndex: uint
-      RawByteOffsetWithinStride: uint
-      SampleFormatBitmap: uint
-      ScaleId: uint }
-
-type InterleavedPrimitiveRawDataBlock =
-    { Start: uint64
-      Count: uint64
-      mutable Skip: uint64 }
-
-type PrimitiveRawDataBlock =
-    | DecimatedPrimitiveRawDataBlock of (uint64 * uint64)
-    | InterleavedPrimitiveRawDataBlock of InterleavedPrimitiveRawDataBlock
-
-type RawDataBlocks =
-    | PrimitiveRawDataBlocks of Type * PrimitiveRawDataBlock ResizeArray
-    | StringRawDataBlocks of (uint64 * uint64 * uint64) ResizeArray
-
-module RawDataBlock =
-
-    let readFormatChangingScaler (buffer: byte ReadOnlySpan byref) bigEndian =
-        { DaqMxDataType = Buffer.readUInt &buffer bigEndian
-          RawBufferIndex = Buffer.readUInt &buffer bigEndian
-          RawByteOffsetWithinStride = Buffer.readUInt &buffer bigEndian
-          SampleFormatBitmap = Buffer.readUInt &buffer bigEndian
-          ScaleId = Buffer.readUInt &buffer bigEndian }

+ 0 - 547
Tdms/Reader.fs

@@ -1,547 +0,0 @@
-namespace FSharp.Data.Tdms
-
-open System
-open System.Buffers
-open System.IO
-open System.Numerics
-open System.Runtime.InteropServices
-open System.Text
-
-module Reader =
-
-    type CastMemoryManager<'tfrom, 'tto when 'tfrom: struct and 'tfrom: (new: unit -> 'tfrom) and 'tfrom :> ValueType and 'tto: struct and 'tto: (new: unit
-                                                                                                                                                       -> 'tto) and 'tto :> ValueType>(memory: Memory<'tfrom>) =
-        inherit MemoryManager<'tto>()
-
-        override _.GetSpan() =
-            MemoryMarshal.Cast<'tfrom, 'tto> memory.Span
-
-        override _.Dispose _ = ()
-        override _.Pin _ = raise (NotSupportedException())
-        override _.Unpin() = raise (NotSupportedException())
-
-    let cast<'tfrom, 'tto when 'tfrom: struct and 'tfrom: (new: unit -> 'tfrom) and 'tfrom :> ValueType and 'tto: struct and 'tto: (new: unit
-                                                                                                                                         -> 'tto) and 'tto :> ValueType>
-        (memory: Memory<'tfrom>)
-        =
-        if typeof<'tfrom> = typeof<'tto> then
-            box memory :?> Memory<'tto>
-        else
-            (new CastMemoryManager<'tfrom, 'tto>(memory))
-                .Memory
-
-    let readPrimitiveRawData<'t when 't: struct and 't: (new: unit -> 't) and 't :> ValueType>
-        (stream: Stream)
-        (segments: PrimitiveRawDataBlock seq)
-        bigEndian
-        =
-        let mutable position = 0
-        let size = sizeof<'t>
-
-        let data =
-            Seq.sumBy
-                (function
-                | DecimatedPrimitiveRawDataBlock (_, size) -> size
-                | InterleavedPrimitiveRawDataBlock { Count = count } -> count)
-                segments
-            |> int
-            |> Array.zeroCreate<'t>
-
-        let span =
-            MemoryMarshal.Cast<'t, byte>(data.AsSpan())
-
-        for segment in segments do
-            match segment with
-            | DecimatedPrimitiveRawDataBlock (start, length) ->
-                stream.Seek(int64 start, SeekOrigin.Begin)
-                |> ignore
-
-                stream.Read(span.Slice(position * size, int length * size))
-                |> ignore
-
-                position <- position + int length
-            | InterleavedPrimitiveRawDataBlock { Start = start
-                                                 Count = count
-                                                 Skip = skip } ->
-                stream.Seek(int64 start, SeekOrigin.Begin)
-                |> ignore
-
-                for _ = 0 to int count - 1 do
-                    stream.Read(span.Slice(position * size, size))
-                    |> ignore
-
-                    stream.Seek(int64 skip, SeekOrigin.Current)
-                    |> ignore
-
-                    position <- position + 1
-
-
-        if bigEndian && size > 1 then
-            span.Reverse()
-            Array.Reverse data
-
-        data
-
-    let readComplexRawData (stream: Stream) (segments: PrimitiveRawDataBlock seq) bigEndian =
-        if not bigEndian then
-            readPrimitiveRawData<Complex> stream segments false
-        else
-            let mutable position = 0
-            let size = sizeof<Complex>
-
-            let data =
-                Seq.sumBy
-                    (function
-                    | DecimatedPrimitiveRawDataBlock (_, size) -> size
-                    | InterleavedPrimitiveRawDataBlock { Count = count } -> count)
-                    segments
-                |> int
-                |> Array.zeroCreate<Complex>
-
-            let span =
-                MemoryMarshal.Cast<Complex, byte>(data.AsSpan())
-
-            for segment in segments do
-                match segment with
-                | DecimatedPrimitiveRawDataBlock (start, length) ->
-                    stream.Seek(int64 start, SeekOrigin.Begin)
-                    |> ignore
-
-                    stream.Read(span.Slice(position * size, int length * size))
-                    |> ignore
-
-                    position <- position + int length
-                | InterleavedPrimitiveRawDataBlock { Start = start
-                                                     Count = count
-                                                     Skip = skip } ->
-                    stream.Seek(int64 start, SeekOrigin.Begin)
-                    |> ignore
-
-                    for _ = 0 to int count - 1 do
-                        stream.Read(span.Slice(position * size, size))
-                        |> ignore
-
-                        stream.Seek(int64 skip, SeekOrigin.Current)
-                        |> ignore
-
-                        position <- position + 1
-
-            span.Reverse()
-
-            MemoryMarshal
-                .Cast<Complex, double>(data.AsSpan())
-                .Reverse()
-
-            data
-
-    let readTimestampRawData (stream: Stream) (segments: PrimitiveRawDataBlock seq) bigEndian =
-        if not bigEndian then
-            readPrimitiveRawData<Timestamp> stream segments false
-        else
-            let mutable position = 0
-            let size = sizeof<Timestamp>
-
-            let data =
-                Seq.sumBy
-                    (function
-                    | DecimatedPrimitiveRawDataBlock (_, size) -> size
-                    | InterleavedPrimitiveRawDataBlock { Count = count } -> count)
-                    segments
-                |> int
-                |> Array.zeroCreate<Timestamp>
-
-            let span =
-                MemoryMarshal.Cast<Timestamp, byte>(data.AsSpan())
-
-            for segment in segments do
-                match segment with
-                | DecimatedPrimitiveRawDataBlock (start, length) ->
-                    stream.Seek(int64 start, SeekOrigin.Begin)
-                    |> ignore
-
-                    stream.Read(span.Slice(position * size, int length * size))
-                    |> ignore
-
-                    position <- position + int length
-                | InterleavedPrimitiveRawDataBlock { Start = start
-                                                     Count = count
-                                                     Skip = skip } ->
-                    stream.Seek(int64 start, SeekOrigin.Begin)
-                    |> ignore
-
-                    for _ = 0 to int count - 1 do
-                        stream.Read(span.Slice(position * size, size))
-                        |> ignore
-
-                        stream.Seek(int64 skip, SeekOrigin.Current)
-                        |> ignore
-
-                        position <- position + 1
-
-            span.Reverse()
-            Array.Reverse data
-            data
-
-    let readFloat80RawData (stream: Stream) (segments: PrimitiveRawDataBlock seq) bigEndian =
-        if not bigEndian then
-            readPrimitiveRawData<float80> stream segments false
-        else
-            let mutable position = 0
-            let size = sizeof<float80>
-
-            let data =
-                Seq.sumBy
-                    (function
-                    | DecimatedPrimitiveRawDataBlock (_, size) -> size
-                    | InterleavedPrimitiveRawDataBlock { Count = count } -> count)
-                    segments
-                |> int
-                |> Array.zeroCreate<float80>
-
-            let span =
-                MemoryMarshal.Cast<float80, byte>(data.AsSpan())
-
-            for segment in segments do
-                match segment with
-                | DecimatedPrimitiveRawDataBlock (start, length) ->
-
-                    stream.Seek(int64 start, SeekOrigin.Begin)
-                    |> ignore
-
-                    stream.Read(span.Slice(position * size, int length * size))
-                    |> ignore
-
-                    position <- position + int length
-                | InterleavedPrimitiveRawDataBlock { Start = start
-                                                     Count = count
-                                                     Skip = skip } ->
-                    stream.Seek(int64 start, SeekOrigin.Begin)
-                    |> ignore
-
-                    for _ = 0 to int count - 1 do
-                        stream.Read(span.Slice(position * size, size))
-                        |> ignore
-
-                        stream.Seek(int64 skip, SeekOrigin.Current)
-                        |> ignore
-
-                        position <- position + 1
-
-            MemoryMarshal.Cast<byte, float80>(span).Reverse()
-
-            Array.Reverse data
-            data
-
-    let readStringRawData (stream: Stream) (segments: (uint64 * uint64 * uint64) seq) bigEndian =
-        let offsets =
-            Seq.map (fun (_, length, _) -> length) segments
-            |> Seq.max
-            |> int
-            |> ArrayPool<uint>.Shared.Rent
-
-        let data =
-            Seq.map (fun (_, _, bytes) -> bytes) segments
-            |> Seq.max
-            |> int
-            |> ArrayPool<uint8>.Shared.Rent
-
-        let strings =
-            Seq.sumBy (fun (_, length, _) -> length) segments
-            |> int
-            |> Array.zeroCreate<string>
-
-        let mutable position = 0
-
-        for (start, length, bytes) in segments do
-            stream.Seek(int64 start, SeekOrigin.Begin)
-            |> ignore
-
-            let offsetsSpan = offsets.AsSpan().Slice(0, int length)
-
-            let offsetsByteSpan =
-                MemoryMarshal.Cast<uint, uint8>(offsetsSpan)
-
-            stream.Read(offsetsByteSpan) |> ignore
-
-            if bigEndian then
-                offsetsByteSpan.Reverse()
-                offsetsSpan.Reverse()
-
-            let mutable dataSpan = data.AsSpan().Slice(0, int bytes)
-
-            stream.Read(dataSpan) |> ignore
-
-            let mutable offset = 0
-
-            for index = 0 to offsetsSpan.Length - 1 do
-                strings.[position] <-
-                    Encoding.UTF8.GetString(
-                        dataSpan
-                            .Slice(0, int offsets.[index] - offset)
-                            .ToArray()
-                    )
-
-                dataSpan <- dataSpan.Slice(int offsets.[index] - offset)
-                offset <- int offsets.[index]
-                position <- position + 1
-
-        ArrayPool<byte>.Shared.Return(data, false)
-        ArrayPool<uint>.Shared.Return(offsets, false)
-        strings
-
-    let readPrimitiveRawDataAsync<'t when 't: struct and 't: (new: unit -> 't) and 't :> ValueType>
-        ct
-        (stream: Stream)
-        (segments: PrimitiveRawDataBlock seq)
-        bigEndian
-        =
-        let mutable position = 0
-        let size = sizeof<'t>
-
-        let data =
-            Seq.sumBy
-                (function
-                | DecimatedPrimitiveRawDataBlock (_, size) -> size
-                | InterleavedPrimitiveRawDataBlock { Count = count } -> count)
-                segments
-            |> int
-            |> Array.zeroCreate<'t>
-
-        let memory = cast<'t, byte> (data.AsMemory())
-
-        backgroundTask {
-            for segment in segments do
-                match segment with
-                | DecimatedPrimitiveRawDataBlock (start, length) ->
-                    stream.Seek(int64 start, SeekOrigin.Begin)
-                    |> ignore
-
-                    let! _ = stream.ReadAsync(memory.Slice(position * size, int length * size), ct)
-
-                    position <- position + int length
-                | InterleavedPrimitiveRawDataBlock { Start = start
-                                                     Count = count
-                                                     Skip = skip } ->
-                    stream.Seek(int64 start, SeekOrigin.Begin)
-                    |> ignore
-
-                    for _ = 0 to int count - 1 do
-                        let! _ = stream.ReadAsync(memory.Slice(position * size, size), ct)
-
-                        stream.Seek(int64 skip, SeekOrigin.Current)
-                        |> ignore
-
-                        position <- position + 1
-
-            if bigEndian then
-                memory.Span.Reverse()
-                Array.Reverse data
-
-            return data
-        }
-
-    let readFloat80RawDataAsync ct (stream: Stream) (segments: PrimitiveRawDataBlock seq) bigEndian =
-        if not bigEndian then
-            readPrimitiveRawDataAsync<float80> ct stream segments false
-        else
-            backgroundTask {
-                let mutable position = 0
-                let size = sizeof<float80>
-
-                let data =
-                    Seq.sumBy
-                        (function
-                        | DecimatedPrimitiveRawDataBlock (_, size) -> size
-                        | InterleavedPrimitiveRawDataBlock { Count = count } -> count)
-                        segments
-                    |> int
-                    |> Array.zeroCreate<float80>
-
-                let memory = cast<float80, byte> (data.AsMemory())
-
-                for segment in segments do
-                    match segment with
-                    | DecimatedPrimitiveRawDataBlock (start, length) ->
-
-                        stream.Seek(int64 start, SeekOrigin.Begin)
-                        |> ignore
-
-                        let! _ = stream.ReadAsync(memory.Slice(position * size, int length * size), ct)
-
-                        position <- position + int length
-                    | InterleavedPrimitiveRawDataBlock { Start = start
-                                                         Count = count
-                                                         Skip = skip } ->
-                        stream.Seek(int64 start, SeekOrigin.Begin)
-                        |> ignore
-
-                        for _ = 0 to int count - 1 do
-                            let! _ = stream.ReadAsync(memory.Slice(position * size, size), ct)
-
-                            stream.Seek(int64 skip, SeekOrigin.Current)
-                            |> ignore
-
-                            position <- position + 1
-
-                MemoryMarshal
-                    .Cast<byte, float80>(memory.Span)
-                    .Reverse()
-
-                Array.Reverse data
-                return data
-            }
-
-    let readComplexRawDataAsync ct (stream: Stream) (segments: PrimitiveRawDataBlock seq) bigEndian =
-        if not bigEndian then
-            readPrimitiveRawDataAsync<Complex> ct stream segments false
-        else
-            let mutable position = 0
-            let size = sizeof<Complex>
-
-            let data =
-                Seq.sumBy
-                    (function
-                    | DecimatedPrimitiveRawDataBlock (_, size) -> size
-                    | InterleavedPrimitiveRawDataBlock { Count = count } -> count)
-                    segments
-                |> int
-                |> Array.zeroCreate<Complex>
-
-            let memory = cast<Complex, byte> (data.AsMemory())
-
-            backgroundTask {
-                for segment in segments do
-                    match segment with
-                    | DecimatedPrimitiveRawDataBlock (start, length) ->
-                        stream.Seek(int64 start, SeekOrigin.Begin)
-                        |> ignore
-
-                        let! _ = stream.ReadAsync(memory.Slice(position * size, int length * size), ct)
-
-                        position <- position + int length
-                    | InterleavedPrimitiveRawDataBlock { Start = start
-                                                         Count = count
-                                                         Skip = skip } ->
-                        stream.Seek(int64 start, SeekOrigin.Begin)
-                        |> ignore
-
-                        for _ = 0 to int count - 1 do
-                            let! _ = stream.ReadAsync(memory.Slice(position * size, size), ct)
-
-                            stream.Seek(int64 skip, SeekOrigin.Current)
-                            |> ignore
-
-                            position <- position + 1
-
-                memory.Span.Reverse()
-
-                cast<Complex, double>(data.AsMemory())
-                    .Span.Reverse()
-
-                return data
-            }
-
-    let readTimestampRawDataAsync ct (stream: Stream) (segments: PrimitiveRawDataBlock seq) bigEndian =
-        if not bigEndian then
-            readPrimitiveRawDataAsync<Timestamp> ct stream segments false
-        else
-            let mutable position = 0
-            let size = sizeof<Timestamp>
-
-            let data =
-                Seq.sumBy
-                    (function
-                    | DecimatedPrimitiveRawDataBlock (_, size) -> size
-                    | InterleavedPrimitiveRawDataBlock { Count = count } -> count)
-                    segments
-                |> int
-                |> Array.zeroCreate<Timestamp>
-
-            let memory = cast<Timestamp, byte> (data.AsMemory())
-
-            backgroundTask {
-                for segment in segments do
-                    match segment with
-                    | DecimatedPrimitiveRawDataBlock (start, length) ->
-                        stream.Seek(int64 start, SeekOrigin.Begin)
-                        |> ignore
-
-                        let! _ = stream.ReadAsync(memory.Slice(position * size, int length * size), ct)
-
-                        position <- position + int length
-                    | InterleavedPrimitiveRawDataBlock { Start = start
-                                                         Count = count
-                                                         Skip = skip } ->
-                        stream.Seek(int64 start, SeekOrigin.Begin)
-                        |> ignore
-
-                        for _ = 0 to int count - 1 do
-                            let! _ = stream.ReadAsync(memory.Slice(position * size, size), ct)
-
-                            stream.Seek(int64 skip, SeekOrigin.Current)
-                            |> ignore
-
-                            position <- position + 1
-
-                memory.Span.Reverse()
-                Array.Reverse data
-                return data
-            }
-
-    let readStringRawDataAsync ct (stream: Stream) (segments: (uint64 * uint64 * uint64) seq) bigEndian =
-        backgroundTask {
-            let offsets =
-                Seq.map (fun (_, length, _) -> length) segments
-                |> Seq.max
-                |> int
-                |> ArrayPool<uint>.Shared.Rent
-
-            let data =
-                Seq.map (fun (_, _, bytes) -> bytes) segments
-                |> Seq.max
-                |> int
-                |> ArrayPool<uint8>.Shared.Rent
-
-            let strings =
-                Seq.sumBy (fun (_, length, _) -> length) segments
-                |> int
-                |> Array.zeroCreate<string>
-
-            let mutable position = 0
-
-            for (start, length, bytes) in segments do
-                stream.Seek(int64 start, SeekOrigin.Begin)
-                |> ignore
-
-                let offsetsMemory = offsets.AsMemory().Slice(0, int length)
-
-                let offsetsByteMemory = cast<uint, uint8> offsetsMemory
-
-                let! _ = stream.ReadAsync(offsetsByteMemory, ct)
-
-                if bigEndian then
-                    offsetsByteMemory.Span.Reverse()
-                    offsetsMemory.Span.Reverse()
-
-                let mutable dataMemory = data.AsMemory().Slice(0, int bytes)
-
-                let! _ = stream.ReadAsync(dataMemory, ct)
-
-                let mutable offset = 0
-
-                for index = 0 to offsetsMemory.Length - 1 do
-                    strings.[position] <-
-                        Encoding.UTF8.GetString(
-                            dataMemory
-                                .Slice(0, int offsets.[index] - offset)
-                                .ToArray()
-                        )
-
-                    dataMemory <- dataMemory.Slice(int offsets.[index] - offset)
-                    offset <- int offsets.[index]
-                    position <- position + 1
-
-            ArrayPool<byte>.Shared.Return(data, false)
-            ArrayPool<uint>.Shared.Return(offsets, false)
-            return strings
-        }

+ 0 - 240
Tdms/Segment.fs

@@ -1,240 +0,0 @@
-namespace FSharp.Data.Tdms
-
-open System
-open System.Buffers
-open System.IO
-open System.Numerics
-open System.Runtime.InteropServices
-
-type Tag =
-    | Tdsm = 1834173524u
-    | Tdsh = 1750287444u
-
-[<Flags>]
-type TableOfContents =
-    | ContainsMetaData = 2u
-    | ContainsRawData = 8u
-    | ContainsDaqMxRawData = 128u
-    | ContainsInterleavedData = 32u
-    | ContainsBigEndianData = 64u
-    | ContainsNewObjectList = 4u
-
-type Version =
-    | ``1.0`` = 4712u
-    | ``2.0`` = 4713u
-
-[<Struct>]
-type LeadIn =
-    { Tag: Tag
-      TableOfContents: TableOfContents
-      Version: Version
-      NextSegmentOffset: uint64
-      RawDataOffset: uint64 }
-
-module Segment =
-
-    let readLeadIn (buffer: byte ReadOnlySpan byref) =
-        let tag =
-            Buffer.readUInt &buffer false
-            |> LanguagePrimitives.EnumOfValue<uint, Tag>
-
-        let tableOfContents =
-            Buffer.readUInt &buffer false
-            |> LanguagePrimitives.EnumOfValue<uint, TableOfContents>
-
-        let bigEndian =
-            tableOfContents.HasFlag(TableOfContents.ContainsBigEndianData)
-
-        { Tag = tag
-          TableOfContents = tableOfContents
-          Version =
-              Buffer.readUInt &buffer bigEndian
-              |> LanguagePrimitives.EnumOfValue<uint, Version>
-          NextSegmentOffset = Buffer.readUInt64 &buffer bigEndian
-          RawDataOffset = Buffer.readUInt64 &buffer bigEndian }
-
-    let readPropertyValue (buffer: byte ReadOnlySpan byref) bigEndian propertyType =
-        if propertyType = typeof<unit> then
-            buffer <- buffer.Slice 1
-            box ()
-        elif propertyType = typeof<bool> then
-            let value = box (buffer.[0] <> 0uy)
-            buffer <- buffer.Slice 1
-            value
-        elif propertyType = typeof<int8> then
-            let value =
-                box (MemoryMarshal.Cast<uint8, int8> buffer).[0]
-
-            buffer <- buffer.Slice 1
-            value
-        elif propertyType = typeof<int16> then
-            Buffer.readInt16 &buffer bigEndian |> box
-        elif propertyType = typeof<int> then
-            Buffer.readInt &buffer bigEndian |> box
-        elif propertyType = typeof<int64> then
-            Buffer.readInt64 &buffer bigEndian |> box
-        elif propertyType = typeof<uint8> then
-            let value = box buffer.[0]
-            buffer <- buffer.Slice 1
-            value
-        elif propertyType = typeof<uint16> then
-            Buffer.readUInt16 &buffer bigEndian |> box
-        elif propertyType = typeof<uint> then
-            Buffer.readUInt &buffer bigEndian |> box
-        elif propertyType = typeof<uint64> then
-            Buffer.readUInt64 &buffer bigEndian |> box
-        elif propertyType = typeof<float32> then
-            Buffer.readFloat32 &buffer bigEndian |> box
-        elif propertyType = typeof<float> then
-            Buffer.readFloat &buffer bigEndian |> box
-        elif propertyType = typeof<struct (float32 * float32)> then
-            struct (Buffer.readFloat32 &buffer bigEndian |> float, Buffer.readFloat32 &buffer bigEndian |> float)
-            |> box
-        elif propertyType = typeof<Complex> then
-            Complex(Buffer.readFloat &buffer bigEndian, Buffer.readFloat &buffer bigEndian)
-            |> box
-        elif propertyType = typeof<float80> then
-            Buffer.readFloat80 &buffer bigEndian |> box
-        elif propertyType = typeof<Timestamp> then
-            (if bigEndian then
-                 { SecondsSinceNiEpoch = Buffer.readInt64 &buffer bigEndian
-                   FractionsOfASecond = Buffer.readUInt64 &buffer bigEndian }
-             else
-                 { FractionsOfASecond = Buffer.readUInt64 &buffer bigEndian
-                   SecondsSinceNiEpoch = Buffer.readInt64 &buffer bigEndian })
-            |> box
-        elif propertyType = typeof<string> then
-            Buffer.readString &buffer bigEndian |> box
-        else
-            failwithf "Property type not implemented: %A" propertyType
-
-    let createObject name (objects: _ ResizeArray) bigEndian =
-        match Seq.tryFind (fun object -> object.Name = name) objects with
-        | Some object -> object
-        | None ->
-            let object =
-                { Name = name
-                  BigEndian = bigEndian
-                  RawDataBlocks = None
-                  Properties = ResizeArray() }
-
-            objects.Add object
-            object
-
-    let readMetaData objects rawDataOffset nextSegmentOffset (buffer: _ byref) bigEndian interleaved =
-        let objectCount = Buffer.readInt &buffer bigEndian
-        let newOrUpdatedObjects = Array.zeroCreate objectCount
-        let objectsWithRawData = ResizeArray()
-        let mutable rawDataPosition = rawDataOffset
-
-        for i = 0 to objectCount - 1 do
-            let object =
-                createObject (Buffer.readString &buffer bigEndian) objects bigEndian
-
-            newOrUpdatedObjects.[i] <- object
-
-            let rawDataSkip =
-                Object.readRawDataIndex object rawDataPosition &buffer bigEndian interleaved
-
-            rawDataPosition <- rawDataPosition + rawDataSkip
-
-            if rawDataSkip > 0uL then
-                objectsWithRawData.Add object
-
-            let propertyCount = Buffer.readUInt &buffer bigEndian |> int
-
-            for j = 0 to propertyCount - 1 do
-                let propertyName = Buffer.readString &buffer bigEndian
-                let propertyType = Buffer.readType &buffer bigEndian
-
-                let propertyValue =
-                    readPropertyValue &buffer bigEndian propertyType
-
-                let property =
-                    { Name = propertyName
-                      Type = propertyType
-                      Raw = propertyValue }
-
-                match Seq.tryFindIndex (fun (property: Property) -> property.Name = propertyName) object.Properties with
-                | None -> object.Properties.Add property
-                | Some index -> object.Properties.[index] <- property
-
-        let sizes, rawDataBlocksToUpdate =
-            Seq.choose
-                (fun ({ RawDataBlocks = rawDataBlocks }: FSharp.Data.Tdms.Object) ->
-                    Option.bind
-                        (fun rawDataBlocks' ->
-                            match rawDataBlocks' with
-                            | PrimitiveRawDataBlocks (ty, primitiveRawDataBlockArray) ->
-                                Seq.tryLast primitiveRawDataBlockArray
-                                |> Option.map
-                                    (function
-                                    | DecimatedPrimitiveRawDataBlock (start, count) ->
-                                        uint64 (Marshal.SizeOf ty) * count, rawDataBlocks'
-                                    | InterleavedPrimitiveRawDataBlock { Start = start; Count = count } ->
-                                        uint64 (Marshal.SizeOf ty) * count, rawDataBlocks')
-                            | StringRawDataBlocks stringRawDataBlockArray ->
-                                Seq.tryLast stringRawDataBlockArray
-                                |> Option.map (fun (_, _, bytes) -> bytes, rawDataBlocks'))
-                        rawDataBlocks)
-                objectsWithRawData
-            |> Seq.toArray
-            |> Array.unzip
-
-        let chunkSize = Array.sum sizes
-
-        if chunkSize > 0uL then
-            let chunkOffsets =
-                [ chunkSize .. chunkSize .. (nextSegmentOffset - rawDataOffset) - chunkSize ]
-
-            for rawDataBlocks in rawDataBlocksToUpdate do
-                match rawDataBlocks with
-                | PrimitiveRawDataBlocks (_, primitiveRawDataBlockArray) ->
-                    Seq.tryLast primitiveRawDataBlockArray
-                    |> Option.iter
-                        (function
-                        | DecimatedPrimitiveRawDataBlock (start, count) ->
-                            primitiveRawDataBlockArray.AddRange(
-                                List.map
-                                    (fun chunkOffset -> DecimatedPrimitiveRawDataBlock(start + chunkOffset, count))
-                                    chunkOffsets
-                            )
-                        | InterleavedPrimitiveRawDataBlock ({ Start = start } as block) ->
-                            primitiveRawDataBlockArray.AddRange(
-                                List.map
-                                    (fun chunkOffset ->
-                                        InterleavedPrimitiveRawDataBlock
-                                            { block with
-                                                  Start = start + chunkOffset })
-                                    chunkOffsets
-                            ))
-                | StringRawDataBlocks stringRawDataBlockArray ->
-                    Seq.tryLast stringRawDataBlockArray
-                    |> Option.iter
-                        (fun (start, count, bytes) ->
-                            stringRawDataBlockArray.AddRange(
-                                List.map (fun chunkOffset -> start + chunkOffset, count, bytes) chunkOffsets
-                            ))
-
-        if interleaved then
-            Array.iter
-                (fun ({ RawDataBlocks = rawDataBlocks }: FSharp.Data.Tdms.Object) ->
-                    match rawDataBlocks with
-                    | None -> ()
-                    | Some (StringRawDataBlocks _) -> ()
-                    | Some (PrimitiveRawDataBlocks (ty, primitiveRawDataBlocksArray)) ->
-                        Seq.tryLast primitiveRawDataBlocksArray
-                        |> Option.iter
-                            (function
-                            | DecimatedPrimitiveRawDataBlock _ -> ()
-                            | InterleavedPrimitiveRawDataBlock interleavedPrimitiveRawDataBlock ->
-                                interleavedPrimitiveRawDataBlock.Skip <-
-                                    (rawDataPosition - rawDataOffset)
-                                    - uint64 (Marshal.SizeOf ty)))
-                newOrUpdatedObjects
-
-    let tdsh =
-        [| 0x54uy
-           0x44uy
-           0x53uy
-           0x68uy |]

+ 0 - 26
Tdms/Timestamp.fs

@@ -1,26 +0,0 @@
-namespace FSharp.Data.Tdms
-
-open System
-open System.Runtime.CompilerServices
-
-#if !IS_DESIGNTIME
-[<Struct; IsReadOnly>]
-#else
-[<Struct>]
-#endif
-type Timestamp =
-    { FractionsOfASecond: uint64
-      SecondsSinceNiEpoch: int64 }
-
-module Timestamp =
-  
-  let niEpochDateTime = DateTime(1904, 1, 1, 0, 0, 0, DateTimeKind.Utc)
-
-  let niEpochDateTimeOffset = DateTimeOffset(1904, 1, 1, 0, 0, 0, TimeSpan.Zero)
-
-  let toTimeSpan { SecondsSinceNiEpoch = secondsSinceNiEpoch; FractionsOfASecond = fractionsOfASecond } =
-    TimeSpan.FromSeconds (float secondsSinceNiEpoch) + TimeSpan.FromSeconds (float fractionsOfASecond / float UInt64.MaxValue)
-
-  let toDateTime timestamp = (niEpochDateTime + toTimeSpan timestamp).ToLocalTime()
-
-  let toDateTimeOffset timestamp = (niEpochDateTimeOffset + toTimeSpan timestamp).ToLocalTime()

+ 0 - 89
TdmsFile/BinaryReaderExtensions.cs

@@ -1,89 +0,0 @@
-using System;
-using System.IO;
-using System.Text;
-
-namespace NationalInstruments.Tdms
-{
-    public static class BinaryReaderExtensions
-    {
-        public static string ReadString(this BinaryReader reader, int length)
-        {
-            return Encoding.UTF8.GetString(reader.ReadBytes(length));
-        }
-
-        public static string? ReadLengthPrefixedString(this BinaryReader reader)
-        {
-            return Read<string>(reader, DataType.String);
-        }
-
-        public static T? Read<T>(this BinaryReader reader, int dataType)
-        {
-            return (T?)Read(reader, dataType);
-        }
-
-        public static object? Read(this BinaryReader reader, int dataType)
-        {
-            switch (dataType)
-            {
-                case DataType.Empty: return null;
-                case DataType.Void: reader.ReadByte(); return null;
-                case DataType.Integer8: return reader.ReadSByte();
-                case DataType.Integer16: return reader.ReadInt16();
-                case DataType.Integer32: return reader.ReadInt32();
-                case DataType.Integer64: return reader.ReadInt64();
-                case DataType.UnsignedInteger8: return reader.ReadByte();
-                case DataType.UnsignedInteger16: return reader.ReadUInt16();
-                case DataType.UnsignedInteger32: return reader.ReadUInt32();
-                case DataType.UnsignedInteger64: return reader.ReadUInt64();
-                case DataType.SingleFloat:
-                case DataType.SingleFloatWithUnit: return reader.ReadSingle();
-                case DataType.DoubleFloat:
-                case DataType.DoubleFloatWithUnit: return reader.ReadDouble();
-                case DataType.String: return Encoding.UTF8.GetString(reader.ReadBytes(reader.ReadInt32()));
-                case DataType.Boolean: return reader.ReadBoolean();
-                case DataType.TimeStamp:
-                    return new DateTime(1904, 1, 1, 0, 0, 0, DateTimeKind.Utc)
-                        .AddSeconds(reader.ReadUInt64() / (double)ulong.MaxValue)       //fixed truncate error in old code 
-                        .AddSeconds(reader.ReadInt64())
-                        .ToLocalTime(); 
-                default: throw new ArgumentException("Unknown data type " + dataType, "dataType");
-            }
-        }
-    }
-
-    public static class BinaryWriterExtensions
-    {
-        public static void Write(this BinaryWriter writer, int dataType, object data)
-        {
-            switch (dataType)
-            {
-                case DataType.Empty: break;
-                case DataType.Void: writer.Write((byte)0); break;
-                case DataType.Integer8: writer.Write((sbyte)data); break;
-                case DataType.Integer16: writer.Write((Int16)data); break;
-                case DataType.Integer32: writer.Write((Int32)data); break;
-                case DataType.Integer64: writer.Write((Int64)data); break;
-                case DataType.UnsignedInteger8: writer.Write((byte)data); break;
-                case DataType.UnsignedInteger16: writer.Write((UInt16)data); break;
-                case DataType.UnsignedInteger32: writer.Write((UInt32)data); break;
-                case DataType.UnsignedInteger64: writer.Write((UInt16)data); break;
-                case DataType.SingleFloat:
-                case DataType.SingleFloatWithUnit: writer.Write((float)data); break;
-                case DataType.DoubleFloat:
-                case DataType.DoubleFloatWithUnit: writer.Write((double)data); break;
-                case DataType.String:
-                    byte[] bytes = Encoding.UTF8.GetBytes((string)data);
-                    writer.Write((Int32)bytes.Length);
-                    writer.Write(bytes);
-                    break;
-                case DataType.Boolean: writer.Write((bool)data); break;
-                case DataType.TimeStamp:
-                    var t = (((DateTime)data).ToUniversalTime() - new DateTime(1904, 1, 1, 0, 0, 0, DateTimeKind.Utc));
-                    writer.Write((UInt64)((t.TotalSeconds % 1) * ulong.MaxValue));
-                    writer.Write((Int64)t.TotalSeconds);
-                    break;
-                default: throw new ArgumentException("Unknown data type " + dataType, "dataType");
-            }
-        }
-    }
-}

+ 0 - 34
TdmsFile/Channel.cs

@@ -1,34 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-
-namespace NationalInstruments.Tdms
-{
-    public class Channel
-    {
-        private readonly IEnumerable<Reader.RawData> _rawData;
-        private readonly Reader _reader;
-
-        public Channel(string name, IDictionary<string, object> properties, IEnumerable<Reader.RawData> rawData, Reader reader)
-        {
-            _rawData = rawData;
-            _reader = reader;
-            Name = name;
-            Properties = properties;
-        }
-
-        public string Name { get; private set; }
-        public bool HasData { get { return _rawData.Any(); } }
-        public long DataCount { get { return _rawData.Sum(x => x.Count); } }
-        public Type? DataType { get { return _rawData?.Select(x => x.ClrDataType)?.FirstOrDefault(); } }
-        public IDictionary<string, object> Properties { get; private set; }
-
-        public IEnumerable<Reader.RawData> RawData { get { return _rawData; } }
-
-        public IEnumerable<T> GetData<T>()
-        {
-            return _rawData.SelectMany(_reader.ReadRawData).Select(value => (T)value);
-        }
-    }
-}

+ 0 - 100
TdmsFile/DataType.cs

@@ -1,100 +0,0 @@
-using System;
-
-namespace NationalInstruments.Tdms
-{
-    public class DataType
-    {
-        public const int Empty = 0x0000000F;
-        public const int Void = 0x00000000;
-        public const int Integer8 = 0x00000001;
-        public const int Integer16 = 0x00000002;
-        public const int Integer32 = 0x00000003;
-        public const int Integer64 = 0x00000004;
-        public const int UnsignedInteger8 = 0x00000005;
-        public const int UnsignedInteger16 = 0x00000006;
-        public const int UnsignedInteger32 = 0x00000007;
-        public const int UnsignedInteger64 = 0x00000008;
-        public const int SingleFloat = 0x00000009;
-        public const int DoubleFloat = 0x0000000A;
-        public const int ExtendedFloat = 0x0000000B;
-        public const int SingleFloatWithUnit = 0x00000019;
-        public const int DoubleFloatWithUnit = 0x0000001A;
-        public const int ExtendedFloatWithUnit = 0x0000001B;
-        public const int String = 0x00000020;
-        public const int Boolean = 0x00000021;
-        public const int TimeStamp = 0x00000044;
-
-        public static long GetArrayLength(int dataType, long size)
-        {
-            return GetLength(dataType) * size;
-        }
-
-        public static int GetLength(int dataType)
-        {
-            switch (dataType)
-            {
-                case Empty: return 0;
-                case Void: return 1;
-                case Integer8: return 1;
-                case Integer16: return 2;
-                case Integer32: return 4;
-                case Integer64: return 8;
-                case UnsignedInteger8: return 1;
-                case UnsignedInteger16: return 2;
-                case UnsignedInteger32: return 4;
-                case UnsignedInteger64: return 8;
-                case SingleFloat:
-                case SingleFloatWithUnit: return 4;
-                case DoubleFloat:
-                case DoubleFloatWithUnit: return 8;
-                case Boolean: return 1;
-                case TimeStamp: return 16;
-                default: throw new ArgumentException("Cannot determine size of data type " + dataType, "dataType");
-            }
-        }
-
-        public static Type GetClrType(int dataType)
-        {
-            switch (dataType)
-            {
-                case Empty: return typeof(object);
-                case Void: return typeof(object);
-                case Integer8: return typeof(sbyte);
-                case Integer16: return typeof(short);
-                case Integer32: return typeof(int);
-                case Integer64: return typeof(long);
-                case UnsignedInteger8: return typeof(byte);
-                case UnsignedInteger16: return typeof(ushort);
-                case UnsignedInteger32: return typeof(uint);
-                case UnsignedInteger64: return typeof(ulong);
-                case SingleFloat:
-                case SingleFloatWithUnit: return typeof(float);
-                case DoubleFloat:
-                case DoubleFloatWithUnit: return typeof(double);
-                case Boolean: return typeof(bool);
-                case String: return typeof(string);
-                case TimeStamp: return typeof(DateTime);
-                default: throw new Exception("Unknown data type " + dataType);
-            }
-        }
-
-        public static int GetDataType(object value)
-        {
-            if (value == null) return Void;
-            else if (value.GetType() == typeof(bool)) return Boolean;
-            else if (value.GetType() == typeof(sbyte)) return Integer8;
-            else if (value.GetType() == typeof(Int16)) return Integer16;
-            else if (value.GetType() == typeof(Int32)) return Integer32;
-            else if (value.GetType() == typeof(Int64)) return Integer64;
-            else if (value.GetType() == typeof(byte)) return UnsignedInteger8;
-            else if (value.GetType() == typeof(UInt16)) return UnsignedInteger16;
-            else if (value.GetType() == typeof(UInt32)) return UnsignedInteger32;
-            else if (value.GetType() == typeof(UInt64)) return UnsignedInteger64;
-            else if (value.GetType() == typeof(float)) return SingleFloat;
-            else if (value.GetType() == typeof(double)) return DoubleFloat;
-            else if (value.GetType() == typeof(string)) return String;
-            else if (value.GetType() == typeof(DateTime)) return TimeStamp;
-            else throw new Exception("Unknown data type " + value.GetType());
-        }
-    }
-}

+ 0 - 269
TdmsFile/File.cs

@@ -1,269 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using System.Linq;
-
-namespace NationalInstruments.Tdms
-{
-    public class File : IEnumerable<Group>, IDisposable
-    {
-        [AllowNull]
-        private readonly Lazy<Stream> _stream;
-
-        private File()
-        {
-            Properties = new Dictionary<string, object>();
-            Groups = new Dictionary<string, Group>();
-        }
-
-        public File(Stream stream) : this()
-        {
-            if (!stream.CanSeek) throw new ArgumentException("Only seekable streams supported.", "stream");
-            _stream = new Lazy<Stream>(() => stream);
-        }
-
-        public File(string path,FileMode mode, FileAccess access) : this()
-        {
-            _stream = new Lazy<Stream>(() => new FileStream(path, mode,access));
-        }
-
-        public IDictionary<string, object> Properties { get; private set; }
-        public IDictionary<string, Group> Groups { get; private set; }
-
-        public File Open()
-        {
-            var reader = new Reader(_stream.Value);
-            var metadata = LoadMetadata(reader).ToList();
-            LoadFile(metadata);
-            LoadGroups(Groups, metadata);
-            LoadChannels(Groups, metadata, reader);
-            return this;
-        }
-
-        /// <summary>
-        /// This will re-write the TDMS file. Mostly used for write demonstration. Although, this will also defragment the file. 
-        /// </summary>
-        /// <param name="path"></param>
-        public void ReWrite(string path)
-        {
-            using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write))
-                ReWrite(stream);
-        }
-
-        /// <summary>
-        /// This will re-write the TDMS file. Mostly used for write demonstration. Although, this will also defragment the file. 
-        /// </summary>
-        /// <param name="stream"></param>
-        public void ReWrite(Stream stream)
-        {
-            WriteSegment segment = new WriteSegment(stream);
-            segment.Header.TableOfContents.HasRawData = Groups.SelectMany(g => g.Value.Channels.Values, (g, c) => c.HasData).Any();
-            //when we re-write the file, no data shall be interleaved. (It's an all or nothing situation, with only 1 segment)
-            //segment.Header.TableOfContents.RawDataIsInterleaved = Groups.SelectMany(g => g.Value.Channels.Values, (g, c) => c.RawData.First().IsInterleaved).Any();
-
-            //Top level
-            Reader.Metadata m = new Reader.Metadata();
-            m.Path = new string[0];
-            m.Properties = Properties;
-            segment.MetaData.Add(m);
-
-            //Groups
-            foreach(KeyValuePair<string, Group> group in Groups)
-            {
-                m = new Reader.Metadata();
-                m.Path = new string[] { group.Key };
-                m.Properties = group.Value.Properties;
-                segment.MetaData.Add(m);
-
-                //Channels
-                foreach (KeyValuePair<string, Channel> channel in group.Value.Channels)
-                {
-                    Reader.RawData[] raws = channel.Value.RawData.ToArray();
-
-                    //Add first part
-                    m = new Reader.Metadata();
-                    m.Path = new string[] { group.Key, channel.Key };
-                    m.Properties = channel.Value.Properties;
-                    m.RawData = raws[0];
-                    segment.MetaData.Add(m);
-
-                    //Add the other parts (if any)
-                    for(int i = 1; i < raws?.Length; i++)
-                    {
-                        m = new Reader.Metadata();
-                        m.Path = new string[] { group.Key, channel.Key };
-                        m.RawData = raws[i];
-                        segment.MetaData.Add(m);
-                    }
-                }
-            }
-
-            //Write all raw data
-            Writer writer = segment.Open();
-            var reader = new Reader(_stream.Value);
-            foreach (KeyValuePair<string, Group> group in Groups)
-                foreach (KeyValuePair<string, Channel> channel in group.Value.Channels)
-                    foreach (Reader.RawData raw in channel.Value.RawData)
-                    {
-                        var data = reader.ReadRawData(raw);
-                        raw.IsInterleaved = false;  //when we re-write the file, no data shall be interleaved
-                        writer.WriteRawData(raw, data);
-                    }
-
-            //close up
-            segment.Close();
-        }
-
-        private void LoadFile(IEnumerable<Reader.Metadata> metadata)
-        {
-            metadata.Where(x => x.Path.Length == 0)
-                .SelectMany(m => m.Properties).ToList()
-                .ForEach(x => Properties[x.Key] = x.Value);
-        }
-
-        private static void LoadGroups(IDictionary<string, Group> groups, IEnumerable<Reader.Metadata> metadata)
-        {
-            var groupMetadata = metadata.Where(x => x.Path.Length == 1).
-                                         GroupBy(x => x.Path[0], (k, r) => r.OrderByDescending(y => y.Properties.Count).First());
-            foreach (var group in groupMetadata)
-                groups.Add(group.Path[0], new Group(group.Path[0], group.Properties));
-
-            // add implicit groups
-            foreach (var groupName in metadata.Where(x => x.Path.Length > 1 && !groups.ContainsKey(x.Path[0])).Select(x => x.Path[0]))
-                groups.Add(groupName, new Group(groupName, new Dictionary<string, object>()));
-        }
-
-        private static void LoadChannels(IDictionary<string, Group> groups, IEnumerable<Reader.Metadata> metadata, Reader reader)
-        {
-            var channelMetadata = metadata
-                .Where(x => x.Path.Length == 2)
-                .GroupBy(x => Tuple.Create(x.Path[0], x.Path[1]))
-                .Join(groups, x => x.First().Path[0], x => x.Key, (c, g) => Tuple.Create(g.Value, c));
-            foreach (var channel in channelMetadata)
-                channel.Item1.Channels.Add(channel.Item2.First().Path[1], new Channel(channel.Item2.First().Path[1],
-                    channel.Item2.OrderByDescending(y => y.Properties.Count).First().Properties,
-                    channel.Item2.Where(x => x.RawData.Count > 0).Select(x => x.RawData), reader));
-        }
-
-        private static IEnumerable<Reader.Metadata> LoadMetadata(Reader reader)
-        {
-            var segments = GetSegments(reader).ToList();
-
-            var prevMetaDataLookup = new Dictionary<string, Dictionary<string, Reader.Metadata>>();
-            foreach (var segment in segments)
-            {
-                if (!(segment.TableOfContents.ContainsNewObjects || 
-                    segment.TableOfContents.HasDaqMxData || 
-                    segment.TableOfContents.HasMetaData || 
-                    segment.TableOfContents.HasRawData)) {
-                    continue;
-                }
-                var metadatas = reader.ReadMetadata(segment);
-                long rawDataSize = 0;
-                long nextOffset = segment.RawDataOffset;
-
-                foreach (var m in metadatas)
-                {
-                    if (m.RawData.Count == 0 && m.Path.Length > 1)
-                    {
-                        // apply previous metadata if available
-                        if (prevMetaDataLookup.ContainsKey(m.Path[0]) && prevMetaDataLookup[m.Path[0]].ContainsKey(m.Path[1]))
-                        {
-                            var prevMetaData = prevMetaDataLookup[m.Path[0]][m.Path[1]];
-                            if (prevMetaData != null)
-                            {
-                                m.RawData.Count = segment.TableOfContents.HasRawData ? prevMetaData.RawData.Count : 0;
-                                m.RawData.DataType = prevMetaData.RawData.DataType;
-                                m.RawData.ClrDataType = prevMetaData.RawData.ClrDataType;
-                                m.RawData.Offset = segment.RawDataOffset + rawDataSize;
-                                m.RawData.IsInterleaved = prevMetaData.RawData.IsInterleaved;
-                                m.RawData.InterleaveStride = prevMetaData.RawData.InterleaveStride;
-                                m.RawData.Size = prevMetaData.RawData.Size;
-                                m.RawData.Dimension = prevMetaData.RawData.Dimension;
-                            }
-                        }
-                    }
-                    if (m.RawData.IsInterleaved && segment.NextSegmentOffset <= 0)
-                    {
-                        m.RawData.Count = segment.NextSegmentOffset > 0
-                            ? (segment.NextSegmentOffset - m.RawData.Offset + m.RawData.InterleaveStride - 1)/
-                              m.RawData.InterleaveStride
-                            : (reader.FileSize - m.RawData.Offset + m.RawData.InterleaveStride - 1)/
-                              m.RawData.InterleaveStride;
-                    }
-                    if (m.Path.Length > 1)
-                    {
-                        rawDataSize += m.RawData.Size;
-                        nextOffset += m.RawData.Size;
-                    }
-                }
-
-                var implicitMetadatas = new List<Reader.Metadata>();
-                if (metadatas.All(m => !m.RawData.IsInterleaved && m.RawData.Size > 0))
-                {
-                    while (nextOffset < segment.NextSegmentOffset ||
-                           (segment.NextSegmentOffset == -1 && nextOffset < reader.FileSize))
-                    {
-                        // Incremental Meta Data see http://www.ni.com/white-paper/5696/en/#toc1
-                        foreach (var m in metadatas)
-                        {
-                            if (m.Path.Length > 1)
-                            {
-                                var implicitMetadata = new Reader.Metadata()
-                                {
-                                    Path = m.Path,
-                                    RawData = new Reader.RawData()
-                                    {
-                                        Count = m.RawData.Count,
-                                        DataType = m.RawData.DataType,
-                                        ClrDataType = m.RawData.ClrDataType,
-                                        Offset = nextOffset,
-                                        IsInterleaved = m.RawData.IsInterleaved,
-                                        Size = m.RawData.Size,
-                                        Dimension = m.RawData.Dimension
-                                    },
-                                    Properties = m.Properties
-                                };
-                                implicitMetadatas.Add(implicitMetadata);
-                                nextOffset += implicitMetadata.RawData.Size;
-                            }
-                        }
-                    }
-                }
-                var metadataWithImplicit = metadatas.Concat(implicitMetadatas).ToList();
-                foreach (var metadata in metadataWithImplicit)
-                {
-                    if (metadata.Path.Length == 2)
-                    {
-                        if (!prevMetaDataLookup.ContainsKey(metadata.Path[0]))
-                        {
-                            prevMetaDataLookup[metadata.Path[0]] = new Dictionary<string, Reader.Metadata>();
-                        }
-                        prevMetaDataLookup[metadata.Path[0]][metadata.Path[1]] = metadata;
-                    }
-                    yield return metadata;
-                }
-            }
-        }
-
-        private static IEnumerable<Reader.Segment> GetSegments(Reader reader)
-        {
-            var segment = reader.ReadFirstSegment();
-            while (segment != null)
-            {
-                yield return segment;
-                segment = reader.ReadSegment(segment.NextSegmentOffset);
-            }
-        }
-
-        public IEnumerator<Group> GetEnumerator() { return Groups.Values.GetEnumerator(); }
-        IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
-
-        public void Dispose()
-        {
-            _stream.Value.Dispose();
-        }
-    }
-}

+ 0 - 22
TdmsFile/Group.cs

@@ -1,22 +0,0 @@
-using System.Collections;
-using System.Collections.Generic;
-
-namespace NationalInstruments.Tdms
-{
-    public class Group : IEnumerable<Channel>
-    {
-        public Group(string name, IDictionary<string, object> properties)
-        {
-            Name = name;
-            Properties = properties;
-            Channels = new Dictionary<string, Channel>();
-        }
-
-        public string Name { get; private set; }
-        public IDictionary<string, object> Properties { get; private set; } 
-        public IDictionary<string, Channel> Channels { get; private set; }
-
-        public IEnumerator<Channel> GetEnumerator() { return Channels.Values.GetEnumerator(); }
-        IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
-    }
-}

+ 0 - 198
TdmsFile/Reader.cs

@@ -1,198 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-
-namespace NationalInstruments.Tdms
-{
-    public class Reader
-    {
-        private readonly BinaryReader _reader;
-
-        public Reader(Stream stream)
-        {
-            _reader = new BinaryReader(stream);
-        }
-
-        public Segment? ReadFirstSegment()
-        {
-            return ReadSegment(0);
-        }
-
-        public Segment? ReadSegment(long offset)
-        {
-            if (offset < 0 || offset >= _reader.BaseStream.Length) return null;
-            _reader.BaseStream.Seek(offset, SeekOrigin.Begin);
-            var leadin = new Segment { Offset = offset, MetadataOffset = offset + Segment.Length };
-            leadin.Identifier = Encoding.ASCII.GetString(_reader.ReadBytes(4));
-            var tableOfContentsMask = _reader.ReadInt32();
-            leadin.TableOfContents = new TableOfContents
-                {
-                    ContainsNewObjects = ((tableOfContentsMask >> 2) & 1) == 1,
-                    HasDaqMxData = ((tableOfContentsMask >> 7) & 1) == 1,
-                    HasMetaData = ((tableOfContentsMask >> 1) & 1) == 1,
-                    HasRawData = ((tableOfContentsMask >> 3) & 1) == 1,
-                    NumbersAreBigEndian = ((tableOfContentsMask >> 6) & 1) == 1,
-                    RawDataIsInterleaved = ((tableOfContentsMask >> 5) & 1) == 1
-                };
-            leadin.Version = _reader.ReadInt32();
-            Func<long, long> resetWhenEol = x => x < _reader.BaseStream.Length ? x : -1;
-            leadin.NextSegmentOffset = resetWhenEol(_reader.ReadInt64() + offset + Segment.Length);
-            leadin.RawDataOffset = _reader.ReadInt64() + offset + Segment.Length;
-            return leadin;
-        }
-
-        public IList<Metadata> ReadMetadata(Segment segment)
-        {
-            _reader.BaseStream.Seek(segment.MetadataOffset, SeekOrigin.Begin);
-            var objectCount = _reader.ReadInt32();
-            var metadatas = new List<Metadata>();
-            var rawDataOffset = segment.RawDataOffset;
-            bool isInterleaved = segment.TableOfContents.RawDataIsInterleaved;
-            int interleaveStride = 0;
-            for (var x = 0; x < objectCount; x++)
-            {
-                var metadata = new Metadata();
-                metadata.Path = Regex.Matches(Encoding.UTF8.GetString(_reader.ReadBytes(_reader.ReadInt32())), "'(.*?)'").Cast<Match>().
-                                SelectMany(y => y.Groups.Cast<System.Text.RegularExpressions.Group>().Skip(1), (m, g) => g.Value).ToArray();
-                metadata.RawData = new RawData();
-                var rawDataIndexLength = _reader.ReadInt32();
-                if (rawDataIndexLength > 0)
-                {
-                    metadata.RawData.Offset = rawDataOffset;
-                    metadata.RawData.IsInterleaved = segment.TableOfContents.RawDataIsInterleaved;
-                    metadata.RawData.DataType = _reader.ReadInt32();
-                    metadata.RawData.ClrDataType = DataType.GetClrType(metadata.RawData.DataType);
-                    metadata.RawData.Dimension = _reader.ReadInt32();
-                    metadata.RawData.Count = _reader.ReadInt64();
-                    metadata.RawData.Size = rawDataIndexLength == 28 ? _reader.ReadInt64() :
-                                                DataType.GetArrayLength(metadata.RawData.DataType, metadata.RawData.Count);
-                    if (isInterleaved)
-                    {
-                        //fixed error. The interleave stride is the sum of all channel (type) dataSizes
-                        rawDataOffset += DataType.GetLength(metadata.RawData.DataType);
-                        interleaveStride += DataType.GetLength(metadata.RawData.DataType);
-                    }
-                    else
-                        rawDataOffset += metadata.RawData.Size;
-                }
-                var propertyCount = _reader.ReadInt32();
-                metadata.Properties = new Dictionary<string, object>();
-                for (var y = 0; y < propertyCount; y++)
-                {
-                    var key = _reader.ReadLengthPrefixedString() ?? string.Empty;
-                    var value = _reader.Read(_reader.ReadInt32());
-                    metadata.Properties[key] = value!;
-                }
-                metadatas.Add(metadata);
-            }
-            if (isInterleaved)
-            {
-                foreach (var metadata in metadatas)
-                {
-                    if (metadata.RawData.ClrDataType != null)
-                    {
-                        metadata.RawData.InterleaveStride = interleaveStride;
-
-                        metadata.RawData.Count = segment.NextSegmentOffset > 0
-                            ? (segment.NextSegmentOffset - metadata.RawData.Offset + interleaveStride - 1) / interleaveStride
-                            : (_reader.BaseStream.Length - metadata.RawData.Offset + interleaveStride - 1) / interleaveStride;
-                    }
-                }
-            }
-            return metadatas;
-        }
-
-        public IEnumerable<object> ReadRawData(RawData rawData)
-        {
-            if (rawData.IsInterleaved)
-                return ReadRawInterleaved(rawData.Offset, rawData.Count, rawData.DataType, rawData.InterleaveStride - DataType.GetLength(rawData.DataType));    //fixed error
-            return rawData.DataType == DataType.String ? ReadRawStrings(rawData.Offset, rawData.Count) :
-                                                         ReadRawFixed(rawData.Offset, rawData.Count, rawData.DataType);
-        }
-
-        private IEnumerable<object> ReadRawFixed(long offset, long count, int dataType)
-        {
-            _reader.BaseStream.Seek(offset, SeekOrigin.Begin);
-            for (var x = 0; x < count; x++) yield return _reader.Read(dataType);
-        }
-
-        private IEnumerable<object> ReadRawInterleaved(long offset, long count, int dataType, int interleaveSkip)
-        {
-            _reader.BaseStream.Seek(offset, SeekOrigin.Begin);
-            for (var x = 0; x < count; x++)
-            {
-                var value = _reader.Read(dataType);
-                _reader.BaseStream.Seek(interleaveSkip, SeekOrigin.Current);
-                yield return value;
-            }
-        }
-
-        private IEnumerable<object> ReadRawStrings(long offset, long count)
-        {
-            _reader.BaseStream.Seek(offset, SeekOrigin.Begin);
-            var dataOffset = offset + (count * 4);
-            var indexPosition = _reader.BaseStream.Position;
-            var dataPosition = dataOffset;
-            for (var x = 0; x < count; x++)
-            {
-                var endOfString = _reader.ReadInt32();
-                indexPosition = _reader.BaseStream.Position;
-
-                _reader.BaseStream.Seek(dataPosition, SeekOrigin.Begin);
-                yield return _reader.ReadString((int)((dataOffset + endOfString) - dataPosition));
-
-                dataPosition = dataOffset + endOfString;
-                _reader.BaseStream.Seek(indexPosition, SeekOrigin.Begin);
-            }
-        }
-
-        public long FileSize
-        {
-            get { return _reader.BaseStream.Length; }
-        }
-
-        public class Segment
-        {
-            public const long Length = 28;
-            public long Offset { get; set; }
-            public long MetadataOffset { get; set; }
-            public long RawDataOffset { get; set; }
-            public long NextSegmentOffset { get; set; }
-            public string Identifier { get; set; } = string.Empty;
-            public TableOfContents TableOfContents { get; set; } = new TableOfContents();
-            public int Version { get; set; }
-        }
-
-        public class TableOfContents
-        {
-            public bool HasMetaData { get; set; }
-            public bool HasRawData { get; set; }
-            public bool HasDaqMxData { get; set; }
-            public bool RawDataIsInterleaved { get; set; }
-            public bool NumbersAreBigEndian { get; set; }
-            public bool ContainsNewObjects { get; set; }
-        }
-
-        public class Metadata
-        {
-            public string[] Path { get; set; }= new string[0];
-            public RawData RawData { get; set; } = new RawData();
-            public IDictionary<string, object> Properties { get; set; } = new Dictionary<string, object>();
-        }
-
-        public class RawData
-        {
-            public long Offset { get; set; }
-            public int DataType { get; set; }
-            public Type? ClrDataType { get; set; } = null;
-            public int Dimension { get; set; }
-            public long Count { get; set; }
-            public long Size { get; set; }
-            public bool IsInterleaved { get; set; }
-            public int InterleaveStride { get; set; }
-        }
-    }
-}

+ 0 - 20
TdmsFile/TdmsFile.projitems

@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
-    <HasSharedItems>true</HasSharedItems>
-    <SharedGUID>6a45fecc-b176-47b8-89d1-d3bcc4fbf12e</SharedGUID>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration">
-    <Import_RootNamespace>TdmsFile</Import_RootNamespace>
-  </PropertyGroup>
-  <ItemGroup>
-    <Compile Include="$(MSBuildThisFileDirectory)BinaryReaderExtensions.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)Channel.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)DataType.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)File.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)Group.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)Reader.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)Writer.cs" />
-  </ItemGroup>
-</Project>

+ 0 - 13
TdmsFile/TdmsFile.shproj

@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>6a45fecc-b176-47b8-89d1-d3bcc4fbf12e</ProjectGuid>
-    <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
-  </PropertyGroup>
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
-  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
-  <PropertyGroup />
-  <Import Project="TdmsFile.projitems" Label="Shared" />
-  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
-</Project>

+ 0 - 237
TdmsFile/Writer.cs

@@ -1,237 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace NationalInstruments.Tdms
-{
-    public class Writer
-    {
-        private readonly BinaryWriter _writer;
-
-        public Stream BaseStream { get { return _writer.BaseStream; } }
-
-        public Writer(Stream stream)
-        {
-            _writer = new BinaryWriter(stream);
-        }
-
-        public void WriteSegment(long offset, Reader.Segment leadin)
-        {
-            _writer.BaseStream.Seek(offset, SeekOrigin.Begin);
-            _writer.Write(Encoding.ASCII.GetBytes(leadin.Identifier), 0, 4);
-            Int32 tableOfContentsMask = 0;
-            if (leadin.TableOfContents.ContainsNewObjects) tableOfContentsMask |= 1 << 2;
-            if (leadin.TableOfContents.HasDaqMxData) tableOfContentsMask |= 1 << 7;
-            if (leadin.TableOfContents.HasMetaData) tableOfContentsMask |= 1 << 1;
-            if (leadin.TableOfContents.HasRawData) tableOfContentsMask |= 1 << 3;
-            if (leadin.TableOfContents.NumbersAreBigEndian) tableOfContentsMask |= 1 << 6;
-            if (leadin.TableOfContents.RawDataIsInterleaved) tableOfContentsMask |= 1 << 5;
-            _writer.Write(tableOfContentsMask);
-            _writer.Write(leadin.Version);
-            _writer.Write((Int64)leadin.NextSegmentOffset);
-            _writer.Write((Int64)leadin.RawDataOffset);
-        }
-
-        public static string GetEncodePath(params string[] path)
-        {
-            return path == null || path.Length == 0 ? "/" : path.Length == 1 ? "/'" + path[0] + "'" : "/'" + path[0] + "'/'" + path[1] + "'";
-        }
-
-        public void WriteMetadata(IList<Reader.Metadata> metadatas)
-        {
-            _writer.Write((Int32)metadatas.Count);
-            foreach(var metadata in metadatas)
-            {
-                _writer.Write(DataType.String, GetEncodePath(metadata.Path));
-
-                //DAQmx Format Changing scaler 0x1269, DAQmx Digital Line scalar 0x1369
-                /* If the raw data index of this object in this segment exactly matches the index the same object had in the previous segment, an unsigned 32-bit integer (0x0000000) will be stored instead of the index information. */
-                if (metadata.RawData == null) _writer.Write((Int32)(-1)); 
-                else
-                {
-                    _writer.Write((Int32)20 + (metadata.RawData.DataType == DataType.String ? 8 : 0));
-                    _writer.Write((Int32)metadata.RawData.DataType);
-                    _writer.Write((Int32)metadata.RawData.Dimension);   //must be 1 
-                    _writer.Write((UInt64)metadata.RawData.Count);
-                    if (metadata.RawData.DataType == DataType.String) _writer.Write((UInt64)metadata.RawData.Size);
-                }
-                _writer.Write((Int32)(metadata.Properties?.Count ?? 0));
-                foreach(KeyValuePair<string, object> entry in (metadata.Properties ?? new Dictionary<string, object>()))
-                {
-                    _writer.Write(DataType.String, entry.Key);
-                    int dataType = DataType.GetDataType(entry.Value);
-                    _writer.Write((Int32)dataType);
-                    _writer.Write((Int32)dataType, entry.Value);
-                }
-            }
-        }
-
-        public void WriteRawData(Reader.RawData rawData, IEnumerable<object> data)
-        {
-            if (rawData.IsInterleaved) WriteRawInterleaved(rawData.DataType, rawData.Size, rawData.InterleaveStride, data);
-            else if (rawData.DataType == DataType.String) WriteRawStrings(rawData.Count, data);
-            else WriteRawFixed(rawData.DataType, data);
-        }
-
-        public void WriteRawInterleaved(int dataType, long dataSize, int interleaveStride, IEnumerable<object> data)
-        {
-            long offset = _writer.BaseStream.Position;
-            foreach (object o in data)
-            {
-                _writer.Write(dataType, o);
-                _writer.BaseStream.Seek(interleaveStride - dataSize, SeekOrigin.Current);
-            }
-            _writer.BaseStream.Seek(offset + dataSize, SeekOrigin.Begin);   //move cursor to next channel
-        }
-
-        public void WriteRawFixed(int dataType, IEnumerable<object> data)
-        {
-            foreach(object o in data) _writer.Write(dataType, o);
-        }
-
-        public void WriteRawStrings(long count, IEnumerable<object> data)
-        {
-            long indexPosition = _writer.BaseStream.Position;
-            long dataOffset = indexPosition + (count * 4);
-            long baseOffset = dataOffset;
-            foreach (object o in data)
-            {
-                //write string
-                _writer.BaseStream.Seek(dataOffset, SeekOrigin.Begin);
-                _writer.Write(Encoding.UTF8.GetBytes((string)o));
-                int relative_offset = (int)(_writer.BaseStream.Position - baseOffset);
-                int length = (int)(_writer.BaseStream.Position - dataOffset);
-
-                //write index
-                _writer.BaseStream.Seek(indexPosition, SeekOrigin.Begin);
-                _writer.Write((Int32)relative_offset);
-
-                //increment
-                indexPosition += 4;
-                dataOffset += length;
-            }
-            _writer.BaseStream.Seek(dataOffset, SeekOrigin.Begin);  //move cursor to end
-        }
-    }
-
-    /// <summary>
-    /// Small helper class for the writer. This will serialize the binary segment proper.
-    /// </summary>
-    public class WriteSegment : IDisposable
-    {
-        private Writer _writer;
-        private bool _isOpen = false;
-        private long _startOffset;
-        private bool _ownsStream = false;
-
-        public Stream BaseStream { get { return _writer.BaseStream; } }
-        public Reader.Segment Header { get; set; }
-        public List<Reader.Metadata> MetaData { get; set; }
-
-        public WriteSegment(Stream stream)
-        {
-            _writer = new Writer(stream);
-
-            //default header
-            Header = new Reader.Segment();
-            Header.Identifier = "TDSm";
-            Header.Version = 4713;
-            Header.TableOfContents = new Reader.TableOfContents();
-            Header.TableOfContents.HasMetaData = true;  //it would be rather odd with a TDMS file with no meta data. (Then there would be no raw data either)
-            Header.NextSegmentOffset = -1; //no more segments
-            Header.RawDataOffset = 0;  //for now
-
-            MetaData = new List<Reader.Metadata>();
-        }
-
-        public WriteSegment(string path) : this(new FileStream(path, FileMode.Create, FileAccess.Write))
-        {
-            _ownsStream = true;
-        }
-
-        public Writer Open()
-        {
-            if (_isOpen) throw new Exception("The TDMS segment is already open. It cannot be re-opened");
-            if (MetaData.Count == 0) throw new Exception("First insert some meta data");
-
-            //write header
-            _startOffset = BaseStream.Position;
-            _writer.WriteSegment(_startOffset, Header);
-            _writer.WriteMetadata(MetaData);
-            Header.RawDataOffset = BaseStream.Position - Reader.Segment.Length - _startOffset;
-
-            _isOpen = true;
-            return _writer;
-        }
-
-        public void Close()
-        {
-            if (!_isOpen) return;
-
-            //Re-write raw and next offset
-            long end_offset = BaseStream.Position;
-            Header.NextSegmentOffset = end_offset - _startOffset - Reader.Segment.Length;
-            _writer.WriteSegment(_startOffset, Header);
-            _writer.WriteMetadata(MetaData);     //meta data contains byte count. These should be updated before 'closing'
-            BaseStream.Seek(end_offset, SeekOrigin.Begin);  //set cursor at end
-
-            //close stream 
-            if (_ownsStream) BaseStream.Close();
-
-            _isOpen = false;
-        }
-
-        public void Dispose()
-        {
-            Close();
-        }
-
-        #region " Helper functions for creating new TDMS files (with properties) "
-
-        public static Reader.Metadata GenerateStandardProperties(string description, params string[] path)
-        {
-            Reader.Metadata meta = new Reader.Metadata();
-            meta.Path = path;
-            meta.Properties = new Dictionary<string, object>();
-            if (!string.IsNullOrEmpty(description)) meta.Properties.Add("description", description);
-            return meta;
-        }
-
-        public static Reader.Metadata GenerateStandardRoot(string name, string author, string description, DateTime datetime)
-        {
-            Reader.Metadata meta = GenerateStandardProperties(description, new string[0]);
-            if (!string.IsNullOrEmpty(name)) meta.Properties.Add("name", name);
-            if (!string.IsNullOrEmpty(author)) meta.Properties.Add("author", author);
-            if (datetime != new DateTime(1, 1, 1)) meta.Properties.Add("datetime", datetime);
-            return meta;
-        }
-
-        public static Reader.Metadata GenerateStandardGroup(string name, string description)
-        {
-            Reader.Metadata meta = GenerateStandardProperties( description, name);
-            return meta;
-        }
-
-        public static Reader.Metadata GenerateStandardChannel(string groupName, string name, string description, string yUnitString, string xUnitString, string xName, DateTime startTime, double increment, Type dataType, int dataCount, int stringBlobLength = 0)
-        {
-            Reader.Metadata meta = GenerateStandardProperties( description, groupName, name);
-            if(!string.IsNullOrEmpty(yUnitString)) meta.Properties.Add("unit_string", yUnitString);
-            if(!string.IsNullOrEmpty(xUnitString)) meta.Properties.Add("wf_xunit_string", xUnitString);
-            if(!string.IsNullOrEmpty(xName)) meta.Properties.Add("wf_xname", xName);
-            if(startTime != new DateTime(1,1,1)) meta.Properties.Add("wf_start_time", startTime);
-            if(increment != 0) meta.Properties.Add("wf_increment", increment);
-
-            meta.RawData = new Reader.RawData();
-            meta.RawData.DataType = DataType.GetDataType(Activator.CreateInstance(dataType)!);
-            meta.RawData.Count = dataCount;
-            meta.RawData.Dimension = 1; //always 1
-            if (dataType == typeof(string)) meta.RawData.Size = stringBlobLength;
-
-            return meta;
-        }
-
-        #endregion  
-    }
-}
-