Add a more functional (i.e. fewer-stubs) implementation of System.Data.Linq.
[mono.git] / mcs / class / System.Data.OracleClient / System.Data.OracleClient.Oci / OciLobLocator.cs
index bb6f92231add16f4548d4b63c93dac2dcf874465..e51c79e360f15497fbc939a9e7f9da802d8f9cdc 100644 (file)
 // 
 
 using System;
+using System.Data.OracleClient;
 using System.Runtime.InteropServices;
 
 namespace System.Data.OracleClient.Oci {
-       internal sealed class OciLobLocator : OciDescriptorHandle, IOciDescriptorHandle, IDisposable
+       internal sealed class OciLobLocator : OciDescriptorHandle, IDisposable
        {
+               #region Fields
+
+               bool disposed = false;
+               OciErrorHandle errorHandle;
+               OciServiceHandle service;
+               OciDataType type;
+
+               #endregion // Fields
+
                #region Constructors
 
-               public OciLobLocator (OciEnvironmentHandle environment, IntPtr handle)
-                       : base (OciDescriptorType.LobLocator, environment, handle)
+               public OciLobLocator (OciHandle parent, IntPtr handle)
+                       : base (OciHandleType.LobLocator, parent, handle)
                {
                }
 
                #endregion // Constructors
 
+               #region Properties 
+
+               public OciErrorHandle ErrorHandle {
+                       get { return errorHandle; }
+                       set { errorHandle = value; }
+               }
+
+               public OciServiceHandle Service {
+                       get { return service; }
+                       set { service = value; }
+               }
+
+               public OciDataType LobType {    
+                       get { return type; }
+                       set { type = value; }
+               }
+               
+               #endregion // Properties
+
                #region Methods
 
-               public void Dispose ()
+               public void BeginBatch (OracleLobOpenMode mode)
+               {
+                       int status = 0;
+                       status = OciCalls.OCILobOpen (Service, 
+                                               ErrorHandle,
+                                               Handle,
+                                               (byte) mode);
+
+                       if (status != 0) {
+                               OciErrorInfo info = ErrorHandle.HandleError ();
+                               throw new OracleException (info.ErrorCode, info.ErrorMessage);
+                       }
+               }
+
+               public uint Copy (OciLobLocator destination, uint amount, uint destinationOffset, uint sourceOffset)
                {
-                       Environment.FreeDescriptor (this);
+                       OciCalls.OCILobCopy (Service,
+                                       ErrorHandle,
+                                       destination,
+                                       Handle,
+                                       amount,
+                                       destinationOffset,
+                                       sourceOffset);
+                       return amount;
+               }
+
+               protected override void Dispose (bool disposing)
+               {
+                       if (!disposed) {
+                               disposed = true;
+                               base.Dispose ();
+                       }
+               }
+
+               public void EndBatch ()
+               {
+                       int status = 0;
+                       status = OciCalls.OCILobClose (Service, ErrorHandle, this);
+
+                       if (status != 0) {
+                               OciErrorInfo info = ErrorHandle.HandleError ();
+                               throw new OracleException (info.ErrorCode, info.ErrorMessage);
+                       }
+               }
+
+               public uint Erase (uint offset, uint amount)
+               {
+                       int status = 0;
+                       uint output = amount;
+                       status = OciCalls.OCILobErase (Service,
+                                               ErrorHandle,
+                                               this,
+                                               ref output,
+                                               (uint) offset);
+
+                       if (status != 0) {
+                               OciErrorInfo info = ErrorHandle.HandleError ();
+                               throw new OracleException (info.ErrorCode, info.ErrorMessage);
+                       }
+
+                       return output;
+               }
+
+               public int GetChunkSize ()
+               {
+                       int status = 0;
+                       uint output;
+                       status = OciCalls.OCILobGetChunkSize (Service,
+                                                       ErrorHandle,
+                                                       this,
+                                                       out output);
+
+                       if (status != 0) {
+                               OciErrorInfo info = ErrorHandle.HandleError ();
+                               throw new OracleException (info.ErrorCode, info.ErrorMessage);
+                       }
+
+                       return (int) output;
+               }
+
+               public long GetLength (bool binary)
+               {
+                       int status = 0;
+                       uint output;
+                       status = OciCalls.OCILobGetLength (Service, 
+                                               ErrorHandle,
+                                               this,
+                                               out output);
+                       if (status != 0) {
+                               OciErrorInfo info = ErrorHandle.HandleError ();
+                               throw new OracleException (info.ErrorCode, info.ErrorMessage);
+                       }
+
+                       if (!binary)
+                               output *= 2;
+
+                       return (long) output;
+               }
+
+               public int Read (byte[] buffer, uint offset, uint count, bool binary)
+               {
+                       int status = 0;
+                       uint amount = count;
+
+                       // Character types are UTF-16, so amount of characters is 1/2
+                       // the amount of bytes
+                       if (!binary) 
+                               amount /= 2;
+
+                       status = OciCalls.OCILobRead (Service,
+                                               ErrorHandle,
+                                               this,
+                                               ref amount,
+                                               offset,
+                                               buffer,
+                                               count,
+                                               IntPtr.Zero,
+                                               IntPtr.Zero,
+                                               1000,  // OCI_UCS2ID
+                                               0);    // Ignored if csid is specified as above
+
+                       if (status != 0) {
+                               OciErrorInfo info = ErrorHandle.HandleError ();
+                               throw new OracleException (info.ErrorCode, info.ErrorMessage);
+                       }
+
+                       return (int) amount;
+               }
+
+               public void Trim (uint newlen)
+               {
+                       int status = 0;
+                       status = OciCalls.OCILobTrim (Service,
+                                               ErrorHandle,
+                                               this,
+                                               newlen);
+
+                       if (status != 0) {
+                               OciErrorInfo info = ErrorHandle.HandleError ();
+                               throw new OracleException (info.ErrorCode, info.ErrorMessage);
+                       }
+
+               }
+
+               public int Write (byte[] buffer, uint offset, uint count, OracleType type)
+               {
+                       int status = 0;
+                       uint amount = count;
+
+                       if (type == OracleType.Clob)
+                               amount /= 2;
+
+                       status = OciCalls.OCILobWrite (Service,
+                                               ErrorHandle,
+                                               this,
+                                               ref amount,
+                                               offset,
+                                               buffer,
+                                               count,
+                                               0,    // OCI_ONE_PIECE
+                                               IntPtr.Zero,
+                                               IntPtr.Zero,
+                                               1000, // OCI_UCS2ID
+                                               0);
+
+                       if (status != 0) {
+                               OciErrorInfo info = ErrorHandle.HandleError ();
+                               throw new OracleException (info.ErrorCode, info.ErrorMessage);
+                       }
+
+                       return (int) amount;
                }
 
                #endregion // Methods