[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);
+			
+		}
+
+