Exemplo n.º 1
0
        public static object InflateColumnData(Stream source, TDSDataType column, Object dataTypeSpecific)
        {
            // Dispatch further reading based on the type
            switch (column)
            {
            case TDSDataType.Null:
            {
                // No data associated with it
                return(null);
            }

            case TDSDataType.DateTime:
            {
                int  daypart  = TDSUtilities.ReadInt(source);
                uint timepart = TDSUtilities.ReadUInt(source);
                return(null);
            }

            case TDSDataType.DateTime2N:
            {
                var length  = (byte)source.ReadByte();
                var rawDate = new byte[length];
                source.Read(rawDate, 0, length);
                uint secondIncrements = 0;
                for (int i = 0; i < length - 3; i++)
                {
                    secondIncrements += (uint)(rawDate[i] << (8 * i));
                }
                var days = (uint)rawDate[length - 3] + (uint)(rawDate[length - 2] << 8) +
                           (uint)(rawDate[length - 1] << 16);
                var date = new DateTime(1, 1, 1).AddDays(days).AddSeconds(secondIncrements * Math.Pow(10, -1 * 5));
                return(date);
            }

            case TDSDataType.Bit:
            case TDSDataType.Int1:
            {
                // Bit, 1 byte data representation
                return((byte)source.ReadByte());
            }

            case TDSDataType.Int2:
            {
                // SmallInt, 2 byte data representation
                return(unchecked ((short)TDSUtilities.ReadUShort(source)));
            }

            case TDSDataType.Int4:
            {
                // Int, 4 byte data representation
                return(unchecked ((int)TDSUtilities.ReadUInt(source)));
            }

            case TDSDataType.Float8:
            {
                // Float (8 byte data representation)
                return(BitConverter.ToDouble(BitConverter.GetBytes(TDSUtilities.ReadULong(source)), 0));
            }

            case TDSDataType.Int8:
            {
                // BigInt (8 byte data representation)
                return(unchecked ((long)TDSUtilities.ReadULong(source)));
            }

            case TDSDataType.BitN:
            {
                // Read length
                byte length = (byte)source.ReadByte();

                // Check if null
                if (length == 0)
                {
                    // No data
                    return(null);
                }

                // Bit, 1 byte data representation
                return((byte)source.ReadByte());
            }

            case TDSDataType.IntN:
            {
                // Read length
                byte length = (byte)source.ReadByte();

                // Check integer length
                switch (length)
                {
                case 0:
                {
                    // No data
                    return(null);
                }

                case 1:
                {
                    // Bit data
                    return((byte)source.ReadByte());
                }

                case 2:
                {
                    // Short data
                    return(unchecked ((short)TDSUtilities.ReadUShort(source)));
                }

                case 4:
                {
                    // Integer data
                    return(unchecked ((int)TDSUtilities.ReadUInt(source)));
                }

                case 8:
                {
                    // Integer data
                    return(unchecked ((long)TDSUtilities.ReadULong(source)));
                }

                default:
                {
                    // We don't know how to inflate this integer
                    throw new InvalidDataException(string.Format("Unable to inflate integer of {0} bytes", length));
                }
                }
            }

            case TDSDataType.NumericN:
            {
                // Read length
                byte length = (byte)source.ReadByte();

                // Check if null
                if (length == 0)
                {
                    // No data
                    return(null);
                }

                // Allocate value container
                byte[] guidBytes = new byte[length];

                // Read value
                source.Read(guidBytes, 0, guidBytes.Length);

                // Instantiate type
                return(guidBytes);
            }

            case TDSDataType.Guid:
            {
                // Read the length
                byte length = (byte)source.ReadByte();

                // Check if we have any data
                if (length == 0x0000)
                {
                    // No data
                    return(null);
                }

                // Allocate value container
                byte[] guidBytes = new byte[length];

                // Read value
                source.Read(guidBytes, 0, guidBytes.Length);

                // Convert to type
                return(new Guid(guidBytes));
            }

            case TDSDataType.BigVarChar:
            case TDSDataType.BigChar:
            {
                // Read length
                ushort length = TDSUtilities.ReadUShort(source);

                // Check if we have any data
                if (length == 0xFFFF)
                {
                    // No data
                    return(null);
                }

                // Allocate value container
                byte[] textBytes = new byte[length];

                // Read value
                source.Read(textBytes, 0, textBytes.Length);

                // Convert to type
                return(Encoding.ASCII.GetString(textBytes));
            }

            case TDSDataType.NVarChar:
            {
                // Check if MAX type
                if ((dataTypeSpecific as TDSShilohVarCharColumnSpecific).Length == 0xFFFF)
                {
                    // Read the length of partialy length-prefixed type
                    ulong length = TDSUtilities.ReadULong(source);

                    // Check the value
                    if (length == 0xFFFFFFFFFFFFFFFF)
                    {
                        // There's no data
                        return(null);
                    }
                    else if (length == 0xFFFFFFFFFFFFFFFE)
                    {
                        throw new NotImplementedException("UNKNOWN_PLP_LEN is not implemented yet");
                    }
                    else
                    {
                        // Allocate a memory stream
                        MemoryStream chunks = new MemoryStream();

                        // Size of the last chunk
                        uint chunkLength = 0;

                        // Iterate until we read the whole data
                        do
                        {
                            // Read the length of the chunk
                            chunkLength = TDSUtilities.ReadUInt(source);

                            // Allocate chunk container
                            byte[] chunk = new byte[chunkLength];

                            // Read value
                            source.Read(chunk, 0, chunk.Length);

                            // Append into the stream
                            chunks.Write(chunk, 0, chunk.Length);
                        }while (chunkLength > 0);

                        // Convert to byte array
                        byte[] byteString = chunks.ToArray();

                        // Serialize the data into the string
                        return(Encoding.Unicode.GetString(byteString, 0, byteString.Length));
                    }
                }
                else
                {
                    // Read length
                    ushort length = TDSUtilities.ReadUShort(source);

                    // Check if we have any data
                    if (length == 0xFFFF)
                    {
                        // No data
                        return(null);
                    }

                    // Read the whole string at once
                    return(TDSUtilities.ReadString(source, (ushort)length));
                }
            }

            case TDSDataType.BigVarBinary:
            {
                byte[] bytes = null;

                // Check if MAX type
                if ((ushort)dataTypeSpecific == 0xFFFF)
                {
                    // Read the length of partialy length-prefixed type
                    ulong length = TDSUtilities.ReadULong(source);

                    // Check the value
                    if (length == 0xFFFFFFFFFFFFFFFF)
                    {
                        // There's no data
                        return(null);
                    }
                    else if (length == 0xFFFFFFFFFFFFFFFE)
                    {
                        throw new NotImplementedException("UNKNOWN_PLP_LEN is not implemented yet");
                    }
                    else
                    {
                        // Allocate a memory stream
                        MemoryStream chunks = new MemoryStream();

                        // Size of the last chunk
                        uint chunkLength = 0;

                        // Iterate until we read the whole data
                        do
                        {
                            // Read the length of the chunk
                            chunkLength = TDSUtilities.ReadUInt(source);

                            // Allocate chunk container
                            byte[] chunk = new byte[chunkLength];

                            // Read value
                            source.Read(chunk, 0, chunk.Length);

                            // Append into the stream
                            chunks.Write(chunk, 0, chunk.Length);
                        }while (chunkLength > 0);

                        // Serialize to byte array
                        bytes = chunks.ToArray();
                    }
                }
                else
                {
                    // Read length
                    ushort length = TDSUtilities.ReadUShort(source);

                    // Check if we have any data
                    if (length == 0xFFFF)
                    {
                        // No data
                        return(null);
                    }

                    // Allocate value container
                    bytes = new byte[length];

                    // Read value
                    source.Read(bytes, 0, bytes.Length);
                }

                // Convert to type
                return(bytes);
            }

            case TDSDataType.BigBinary:
            {
                // Read length
                ushort length = TDSUtilities.ReadUShort(source);

                // Check if we have any data
                if (length == 0xFFFF)
                {
                    // No data
                    return(null);
                }

                // Allocate value container
                byte[] bytes = new byte[length];

                // Read value
                source.Read(bytes, 0, bytes.Length);

                // Convert to type
                return(bytes);
            }

            default:
            {
                // We don't know this type
                throw new NotImplementedException(string.Format("Unrecognized data type {0} for inflation", column));
            }
            }
        }
