BaseTDMSLevel.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. using System;
  2. using System.ComponentModel;
  3. using System.Diagnostics.CodeAnalysis;
  4. using TDMS.Common;
  5. using TDMS.Externals;
  6. namespace TDMS.Default
  7. {
  8. internal abstract class BaseTDMSLevel : ITDMSLevel
  9. {
  10. protected IntPtr _SelfPtr;
  11. internal IntPtr GetPtr()
  12. {
  13. return _SelfPtr;
  14. }
  15. [AllowNull]
  16. public PropertyOperator PropertyOperator { get; protected internal set; }
  17. #region Implementation of ITDMSLevelPropertyOperation
  18. /// <inheritdoc />
  19. public virtual void CreateOrUpdateProperty<T>(string propertyName, T propertyValue)
  20. {
  21. if (!PropertyExists(propertyName))
  22. CreateProperty(propertyName, propertyValue);
  23. else
  24. UpdateProperty(propertyName, propertyValue);
  25. }
  26. protected virtual void CreateProperty<T>(string propertyName, T propertyValue)
  27. {
  28. int success;
  29. switch (propertyValue)
  30. {
  31. case string stringValue:
  32. PropertyOperator.CreateStringValue(propertyName, Tail(stringValue)); break;
  33. case byte byteValue:
  34. PropertyOperator.CreateByteValue(propertyName, byteValue); break;
  35. case short shortValue:
  36. PropertyOperator.CreateShortValue(propertyName, shortValue); break;
  37. case int intValue:
  38. PropertyOperator.CreateIntValue(propertyName, intValue); break;
  39. case float floatValue:
  40. PropertyOperator.CreateFloatValue(propertyName, floatValue); break;
  41. case double doubleValue:
  42. PropertyOperator.CreateDoubleValue(propertyName, doubleValue); break;
  43. case DateTime dateTimeValue:
  44. PropertyOperator.CreateDateTimeValue(propertyName, dateTimeValue); break;
  45. default:
  46. throw new ArgumentException("Unsupported property value type");
  47. }
  48. }
  49. protected virtual void UpdateProperty<T>(string propertyName, T propertyValue)
  50. {
  51. int success;
  52. switch (propertyValue)
  53. {
  54. case string stringValue:
  55. PropertyOperator.SetStringValue(propertyName, Tail(stringValue)); break;
  56. case byte byteValue:
  57. PropertyOperator.SetByteValue(propertyName, byteValue); break;
  58. case short shortValue:
  59. PropertyOperator.SetShortValue(propertyName, shortValue); break;
  60. case int intValue:
  61. PropertyOperator.SetIntValue(propertyName, intValue); break;
  62. case float floatValue:
  63. PropertyOperator.SetFloatValue(propertyName, floatValue); break;
  64. case double doubleValue:
  65. PropertyOperator.SetDoubleValue(propertyName, doubleValue); break;
  66. case DateTime dateTimeValue:
  67. PropertyOperator.SetDateTimeValue(propertyName, dateTimeValue); break;
  68. default:
  69. throw new ArgumentException("Unsupported property value type");
  70. }
  71. }
  72. /// <inheritdoc />
  73. public virtual bool PropertyExists(string propertyName)
  74. {
  75. return PropertyOperator.Exists(propertyName);
  76. }
  77. /// <inheritdoc />
  78. public string[] GetPropertyNames()
  79. {
  80. return PropertyOperator.GetPropertyNames();
  81. }
  82. /// <inheritdoc />
  83. public virtual bool TryGetProperty<T>(string propertyName, out T propertyValue)
  84. {
  85. if(!PropertyExists(propertyName))
  86. {
  87. propertyValue = default;
  88. return false;
  89. }
  90. var srcDataType = PropertyOperator.GetDataType(propertyName);
  91. var type = typeof(T).ToDataType();
  92. if(srcDataType != type)
  93. {
  94. var e = new InvalidCastException(
  95. $"The data type of the property '{propertyName}' is not '{type}', is '{srcDataType}'.");
  96. throw new TDMSErrorException($"{type} is error input arg", e);
  97. }
  98. switch (type)
  99. {
  100. case TDMSDataType.String:
  101. {
  102. propertyValue = (T)(object)PropertyOperator.GetStringValue(propertyName);
  103. return true;
  104. }
  105. case TDMSDataType.UInt8:
  106. {
  107. propertyValue = (T)(object)PropertyOperator.GetByteValue(propertyName);
  108. return true;
  109. }
  110. case TDMSDataType.Int16:
  111. {
  112. propertyValue = (T)(object)PropertyOperator.GetShortValue(propertyName);
  113. return true;
  114. }
  115. case TDMSDataType.Int32:
  116. {
  117. propertyValue = (T)(object)PropertyOperator.GetIntValue(propertyName);
  118. return true;
  119. }
  120. case TDMSDataType.Float:
  121. {
  122. propertyValue = (T)(object)PropertyOperator.GetFloatValue(propertyName);
  123. return true;
  124. }
  125. case TDMSDataType.Double:
  126. {
  127. propertyValue = (T)(object)PropertyOperator.GetDoubleValue(propertyName);
  128. return true;
  129. }
  130. case TDMSDataType.Timestamp:
  131. {
  132. propertyValue = (T)(object)PropertyOperator.GetDateTimeValue(propertyName);
  133. return true;
  134. }
  135. case TDMSDataType.UnDefine:
  136. default:
  137. throw new InvalidEnumArgumentException();
  138. }
  139. }
  140. #endregion
  141. #region Implementation of ITDMSLevel
  142. protected void SetNameAndDescription()
  143. {
  144. Name = GetDefaultProperty(Constants.DDC_LEVEL_NAME);
  145. Description = GetDefaultProperty(Constants.DDC_LEVEL_DESCRIPTION);
  146. }
  147. /// <summary> 快速获取层级的默认属性值 </summary>
  148. protected string GetDefaultProperty(string propertyName)
  149. {
  150. var has = TryGetProperty<string>(propertyName, out var propertyValue);
  151. if(!has)
  152. throw new TDMSErrorException($"Failed to retrieve the default '{propertyName}' property.");
  153. return propertyValue;
  154. }
  155. /// <inheritdoc />
  156. public string Name { get; private set; }
  157. /// <inheritdoc />
  158. public string Description { get; private set; }
  159. /// <inheritdoc />
  160. public abstract bool Close();
  161. /// <inheritdoc />
  162. public abstract ulong ChildCount { get; }
  163. /// <inheritdoc />
  164. public abstract bool Clear();
  165. /// <inheritdoc />
  166. public abstract bool Contains(string levelName);
  167. /// <inheritdoc />
  168. public abstract bool TryGetItem(string levelName, out ITDMSLevel level);
  169. /// <inheritdoc />
  170. public abstract bool Remove(string levelName);
  171. /// <inheritdoc />
  172. public abstract bool RemoveAt(int index);
  173. #endregion
  174. #region Implementation of IDisposable
  175. protected bool _IsClosed;
  176. ~BaseTDMSLevel()
  177. {
  178. Dispose(false);
  179. }
  180. protected virtual void Dispose(bool disposing)
  181. {
  182. PropertyOperator?.Dispose();
  183. if(_SelfPtr != IntPtr.Zero)
  184. {
  185. _IsClosed = Close();
  186. _SelfPtr = IntPtr.Zero;
  187. }
  188. if(disposing)
  189. {
  190. // 释放托管资源
  191. }
  192. }
  193. public void Dispose()
  194. {
  195. Dispose(true);
  196. GC.SuppressFinalize(this);
  197. }
  198. #endregion
  199. protected static string Tail(string source)
  200. {
  201. return $"{source}";
  202. }
  203. }
  204. }