2010-03-26 Veerapuram Varadhan <vvaradhan@novell.com>
[mono.git] / mcs / class / System.Data / System.Data.SqlTypes / SqlBytes.cs
1 //
2 // System.Data.SqlTypes.SqlBytes
3 //
4 // Author:
5 //   Tim Coleman <tim@timcoleman.com>
6 //
7 // Copyright (C) Tim Coleman, 2003
8 //
9
10 //
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 #if NET_2_0
34
35 using System;
36 using System.Globalization;
37 using System.IO;
38 using System.Xml;
39 using System.Xml.Schema;
40 using System.Xml.Serialization;
41 using System.Runtime.Serialization;
42
43 namespace System.Data.SqlTypes
44 {
45         [SerializableAttribute]
46         [XmlSchemaProvider ("GetXsdType")]
47         public sealed class SqlBytes : INullable, IXmlSerializable, ISerializable
48         {
49                 #region Fields
50
51                 bool notNull;
52                 byte [] buffer;
53                 StorageState storage = StorageState.UnmanagedBuffer;
54                 Stream stream = null;
55
56                 #endregion
57
58                 #region Constructors
59
60                 public SqlBytes ()
61                 {
62                         buffer = null;
63                         notNull = false;
64                 }
65
66                 public SqlBytes (byte[] buffer)
67                 {
68                         if (buffer == null) {
69                                 notNull = false;
70                                 buffer = null;
71                         }
72                         else {
73                                 notNull = true;
74                                 this.buffer = buffer;
75                                 storage = StorageState.Buffer;
76                         }
77                 }
78
79                 public SqlBytes (SqlBinary value)
80                 {
81                         if (value.IsNull) {
82                                 notNull = false;
83                                 buffer = null;
84                         }
85                         else {
86                                 notNull = true;
87                                 buffer = value.Value;
88                                 storage = StorageState.Buffer;
89                         }
90                 }
91
92                 public SqlBytes (Stream s)
93                 {
94                         if (s == null) {
95                                 notNull = false;
96                                 buffer = null;
97                         } else {
98                                 notNull = true;
99                                 int len = (int) s.Length;
100                                 buffer = new byte [len];
101                                 s.Read (buffer, 0, len);
102                                 storage = StorageState.Stream;
103                                 stream = s;
104                         }
105                 }
106
107                 #endregion
108
109                 #region Properties
110
111                 public byte [] Buffer {
112                         get { return buffer; }
113                 }
114
115                 public bool IsNull {
116                         get { return !notNull; }
117                 }
118
119                 public byte this [long offset] {
120                         set {
121                                 if (notNull && offset >= 0 && offset < buffer.Length)
122                                         buffer [offset] = value;
123                         }
124                         get {
125                                 if (buffer == null)
126                                         throw new SqlNullValueException ("Data is Null");
127                                 if (offset < 0 || offset >= buffer.Length)
128                                         throw new ArgumentOutOfRangeException ("Parameter name: offset");
129                                 return buffer [offset];
130                         }
131                 }
132
133                 public long Length {
134                         get {
135                                 if (!notNull || buffer == null)
136                                         throw new SqlNullValueException ("Data is Null");
137                                 if (buffer.Length < 0)
138                                         return -1;
139                                 return buffer.Length;
140                         }
141                 }
142
143                 public long MaxLength {
144                         get {
145                                 if (!notNull || buffer == null || storage == StorageState.Stream)
146                                         return -1;
147                                 return buffer.Length;
148                         }
149                 }
150
151                 public static SqlBytes Null {
152                         get {
153                                 return new SqlBytes ();
154                         }
155                 }
156
157                 public StorageState Storage {
158                         get {
159                                 if (storage == StorageState.UnmanagedBuffer)
160                                         throw new SqlNullValueException ("Data is Null");
161                                 return storage;
162                         }
163                 }
164
165                 public Stream Stream {
166                         set {
167                                 stream = value;
168                         }
169                         get {
170                                 return stream;
171                         }
172                 }
173
174                 public byte [] Value {
175                         get {
176                                 if (buffer == null)
177                                         return buffer;
178                                 return (byte []) buffer.Clone ();
179                         }
180                 }
181
182                 #endregion
183
184                 #region Methods
185
186                 public void SetLength (long value)
187                 {
188                         if (buffer == null)
189                                 throw new SqlTypeException ("There is no buffer. Read or write operation failed.");
190                         if (value < 0 || value > buffer.Length)
191                                 throw new ArgumentOutOfRangeException ("Specified argument was out of the range of valid values.");
192                         Array.Resize (ref buffer, (int) value);
193                 }
194
195                 public void SetNull ()
196                 {
197                         buffer = null;
198                         notNull = false;
199                 }
200
201                 public static explicit operator SqlBytes (SqlBinary value)
202                 {
203                         if (value.IsNull)
204                                 return Null;
205                         else
206                                 return new SqlBytes (value.Value);
207                 }
208
209                 public static explicit operator SqlBinary (SqlBytes value)
210                 {
211                         if (value.IsNull)
212                                 return SqlBinary.Null;
213                         else
214                                 return new SqlBinary (value.Value);
215                 }
216
217                 public SqlBinary ToSqlBinary ()
218                 {
219                         return new SqlBinary (buffer);
220                 }
221
222                 public static XmlQualifiedName GetXsdType (XmlSchemaSet schemaSet)
223                 {
224                         XmlQualifiedName qualifiedName = new XmlQualifiedName ("base64Binary", "http://www.w3.org/2001/XMLSchema");
225                         return qualifiedName;
226                 }
227                 
228                 [MonoTODO]
229                 XmlSchema IXmlSerializable.GetSchema ()
230                 {
231                         throw new NotImplementedException ();
232                 }
233
234                 [MonoTODO]
235                 void IXmlSerializable.ReadXml (XmlReader r)
236                 {
237                         throw new NotImplementedException ();
238                 }
239
240                 [MonoTODO]
241                 void IXmlSerializable.WriteXml (XmlWriter writer)
242                 {
243                         throw new NotImplementedException ();
244                 }
245
246                 [MonoTODO]
247                 void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
248                 {
249                         throw new NotImplementedException ();
250                 }
251
252                 public long Read (long offset, byte [] buffer, int offsetInBuffer, int count)
253                 {
254                         if (buffer == null)
255                                 throw new ArgumentNullException ("buffer");
256
257                         if (IsNull)
258                                 throw new SqlNullValueException ("There is no buffer. Read or write failed");
259                         
260                         if (count > MaxLength || count > buffer.Length || 
261                             count < 0 || ((offsetInBuffer + count) > buffer.Length))
262                                 throw new ArgumentOutOfRangeException ("count");
263                         
264                         if (offset < 0 || offset > MaxLength)
265                                 throw new ArgumentOutOfRangeException ("offset");
266                         
267                         if (offsetInBuffer < 0 || offsetInBuffer > buffer.Length)
268                                 throw new ArgumentOutOfRangeException ("offsetInBuffer");
269                         
270                         /* Final count of what will be copied */
271                         long actualCount = count;
272                         if (count + offset > Length )
273                                 actualCount = Length - offset;
274                         
275                         Array.Copy (this.buffer, offset, buffer, offsetInBuffer, actualCount);
276                         
277                         return actualCount;
278                 }
279
280                 public void Write (long offset, byte [] buffer, int offsetInBuffer, int count)
281                 {
282                         if (buffer == null)
283                                 throw new ArgumentNullException ("buffer");
284
285                         if (IsNull)
286                                 throw new SqlTypeException ("There is no buffer. Read or write operation failed.");
287                                                         
288                         if (offset < 0) 
289                                 throw new ArgumentOutOfRangeException ("offset");
290                         
291                         if (offsetInBuffer < 0 || offsetInBuffer > buffer.Length 
292                             || offsetInBuffer > Length 
293                             || offsetInBuffer + count > Length
294                             || offsetInBuffer + count > buffer.Length)
295                                 throw new ArgumentOutOfRangeException ("offsetInBuffer");
296                         
297                         if (count < 0 || count > MaxLength)
298                                 throw new ArgumentOutOfRangeException ("count");
299                         
300                         if (offset > MaxLength || offset+count > MaxLength)
301                                 throw new SqlTypeException ("The buffer is insufficient. Read or write operation failed.");
302                         
303                         if (count + offset > Length && 
304                             count + offset <= MaxLength)
305                                 SetLength (count);
306                         
307                         Array.Copy (buffer, offsetInBuffer, this.buffer, offset, count);
308                 }
309
310                 #endregion
311         }
312 }
313
314 #endif