Mark tests as not working under TARGET_JVM
[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 #if NET_2_0
116                 public static SqlBinary Add (SqlBinary x, SqlBinary y)
117                 {
118                         return (x + y);
119                 }
120 #endif
121
122                 public int CompareTo (object value)
123                 {
124                         if (value == null)
125                                 return 1;
126                         if (!(value is SqlBinary))
127                                 throw new ArgumentException (Locale.GetText ("Value is not a System.Data.SqlTypes.SqlBinary"));
128
129                         return CompareTo ((SqlBinary) value);
130                 }
131 #if NET_2_0
132                 public
133 #endif
134                 int CompareTo (SqlBinary value) 
135                 {
136                         if (value.IsNull)
137                                 return 1;
138                         else
139                                 return Compare (this, value);
140                 }
141
142                 public static SqlBinary Concat (SqlBinary x, SqlBinary y) 
143                 {
144                         return (x + y);
145                 }
146
147                 public override bool Equals (object value) 
148                 {
149                         if (!(value is SqlBinary))
150                                 return false;
151                         else if (this.IsNull && ((SqlBinary)value).IsNull)
152                                 return true;
153                         else if (((SqlBinary)value).IsNull)
154                                 return false;
155                         else
156                                 return (bool) (this == (SqlBinary)value);
157                 }
158
159                 public static SqlBoolean Equals(SqlBinary x, SqlBinary y) 
160                 {
161                         return (x == y);
162                 }
163
164                 public override int GetHashCode () 
165                 {
166                         // FIXME: I'm not sure is this a right way
167                         int result = 10;
168                         for (int i = 0; i < value.Length; i++) {
169                                 
170                                 result = 91 * result + (int)value [i];
171                         }
172                         
173                         return result;
174                 }
175
176                 #endregion
177
178                 #region Operators
179
180                 public static SqlBoolean GreaterThan (SqlBinary x, SqlBinary y) 
181                 {
182                         return (x > y);
183                 }
184
185                 public static SqlBoolean GreaterThanOrEqual (SqlBinary x, SqlBinary y) 
186                 {
187                         return (x >= y);
188                 }
189
190                 public static SqlBoolean LessThan (SqlBinary x, SqlBinary y) 
191                 {
192                         return (x < y);
193                 }
194
195                 public static SqlBoolean LessThanOrEqual (SqlBinary x, SqlBinary y) 
196                 {
197                         return (x <= y);
198                 }
199
200                 public static SqlBoolean NotEquals (SqlBinary x, SqlBinary y) 
201                 {
202                         return (x != y);
203                 }
204
205                 public SqlGuid ToSqlGuid () 
206                 {
207                         return (SqlGuid)this;
208                 }
209
210                 public override string ToString () 
211                 {
212                         if (!notNull)
213                                 return "Null";
214                         return "SqlBinary(" + value.Length + ")";
215                 }
216
217                 #endregion
218
219                 #region Operators
220
221                 public static SqlBinary operator + (SqlBinary x, SqlBinary y) 
222                 {
223                         byte [] b = new byte [x.Value.Length + y.Value.Length];
224                         int j = 0;
225                         int i;
226
227                         for (i = 0; i < x.Value.Length; i++) 
228                                 b [i] = x.Value [i];
229                         
230
231                         for (; i < (x.Value.Length + y.Value.Length); i++) {
232                                 b [i] = y.Value [j];
233                                 j++;
234                         }       
235                         
236                         return new SqlBinary (b);
237                 }
238                         
239                 public static SqlBoolean operator == (SqlBinary x, SqlBinary y) 
240                 {
241                         if (x.IsNull || y.IsNull) 
242                                 return SqlBoolean.Null;
243                         else
244                                 return new SqlBoolean (Compare (x, y) == 0);
245                 }
246
247                 public static SqlBoolean operator > (SqlBinary x, SqlBinary y) 
248                 {
249                         if (x.IsNull || y.IsNull) 
250                                 return SqlBoolean.Null;
251
252                         return new SqlBoolean (Compare (x, y) > 0);
253                 }
254
255                 public static SqlBoolean operator >= (SqlBinary x, SqlBinary y) 
256                 {
257                         if (x.IsNull || y.IsNull) 
258                                 return SqlBoolean.Null;
259
260                         return new SqlBoolean (Compare (x, y) >= 0);
261                 }
262
263                 public static SqlBoolean operator != (SqlBinary x, SqlBinary y) 
264                 {
265                         if (x.IsNull || y.IsNull) 
266                                 return SqlBoolean.Null;
267                         else
268                                 return new SqlBoolean (Compare (x, y) != 0);
269                 }
270
271                 public static SqlBoolean operator < (SqlBinary x, SqlBinary y) 
272                 {
273                         if (x.IsNull || y.IsNull) 
274                                 return SqlBoolean.Null;
275
276                         return new SqlBoolean (Compare (x, y) < 0);
277                 }
278
279                 public static SqlBoolean operator <= (SqlBinary x, SqlBinary y) 
280                 {
281                         if (x.IsNull || y.IsNull) 
282                                 return SqlBoolean.Null;
283
284                         return new SqlBoolean (Compare (x, y) <= 0);
285                 }
286
287                 public static explicit operator byte[] (SqlBinary x) 
288                 {
289                         return x.Value;
290                 }
291
292                 public static explicit operator SqlBinary (SqlGuid x) 
293                 {
294                         return new SqlBinary (x.ToByteArray ());
295                 }
296
297                 public static implicit operator SqlBinary (byte[] x) 
298                 {
299                         return new SqlBinary (x);
300                 }
301
302                 #endregion
303
304                 // Helper method to Compare methods and operators.
305                 // Returns 0 if x == y
306                 //         1 if x > y
307                 //        -1 if x < y
308                 private static int Compare(SqlBinary x, SqlBinary y)
309                 {
310                         
311                         int LengthDiff = 0;
312
313                         // If they are different size test are bytes something else than 0
314                         if (x.Value.Length != y.Value.Length) {
315                                 
316                                 LengthDiff = x.Value.Length - y.Value.Length;
317
318                                 // If more than zero, x is longer
319                                 if (LengthDiff > 0) {
320                                         
321                                         for (int i = x.Value.Length - 1; i > x.Value.Length - LengthDiff; i--) {
322                                                 // If byte is more than zero the x is bigger
323                                                 if (x.Value [i] != (byte)0)
324                                                         return 1;
325                                         }
326                                 } else {
327
328                                         for (int i = y.Value.Length - 1; i > y.Value.Length - LengthDiff; i--) {
329                                                 // If byte is more than zero then y is bigger
330                                                 if (y.Value [i] != (byte)0)
331                                                         return -1;
332                                         }
333                                 }                               
334                         }
335
336                         // choose shorter
337                         int lenght = (LengthDiff > 0) ? y.Value.Length : x.Value.Length;
338
339                         for (int i = lenght - 1 ; i > 0; i--) {
340                                 
341                                 byte X = x.Value [i];
342                                 byte Y = y.Value [i];
343                                 
344                                 if (X > Y) 
345                                         return 1;
346                                 else if (X < Y)
347                                         return -1;
348                         }
349
350                         // If we are here, x and y were same size
351                         return 0;
352                 }
353 #if NET_2_0
354                 public static XmlQualifiedName GetXsdType (XmlSchemaSet schemaSet)
355                 {
356                         XmlQualifiedName qualifiedName = new XmlQualifiedName ("base64Binary", "http://www.w3.org/2001/XMLSchema");
357                         return qualifiedName;
358                 }
359                 
360                 [MonoTODO]
361                 XmlSchema IXmlSerializable.GetSchema ()
362                 {
363                         throw new NotImplementedException ();
364                 }
365                 
366                 [MonoTODO]
367                 void IXmlSerializable.ReadXml (XmlReader reader)
368                 {
369                         throw new NotImplementedException ();
370                 }
371                 
372                 [MonoTODO]
373                 void IXmlSerializable.WriteXml (XmlWriter writer) 
374                 {
375                         throw new NotImplementedException ();
376                 }
377 #endif
378         }
379 }