DataContainer.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997
  1. //
  2. // Copyright (C) 2008 Novell, Inc (http://www.novell.com)
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining
  5. // a copy of this software and associated documentation files (the
  6. // "Software"), to deal in the Software without restriction, including
  7. // without limitation the rights to use, copy, modify, merge, publish,
  8. // distribute, sublicense, and/or sell copies of the Software, and to
  9. // permit persons to whom the Software is furnished to do so, subject to
  10. // the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be
  13. // included in all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  19. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  20. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  21. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. //
  23. using System;
  24. using System.Collections;
  25. using System.Reflection;
  26. using System.Reflection.Emit;
  27. namespace System.Data.Common
  28. {
  29. internal abstract class DataContainer {
  30. BitArray null_values;
  31. System.Type _type;
  32. DataColumn _column;
  33. // implementing class protocol
  34. protected abstract object GetValue (int index);
  35. internal abstract long GetInt64 (int index);
  36. // used to set the array value to something neutral when the corresponding item is null (in the database sense)
  37. // note: we don't actually ever look at the value written there, but the GC may like us to avoid keeping stale
  38. // values in the array.
  39. protected abstract void ZeroOut (int index);
  40. protected abstract void SetValue (int index, object value);
  41. protected abstract void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field);
  42. protected abstract void DoCopyValue (DataContainer from, int from_index, int to_index);
  43. protected abstract int DoCompareValues (int index1, int index2);
  44. protected abstract void Resize (int length);
  45. internal object this [int index] {
  46. get { return IsNull (index) ? DBNull.Value : GetValue (index); }
  47. set {
  48. if (value == null) {
  49. CopyValue (Column.Table.DefaultValuesRowIndex, index);
  50. return;
  51. }
  52. bool is_dbnull = value == DBNull.Value;
  53. if (is_dbnull)
  54. ZeroOut (index);
  55. else
  56. SetValue (index, value);
  57. null_values [index] = is_dbnull;
  58. }
  59. }
  60. internal int Capacity {
  61. get { return null_values != null ? null_values.Count : 0; }
  62. set {
  63. int old_capacity = Capacity;
  64. if (value == old_capacity)
  65. return;
  66. if (null_values == null)
  67. null_values = new BitArray (value);
  68. else
  69. null_values.Length = value;
  70. Resize (value);
  71. }
  72. }
  73. internal Type Type {
  74. get { return _type; }
  75. }
  76. protected DataColumn Column {
  77. get { return _column; }
  78. }
  79. internal static DataContainer Create (Type type, DataColumn column)
  80. {
  81. DataContainer container;
  82. switch (Type.GetTypeCode(type)) {
  83. case TypeCode.Int16:
  84. container = new Int16DataContainer ();
  85. break;
  86. case TypeCode.Int32:
  87. container = new Int32DataContainer ();
  88. break;
  89. case TypeCode.Int64:
  90. container = new Int64DataContainer ();
  91. break;
  92. case TypeCode.String:
  93. container = new StringDataContainer ();
  94. break;
  95. case TypeCode.Boolean:
  96. container = new BitDataContainer ();
  97. break;
  98. case TypeCode.Byte:
  99. container = new ByteDataContainer ();
  100. break;
  101. case TypeCode.Char:
  102. container = new CharDataContainer ();
  103. break;
  104. case TypeCode.Double:
  105. container = new DoubleDataContainer ();
  106. break;
  107. case TypeCode.SByte:
  108. container = new SByteDataContainer ();
  109. break;
  110. case TypeCode.Single:
  111. container = new SingleDataContainer ();
  112. break;
  113. case TypeCode.UInt16:
  114. container = new UInt16DataContainer ();
  115. break;
  116. case TypeCode.UInt32:
  117. container = new UInt32DataContainer ();
  118. break;
  119. case TypeCode.UInt64:
  120. container = new UInt64DataContainer ();
  121. break;
  122. case TypeCode.DateTime:
  123. container = new DateTimeDataContainer ();
  124. break;
  125. case TypeCode.Decimal:
  126. container = new DecimalDataContainer ();
  127. break;
  128. default:
  129. container = new ObjectDataContainer ();
  130. break;
  131. }
  132. container._type = type;
  133. container._column = column;
  134. return container;
  135. }
  136. internal static object GetExplicitValue (object value)
  137. {
  138. Type valueType = value.GetType ();
  139. MethodInfo method = valueType.GetMethod ("op_Explicit", new Type[]{valueType});
  140. if (method != null)
  141. return (method.Invoke (value, new object[]{value}));
  142. return null;
  143. }
  144. internal object GetContainerData (object value)
  145. {
  146. object obj;
  147. TypeCode tc;
  148. if (_type.IsInstanceOfType (value)) {
  149. return value;
  150. } else if ((tc = Type.GetTypeCode (_type)) == TypeCode.String) {
  151. return (Convert.ToString (value));
  152. } else if (value is IConvertible) {
  153. switch (tc) {
  154. case TypeCode.Int16:
  155. return (Convert.ToInt16 (value));
  156. case TypeCode.Int32:
  157. return (Convert.ToInt32 (value));
  158. case TypeCode.Int64:
  159. return (Convert.ToInt64 (value));
  160. case TypeCode.Boolean:
  161. return (Convert.ToBoolean (value));
  162. case TypeCode.Byte:
  163. return (Convert.ToByte (value));
  164. case TypeCode.Char:
  165. return (Convert.ToChar (value));
  166. case TypeCode.Double:
  167. return (Convert.ToDouble (value));
  168. case TypeCode.SByte:
  169. return (Convert.ToSByte (value));
  170. case TypeCode.Single:
  171. return (Convert.ToSingle (value));
  172. case TypeCode.UInt16:
  173. return (Convert.ToUInt16 (value));
  174. case TypeCode.UInt32:
  175. return (Convert.ToUInt32 (value));
  176. case TypeCode.UInt64:
  177. return (Convert.ToUInt64 (value));
  178. case TypeCode.DateTime:
  179. return (Convert.ToDateTime (value));
  180. case TypeCode.Decimal:
  181. return (Convert.ToDecimal (value));
  182. default:
  183. throw new InvalidCastException ();
  184. }
  185. } else if ((obj = GetExplicitValue (value)) != null) {
  186. return (obj);
  187. } else {
  188. throw new InvalidCastException ();
  189. }
  190. }
  191. internal bool IsNull (int index)
  192. {
  193. return null_values == null || null_values [index];
  194. }
  195. internal void FillValues (int fromIndex)
  196. {
  197. for (int i = 0; i < Capacity; i++)
  198. CopyValue (fromIndex, i);
  199. }
  200. internal void CopyValue (int from_index, int to_index)
  201. {
  202. CopyValue (this, from_index, to_index);
  203. }
  204. internal void CopyValue (DataContainer from, int from_index, int to_index)
  205. {
  206. DoCopyValue (from, from_index, to_index);
  207. null_values [to_index] = from.null_values [from_index];
  208. }
  209. internal void SetItemFromDataRecord (int index, IDataRecord record, int field)
  210. {
  211. if (record.IsDBNull (field))
  212. this [index] = DBNull.Value;
  213. else if (record is ISafeDataRecord)
  214. SetValueFromSafeDataRecord (index, (ISafeDataRecord) record, field);
  215. else
  216. this [index] = record.GetValue (field);
  217. }
  218. internal int CompareValues (int index1, int index2)
  219. {
  220. bool null1 = IsNull (index1);
  221. bool null2 = IsNull (index2);
  222. if (null1 == null2)
  223. return null1 ? 0 : DoCompareValues (index1, index2);
  224. return null1 ? -1 : 1;
  225. }
  226. }
  227. sealed class BitDataContainer : DataContainer {
  228. BitArray _values;
  229. protected override object GetValue (int index)
  230. {
  231. return _values [index];
  232. }
  233. protected override void ZeroOut (int index)
  234. {
  235. _values [index] = false;
  236. }
  237. protected override void SetValue (int index, object value)
  238. {
  239. _values [index] = (bool) GetContainerData (value);
  240. }
  241. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  242. {
  243. _values [index] = record.GetBooleanSafe (field);
  244. }
  245. protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
  246. {
  247. _values [to_index] = ((BitDataContainer) from)._values [from_index];
  248. }
  249. protected override int DoCompareValues (int index1, int index2)
  250. {
  251. bool val1 = _values [index1];
  252. bool val2 = _values [index2];
  253. return val1 == val2 ? 0 : val1 ? 1 : -1;
  254. }
  255. protected override void Resize (int size)
  256. {
  257. if (_values == null)
  258. _values = new BitArray (size);
  259. else
  260. _values.Length = size;
  261. }
  262. internal override long GetInt64 (int index)
  263. {
  264. return Convert.ToInt64 (_values [index]);
  265. }
  266. }
  267. sealed class CharDataContainer : DataContainer {
  268. char [] _values;
  269. protected override object GetValue (int index)
  270. {
  271. return _values [index];
  272. }
  273. protected override void ZeroOut (int index)
  274. {
  275. _values [index] = '\0';
  276. }
  277. protected override void SetValue (int index, object value)
  278. {
  279. _values [index] = (char) GetContainerData (value);
  280. }
  281. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  282. {
  283. _values [index] = record.GetCharSafe (field);
  284. }
  285. protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
  286. {
  287. _values [to_index] = ((CharDataContainer) from)._values [from_index];
  288. }
  289. protected override int DoCompareValues (int index1, int index2)
  290. {
  291. char val1 = _values [index1];
  292. char val2 = _values [index2];
  293. return val1 == val2 ? 0 : val1 < val2 ? -1 : 1;
  294. }
  295. protected override void Resize (int size)
  296. {
  297. if (_values == null) {
  298. _values = new char [size];
  299. return;
  300. }
  301. char[] tmp = new char [size];
  302. Array.Copy (_values, 0, tmp, 0, _values.Length);
  303. _values = tmp;
  304. }
  305. internal override long GetInt64 (int index)
  306. {
  307. return Convert.ToInt64 (_values [index]);
  308. }
  309. }
  310. sealed class ByteDataContainer : DataContainer {
  311. byte [] _values;
  312. protected override object GetValue (int index)
  313. {
  314. return _values [index];
  315. }
  316. protected override void ZeroOut (int index)
  317. {
  318. _values [index] = 0;
  319. }
  320. protected override void SetValue (int index, object value)
  321. {
  322. _values [index] = (byte) GetContainerData (value);
  323. }
  324. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  325. {
  326. _values [index] = record.GetByteSafe (field);
  327. }
  328. protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
  329. {
  330. _values [to_index] = ((ByteDataContainer) from)._values [from_index];
  331. }
  332. protected override int DoCompareValues (int index1, int index2)
  333. {
  334. int val1 = _values [index1];
  335. int val2 = _values [index2];
  336. return val1 - val2;
  337. }
  338. protected override void Resize (int size)
  339. {
  340. if (_values == null) {
  341. _values = new byte [size];
  342. return;
  343. }
  344. byte[] tmp = new byte [size];
  345. Array.Copy (_values, 0, tmp, 0, _values.Length);
  346. _values = tmp;
  347. }
  348. internal override long GetInt64 (int index)
  349. {
  350. return _values [index];
  351. }
  352. }
  353. sealed class SByteDataContainer : DataContainer {
  354. sbyte [] _values;
  355. protected override object GetValue (int index)
  356. {
  357. return _values [index];
  358. }
  359. protected override void ZeroOut (int index)
  360. {
  361. _values [index] = 0;
  362. }
  363. protected override void SetValue (int index, object value)
  364. {
  365. _values [index] = (sbyte) GetContainerData (value);
  366. }
  367. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  368. {
  369. _values [index] = (sbyte) record.GetByteSafe (field);
  370. }
  371. protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
  372. {
  373. _values [to_index] = ((SByteDataContainer) from)._values [from_index];
  374. }
  375. protected override int DoCompareValues (int index1, int index2)
  376. {
  377. int val1 = _values [index1];
  378. int val2 = _values [index2];
  379. return val1 - val2;
  380. }
  381. protected override void Resize (int size)
  382. {
  383. if (_values == null) {
  384. _values = new sbyte [size];
  385. return;
  386. }
  387. sbyte[] tmp = new sbyte [size];
  388. Array.Copy (_values, 0, tmp, 0, _values.Length);
  389. _values = tmp;
  390. }
  391. internal override long GetInt64 (int index)
  392. {
  393. return _values [index];
  394. }
  395. }
  396. sealed class Int16DataContainer : DataContainer {
  397. short [] _values;
  398. protected override object GetValue (int index)
  399. {
  400. return _values [index];
  401. }
  402. protected override void ZeroOut (int index)
  403. {
  404. _values [index] = 0;
  405. }
  406. protected override void SetValue (int index, object value)
  407. {
  408. _values [index] = (short) GetContainerData (value);
  409. }
  410. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  411. {
  412. _values [index] = record.GetInt16Safe (field);
  413. }
  414. protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
  415. {
  416. _values [to_index] = ((Int16DataContainer) from)._values [from_index];
  417. }
  418. protected override int DoCompareValues (int index1, int index2)
  419. {
  420. int val1 = _values [index1];
  421. int val2 = _values [index2];
  422. return val1 - val2;
  423. }
  424. protected override void Resize (int size)
  425. {
  426. if (_values == null) {
  427. _values = new short [size];
  428. return;
  429. }
  430. short[] tmp = new short [size];
  431. Array.Copy (_values, 0, tmp, 0, _values.Length);
  432. _values = tmp;
  433. }
  434. internal override long GetInt64 (int index)
  435. {
  436. return _values [index];
  437. }
  438. }
  439. sealed class UInt16DataContainer : DataContainer {
  440. ushort [] _values;
  441. protected override object GetValue (int index)
  442. {
  443. return _values [index];
  444. }
  445. protected override void ZeroOut (int index)
  446. {
  447. _values [index] = 0;
  448. }
  449. protected override void SetValue (int index, object value)
  450. {
  451. _values [index] = (ushort) GetContainerData (value);
  452. }
  453. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  454. {
  455. _values [index] = (ushort) record.GetInt16Safe (field);
  456. }
  457. protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
  458. {
  459. _values [to_index] = ((UInt16DataContainer) from)._values [from_index];
  460. }
  461. protected override int DoCompareValues (int index1, int index2)
  462. {
  463. int val1 = _values [index1];
  464. int val2 = _values [index2];
  465. return val1 - val2;
  466. }
  467. protected override void Resize (int size)
  468. {
  469. if (_values == null) {
  470. _values = new ushort [size];
  471. return;
  472. }
  473. ushort[] tmp = new ushort [size];
  474. Array.Copy (_values, 0, tmp, 0, _values.Length);
  475. _values = tmp;
  476. }
  477. internal override long GetInt64 (int index)
  478. {
  479. return _values [index];
  480. }
  481. }
  482. sealed class Int32DataContainer : DataContainer {
  483. int [] _values;
  484. protected override object GetValue (int index)
  485. {
  486. return _values [index];
  487. }
  488. protected override void ZeroOut (int index)
  489. {
  490. _values [index] = 0;
  491. }
  492. protected override void SetValue (int index, object value)
  493. {
  494. _values [index] = (int) GetContainerData (value);
  495. }
  496. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  497. {
  498. _values [index] = record.GetInt32Safe (field);
  499. }
  500. protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
  501. {
  502. _values [to_index] = ((Int32DataContainer) from)._values [from_index];
  503. }
  504. protected override int DoCompareValues (int index1, int index2)
  505. {
  506. int val1 = _values [index1];
  507. int val2 = _values [index2];
  508. return val1 == val2 ? 0 : val1 < val2 ? -1 : 1;
  509. }
  510. protected override void Resize (int size)
  511. {
  512. if (_values == null) {
  513. _values = new int [size];
  514. return;
  515. }
  516. int[] tmp = new int [size];
  517. Array.Copy (_values, 0, tmp, 0, _values.Length);
  518. _values = tmp;
  519. }
  520. internal override long GetInt64 (int index)
  521. {
  522. return _values [index];
  523. }
  524. }
  525. sealed class UInt32DataContainer : DataContainer {
  526. uint [] _values;
  527. protected override object GetValue (int index)
  528. {
  529. return _values [index];
  530. }
  531. protected override void ZeroOut (int index)
  532. {
  533. _values [index] = 0;
  534. }
  535. protected override void SetValue (int index, object value)
  536. {
  537. _values [index] = (uint) GetContainerData (value);
  538. }
  539. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  540. {
  541. _values [index] = (uint) record.GetInt32Safe (field);
  542. }
  543. protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
  544. {
  545. _values [to_index] = ((UInt32DataContainer) from)._values [from_index];
  546. }
  547. protected override int DoCompareValues (int index1, int index2)
  548. {
  549. uint val1 = _values [index1];
  550. uint val2 = _values [index2];
  551. return val1 == val2 ? 0 : val1 < val2 ? -1 : 1;
  552. }
  553. protected override void Resize (int size)
  554. {
  555. if (_values == null) {
  556. _values = new uint [size];
  557. return;
  558. }
  559. uint[] tmp = new uint [size];
  560. Array.Copy (_values, 0, tmp, 0, _values.Length);
  561. _values = tmp;
  562. }
  563. internal override long GetInt64 (int index)
  564. {
  565. return _values [index];
  566. }
  567. }
  568. sealed class Int64DataContainer : DataContainer {
  569. long [] _values;
  570. protected override object GetValue (int index)
  571. {
  572. return _values [index];
  573. }
  574. protected override void ZeroOut (int index)
  575. {
  576. _values [index] = 0;
  577. }
  578. protected override void SetValue (int index, object value)
  579. {
  580. _values [index] = (long) GetContainerData (value);
  581. }
  582. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  583. {
  584. _values [index] = record.GetInt64Safe (field);
  585. }
  586. protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
  587. {
  588. _values [to_index] = ((Int64DataContainer) from)._values [from_index];
  589. }
  590. protected override int DoCompareValues (int index1, int index2)
  591. {
  592. long val1 = _values [index1];
  593. long val2 = _values [index2];
  594. return val1 == val2 ? 0 : val1 < val2 ? -1 : 1;
  595. }
  596. protected override void Resize (int size)
  597. {
  598. if (_values == null) {
  599. _values = new long [size];
  600. return;
  601. }
  602. long[] tmp = new long [size];
  603. Array.Copy (_values, 0, tmp, 0, _values.Length);
  604. _values = tmp;
  605. }
  606. internal override long GetInt64 (int index)
  607. {
  608. return _values [index];
  609. }
  610. }
  611. sealed class UInt64DataContainer : DataContainer {
  612. ulong [] _values;
  613. protected override object GetValue (int index)
  614. {
  615. return _values [index];
  616. }
  617. protected override void ZeroOut (int index)
  618. {
  619. _values [index] = 0;
  620. }
  621. protected override void SetValue (int index, object value)
  622. {
  623. _values [index] = (ulong) GetContainerData (value);
  624. }
  625. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  626. {
  627. _values [index] = (ulong) record.GetInt64Safe (field);
  628. }
  629. protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
  630. {
  631. _values [to_index] = ((UInt64DataContainer) from)._values [from_index];
  632. }
  633. protected override int DoCompareValues (int index1, int index2)
  634. {
  635. ulong val1 = _values [index1];
  636. ulong val2 = _values [index2];
  637. return val1 == val2 ? 0 : val1 < val2 ? -1 : 1;
  638. }
  639. protected override void Resize (int size)
  640. {
  641. if (_values == null) {
  642. _values = new ulong [size];
  643. return;
  644. }
  645. ulong[] tmp = new ulong [size];
  646. Array.Copy (_values, 0, tmp, 0, _values.Length);
  647. _values = tmp;
  648. }
  649. internal override long GetInt64 (int index)
  650. {
  651. return Convert.ToInt64 (_values [index]);
  652. }
  653. }
  654. sealed class SingleDataContainer : DataContainer {
  655. float [] _values;
  656. protected override object GetValue (int index)
  657. {
  658. return _values [index];
  659. }
  660. protected override void ZeroOut (int index)
  661. {
  662. _values [index] = 0;
  663. }
  664. protected override void SetValue (int index, object value)
  665. {
  666. _values [index] = (float) GetContainerData (value);
  667. }
  668. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  669. {
  670. _values [index] = record.GetFloatSafe (field);
  671. }
  672. protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
  673. {
  674. _values [to_index] = ((SingleDataContainer) from)._values [from_index];
  675. }
  676. protected override int DoCompareValues (int index1, int index2)
  677. {
  678. float val1 = _values [index1];
  679. float val2 = _values [index2];
  680. return val1 == val2 ? 0 : val1 < val2 ? -1 : 1;
  681. }
  682. protected override void Resize (int size)
  683. {
  684. if (_values == null) {
  685. _values = new float [size];
  686. return;
  687. }
  688. float[] tmp = new float [size];
  689. Array.Copy (_values, 0, tmp, 0, _values.Length);
  690. _values = tmp;
  691. }
  692. internal override long GetInt64 (int index)
  693. {
  694. return Convert.ToInt64 (_values [index]);
  695. }
  696. }
  697. sealed class DoubleDataContainer : DataContainer {
  698. double [] _values;
  699. protected override object GetValue (int index)
  700. {
  701. return _values [index];
  702. }
  703. protected override void ZeroOut (int index)
  704. {
  705. _values [index] = 0;
  706. }
  707. protected override void SetValue (int index, object value)
  708. {
  709. _values [index] = (double) GetContainerData (value);
  710. }
  711. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  712. {
  713. _values [index] = record.GetDoubleSafe (field);
  714. }
  715. protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
  716. {
  717. _values [to_index] = ((DoubleDataContainer) from)._values [from_index];
  718. }
  719. protected override int DoCompareValues (int index1, int index2)
  720. {
  721. double val1 = _values [index1];
  722. double val2 = _values [index2];
  723. return val1 == val2 ? 0 : val1 < val2 ? -1 : 1;
  724. }
  725. protected override void Resize (int size)
  726. {
  727. if (_values == null) {
  728. _values = new double [size];
  729. return;
  730. }
  731. double[] tmp = new double [size];
  732. Array.Copy (_values, 0, tmp, 0, _values.Length);
  733. _values = tmp;
  734. }
  735. internal override long GetInt64 (int index)
  736. {
  737. return Convert.ToInt64 (_values[index]);
  738. }
  739. }
  740. class ObjectDataContainer : DataContainer {
  741. object [] _values;
  742. protected override object GetValue (int index)
  743. {
  744. return _values [index];
  745. }
  746. protected override void ZeroOut (int index)
  747. {
  748. _values [index] = null;
  749. }
  750. protected override void SetValue (int index, object value)
  751. {
  752. _values [index] = value;
  753. }
  754. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  755. {
  756. _values [index] = record.GetValue (field);
  757. }
  758. protected override void DoCopyValue (DataContainer from, int from_index, int to_index)
  759. {
  760. _values [to_index] = ((ObjectDataContainer) from)._values [from_index];
  761. }
  762. protected override int DoCompareValues (int index1, int index2)
  763. {
  764. object obj1 = _values [index1];
  765. object obj2 = _values [index2];
  766. if (obj1 == obj2)
  767. return 0;
  768. if (obj1 is IComparable) {
  769. try {
  770. return ((IComparable)obj1).CompareTo (obj2);
  771. } catch {
  772. if (obj2 is IComparable) {
  773. obj2 = Convert.ChangeType (obj2, Type.GetTypeCode (obj1.GetType ()));
  774. return ((IComparable)obj1).CompareTo (obj2);
  775. }
  776. }
  777. }
  778. return String.Compare (obj1.ToString (), obj2.ToString ());
  779. }
  780. protected override void Resize (int size)
  781. {
  782. if (_values == null) {
  783. _values = new object [size];
  784. return;
  785. }
  786. object[] tmp = new object [size];
  787. Array.Copy (_values, 0, tmp, 0, _values.Length);
  788. _values = tmp;
  789. }
  790. internal override long GetInt64 (int index)
  791. {
  792. return Convert.ToInt64 (_values [index]);
  793. }
  794. }
  795. sealed class DateTimeDataContainer : ObjectDataContainer {
  796. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  797. {
  798. base.SetValue (index, record.GetDateTimeSafe (field));
  799. }
  800. protected override void SetValue (int index, object value)
  801. {
  802. base.SetValue (index, GetContainerData (value));
  803. }
  804. }
  805. sealed class DecimalDataContainer : ObjectDataContainer {
  806. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  807. {
  808. base.SetValue (index, record.GetDecimalSafe (field));
  809. }
  810. protected override void SetValue (int index, object value)
  811. {
  812. base.SetValue (index, GetContainerData (value));
  813. }
  814. }
  815. sealed class StringDataContainer : ObjectDataContainer {
  816. private void SetValue (int index, string value)
  817. {
  818. if (value != null && Column.MaxLength >= 0 && Column.MaxLength < value.Length)
  819. throw new ArgumentException ("Cannot set column '" + Column.ColumnName + "' to '" + value + "'. The value violates the MaxLength limit of this column.");
  820. base.SetValue (index, value);
  821. }
  822. protected override void SetValue (int index, object value)
  823. {
  824. SetValue (index, (string) GetContainerData (value));
  825. }
  826. protected override void SetValueFromSafeDataRecord (int index, ISafeDataRecord record, int field)
  827. {
  828. SetValue (index, record.GetStringSafe (field));
  829. }
  830. protected override int DoCompareValues (int index1, int index2)
  831. {
  832. DataTable table = Column.Table;
  833. return String.Compare ((string) this [index1], (string) this [index2], !table.CaseSensitive, table.Locale);
  834. }
  835. }
  836. }