[Mono-bugs] [Bug 70228][Nor] Changed - SybaseClient bug on reading Decimal Fields
bugzilla-daemon@bugzilla.ximian.com
bugzilla-daemon@bugzilla.ximian.com
Thu, 13 Jan 2005 21:27:57 -0500 (EST)
Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.
Changed by danielmorgan@verizon.net.
http://bugzilla.ximian.com/show_bug.cgi?id=70228
--- shadow/70228 2005-01-13 20:30:05.000000000 -0500
+++ shadow/70228.tmp.32654 2005-01-13 21:27:57.000000000 -0500
@@ -138,6 +138,85 @@
I ran this on Mono 1.1.3 and Mono 1.0.5. Both on Windows XP Pro SP2.
+
+------- Additional Comments From danielmorgan@verizon.net 2005-01-13 21:27 -------
+The fix above had a negative value when it should have been positive.
+ Also, the fix broke GetDecimalValue for SqlClient.
+
+Based on your fix, here is a fix that works for me on both
+System.Data.SqlClient and Mono.Data.SybaseClient.
+
+If you and Suresh are satisfied with this fix, I will commit it to svn.
+
+ private object GetDecimalValue (byte precision, byte scale)
+ {
+ if (tdsVersion < TdsVersion.tds70)
+ return GetDecimalValueTds50 (precision, scale);
+ else
+ return GetDecimalValueTds70 (precision, scale);
+ }
+
+ private object GetDecimalValueTds70 (byte precision, byte scale)
+ {
+ int[] bits = new int[4] {0,0,0,0};
+
+ int len = (comm.GetByte() & 0xff) - 1;
+ if (len < 0)
+ return DBNull.Value;
+
+ bool positive = (comm.GetByte () == 1);
+
+ if (len > 16)
+ throw new OverflowException ();
+
+ for (int i = 0, index = 0; i < len && i < 16; i += 4, index += 1)
+ bits[index] = comm.GetTdsInt ();
+
+ if (bits [3] != 0)
+ return new TdsBigDecimal (precision, scale, !positive, bits);
+ else
+ return new Decimal (bits[0], bits[1], bits[2], !positive, scale);
+ }
+
+ private object GetDecimalValueTds50 (byte precision, byte scale)
+ {
+ int[] bits = new int[4] {0,0,0,0};
+
+ int len = (comm.GetByte() & 0xff);
+ if (len == 0)
+ return DBNull.Value;
+
+ byte[] dec_bytes=comm.GetBytes(len,false);
+
+ byte[] easy=new byte[4];
+
+ bool positive = dec_bytes[0]==1;
+
+ if (len > 17)
+ throw new OverflowException ();
+
+ for (int i = 1, index = 0; i < len && i < 16; i +=
+ 4, index += 1) {
+ for(int j=0; j<4; j++)
+ if(i+j<len)
+ easy[j]=dec_bytes[len-
+ (i+j)];
+ else
+ easy[j]=0;
+ if(!BitConverter.IsLittleEndian)
+ easy=comm.Swap(easy);
+ bits[index] = BitConverter.ToInt32(easy,0);
+ }
+ if (bits [3] != 0)
+ return new TdsBigDecimal (precision,
+ scale, positive, bits);
+ else
+ return new Decimal(bits[0], bits[1], bits
+ [2], positive, scale);
+
+ }
+
+