DataValue_t.cs 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace IACommService4CSharp
  7. {
  8. public static class DType
  9. {
  10. public const UInt32 Undefined = 0u; /* undefined type */
  11. public const UInt32 Boolean = 1u; /* boolean */
  12. public const UInt32 SByte = 2u; /* signed byte */
  13. public const UInt32 Byte = 3u; /* unsigned byte */
  14. public const UInt32 Int16 = 4u; /* signed 16 bit integer */
  15. public const UInt32 UInt16 = 5u; /* unsigned 16 bit integer */
  16. public const UInt32 Int32 = 6u; /* signed 32 bit integer */
  17. public const UInt32 UInt32 = 7u; /* unsigned 32 bit integer */
  18. public const UInt32 Int64 = 8u; /* signed 64 bit integer */
  19. public const UInt32 UInt64 = 9u; /* unsigned 64 bit integer */
  20. public const UInt32 Float = 10u; /* 32 bit single precision floating point */
  21. public const UInt32 Double = 11u; /* 64 bit double precision floating point */
  22. public const UInt32 String = 12u; /* UTF-8 string */
  23. public const UInt32 Complex = 100u; /* complex type, such as Structure */
  24. public const UInt32 Custom = 200u; /* custom type */
  25. };
  26. public class DataValue_t : IDisposable
  27. {
  28. private static Dictionary<uint, Type> m_dataTypeDic = new Dictionary<uint, Type>()
  29. {
  30. { DType.Boolean, typeof(bool) },
  31. { DType.SByte, typeof(sbyte) },
  32. { DType.Byte, typeof(byte) },
  33. { DType.Int16, typeof(short) },
  34. { DType.UInt16, typeof(ushort) },
  35. { DType.Int32, typeof(int) },
  36. { DType.UInt32, typeof(uint) },
  37. { DType.Int64, typeof(long) },
  38. { DType.UInt64, typeof(ulong) },
  39. { DType.Float, typeof(float) },
  40. { DType.Double, typeof(double) },
  41. { DType.String, typeof(string) },
  42. { DType.Custom, typeof(sbyte[]) },
  43. { DType.Undefined, null }
  44. };
  45. private IDataValue4CSharp m_value;
  46. private bool m_disposed = false;
  47. private bool m_isReference = false;
  48. public DataValue_t(uint dataType = DType.Undefined, uint[] dimensions = null)
  49. {
  50. m_value = DataValueFactory4CSharp.Create(dataType, dimensions);
  51. if (m_value is null)
  52. throw new IACommServiceException(ErrorCode.InvalidArgument);
  53. }
  54. public DataValue_t(object value)
  55. {
  56. if (value is null)
  57. throw new IACommServiceException(ErrorCode.InvalidArgument);
  58. if (value is DataValue_t)
  59. {
  60. m_value = DataValueFactory4CSharp.Create(DType.Undefined, null);
  61. if (m_value is null)
  62. throw new IACommServiceException(ErrorCode.InternalError);
  63. CopyFrom((DataValue_t)value);
  64. return;
  65. }
  66. Type valueType = value.GetType();
  67. uint[] dimensions = null;
  68. if (value is Array)
  69. {
  70. var arrayValue = value as Array;
  71. dimensions = new uint[arrayValue.Rank];
  72. for (int index = 0; index < arrayValue.Rank; index++)
  73. {
  74. dimensions[index] = (uint)arrayValue.GetLength(index);
  75. }
  76. valueType = valueType.GetElementType();
  77. }
  78. uint dataType = DType.Undefined;
  79. if (m_dataTypeDic.ContainsValue(valueType))
  80. {
  81. dataType = m_dataTypeDic.First(q => q.Value == valueType).Key;
  82. }
  83. else if (valueType.IsValueType && !valueType.IsPrimitive && !valueType.IsEnum)
  84. {
  85. dataType = DType.Complex;
  86. }
  87. else if (valueType.IsEnum)
  88. {
  89. dataType = DType.Int16;
  90. }
  91. else
  92. {
  93. throw new IACommServiceException(ErrorCode.InvalidArgument);
  94. }
  95. m_value = DataValueFactory4CSharp.Create(dataType, dimensions);
  96. Value = value;
  97. }
  98. //Internal use
  99. public DataValue_t(IDataValue4CSharp value)
  100. {
  101. m_value = value;
  102. if (null == m_value)
  103. throw new IACommServiceException(ErrorCode.InvalidArgument);
  104. m_isReference = true;
  105. }
  106. ~DataValue_t()
  107. {
  108. Dispose(false);
  109. }
  110. public uint CopyFrom(DataValue_t value)
  111. {
  112. if(value is null)
  113. return ErrorCode.InvalidArgument;
  114. return m_value.CopyFrom(value.m_value);
  115. }
  116. public uint CopyTo(ref DataValue_t value)
  117. {
  118. if (value is null)
  119. value = new DataValue_t();
  120. return m_value.CopyTo(value.m_value);
  121. }
  122. public uint GetArrayValue(ref uint[] value)
  123. {
  124. return m_value.GetArrayValue(ref value);
  125. }
  126. public uint GetArrayValue(ref long[] value)
  127. {
  128. return m_value.GetArrayValue(ref value);
  129. }
  130. public uint GetArrayValue(ref ulong[] value)
  131. {
  132. return m_value.GetArrayValue(ref value);
  133. }
  134. public uint GetArrayValue(ref bool[] value)
  135. {
  136. return m_value.GetArrayValue(ref value);
  137. }
  138. public uint GetArrayValue(ref sbyte[] value)
  139. {
  140. return m_value.GetArrayValue(ref value);
  141. }
  142. public uint GetArrayValue(ref byte[] value)
  143. {
  144. return m_value.GetArrayValue(ref value);
  145. }
  146. public uint GetArrayValue(ref short[] value)
  147. {
  148. return m_value.GetArrayValue(ref value);
  149. }
  150. public uint GetArrayValue(ref ushort[] value)
  151. {
  152. return m_value.GetArrayValue(ref value);
  153. }
  154. public uint GetArrayValue(ref int[] value)
  155. {
  156. return m_value.GetArrayValue(ref value);
  157. }
  158. public uint GetArrayValue(ref float[] value)
  159. {
  160. return m_value.GetArrayValue(ref value);
  161. }
  162. public uint GetArrayValue(ref string[] value)
  163. {
  164. return m_value.GetArrayValue(ref value);
  165. }
  166. public uint GetArrayValue(ref double[] value)
  167. {
  168. return m_value.GetArrayValue(ref value);
  169. }
  170. public uint GetElement(uint[] indexes, ref DataValue_t value)
  171. {
  172. if (value is null)
  173. value = new DataValue_t();
  174. return m_value.GetElement(indexes, value.m_value);
  175. }
  176. public uint GetElement(uint index, ref DataValue_t value)
  177. {
  178. if (value is null)
  179. value = new DataValue_t();
  180. return m_value.GetElement(index, value.m_value);
  181. }
  182. public uint GetValue(ref bool value)
  183. {
  184. return m_value.GetValue(ref value);
  185. }
  186. public uint GetValue(ref sbyte value)
  187. {
  188. return m_value.GetValue(ref value);
  189. }
  190. public uint GetValue(ref byte value)
  191. {
  192. return m_value.GetValue(ref value);
  193. }
  194. public uint GetValue(ref short value)
  195. {
  196. return m_value.GetValue(ref value);
  197. }
  198. public uint GetValue(ref uint value)
  199. {
  200. return m_value.GetValue(ref value);
  201. }
  202. public uint GetValue(ref int value)
  203. {
  204. return m_value.GetValue(ref value);
  205. }
  206. public uint GetValue(ref long value)
  207. {
  208. return m_value.GetValue(ref value);
  209. }
  210. public uint GetValue(ref ulong value)
  211. {
  212. return m_value.GetValue(ref value);
  213. }
  214. public uint GetValue(ref float value)
  215. {
  216. return m_value.GetValue(ref value);
  217. }
  218. public uint GetValue(ref double value)
  219. {
  220. return m_value.GetValue(ref value);
  221. }
  222. public uint GetValue(ref string value)
  223. {
  224. return m_value.GetValue(ref value);
  225. }
  226. public uint GetValue(ref sbyte[] value)
  227. {
  228. return m_value.GetValue(ref value);
  229. }
  230. public uint GetValue(string field, ref DataValue_t value)
  231. {
  232. if (value is null)
  233. value = new DataValue_t();
  234. return m_value.GetValue(field, value.m_value);
  235. }
  236. public uint GetValue(ref ushort value)
  237. {
  238. return m_value.GetValue(ref value);
  239. }
  240. public uint Reset(uint dataType = DType.Undefined, uint[] dimensions = null)
  241. {
  242. return m_value.Reset(dataType, dimensions);
  243. }
  244. public uint SetArrayValue(byte[] value)
  245. {
  246. return m_value.SetArrayValue(value);
  247. }
  248. public uint SetArrayValue(bool[] value)
  249. {
  250. return m_value.SetArrayValue(value);
  251. }
  252. public uint SetArrayValue(sbyte[] value)
  253. {
  254. return m_value.SetArrayValue(value);
  255. }
  256. public uint SetArrayValue(short[] value)
  257. {
  258. return m_value.SetArrayValue(value);
  259. }
  260. public uint SetArrayValue(float[] value)
  261. {
  262. return m_value.SetArrayValue(value);
  263. }
  264. public uint SetArrayValue(int[] value)
  265. {
  266. return m_value.SetArrayValue(value);
  267. }
  268. public uint SetArrayValue(uint[] value)
  269. {
  270. return m_value.SetArrayValue(value);
  271. }
  272. public uint SetArrayValue(long[] value)
  273. {
  274. return m_value.SetArrayValue(value);
  275. }
  276. public uint SetArrayValue(ulong[] value)
  277. {
  278. return m_value.SetArrayValue(value);
  279. }
  280. public uint SetArrayValue(double[] value)
  281. {
  282. return m_value.SetArrayValue(value);
  283. }
  284. public uint SetArrayValue(string[] value)
  285. {
  286. return m_value.SetArrayValue(value);
  287. }
  288. public uint SetArrayValue(ushort[] value)
  289. {
  290. return m_value.SetArrayValue(value);
  291. }
  292. public uint SetElement(uint index, DataValue_t value)
  293. {
  294. if (value is null)
  295. return ErrorCode.InvalidArgument;
  296. return m_value.SetElement(index, value.m_value);
  297. }
  298. public uint SetElement(uint[] indexes, DataValue_t value)
  299. {
  300. if (value is null)
  301. return ErrorCode.InvalidArgument;
  302. return m_value.SetElement(indexes, value.m_value);
  303. }
  304. public uint SetValue(string field, DataValue_t value)
  305. {
  306. if (value is null)
  307. return ErrorCode.InvalidArgument;
  308. return m_value.SetValue(field, value.m_value);
  309. }
  310. public uint SetValue(sbyte[] value)
  311. {
  312. return m_value.SetValue(value);
  313. }
  314. public uint SetValue(ulong value)
  315. {
  316. return m_value.SetValue(value);
  317. }
  318. public uint SetValue(long value)
  319. {
  320. return m_value.SetValue(value);
  321. }
  322. public uint SetValue(uint value)
  323. {
  324. return m_value.SetValue(value);
  325. }
  326. public uint SetValue(short value)
  327. {
  328. return m_value.SetValue(value);
  329. }
  330. public uint SetValue(ushort value)
  331. {
  332. return m_value.SetValue(value);
  333. }
  334. public uint SetValue(byte value)
  335. {
  336. return m_value.SetValue(value);
  337. }
  338. public uint SetValue(sbyte value)
  339. {
  340. return m_value.SetValue(value);
  341. }
  342. public uint SetValue(bool value)
  343. {
  344. return m_value.SetValue(value);
  345. }
  346. public uint SetValue(string value)
  347. {
  348. return m_value.SetValue(value);
  349. }
  350. public uint SetValue(double value)
  351. {
  352. return m_value.SetValue(value);
  353. }
  354. public uint SetValue(int value)
  355. {
  356. return m_value.SetValue(value);
  357. }
  358. public uint SetValue(float value)
  359. {
  360. return m_value.SetValue(value);
  361. }
  362. public object Get(Type valueType = null)
  363. {
  364. if (valueType is null && DataType == DType.Complex)
  365. {
  366. throw new IACommServiceException(ErrorCode.InvalidArgument);
  367. }
  368. if (valueType != null)
  369. {
  370. if (valueType == typeof(DataValue_t) || valueType.IsSubclassOf(typeof(DataValue_t)))
  371. {
  372. object value = null;
  373. if (valueType.Name == typeof(ArrayBase_t<>).Name)
  374. {
  375. if (!IsArray)
  376. throw new IACommServiceException(ErrorCode.DataTypeMismatch);
  377. value = Activator.CreateInstance(valueType, new object[] { new uint[] { 0 } });
  378. }
  379. else if (valueType.IsSubclassOf(typeof(ComplexBase_t)))
  380. {
  381. if (DataType != DType.Complex)
  382. throw new IACommServiceException(ErrorCode.DataTypeMismatch);
  383. value = Activator.CreateInstance(valueType);
  384. }
  385. else
  386. {
  387. value = Activator.CreateInstance(valueType, new object[] { DType.Undefined, null });
  388. }
  389. ((DataValue_t)value).CopyFrom(this);
  390. return value;
  391. }
  392. if (IsArray)
  393. {
  394. if (!valueType.IsArray || valueType.GetArrayRank() != Dimensions.Length)
  395. throw new IACommServiceException(ErrorCode.DataTypeMismatch);
  396. valueType = valueType.GetElementType();
  397. }
  398. if (valueType.IsEnum)
  399. {
  400. if (DataType != DType.Int16)
  401. throw new IACommServiceException(ErrorCode.DataTypeMismatch);
  402. }
  403. else if (valueType.IsValueType && !valueType.IsPrimitive)
  404. {
  405. if (DataType != DType.Complex)
  406. throw new IACommServiceException(ErrorCode.DataTypeMismatch);
  407. }
  408. else if (DataType == DType.Complex || m_dataTypeDic[DataType] != valueType)
  409. {
  410. throw new IACommServiceException(ErrorCode.DataTypeMismatch);
  411. }
  412. }
  413. if (IsArray)
  414. {
  415. int[] tempDimensions = Array.ConvertAll<uint, int>(Dimensions, z => (int)z);
  416. Array arrayValue = null;
  417. switch (DataType)
  418. {
  419. case DType.Boolean:
  420. {
  421. bool[] tempArray = null;
  422. GetArrayValue(ref tempArray);
  423. Convert2MultiDimensionsArray(tempArray, tempDimensions, ref arrayValue);
  424. break;
  425. }
  426. case DType.SByte:
  427. {
  428. sbyte[] tempArray = null;
  429. GetArrayValue(ref tempArray);
  430. Convert2MultiDimensionsArray(tempArray, tempDimensions, ref arrayValue);
  431. break;
  432. }
  433. case DType.Byte:
  434. {
  435. byte[] tempArray = null;
  436. GetArrayValue(ref tempArray);
  437. Convert2MultiDimensionsArray(tempArray, tempDimensions, ref arrayValue);
  438. break;
  439. }
  440. case DType.Int16:
  441. {
  442. short[] tempArray = null;
  443. GetArrayValue(ref tempArray);
  444. if (valueType != null && valueType.IsEnum)
  445. {
  446. arrayValue = Array.CreateInstance(valueType, tempDimensions);
  447. for (int index = 0; index < tempArray.Length; index++)
  448. {
  449. int[] indexes = null;
  450. ConvertIndex(index, tempDimensions, ref indexes);
  451. arrayValue.SetValue(Enum.ToObject(valueType, tempArray[index]), indexes);
  452. }
  453. }
  454. else
  455. {
  456. Convert2MultiDimensionsArray(tempArray, tempDimensions, ref arrayValue);
  457. }
  458. break;
  459. }
  460. case DType.UInt16:
  461. {
  462. ushort[] tempArray = null;
  463. GetArrayValue(ref tempArray);
  464. Convert2MultiDimensionsArray(tempArray, tempDimensions, ref arrayValue);
  465. break;
  466. }
  467. case DType.Int32:
  468. {
  469. int[] tempArray = null;
  470. GetArrayValue(ref tempArray);
  471. Convert2MultiDimensionsArray(tempArray, tempDimensions, ref arrayValue);
  472. break;
  473. }
  474. case DType.UInt32:
  475. {
  476. uint[] tempArray = null;
  477. GetArrayValue(ref tempArray);
  478. Convert2MultiDimensionsArray(tempArray, tempDimensions, ref arrayValue);
  479. break;
  480. }
  481. case DType.Int64:
  482. {
  483. long[] tempArray = null;
  484. GetArrayValue(ref tempArray);
  485. Convert2MultiDimensionsArray(tempArray, tempDimensions, ref arrayValue);
  486. break;
  487. }
  488. case DType.UInt64:
  489. {
  490. ulong[] tempArray = null;
  491. GetArrayValue(ref tempArray);
  492. Convert2MultiDimensionsArray(tempArray, tempDimensions, ref arrayValue);
  493. break;
  494. }
  495. case DType.Float:
  496. {
  497. float[] tempArray = null;
  498. GetArrayValue(ref tempArray);
  499. Convert2MultiDimensionsArray(tempArray, tempDimensions, ref arrayValue);
  500. break;
  501. }
  502. case DType.Double:
  503. {
  504. double[] tempArray = null;
  505. GetArrayValue(ref tempArray);
  506. Convert2MultiDimensionsArray(tempArray, tempDimensions, ref arrayValue);
  507. break;
  508. }
  509. case DType.String:
  510. {
  511. string[] tempArray = null;
  512. GetArrayValue(ref tempArray);
  513. Convert2MultiDimensionsArray(tempArray, tempDimensions, ref arrayValue);
  514. break;
  515. }
  516. case DType.Complex:
  517. {
  518. arrayValue = Array.CreateInstance(valueType, tempDimensions);
  519. DataValue_t elementValue = new DataValue_t();
  520. for (uint index = 0; index < ArraySize; index++)
  521. {
  522. if (GetElement(index, ref elementValue) != ErrorCode.Good)
  523. {
  524. elementValue.Dispose();
  525. throw new IACommServiceException(ErrorCode.InternalError);
  526. }
  527. var element = Convert2Struct(elementValue, valueType);
  528. if (element is null)
  529. {
  530. elementValue.Dispose();
  531. throw new IACommServiceException(ErrorCode.InvalidArgument);
  532. }
  533. int[] indexes = null;
  534. ConvertIndex((int)index, tempDimensions, ref indexes);
  535. arrayValue.SetValue(element, indexes);
  536. }
  537. elementValue.Dispose();
  538. break;
  539. }
  540. default:
  541. {
  542. return null;
  543. }
  544. }
  545. return arrayValue;
  546. }
  547. else
  548. {
  549. switch (DataType)
  550. {
  551. case DType.Boolean:
  552. {
  553. bool value = false;
  554. GetValue(ref value);
  555. return value;
  556. }
  557. case DType.SByte:
  558. {
  559. sbyte value = 0;
  560. GetValue(ref value);
  561. return value;
  562. }
  563. case DType.Byte:
  564. {
  565. byte value = 0;
  566. GetValue(ref value);
  567. return value;
  568. }
  569. case DType.Int16:
  570. {
  571. short value = 0;
  572. GetValue(ref value);
  573. if (valueType != null && valueType.IsEnum)
  574. {
  575. return Enum.ToObject(valueType, value);
  576. }
  577. else
  578. {
  579. return value;
  580. }
  581. }
  582. case DType.UInt16:
  583. {
  584. ushort value = 0;
  585. GetValue(ref value);
  586. return value;
  587. }
  588. case DType.Int32:
  589. {
  590. int value = 0;
  591. GetValue(ref value);
  592. return value;
  593. }
  594. case DType.UInt32:
  595. {
  596. uint value = 0;
  597. GetValue(ref value);
  598. return value;
  599. }
  600. case DType.Int64:
  601. {
  602. long value = 0;
  603. GetValue(ref value);
  604. return value;
  605. }
  606. case DType.UInt64:
  607. {
  608. ulong value = 0;
  609. GetValue(ref value);
  610. return value;
  611. }
  612. case DType.Float:
  613. {
  614. float value = 0;
  615. GetValue(ref value);
  616. return value;
  617. }
  618. case DType.Double:
  619. {
  620. double value = 0;
  621. GetValue(ref value);
  622. return value;
  623. }
  624. case DType.String:
  625. {
  626. string value = null;
  627. GetValue(ref value);
  628. return value;
  629. }
  630. case DType.Custom:
  631. {
  632. sbyte[] value = null;
  633. GetValue(ref value);
  634. return value;
  635. }
  636. case DType.Complex:
  637. {
  638. var value = Convert2Struct(this, valueType);
  639. if (value is null)
  640. throw new IACommServiceException(ErrorCode.DataTypeMismatch);
  641. return value;
  642. }
  643. default:
  644. {
  645. return null;
  646. }
  647. }
  648. }
  649. }
  650. public uint Set(object value)
  651. {
  652. if (value is null)
  653. return ErrorCode.InvalidArgument;
  654. if (value is DataValue_t)
  655. {
  656. if (DataType != ((DataValue_t)value).DataType ||
  657. Dimensions.ToString() != ((DataValue_t)value).Dimensions.ToString())
  658. return ErrorCode.DataTypeMismatch;
  659. CopyFrom((DataValue_t)value);
  660. return ErrorCode.Good;
  661. }
  662. Type valueType = value.GetType();
  663. if (IsArray)
  664. {
  665. if (!valueType.IsArray)
  666. return ErrorCode.DataTypeMismatch;
  667. valueType = valueType.GetElementType();
  668. }
  669. if (valueType.IsEnum)
  670. {
  671. if (DataType != DType.Int16)
  672. return ErrorCode.DataTypeMismatch;
  673. }
  674. else if (valueType.IsValueType && !valueType.IsPrimitive)
  675. {
  676. if (DataType != DType.Complex)
  677. return ErrorCode.DataTypeMismatch;
  678. }
  679. else if (DataType == DType.Complex || m_dataTypeDic[DataType] != valueType)
  680. {
  681. return ErrorCode.DataTypeMismatch;
  682. }
  683. if (IsArray)
  684. {
  685. var tempValue = value as Array;
  686. int[] tempDimensions = Array.ConvertAll<uint, int>(Dimensions, z => (int)z);
  687. if (tempValue.Rank != tempDimensions.Length)
  688. return ErrorCode.DataTypeMismatch;
  689. for (int index = 0; index < tempValue.Rank; index++)
  690. {
  691. if (tempValue.GetLength(index) != tempDimensions[index])
  692. return ErrorCode.DataTypeMismatch;
  693. }
  694. if (valueType.IsEnum)
  695. {
  696. short[] arrayValue = new short[tempValue.Length];
  697. for (int index = 0; index < arrayValue.Length; index++)
  698. {
  699. int[] indexes = null;
  700. ConvertIndex(index, tempDimensions, ref indexes);
  701. arrayValue[index] = Convert.ToInt16(tempValue.GetValue(indexes));
  702. }
  703. return SetArrayValue(arrayValue);
  704. }
  705. else if (DataType == DType.Complex)
  706. {
  707. for (uint index = 0; index < ArraySize; index++)
  708. {
  709. int[] indexes = null;
  710. ConvertIndex((int)index, tempDimensions, ref indexes);
  711. DataValue_t element = new DataValue_t(DType.Complex);
  712. var structElement = tempValue.GetValue(indexes);
  713. var status = Convert2DataValue(structElement, element);
  714. if (ErrorCode.Good == status)
  715. status = SetElement(index, element);
  716. element.Dispose();
  717. if (status != ErrorCode.Good)
  718. return status;
  719. }
  720. return ErrorCode.Good;
  721. }
  722. else
  723. {
  724. switch (DataType)
  725. {
  726. case DType.Boolean:
  727. {
  728. bool[] arrayValue = null;
  729. Convert2SingleDimensionArray(value as Array, tempDimensions, ref arrayValue);
  730. return SetArrayValue(arrayValue);
  731. }
  732. case DType.SByte:
  733. {
  734. sbyte[] arrayValue = null;
  735. Convert2SingleDimensionArray(value as Array, tempDimensions, ref arrayValue);
  736. return SetArrayValue(arrayValue);
  737. }
  738. case DType.Byte:
  739. {
  740. byte[] arrayValue = null;
  741. Convert2SingleDimensionArray(value as Array, tempDimensions, ref arrayValue);
  742. return SetArrayValue(arrayValue);
  743. }
  744. case DType.Int16:
  745. {
  746. short[] arrayValue = null;
  747. Convert2SingleDimensionArray(value as Array, tempDimensions, ref arrayValue);
  748. return SetArrayValue(arrayValue);
  749. }
  750. case DType.UInt16:
  751. {
  752. ushort[] arrayValue = null;
  753. Convert2SingleDimensionArray(value as Array, tempDimensions, ref arrayValue);
  754. return SetArrayValue(arrayValue);
  755. }
  756. case DType.Int32:
  757. {
  758. int[] arrayValue = null;
  759. Convert2SingleDimensionArray(value as Array, tempDimensions, ref arrayValue);
  760. return SetArrayValue(arrayValue);
  761. }
  762. case DType.UInt32:
  763. {
  764. uint[] arrayValue = null;
  765. Convert2SingleDimensionArray(value as Array, tempDimensions, ref arrayValue);
  766. return SetArrayValue(arrayValue);
  767. }
  768. case DType.Int64:
  769. {
  770. long[] arrayValue = null;
  771. Convert2SingleDimensionArray(value as Array, tempDimensions, ref arrayValue);
  772. return SetArrayValue(arrayValue);
  773. }
  774. case DType.UInt64:
  775. {
  776. ulong[] arrayValue = null;
  777. Convert2SingleDimensionArray(value as Array, tempDimensions, ref arrayValue);
  778. return SetArrayValue(arrayValue);
  779. }
  780. case DType.Float:
  781. {
  782. float[] arrayValue = null;
  783. Convert2SingleDimensionArray(value as Array, tempDimensions, ref arrayValue);
  784. return SetArrayValue(arrayValue);
  785. }
  786. case DType.Double:
  787. {
  788. double[] arrayValue = null;
  789. Convert2SingleDimensionArray(value as Array, tempDimensions, ref arrayValue);
  790. return SetArrayValue(arrayValue);
  791. }
  792. case DType.String:
  793. {
  794. string[] arrayValue = null;
  795. Convert2SingleDimensionArray(value as Array, tempDimensions, ref arrayValue);
  796. return SetArrayValue(arrayValue);
  797. }
  798. default:
  799. {
  800. return ErrorCode.DataTypeMismatch;
  801. }
  802. }
  803. }
  804. }
  805. else
  806. {
  807. if (valueType.IsEnum)
  808. {
  809. return SetValue(Convert.ToInt16(value));
  810. }
  811. else if (DataType == DType.Complex)
  812. {
  813. Reset(DType.Complex);
  814. return Convert2DataValue(value, this);
  815. }
  816. else
  817. {
  818. switch (DataType)
  819. {
  820. case DType.Boolean:
  821. return SetValue((bool)value);
  822. case DType.SByte:
  823. return SetValue((sbyte)value);
  824. case DType.Byte:
  825. return SetValue((byte)value);
  826. case DType.Int16:
  827. return SetValue((short)value);
  828. case DType.UInt16:
  829. return SetValue((ushort)value);
  830. case DType.Int32:
  831. return SetValue((int)value);
  832. case DType.UInt32:
  833. return SetValue((uint)value);
  834. case DType.Int64:
  835. return SetValue((long)value);
  836. case DType.UInt64:
  837. return SetValue((ulong)value);
  838. case DType.Float:
  839. return SetValue((float)value);
  840. case DType.Double:
  841. return SetValue((double)value);
  842. case DType.String:
  843. return SetValue((string)value);
  844. case DType.Custom:
  845. return SetValue((sbyte[])value);
  846. default:
  847. return ErrorCode.DataTypeMismatch;
  848. }
  849. }
  850. }
  851. }
  852. public uint DataType
  853. {
  854. get
  855. {
  856. return m_value.DataType();
  857. }
  858. }
  859. public bool IsArray
  860. {
  861. get
  862. {
  863. return m_value.IsArray();
  864. }
  865. }
  866. public uint ArraySize
  867. {
  868. get
  869. {
  870. return m_value.ArraySize();
  871. }
  872. }
  873. public uint[] Dimensions
  874. {
  875. get
  876. {
  877. uint[] dimensions = null;
  878. m_value.GetDimensions(ref dimensions);
  879. return dimensions;
  880. }
  881. }
  882. public object Value
  883. {
  884. get
  885. {
  886. if (DataType == DType.Complex)
  887. throw new IACommServiceException(ErrorCode.NotSupported);
  888. return Get();
  889. }
  890. set
  891. {
  892. Set(value);
  893. }
  894. }
  895. public void Dispose()
  896. {
  897. Dispose(true);
  898. GC.SuppressFinalize(this);
  899. }
  900. protected virtual void Dispose(bool disposeManaged)
  901. {
  902. if (!m_disposed)
  903. {
  904. if (disposeManaged)
  905. {
  906. //do nothing
  907. }
  908. if (!m_isReference)
  909. DataValueFactory4CSharp.Destroy(m_value);
  910. m_value = null;
  911. m_disposed = true;
  912. }
  913. }
  914. //Internal use
  915. public IDataValue4CSharp Internal
  916. {
  917. get
  918. {
  919. return m_value;
  920. }
  921. }
  922. private uint Convert2SingleDimensionArray<T>(Array sourceArray, int[] dimensions, ref T[] targetArray)
  923. {
  924. if (null == sourceArray)
  925. return ErrorCode.InvalidArgument;
  926. targetArray = new T[sourceArray.Length];
  927. for (int index = 0; index < targetArray.Length; index++)
  928. {
  929. int[] indexes = null;
  930. ConvertIndex(index, dimensions, ref indexes);
  931. targetArray[index] = (T)sourceArray.GetValue(indexes);
  932. }
  933. return ErrorCode.Good;
  934. }
  935. private uint Convert2MultiDimensionsArray<T>(T[] sourceArray, int[] dimensions, ref Array targetArray)
  936. {
  937. if (null == sourceArray)
  938. return ErrorCode.InvalidArgument;
  939. targetArray = Array.CreateInstance(typeof(T), dimensions);
  940. for (int index = 0; index < sourceArray.Length; index++)
  941. {
  942. int[] indexes = null;
  943. ConvertIndex(index, dimensions, ref indexes);
  944. targetArray.SetValue(sourceArray[index], indexes);
  945. }
  946. return ErrorCode.Good;
  947. }
  948. private uint ConvertIndex(int index, int[] dimensions, ref int[] indexes)
  949. {
  950. if (null == dimensions)
  951. return ErrorCode.InvalidArgument;
  952. indexes = new int[dimensions.Length];
  953. for (int n = 0; n < indexes.Length; n++)
  954. {
  955. int curLength = (int)dimensions[n];
  956. int lengths = 1;
  957. for (int m = n + 1; m < indexes.Length; m++)
  958. {
  959. lengths *= (int)dimensions[m];
  960. }
  961. indexes[n] = (index / lengths) % curLength;
  962. }
  963. return ErrorCode.Good;
  964. }
  965. private object Convert2Struct(DataValue_t value, Type structType)
  966. {
  967. object retValue = null;
  968. if (structType.IsValueType && !structType.IsPrimitive && !structType.IsEnum)
  969. {
  970. retValue = Activator.CreateInstance(structType);
  971. DataValue_t fieldValue = new DataValue_t();
  972. var fieldInfos = structType.GetFields();
  973. foreach (var fieldInfo in fieldInfos)
  974. {
  975. var status = value.GetValue(fieldInfo.Name, ref fieldValue);
  976. if (status != ErrorCode.Good)
  977. {
  978. fieldValue.Dispose();
  979. throw new IACommServiceException(ErrorCode.InvalidArgument);
  980. }
  981. object field = null;
  982. try
  983. {
  984. field = fieldValue.Get(fieldInfo.FieldType);
  985. }
  986. catch
  987. {
  988. field = null;
  989. }
  990. fieldInfo.SetValue(retValue, field);
  991. }
  992. fieldValue.Dispose();
  993. }
  994. return retValue;
  995. }
  996. private uint Convert2DataValue(object structValue, DataValue_t value)
  997. {
  998. var structType = structValue.GetType();
  999. if (structType.IsValueType && !structType.IsPrimitive && !structType.IsEnum)
  1000. {
  1001. var fieldInfos = structType.GetFields();
  1002. foreach (var fieldInfo in fieldInfos)
  1003. {
  1004. object field = fieldInfo.GetValue(structValue);
  1005. DataValue_t fieldValue = new DataValue_t(field);
  1006. var status = value.SetValue(fieldInfo.Name, fieldValue);
  1007. fieldValue.Dispose();
  1008. if (status != ErrorCode.Good)
  1009. return ErrorCode.InvalidArgument;
  1010. }
  1011. return ErrorCode.Good;
  1012. }
  1013. else
  1014. {
  1015. return ErrorCode.DataTypeMismatch;
  1016. }
  1017. }
  1018. }
  1019. }