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