2010-03-26 Veerapuram Varadhan <vvaradhan@novell.com>
[mono.git] / mcs / class / System.Data / System.Data.SqlTypes / SqlBytes.cs
index 5b2fa1b5031464729d2342660bda5615f59a79ba..c98a1b779cb28d78c01cb2b6c827276fab0b34b5 100644 (file)
@@ -38,74 +38,275 @@ using System.IO;
 using System.Xml;
 using System.Xml.Schema;
 using System.Xml.Serialization;
+using System.Runtime.Serialization;
 
 namespace System.Data.SqlTypes
 {
-       [MonoTODO]
-       public sealed class SqlBytes : INullable, IXmlSerializable
+       [SerializableAttribute]
+       [XmlSchemaProvider ("GetXsdType")]
+       public sealed class SqlBytes : INullable, IXmlSerializable, ISerializable
        {
                #region Fields
 
                bool notNull;
+               byte [] buffer;
+               StorageState storage = StorageState.UnmanagedBuffer;
+               Stream stream = null;
 
                #endregion
 
                #region Constructors
 
-               [MonoTODO]
-               public SqlBytes (byte[] buffer)
+               public SqlBytes ()
                {
-                       notNull = true;
+                       buffer = null;
+                       notNull = false;
                }
 
-               [MonoTODO]
-               public SqlBytes (SqlBinary value)
-                       : this (value.Value)
+               public SqlBytes (byte[] buffer)
                {
+                       if (buffer == null) {
+                               notNull = false;
+                               buffer = null;
+                       }
+                       else {
+                               notNull = true;
+                               this.buffer = buffer;
+                               storage = StorageState.Buffer;
+                       }
                }
 
-               [MonoTODO]
-               public SqlBytes (Stream s)
+               public SqlBytes (SqlBinary value)
                {
-                       notNull = true;
+                       if (value.IsNull) {
+                               notNull = false;
+                               buffer = null;
+                       }
+                       else {
+                               notNull = true;
+                               buffer = value.Value;
+                               storage = StorageState.Buffer;
+                       }
                }
 
-               [MonoTODO]
-               public SqlBytes (IntPtr buffer, long length)
+               public SqlBytes (Stream s)
                {
-                       notNull = true;
+                       if (s == null) {
+                               notNull = false;
+                               buffer = null;
+                       } else {
+                               notNull = true;
+                               int len = (int) s.Length;
+                               buffer = new byte [len];
+                               s.Read (buffer, 0, len);
+                               storage = StorageState.Stream;
+                               stream = s;
+                       }
                }
 
                #endregion
 
                #region Properties
 
-                public bool IsNull {
-                        get { return !notNull; }
-                }
+               public byte [] Buffer {
+                       get { return buffer; }
+               }
+
+               public bool IsNull {
+                       get { return !notNull; }
+               }
+
+               public byte this [long offset] {
+                       set {
+                               if (notNull && offset >= 0 && offset < buffer.Length)
+                                       buffer [offset] = value;
+                       }
+                       get {
+                               if (buffer == null)
+                                       throw new SqlNullValueException ("Data is Null");
+                               if (offset < 0 || offset >= buffer.Length)
+                                       throw new ArgumentOutOfRangeException ("Parameter name: offset");
+                               return buffer [offset];
+                       }
+               }
+
+               public long Length {
+                       get {
+                               if (!notNull || buffer == null)
+                                       throw new SqlNullValueException ("Data is Null");
+                               if (buffer.Length < 0)
+                                       return -1;
+                               return buffer.Length;
+                       }
+               }
+
+               public long MaxLength {
+                       get {
+                               if (!notNull || buffer == null || storage == StorageState.Stream)
+                                       return -1;
+                               return buffer.Length;
+                       }
+               }
+
+               public static SqlBytes Null {
+                       get {
+                               return new SqlBytes ();
+                       }
+               }
+
+               public StorageState Storage {
+                       get {
+                               if (storage == StorageState.UnmanagedBuffer)
+                                       throw new SqlNullValueException ("Data is Null");
+                               return storage;
+                       }
+               }
+
+               public Stream Stream {
+                       set {
+                               stream = value;
+                       }
+                       get {
+                               return stream;
+                       }
+               }
+
+               public byte [] Value {
+                       get {
+                               if (buffer == null)
+                                       return buffer;
+                               return (byte []) buffer.Clone ();
+                       }
+               }
 
                #endregion
 
                #region Methods
 
+               public void SetLength (long value)
+               {
+                       if (buffer == null)
+                               throw new SqlTypeException ("There is no buffer. Read or write operation failed.");
+                       if (value < 0 || value > buffer.Length)
+                               throw new ArgumentOutOfRangeException ("Specified argument was out of the range of valid values.");
+                       Array.Resize (ref buffer, (int) value);
+               }
+
+               public void SetNull ()
+               {
+                       buffer = null;
+                       notNull = false;
+               }
+
+               public static explicit operator SqlBytes (SqlBinary value)
+               {
+                       if (value.IsNull)
+                               return Null;
+                       else
+                               return new SqlBytes (value.Value);
+               }
+
+               public static explicit operator SqlBinary (SqlBytes value)
+               {
+                       if (value.IsNull)
+                               return SqlBinary.Null;
+                       else
+                               return new SqlBinary (value.Value);
+               }
+
+               public SqlBinary ToSqlBinary ()
+               {
+                       return new SqlBinary (buffer);
+               }
+
+               public static XmlQualifiedName GetXsdType (XmlSchemaSet schemaSet)
+               {
+                       XmlQualifiedName qualifiedName = new XmlQualifiedName ("base64Binary", "http://www.w3.org/2001/XMLSchema");
+                       return qualifiedName;
+               }
+               
                [MonoTODO]
                XmlSchema IXmlSerializable.GetSchema ()
                {
                        throw new NotImplementedException ();
                }
-                                                                                
+
                [MonoTODO]
-               void IXmlSerializable.ReadXml (XmlReader reader)
+               void IXmlSerializable.ReadXml (XmlReader r)
                {
                        throw new NotImplementedException ();
                }
-                                                                                
+
                [MonoTODO]
                void IXmlSerializable.WriteXml (XmlWriter writer)
                {
                        throw new NotImplementedException ();
                }
 
+               [MonoTODO]
+               void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public long Read (long offset, byte [] buffer, int offsetInBuffer, int count)
+               {
+                       if (buffer == null)
+                               throw new ArgumentNullException ("buffer");
+
+                       if (IsNull)
+                               throw new SqlNullValueException ("There is no buffer. Read or write failed");
+                       
+                       if (count > MaxLength || count > buffer.Length || 
+                           count < 0 || ((offsetInBuffer + count) > buffer.Length))
+                               throw new ArgumentOutOfRangeException ("count");
+                       
+                       if (offset < 0 || offset > MaxLength)
+                               throw new ArgumentOutOfRangeException ("offset");
+                       
+                       if (offsetInBuffer < 0 || offsetInBuffer > buffer.Length)
+                               throw new ArgumentOutOfRangeException ("offsetInBuffer");
+                       
+                       /* Final count of what will be copied */
+                       long actualCount = count;
+                       if (count + offset > Length )
+                               actualCount = Length - offset;
+                       
+                       Array.Copy (this.buffer, offset, buffer, offsetInBuffer, actualCount);
+                       
+                       return actualCount;
+               }
+
+               public void Write (long offset, byte [] buffer, int offsetInBuffer, int count)
+               {
+                       if (buffer == null)
+                               throw new ArgumentNullException ("buffer");
+
+                       if (IsNull)
+                               throw new SqlTypeException ("There is no buffer. Read or write operation failed.");
+                                                       
+                       if (offset < 0) 
+                               throw new ArgumentOutOfRangeException ("offset");
+                       
+                       if (offsetInBuffer < 0 || offsetInBuffer > buffer.Length 
+                           || offsetInBuffer > Length 
+                           || offsetInBuffer + count > Length
+                           || offsetInBuffer + count > buffer.Length)
+                               throw new ArgumentOutOfRangeException ("offsetInBuffer");
+                       
+                       if (count < 0 || count > MaxLength)
+                               throw new ArgumentOutOfRangeException ("count");
+                       
+                       if (offset > MaxLength || offset+count > MaxLength)
+                               throw new SqlTypeException ("The buffer is insufficient. Read or write operation failed.");
+                       
+                       if (count + offset > Length && 
+                           count + offset <= MaxLength)
+                               SetLength (count);
+                       
+                       Array.Copy (buffer, offsetInBuffer, this.buffer, offset, count);
+               }
+
                #endregion
        }
 }