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
}
}