Grasshopper project system now uses csproj extension
[mono.git] / mcs / class / System.Data / System.Data.SqlTypes / SqlBinary.cs
1 //
2 // System.Data.SqlTypes.SqlBinary
3 //
4 // Author:
5 //   Rodrigo Moya (rodrigo@ximian.com)
6 //   Tim Coleman (tim@timcoleman.com)
7 //   Ville Palo (vi64pa@koti.soon.fi)
8 //
9 // (C) Ximian, Inc.
10 // (C) Copyright 2002 Tim Coleman
11 //
12
13 //
14 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
15 //
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
23 // 
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 // 
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 //
35
36 using System;
37 using System.Xml;
38 using System.Xml.Schema;
39 using System.Globalization;
40 using System.Xml.Serialization;
41
42 namespace System.Data.SqlTypes
43 {
44         /// <summary>
45         /// Represents a variable-length stream of binary data to be stored in or retrieved from a database.
46         /// </summary>
47 #if NET_2_0
48         [SerializableAttribute]
49         [XmlSchemaProvider ("GetSchema")]
50 #endif
51         public struct SqlBinary : INullable, IComparable
52 #if NET_2_0
53                                 , IXmlSerializable
54 #endif
55         {
56
57                 #region Fields
58
59                 byte[] value;
60                 private bool notNull;
61
62                 public static readonly SqlBinary Null;
63
64                 #endregion
65
66                 #region Constructors
67                 
68                 public SqlBinary (byte[] value) 
69                 {
70                         this.value = value;
71                         notNull = true;
72                 }
73
74                 #endregion
75
76                 #region Properties
77
78                 public bool IsNull {
79                         get { return !notNull; }
80                 }
81
82                 public byte this[int index] {
83                         get { 
84                                 if (this.IsNull)
85                                         throw new SqlNullValueException ("The property contains Null.");
86                                 else if (index >= this.Length)
87                                         throw new IndexOutOfRangeException ("The index parameter indicates a position beyond the length of the byte array.");
88                                 else
89                                         return value [index]; 
90                         }
91                 }
92
93                 public int Length {
94                         get { 
95                                 if (this.IsNull)
96                                         throw new SqlNullValueException ("The property contains Null.");
97                                 else
98                                         return value.Length;
99                         }
100                 }
101
102                 public byte[] Value 
103                 {
104                         get { 
105                                 if (this.IsNull) 
106                                         throw new SqlNullValueException ("The property contains Null.");
107                                 else 
108                                         return value; 
109                         }
110                 }
111
112                 #endregion
113
114                 #region Methods
115                 public int CompareTo (object value)
116                 {
117                         if (value == null)
118                                 return 1;
119                         if (!(value is SqlBinary))
120                                 throw new ArgumentException (Locale.GetText ("Value is not a System.Data.SqlTypes.SqlBinary"));
121
122                         return CompareTo ((SqlBinary) value);
123                 }
124 #if NET_2_0
125                 public
126 #endif
127                 int CompareTo (SqlBinary value) 
128                 {
129                         if (value.IsNull)
130                                 return 1;
131                         else
132                                 return Compare (this, value);
133                 }
134
135                 public static SqlBinary Concat (SqlBinary x, SqlBinary y) 
136                 {
137                         return (x + y);
138                 }
139
140                 public override bool Equals (object value) 
141                 {
142                         if (!(value is SqlBinary))
143                                 return false;
144                         else if (this.IsNull && ((SqlBinary)value).IsNull)
145                                 return true;
146                         else if (((SqlBinary)value).IsNull)
147                                 return false;
148                         else
149                                 return (bool) (this == (SqlBinary)value);
150                 }
151
152                 public static SqlBoolean Equals(SqlBinary x, SqlBinary y) 
153                 {
154                         return (x == y);
155                 }
156
157                 public override int GetHashCode () 
158                 {
159                         // FIXME: I'm not sure is this a right way
160                         int result = 10;
161                         for (int i = 0; i < value.Length; i++) {
162                                 
163                                 result = 91 * result + (int)value [i];
164                         }
165                         
166                         return result;
167                 }
168
169                 #endregion
170
171                 #region Operators
172
173                 public static SqlBoolean GreaterThan (SqlBinary x, SqlBinary y) 
174                 {
175                         return (x > y);
176                 }
177
178                 public static SqlBoolean GreaterThanOrEqual (SqlBinary x, SqlBinary y) 
179                 {
180                         return (x >= y);
181                 }
182
183                 public static SqlBoolean LessThan (SqlBinary x, SqlBinary y) 
184                 {
185                         return (x < y);
186                 }
187
188                 public static SqlBoolean LessThanOrEqual (SqlBinary x, SqlBinary y) 
189                 {
190                         return (x <= y);
191                 }
192
193                 public static SqlBoolean NotEquals (SqlBinary x, SqlBinary y) 
194                 {
195                         return (x != y);
196                 }
197
198                 public SqlGuid ToSqlGuid () 
199                 {
200                         return (SqlGuid)this;
201                 }
202
203                 public override string ToString () 
204                 {
205                         if (!notNull)
206                                 return "Null";
207                         return "SqlBinary(" + value.Length + ")";
208                 }
209
210                 #endregion
211
212                 #region Operators
213
214                 [MonoTODO]
215                 public static SqlBinary operator + (SqlBinary x, SqlBinary y) 
216                 {
217                         byte [] b = new byte [x.Value.Length + y.Value.Length];
218                         int j = 0;
219                         int i;
220
221                         for (i = 0; i < x.Value.Length; i++) 
222                                 b [i] = x.Value [i];
223                         
224
225                         for (; i < (x.Value.Length + y.Value.Length); i++) {
226                                 b [i] = y.Value [j];
227                                 j++;
228                         }       
229                         
230                         return new SqlBinary (b);
231                 }
232                         
233                 public static SqlBoolean operator == (SqlBinary x, SqlBinary y) 
234                 {
235                         if (x.IsNull || y.IsNull) 
236                                 return SqlBoolean.Null;
237                         else
238                                 return new SqlBoolean (Compare (x, y) == 0);
239                 }
240
241                 public static SqlBoolean operator > (SqlBinary x, SqlBinary y) 
242                 {
243                         if (x.IsNull || y.IsNull) 
244                                 return SqlBoolean.Null;
245
246                         return new SqlBoolean (Compare (x, y) > 0);
247                 }
248
249                 public static SqlBoolean operator >= (SqlBinary x, SqlBinary y) 
250                 {
251                         if (x.IsNull || y.IsNull) 
252                                 return SqlBoolean.Null;
253
254                         return new SqlBoolean (Compare (x, y) >= 0);
255                 }
256
257                 public static SqlBoolean operator != (SqlBinary x, SqlBinary y) 
258                 {
259                         if (x.IsNull || y.IsNull) 
260                                 return SqlBoolean.Null;
261                         else
262                                 return new SqlBoolean (Compare (x, y) != 0);
263                 }
264
265                 public static SqlBoolean operator < (SqlBinary x, SqlBinary y) 
266                 {
267                         if (x.IsNull || y.IsNull) 
268                                 return SqlBoolean.Null;
269
270                         return new SqlBoolean (Compare (x, y) < 0);
271                 }
272
273                 public static SqlBoolean operator <= (SqlBinary x, SqlBinary y) 
274                 {
275                         if (x.IsNull || y.IsNull) 
276                                 return SqlBoolean.Null;
277
278                         return new SqlBoolean (Compare (x, y) <= 0);
279                 }
280
281                 public static explicit operator byte[] (SqlBinary x) 
282                 {
283                         return x.Value;
284                 }
285
286                 public static explicit operator SqlBinary (SqlGuid x) 
287                 {
288                         return new SqlBinary (x.ToByteArray ());
289                 }
290
291                 public static implicit operator SqlBinary (byte[] x) 
292                 {
293                         return new SqlBinary (x);
294                 }
295
296                 #endregion
297
298                 // Helper method to Compare methods and operators.
299                 // Returns 0 if x == y
300                 //         1 if x > y
301                 //        -1 if x < y
302                 private static int Compare(SqlBinary x, SqlBinary y)
303                 {
304                         
305                         int LengthDiff = 0;
306
307                         // If they are different size test are bytes something else than 0
308                         if (x.Value.Length != y.Value.Length) {
309                                 
310                                 LengthDiff = x.Value.Length - y.Value.Length;
311
312                                 // If more than zero, x is longer
313                                 if (LengthDiff > 0) {
314                                         
315                                         for (int i = x.Value.Length - 1; i > x.Value.Length - LengthDiff; i--) {
316                                                 // If byte is more than zero the x is bigger
317                                                 if (x.Value [i] != (byte)0)
318                                                         return 1;
319                                         }
320                                 } else {
321
322                                         for (int i = y.Value.Length - 1; i > y.Value.Length - LengthDiff; i--) {
323                                                 // If byte is more than zero then y is bigger
324                                                 if (y.Value [i] != (byte)0)
325                                                         return -1;
326                                         }
327                                 }                               
328                         }
329
330                         // choose shorter
331                         int lenght = (LengthDiff > 0) ? y.Value.Length : x.Value.Length;
332
333                         for (int i = lenght - 1 ; i > 0; i--) {
334                                 
335                                 byte X = x.Value [i];
336                                 byte Y = y.Value [i];
337                                 
338                                 if (X > Y) 
339                                         return 1;
340                                 else if (X < Y)
341                                         return -1;
342                         }
343
344                         // If we are here, x and y were same size
345                         return 0;
346                 }
347 #if NET_2_0
348                 [MonoTODO]
349                 XmlSchema IXmlSerializable.GetSchema ()
350                 {
351                         throw new NotImplementedException ();
352                 }
353                 
354                 [MonoTODO]
355                 void IXmlSerializable.ReadXml (XmlReader reader)
356                 {
357                         throw new NotImplementedException ();
358                 }
359                 
360                 [MonoTODO]
361                 void IXmlSerializable.WriteXml (XmlWriter writer) 
362                 {
363                         throw new NotImplementedException ();
364                 }
365 #endif
366         }
367 }