+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
}
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;
}
// 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
#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
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]);