* Tds70.cs: Support writing negative (small)money values. Added
authorGert Driesen <drieseng@users.sourceforge.net>
Tue, 11 Nov 2008 18:18:53 +0000 (18:18 -0000)
committerGert Driesen <drieseng@users.sourceforge.net>
Tue, 11 Nov 2008 18:18:53 +0000 (18:18 -0000)
overflow check for smallmoney values. Fixes bug #428139.
* Tds.cs: Fixed reading negative (small)money values.

svn path=/trunk/mcs/; revision=118527

mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs
mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs

index e8002364c63594806f10c726d6569b78b055b3bf..390c46768e976b1b4b333eecf45106308b154669 100644 (file)
@@ -1,3 +1,9 @@
+2008-11-11  Gert Driesen  <drieseng@users.sourceforge.net>
+
+       * Tds70.cs: Support writing negative (small)money values. Added 
+       overflow check for smallmoney values. Fixes bug #428139.
+       * Tds.cs: Fixed reading negative (small)money values.
+
 2008-11-09  Gert Driesen  <drieseng@users.sourceforge.net>
 
        * TdsConnectionPool.cs: Added TdsConnectionPoolManager.GetConnection
index bb6310642369df37b4b2c7f5e764b1d37d183198..230ae122608232eb3e0abfd8faa57775897704bf 100644 (file)
@@ -1139,12 +1139,23 @@ namespace Mono.Data.Tds.Protocol
                        }
 
                        switch (len) {
-                       case 4:
-                               return new Decimal (Comm.GetTdsInt (), 0, 0, false, 4);
+                       case 4: {
+                               int val = Comm.GetTdsInt ();
+                               bool negative = val < 0;
+                               if (negative)
+                                       val = ~(val - 1);
+                               return new Decimal (val, 0, 0, negative, 4);
+                       }
                        case 8:
                                int hi = Comm.GetTdsInt ();
                                int lo = Comm.GetTdsInt ();
-                               return new Decimal (lo, hi, 0, false, 4);
+                               bool negative = hi < 0;
+
+                               if (negative) {
+                                       hi = ~hi;
+                                       lo = ~(lo - 1);
+                               }
+                               return new Decimal (lo, hi, 0, negative, 4);
                        default:
                                return DBNull.Value;
                        }
index fc47aa87cfdf16d969011b9772356002c328b8fd..5919f2fb3bada358af10b130955cc0322cbd4436 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using Mono.Security.Protocol.Ntlm;
 using System;
+using System.Globalization;
 using System.Text;
 
+using Mono.Security.Protocol.Ntlm;
+
 namespace Mono.Data.Tds.Protocol
 {
        public sealed class Tds70 : Tds
@@ -44,6 +46,8 @@ namespace Mono.Data.Tds.Protocol
                #region Fields
 
                public readonly static TdsVersion Version = TdsVersion.tds70;
+               static readonly decimal SMALLMONEY_MIN = -214748.3648m;
+               static readonly decimal SMALLMONEY_MAX = 214748.3647m;
 
                #endregion // Fields
 
@@ -463,13 +467,30 @@ namespace Mono.Data.Tds.Protocol
                                case "money" : {
                                        Decimal val = (decimal) param.Value;
                                        int[] arr = Decimal.GetBits (val);
-                                       int sign = (val>0 ? 1: -1);
-                                       Comm.Append (sign * arr[1]);
-                                       Comm.Append (sign * arr[0]);
+
+                                       if (val >= 0) {
+                                               Comm.Append (arr[1]);
+                                               Comm.Append (arr[0]);
+                                       } else {
+                                               Comm.Append (~arr[1]);
+                                               Comm.Append (~arr[0] + 1);
+                                       }
                                        break;
                                }
                                case "smallmoney": {
                                        Decimal val = (decimal) param.Value;
+                                       if (val < SMALLMONEY_MIN || val > SMALLMONEY_MAX)
+                                               throw new OverflowException (string.Format (
+                                                       CultureInfo.InvariantCulture,
+                                                       "Value '{0}' is not valid for SmallMoney."
+                                                       + "  Must be between {1:N4} and {2:N4}.",
+#if NET_2_0
+                                                       val,
+#else
+                                                       val.ToString (CultureInfo.CurrentCulture),
+#endif
+                                                       SMALLMONEY_MIN, SMALLMONEY_MAX));
+
                                        int[] arr = Decimal.GetBits (val);
                                        int sign = (val>0 ? 1: -1);
                                        Comm.Append (sign * arr[0]);