Exemplo n.º 2
0
        public static void DeflateTypeVarByte(Stream destination, TDSDataType column, object data, Object dataTypeSpecific)
        {
            // Dispatch further reading based on the type
            switch (column)
            {
            case TDSDataType.Null:
            {
                // No data associated with it
                break;
            }

            case TDSDataType.DateTime2N:
            {
                DateTime date    = (DateTime)data;
                uint     days    = (uint)(date - new DateTime(1, 1, 1)).TotalDays;
                var      seconds = (int)(date - new DateTime(date.Year, date.Month, date.Day)).TotalSeconds;
                ulong    scaledSeconds;
                switch ((byte)dataTypeSpecific)
                {
                case 1:
                case 2:
                    destination.WriteByte(6);

                    scaledSeconds = (ulong)(seconds * Math.Pow(10, 3));
                    destination.WriteByte((byte)scaledSeconds);
                    destination.WriteByte((byte)(scaledSeconds >> 8));
                    destination.WriteByte((byte)(scaledSeconds >> 16));
                    break;

                case 3:
                case 4:
                    destination.WriteByte(7);
                    scaledSeconds = (ulong)(seconds * Math.Pow(10, 4));
                    destination.WriteByte((byte)scaledSeconds);
                    destination.WriteByte((byte)(scaledSeconds >> 8));
                    destination.WriteByte((byte)(scaledSeconds >> 16));
                    destination.WriteByte((byte)(scaledSeconds >> 24));
                    break;

                case 5:
                case 6:
                case 7:
                    destination.WriteByte(8);
                    scaledSeconds = (ulong)(seconds * Math.Pow(10, 5));
                    destination.WriteByte((byte)scaledSeconds);
                    destination.WriteByte((byte)(scaledSeconds >> 8));
                    destination.WriteByte((byte)(scaledSeconds >> 16));
                    destination.WriteByte((byte)(scaledSeconds >> 24));
                    destination.WriteByte((byte)(scaledSeconds >> 32));
                    break;
                }
                destination.WriteByte((byte)days);
                destination.WriteByte((byte)(days >> 8));
                destination.WriteByte((byte)(days >> 16));
                break;
            }

            case TDSDataType.Bit:
            {
                destination.WriteByte((byte)((bool)data ? 1 : 0));
                break;
            }

            case TDSDataType.Int1:
            {
                // Bit, 1 byte data representation
                destination.WriteByte((byte)data);
                break;
            }

            case TDSDataType.Int2:
            {
                // SmallInt, 2 byte data representation
                TDSUtilities.WriteUShort(destination, unchecked ((ushort)((short)data)));
                break;
            }

            case TDSDataType.Int4:
            {
                // Int, 4 byte data representation
                TDSUtilities.WriteUInt(destination, unchecked ((uint)((int)data)));
                break;
            }

            case TDSDataType.Float8:
            {
                // Float (8 byte data representation)
                byte[] floatBytes = BitConverter.GetBytes((double)data);
                destination.Write(floatBytes, 0, floatBytes.Length);
                break;
            }

            case TDSDataType.Int8:
            {
                // BigInt (8 byte data representation)
                TDSUtilities.WriteULong(destination, unchecked ((ulong)((long)data)));
                break;
            }

            case TDSDataType.BitN:
            {
                // Check if data is available
                if (data == null)
                {
                    // No data
                    destination.WriteByte(0);
                }
                else
                {
                    // One byte data
                    destination.WriteByte(1);

                    // Data
                    destination.WriteByte((byte)((bool)data ? 1 : 0));
                }

                break;
            }

            case TDSDataType.IntN:
            {
                // Check if data is available
                if (data == null)
                {
                    // No data
                    destination.WriteByte(0);
                }
                else if (data is byte)
                {
                    // One-byte data
                    destination.WriteByte(1);

                    // Bit data
                    destination.WriteByte((byte)data);
                }
                else if (data is short)
                {
                    // One-byte data
                    destination.WriteByte(2);

                    // Short data
                    TDSUtilities.WriteUShort(destination, unchecked ((ushort)(short)data));
                }
                else if (data is int)
                {
                    // One-byte data
                    destination.WriteByte(4);

                    // Integer data
                    TDSUtilities.WriteUInt(destination, unchecked ((uint)(int)data));
                }
                else if (data is long)
                {
                    // One-byte data
                    destination.WriteByte(8);

                    // Long data
                    TDSUtilities.WriteULong(destination, unchecked ((ulong)(long)data));
                }
                else
                {
                    // We don't know how to deflate this integer
                    throw new InvalidDataException(string.Format("Unable to deflate integer of type {0}", data.GetType().FullName));
                }

                break;
            }

            case TDSDataType.Guid:
            {
                // Check if data is available
                if (data == null)
                {
                    // No data
                    destination.WriteByte(0);
                }
                else
                {
                    // Get bytes
                    byte[] guidBytes = ((Guid)data).ToByteArray();

                    // One byte data length
                    destination.WriteByte((byte)guidBytes.Length);

                    // Data
                    destination.Write(guidBytes, 0, guidBytes.Length);
                }

                break;
            }

            case TDSDataType.BigChar:
            case TDSDataType.BigVarChar:
            {
                // Check if data is available
                if (data == null)
                {
                    // No data
                    TDSUtilities.WriteUShort(destination, 0xFFFF);
                }
                else
                {
                    // Get bytes
                    byte[] textBytes = Encoding.ASCII.GetBytes((string)data);

                    // One data length
                    TDSUtilities.WriteUShort(destination, (ushort)textBytes.Length);

                    // Data
                    destination.Write(textBytes, 0, textBytes.Length);
                }

                break;
            }

            case TDSDataType.NVarChar:
            {
                // Check if data is available
                if (data == null)
                {
                    // No data
                    TDSUtilities.WriteUShort(destination, 0xFFFF);
                }
                else
                {
                    // Get bytes
                    byte[] textBytes = Encoding.Unicode.GetBytes((string)data);

                    // One data length
                    TDSUtilities.WriteUShort(destination, (ushort)textBytes.Length);

                    // Data
                    destination.Write(textBytes, 0, textBytes.Length);
                }

                break;
            }

            case TDSDataType.BigVarBinary:
            case TDSDataType.BigBinary:
            {
                // Check if data is available
                if (data == null)
                {
                    // No data
                    TDSUtilities.WriteUShort(destination, 0xFFFF);
                }
                else
                {
                    // Get bytes
                    byte[] bytes = (byte[])data;

                    // One data length
                    TDSUtilities.WriteUShort(destination, (ushort)bytes.Length);

                    // Data
                    destination.Write(bytes, 0, bytes.Length);
                }

                break;
            }

            case TDSDataType.Xml:
            {
                // Check if data is available
                if (data == null)
                {
                    // No data
                    TDSUtilities.WriteUShort(destination, 0xFFFF);
                }
                else
                {
                    // Get bytes
                    byte[] bytes = Encoding.UTF8.GetBytes((string)data);

                    // One data length
                    TDSUtilities.WriteUShort(destination, (ushort)bytes.Length);

                    // Data
                    destination.Write(bytes, 0, bytes.Length);
                }

                break;
            }

            default:
            {
                // We don't know this type
                throw new NotImplementedException(string.Format("Unrecognized data type {0} for deflation", column));
            }
            }
        }