//
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