OciLobLocator.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. //
  2. // OciLobLocator.cs
  3. //
  4. // Part of managed C#/.NET library System.Data.OracleClient.dll
  5. //
  6. // Part of the Mono class libraries at
  7. // mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci
  8. //
  9. // Assembly: System.Data.OracleClient.dll
  10. // Namespace: System.Data.OracleClient.Oci
  11. //
  12. // Author:
  13. // Tim Coleman <[email protected]>
  14. //
  15. // Copyright (C) Tim Coleman, 2003
  16. //
  17. using System;
  18. using System.Data.OracleClient;
  19. using System.Runtime.InteropServices;
  20. namespace System.Data.OracleClient.Oci {
  21. internal sealed class OciLobLocator : OciDescriptorHandle, IDisposable
  22. {
  23. #region Fields
  24. bool disposed = false;
  25. OciErrorHandle errorHandle;
  26. OciServiceHandle service;
  27. OciDataType type;
  28. #endregion // Fields
  29. #region Constructors
  30. public OciLobLocator (OciHandle parent, IntPtr handle)
  31. : base (OciHandleType.LobLocator, parent, handle)
  32. {
  33. }
  34. #endregion // Constructors
  35. #region Properties
  36. public OciErrorHandle ErrorHandle {
  37. get { return errorHandle; }
  38. set { errorHandle = value; }
  39. }
  40. public OciServiceHandle Service {
  41. get { return service; }
  42. set { service = value; }
  43. }
  44. public OciDataType LobType {
  45. get { return type; }
  46. set { type = value; }
  47. }
  48. #endregion // Properties
  49. #region Methods
  50. [DllImport ("oci")]
  51. static extern int OCILobClose (IntPtr svchp,
  52. IntPtr errhp,
  53. IntPtr locp);
  54. [DllImport ("oci")]
  55. static extern int OCILobCopy (IntPtr svchp,
  56. IntPtr errhp,
  57. IntPtr dst_locp,
  58. IntPtr src_locp,
  59. uint amount,
  60. uint dst_offset,
  61. uint src_offset);
  62. [DllImport ("oci")]
  63. static extern int OCILobErase (IntPtr svchp,
  64. IntPtr errhp,
  65. IntPtr locp,
  66. ref uint amount,
  67. uint offset);
  68. [DllImport ("oci")]
  69. static extern int OCILobGetChunkSize (IntPtr svchp,
  70. IntPtr errhp,
  71. IntPtr locp,
  72. out uint chunk_size);
  73. [DllImport ("oci")]
  74. static extern int OCILobGetLength (IntPtr svchp,
  75. IntPtr errhp,
  76. IntPtr locp,
  77. out uint lenp);
  78. [DllImport ("oci")]
  79. static extern int OCILobOpen (IntPtr svchp,
  80. IntPtr errhp,
  81. IntPtr locp,
  82. byte mode);
  83. [DllImport ("oci")]
  84. static extern int OCILobRead (IntPtr svchp,
  85. IntPtr errhp,
  86. IntPtr locp,
  87. ref uint amtp,
  88. uint offset,
  89. byte[] bufp,
  90. uint bufl,
  91. IntPtr ctxp,
  92. IntPtr cbfp,
  93. ushort csid,
  94. byte csfrm);
  95. [DllImport ("oci")]
  96. static extern int OCILobTrim (IntPtr svchp,
  97. IntPtr errhp,
  98. IntPtr locp,
  99. uint newlen);
  100. [DllImport ("oci")]
  101. static extern int OCILobWrite (IntPtr svchp,
  102. IntPtr errhp,
  103. IntPtr locp,
  104. ref uint amtp,
  105. uint offset,
  106. byte[] bufp,
  107. uint bufl,
  108. byte piece,
  109. IntPtr ctxp,
  110. IntPtr cbfp,
  111. ushort csid,
  112. byte csfrm);
  113. public void BeginBatch (OracleLobOpenMode mode)
  114. {
  115. int status = 0;
  116. status = OCILobOpen (Service,
  117. ErrorHandle,
  118. Handle,
  119. (byte) mode);
  120. if (status != 0) {
  121. OciErrorInfo info = ErrorHandle.HandleError ();
  122. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  123. }
  124. }
  125. public uint Copy (OciLobLocator destination, uint amount, uint destinationOffset, uint sourceOffset)
  126. {
  127. OCILobCopy (Service,
  128. ErrorHandle,
  129. destination,
  130. Handle,
  131. amount,
  132. destinationOffset,
  133. sourceOffset);
  134. return amount;
  135. }
  136. protected override void Dispose (bool disposing)
  137. {
  138. if (!disposed) {
  139. disposed = true;
  140. base.Dispose ();
  141. }
  142. }
  143. public void EndBatch ()
  144. {
  145. int status = 0;
  146. status = OCILobClose (Service, ErrorHandle, this);
  147. if (status != 0) {
  148. OciErrorInfo info = ErrorHandle.HandleError ();
  149. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  150. }
  151. }
  152. public uint Erase (uint offset, uint amount)
  153. {
  154. int status = 0;
  155. uint output = amount;
  156. status = OCILobErase (Service,
  157. ErrorHandle,
  158. this,
  159. ref output,
  160. (uint) offset);
  161. if (status != 0) {
  162. OciErrorInfo info = ErrorHandle.HandleError ();
  163. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  164. }
  165. return output;
  166. }
  167. public int GetChunkSize ()
  168. {
  169. int status = 0;
  170. uint output;
  171. status = OCILobGetChunkSize (Service,
  172. ErrorHandle,
  173. this,
  174. out output);
  175. if (status != 0) {
  176. OciErrorInfo info = ErrorHandle.HandleError ();
  177. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  178. }
  179. return (int) output;
  180. }
  181. public long GetLength (bool binary)
  182. {
  183. int status = 0;
  184. uint output;
  185. status = OCILobGetLength (Service,
  186. ErrorHandle,
  187. this,
  188. out output);
  189. if (status != 0) {
  190. OciErrorInfo info = ErrorHandle.HandleError ();
  191. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  192. }
  193. if (!binary)
  194. output *= 2;
  195. return (long) output;
  196. }
  197. public int Read (byte[] buffer, uint offset, uint count, bool binary)
  198. {
  199. int status = 0;
  200. uint amount = count;
  201. // Character types are UTF-16, so amount of characters is 1/2
  202. // the amount of bytes
  203. if (!binary)
  204. amount /= 2;
  205. status = OCILobRead (Service,
  206. ErrorHandle,
  207. this,
  208. ref amount,
  209. offset,
  210. buffer,
  211. count,
  212. IntPtr.Zero,
  213. IntPtr.Zero,
  214. 1000, // OCI_UCS2ID
  215. 0); // Ignored if csid is specified as above
  216. if (status != 0) {
  217. OciErrorInfo info = ErrorHandle.HandleError ();
  218. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  219. }
  220. return (int) amount;
  221. }
  222. public void Trim (uint newlen)
  223. {
  224. int status = 0;
  225. status = OCILobTrim (Service,
  226. ErrorHandle,
  227. this,
  228. newlen);
  229. if (status != 0) {
  230. OciErrorInfo info = ErrorHandle.HandleError ();
  231. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  232. }
  233. }
  234. public int Write (byte[] buffer, uint offset, uint count, OracleType type)
  235. {
  236. int status = 0;
  237. uint amount = count;
  238. if (type == OracleType.Clob)
  239. amount /= 2;
  240. status = OCILobWrite (Service,
  241. ErrorHandle,
  242. this,
  243. ref amount,
  244. offset,
  245. buffer,
  246. count,
  247. 0, // OCI_ONE_PIECE
  248. IntPtr.Zero,
  249. IntPtr.Zero,
  250. 1000, // OCI_UCS2ID
  251. 0);
  252. if (status != 0) {
  253. OciErrorInfo info = ErrorHandle.HandleError ();
  254. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  255. }
  256. return (int) amount;
  257. }
  258. #endregion // Methods
  259. }
  260. }