using MessagePack; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Threading; using TDMS.Common; using TDMS.Externals; namespace TDMS.Default { internal class TDMSFile : BaseTDMSLevel, ITDMSFile { #region Implementation of ITDMSFile /// [AllowNull] public TDMSFileInfo FileInfo { get; private set; } /// public bool Save() { var success = DDC.SaveFile(_SelfPtr); return success == 0; } public bool IsOpen => _SelfPtr != IntPtr.Zero; /// public bool Open(string filePath) { var tdmsFileInfo = new TDMSFileInfo(filePath); return Open(tdmsFileInfo); } /// public bool Open(TDMSFileInfo fileInfo) { if(!fileInfo.Exists) { return Create(fileInfo); } FileInfo = fileInfo; var success = DDC.OpenFile(fileInfo.FilePath, fileInfo.FileType, out var filePtr); if (success != Error.NoError) return false; _SelfPtr = filePtr; PropertyOperator = new FilePropertyOperator(_SelfPtr); if (TryGetProperty(Constants.DDC_FILE_DATETIME, out var dateTime)) fileInfo.DateTime = dateTime; if(TryGetProperty(Constants.DDC_FILE_NAME, out string name)) fileInfo.Name = name; if(TryGetProperty(Constants.DDC_FILE_DESCRIPTION, out string desc)) fileInfo.Description = desc; if(TryGetProperty(Constants.DDC_FILE_TITLE, out string title)) fileInfo.Title = title; if(TryGetProperty(Constants.DDC_FILE_AUTHOR, out string author)) fileInfo.Author = author; SetNameAndDescription(); return success == 0; } /// public bool Create(string filePath, string fileType, string name, string description, string title, string author) { var tdmsFileInfo = new TDMSFileInfo(filePath) { Name = name, Description = description, Title = title, Author = author }; return Create(tdmsFileInfo); } /// public bool Create(TDMSFileInfo fileInfo) { FileInfo = fileInfo; var success = DDC.CreateFile(FileInfo.FilePath, FileInfo.FileType, FileInfo.Name, FileInfo.Description, FileInfo.Title, FileInfo.Author, out var filePtr); if (success != Error.NoError) return false; _SelfPtr = filePtr; PropertyOperator = new FilePropertyOperator(_SelfPtr); SetNameAndDescription(); CreateOrUpdateProperty(Constants.DDC_FILE_DATETIME, FileInfo.DateTime); //即将存储,添加文件创建时间 var isSave = Save(); Thread.Sleep(6); //持久化到硬盘需要一些时间,略做等待 return success == 0 && isSave; } /// public ITDMSChannelGroup? this[int index] { get { if (index < 0) throw new IndexOutOfRangeException($"Index[{index}] must be greater than or equal to 0"); var count = (int)ChildCount; if (index >= count) throw new IndexOutOfRangeException($"Index[{index}] must be less than the number of channel groups"); var channelGroupsBuffer = new IntPtr[count]; var success = DDC.GetChannelGroups(_SelfPtr, channelGroupsBuffer, (uint)count); if(success!= Error.NoError)return null; var groupPtr = channelGroupsBuffer[index]; return new TDMSChannelGroup(groupPtr); } } /// public ITDMSChannelGroup this[string groupName] { get { if(string.IsNullOrEmpty(groupName)) throw new ArgumentNullException(nameof(groupName), "Group name cannot be null or empty"); var count = ChildCount; if(count <= 0) return null; var channelGroupsBuffer = new IntPtr[count]; var success = DDC.GetChannelGroups(_SelfPtr, channelGroupsBuffer, (uint)count); if (success != Error.NoError) return null; foreach (var intPtr in channelGroupsBuffer) { var group = new TDMSChannelGroup(intPtr); if(group.Name == groupName) return group; group.Dispose(); } return null; } } /// public IDictionary GetDefaultProperties() { var dict = new Dictionary(5); GetDefaultPropertyToDictionary(Constants.DDC_FILE_NAME, dict); GetDefaultPropertyToDictionary(Constants.DDC_FILE_DESCRIPTION, dict); GetDefaultPropertyToDictionary(Constants.DDC_FILE_TITLE, dict); GetDefaultPropertyToDictionary(Constants.DDC_FILE_AUTHOR, dict); GetDefaultPropertyToDictionary(Constants.DDC_FILE_DATETIME, dict); return dict; } private void GetDefaultPropertyToDictionary(string key, Dictionary dict) { if(key == Constants.DDC_FILE_DATETIME) { if(TryGetProperty(key, out DateTime dateTime)) { dict.Add(key, dateTime.ToString("O")); } } else { if(TryGetProperty(key, out string propertyValue)) { dict.Add(key, propertyValue); } } } #endregion #region Implementation of BaseTDMSLevel /// public override bool Close() { if(!_IsClosed) { var success = DDC.CloseFile(_SelfPtr); } return _IsClosed = true; } /// public override ulong ChildCount { get { var success = DDC.CountChannelGroups(_SelfPtr, out var count); return count; } } /// public ITDMSChannelGroup? AddGroup(string groupName, string description = "") { if(string.IsNullOrEmpty(groupName)) throw new TDMSErrorException("Channel group name cannot be null or empty", new ArgumentNullException(nameof(groupName))); if(Contains(groupName)) return null; var success = DDC.AddChannelGroup(_SelfPtr, Tail(groupName), Tail(description), out var groupPtr); if (success != Error.NoError) return null; return new TDMSChannelGroup(groupPtr); } /// public override bool Clear() { var groupsBuffer = new IntPtr[ChildCount]; var success = DDC.GetChannelGroups(_SelfPtr, groupsBuffer, (uint)ChildCount); foreach (var ptr in groupsBuffer) { success = DDC.RemoveChannelGroup(ptr); } return success == 0; } /// public override bool Contains(string groupName) { if(string.IsNullOrEmpty(groupName)) return false; var count = ChildCount; if (count <= 0) return false; var channelGroupsBuffer = new IntPtr[count]; var success = DDC.GetChannelGroups(_SelfPtr, channelGroupsBuffer, (uint)count); if (success != Error.NoError) return false; foreach (var intPtr in channelGroupsBuffer) { using var group = new TDMSChannelGroup(intPtr); if(group.Name == groupName) return true; } return false; } /// public override bool TryGetItem(string groupName, out ITDMSLevel level) { var has = Contains(groupName); if(has) { level = this[groupName]; return true; } level = null; return false; } /// public override bool Remove(string groupName) { if (TryGetItem(groupName, out var group) && group is TDMSChannelGroup @in) { var success = DDC.RemoveChannelGroup(@in.GetPtr()); } return false; } /// public override bool RemoveAt(int index) { var group = this[index]; if(group is TDMSChannelGroup groupIn) { var success = DDC.RemoveChannelGroup(groupIn.GetPtr()); } return false; } #endregion } }