Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Data / System / Data / Sql / sqlnorm.cs / 1 / sqlnorm.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All Rights Reserved. // Information Contained Herein is Proprietary and Confidential. // //[....] //[....] //daltudov //[....] //beysims //[....] //vadimt //[....] //venkar //----------------------------------------------------------------------------- //devnote: perf optimization: consider changing the calls to Array.Reverse to inline unsafe code using System; using System.Collections; using System.Diagnostics; using System.Data; using System.IO; using System.Globalization; using System.Reflection; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Text; namespace Microsoft.SqlServer.Server { // The class that holds the offset, field, and normalizer for // a particular field. internal sealed class FieldInfoEx: IComparable { internal readonly int offset; internal readonly FieldInfo fieldInfo; internal readonly Normalizer normalizer; internal FieldInfoEx(FieldInfo fi, int offset, Normalizer normalizer) { this.fieldInfo = fi; this.offset = offset; Debug.Assert(normalizer!=null, "normalizer argument should not be null!"); this.normalizer = normalizer; } // Sort fields by field offsets. public int CompareTo(object other) { FieldInfoEx otherF = other as FieldInfoEx; if (otherF == null) return -1; return this.offset.CompareTo(otherF.offset); } } // The most complex normalizer, a udt normalizer internal sealed class BinaryOrderedUdtNormalizer: Normalizer { internal readonly FieldInfoEx[] m_fieldsToNormalize; private int m_size; private byte[] m_PadBuffer; internal readonly object NullInstance; //a boolean that tells us if a udt is a "top-level" udt, //i.e. one that does not require a null byte header. private bool m_isTopLevelUdt; [System.Security.Permissions.ReflectionPermission(System.Security.Permissions.SecurityAction.Assert, MemberAccess=true)] private FieldInfo[] GetFields (Type t) { return t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } internal BinaryOrderedUdtNormalizer(Type t, bool isTopLevelUdt) { this.m_skipNormalize = false; if (this.m_skipNormalize) { //if skipping normalization, dont write the null //byte header for IsNull this.m_isTopLevelUdt = true; } //top level udt logic is disabled until we decide //what to do about nested udts this.m_isTopLevelUdt = true; // else // this.m_isTopLevelUdt = isTopLevelUdt; //get all the fields FieldInfo[] fields = GetFields (t); m_fieldsToNormalize = new FieldInfoEx[fields.Length]; int i = 0; foreach (FieldInfo fi in fields) { int offset = Marshal.OffsetOf(fi.DeclaringType, fi.Name).ToInt32(); m_fieldsToNormalize[i++] = new FieldInfoEx(fi, offset, GetNormalizer(fi.FieldType)); } //sort by offset Array.Sort(m_fieldsToNormalize); //if this is not a top-level udt, do setup for null values. //null values need to compare less than all other values, //so prefix a null byte indicator. if (!this.m_isTopLevelUdt) { //get the null value for this type, special case for sql types, which //have a null field if (typeof(System.Data.SqlTypes.INullable).IsAssignableFrom(t)) { PropertyInfo pi = t.GetProperty("Null", BindingFlags.Public | BindingFlags.Static); if (pi == null || pi.PropertyType != t) { FieldInfo fi = t.GetField("Null", BindingFlags.Public | BindingFlags.Static); if (fi == null || fi.FieldType != t) throw new Exception("could not find Null field/property in nullable type " + t); else this.NullInstance = fi.GetValue(null); } else { this.NullInstance = pi.GetValue(null, null); } //create the padding buffer this.m_PadBuffer = new byte[this.Size-1]; } } } internal bool IsNullable { get { return this.NullInstance != null; } } // Normalize the top-level udt internal void NormalizeTopObject(object udt, Stream s) { Normalize(null, udt, s); } // Denormalize a top-level udt and return it internal object DeNormalizeTopObject(Type t, Stream s) { return DeNormalizeInternal(t, s); } private object DeNormalizeInternal(Type t, Stream s) { object result = null; //if nullable and not the top object, read the null marker if (!this.m_isTopLevelUdt && typeof(System.Data.SqlTypes.INullable).IsAssignableFrom(t)) { byte nullByte = (byte) s.ReadByte(); if (nullByte == 0) { result = this.NullInstance; s.Read(m_PadBuffer, 0, m_PadBuffer.Length); return result; } } if (result == null) result = Activator.CreateInstance(t); foreach (FieldInfoEx myField in m_fieldsToNormalize) { myField.normalizer.DeNormalize(myField.fieldInfo, result, s); } return result; } internal override void Normalize(FieldInfo fi, object obj, Stream s) { // if (fi != null) // Console.WriteLine("normalizing " + fi.FieldType + " pos " + s.Position); object inner; if (fi == null) { inner = obj; } else { inner = GetValue(fi, obj); } //If nullable and not the top object, write a null indicator System.Data.SqlTypes.INullable oNullable = inner as System.Data.SqlTypes.INullable; if (oNullable != null && !this.m_isTopLevelUdt) { if (oNullable.IsNull) { s.WriteByte(0); s.Write(m_PadBuffer, 0, m_PadBuffer.Length); return; } else { s.WriteByte(1); } } foreach (FieldInfoEx myField in m_fieldsToNormalize) { myField.normalizer.Normalize(myField.fieldInfo, inner, s); } } internal override void DeNormalize(FieldInfo fi, object recvr, Stream s) { SetValue(fi, recvr, DeNormalizeInternal(fi.FieldType, s)); } internal override int Size { get { if (m_size != 0) return m_size; if (this.IsNullable && !this.m_isTopLevelUdt) m_size = 1; foreach (FieldInfoEx myField in m_fieldsToNormalize) { m_size += myField.normalizer.Size; } return m_size; } } } internal abstract class Normalizer { /* protected internal static string GetString(byte[] array) { StringBuilder sb = new StringBuilder(); //sb.Append("0x"); foreach (byte b in array) { sb.Append(b.ToString("X2", CultureInfo.InvariantCulture)); } return sb.ToString(); } */ protected bool m_skipNormalize; /* internal static bool IsByteOrderedUdt(Type t) { SqlUserDefinedTypeAttribute a = SerializationHelper.GetUdtAttribute(t); return a.IsByteOrdered; } */ internal static Normalizer GetNormalizer(Type t) { Normalizer n = null; if (t.IsPrimitive) { if (t == typeof(byte)) n = new ByteNormalizer(); else if (t == typeof(sbyte)) n = new SByteNormalizer(); else if (t == typeof(bool)) n = new BooleanNormalizer(); else if (t == typeof(short)) n = new ShortNormalizer(); else if (t == typeof(ushort)) n = new UShortNormalizer(); else if (t == typeof(int)) n = new IntNormalizer(); else if (t == typeof(uint)) n = new UIntNormalizer(); else if (t == typeof(float)) n = new FloatNormalizer(); else if (t == typeof(double)) n = new DoubleNormalizer(); else if (t == typeof(long)) n = new LongNormalizer(); else if (t == typeof(ulong)) n = new ULongNormalizer(); } else if (t.IsValueType) { n = new BinaryOrderedUdtNormalizer(t, false); } if (n == null) throw new Exception(Res.GetString(Res.Sql_CanotCreateNormalizer, t.FullName)); n.m_skipNormalize = false; return n; } internal abstract void Normalize(FieldInfo fi, object recvr, Stream s); internal abstract void DeNormalize(FieldInfo fi, object recvr, Stream s); protected void FlipAllBits(byte[] b) { for (int i = 0; i < b.Length; i++) b[i] = (byte) ~b[i]; } [System.Security.Permissions.ReflectionPermission(System.Security.Permissions.SecurityAction.Assert, MemberAccess=true)] protected object GetValue(FieldInfo fi, object obj) { return fi.GetValue(obj); } [System.Security.Permissions.ReflectionPermission(System.Security.Permissions.SecurityAction.Assert, MemberAccess=true)] protected void SetValue(FieldInfo fi, object recvr, object value) { fi.SetValue(recvr, value); } internal abstract int Size { get; } } internal sealed class BooleanNormalizer: Normalizer { internal override void Normalize(FieldInfo fi, object obj, Stream s) { bool b = (bool) GetValue(fi, obj); // Console.WriteLine("normalized " + fi.FieldType + " " + fi.GetValue(obj) // + " to " + (b?"01":"00") + " pos " + s.Position); s.WriteByte((byte)(b?1:0)); } internal override void DeNormalize(FieldInfo fi, object recvr, Stream s) { byte b = (byte) s.ReadByte(); SetValue(fi, recvr, b==1); } internal override int Size { get { return 1; } } } // I could not find a simple way to convert a sbyte to a byte // and vice versa in the framework api. Convert.ToSByte() checks that // the value is in range. // So, we just do the conversion inline. internal sealed class SByteNormalizer: Normalizer { internal override void Normalize(FieldInfo fi, object obj, Stream s) { sbyte sb = (sbyte) GetValue(fi, obj); byte b; unchecked { b = (byte) sb; } if (!this.m_skipNormalize) b ^= 0x80; //flip the sign bit s.WriteByte(b); } internal override void DeNormalize(FieldInfo fi, object recvr, Stream s) { byte b = (byte) s.ReadByte(); if (!this.m_skipNormalize) b ^= 0x80; //flip the sign bit sbyte sb; unchecked { sb = (sbyte) b; } SetValue(fi, recvr, sb); } internal override int Size { get { return 1; } } } internal sealed class ByteNormalizer: Normalizer { internal override void Normalize(FieldInfo fi, object obj, Stream s) { byte b = (byte) GetValue(fi, obj); s.WriteByte(b); } internal override void DeNormalize(FieldInfo fi, object recvr, Stream s) { byte b = (byte) s.ReadByte(); SetValue(fi, recvr, b); } internal override int Size { get { return 1; } } } internal sealed class ShortNormalizer: Normalizer { internal override void Normalize(FieldInfo fi, object obj, Stream s) { byte[] b = BitConverter.GetBytes((short) GetValue(fi, obj)); if (!m_skipNormalize) { Array.Reverse(b); b[0] ^= 0x80; } s.Write(b, 0, b.Length); } internal override void DeNormalize(FieldInfo fi, object recvr, Stream s) { byte[] b = new Byte[2]; s.Read(b, 0, b.Length); if (!m_skipNormalize) { b[0] ^= 0x80; Array.Reverse(b); } SetValue(fi, recvr, BitConverter.ToInt16(b, 0)); } internal override int Size { get { return 2; } } } internal sealed class UShortNormalizer: Normalizer { internal override void Normalize(FieldInfo fi, object obj, Stream s) { byte[] b = BitConverter.GetBytes((ushort) GetValue(fi, obj)); if (!m_skipNormalize) { Array.Reverse(b); } s.Write(b, 0, b.Length); } internal override void DeNormalize(FieldInfo fi, object recvr, Stream s) { byte[] b = new Byte[2]; s.Read(b, 0, b.Length); if (!m_skipNormalize) { Array.Reverse(b); } SetValue(fi, recvr, BitConverter.ToUInt16(b, 0)); } internal override int Size { get { return 2; } } } internal sealed class IntNormalizer: Normalizer { internal override void Normalize(FieldInfo fi, object obj, Stream s) { byte[] b = BitConverter.GetBytes((int) GetValue(fi, obj)); if (!m_skipNormalize) { Array.Reverse(b); b[0] ^= 0x80; } // Console.WriteLine("normalized " + fi.FieldType + " " + fi.GetValue(obj) // + " to " + GetString(b) + " pos " + s.Position); s.Write(b, 0, b.Length); } internal override void DeNormalize(FieldInfo fi, object recvr, Stream s) { byte[] b = new Byte[4]; s.Read(b, 0, b.Length); if (!m_skipNormalize) { b[0] ^= 0x80; Array.Reverse(b); } SetValue(fi, recvr, BitConverter.ToInt32(b, 0)); } internal override int Size { get { return 4; } } } internal sealed class UIntNormalizer: Normalizer { internal override void Normalize(FieldInfo fi, object obj, Stream s) { byte[] b = BitConverter.GetBytes((uint) GetValue(fi, obj)); if (!m_skipNormalize) { Array.Reverse(b); } s.Write(b, 0, b.Length); } internal override void DeNormalize(FieldInfo fi, object recvr, Stream s) { byte[] b = new byte[4]; s.Read(b, 0, b.Length); if (!m_skipNormalize) { Array.Reverse(b); } SetValue(fi, recvr, BitConverter.ToUInt32(b, 0)); } internal override int Size { get { return 4; } } } internal sealed class LongNormalizer: Normalizer { internal override void Normalize(FieldInfo fi, object obj, Stream s) { byte[] b = BitConverter.GetBytes((long) GetValue(fi, obj)); if (!m_skipNormalize) { Array.Reverse(b); b[0] ^= 0x80; } s.Write(b, 0, b.Length); } internal override void DeNormalize(FieldInfo fi, object recvr, Stream s) { byte[] b = new Byte[8]; s.Read(b, 0, b.Length); if (!m_skipNormalize) { b[0] ^= 0x80; Array.Reverse(b); } SetValue(fi, recvr, BitConverter.ToInt64(b, 0)); } internal override int Size { get { return 8; } } } internal sealed class ULongNormalizer: Normalizer { internal override void Normalize(FieldInfo fi, object obj, Stream s) { byte[] b = BitConverter.GetBytes((ulong) GetValue(fi, obj)); if (!m_skipNormalize) { Array.Reverse(b); } // Console.WriteLine("normalized " + fi.FieldType + " " + fi.GetValue(obj) // + " to " + GetString(b)); s.Write(b, 0, b.Length); } internal override void DeNormalize(FieldInfo fi, object recvr, Stream s) { byte[] b = new Byte[8]; s.Read(b, 0, b.Length); if (!m_skipNormalize) { Array.Reverse(b); } SetValue(fi, recvr, BitConverter.ToUInt64(b, 0)); } internal override int Size { get { return 8; } } } internal sealed class FloatNormalizer: Normalizer { internal override void Normalize(FieldInfo fi, object obj, Stream s) { float f = (float) GetValue(fi, obj); byte[] b = BitConverter.GetBytes(f); if (!m_skipNormalize) { Array.Reverse(b); if ((b[0] & 0x80) == 0) { // This is a positive number. // Flip the highest bit b[0] ^= 0x80; } else { // This is a negative number. // If all zeroes, means it was a negative zero. // Treat it same as positive zero, so that // the normalized key will compare equal. if (f < 0) FlipAllBits(b); } } s.Write(b, 0, b.Length); } internal override void DeNormalize(FieldInfo fi, object recvr, Stream s) { byte[] b = new Byte[4]; s.Read(b, 0, b.Length); if (!m_skipNormalize) { if ((b[0] & 0x80) > 0) { // This is a positive number. // Flip the highest bit b[0] ^= 0x80; } else { // This is a negative number. FlipAllBits(b); } Array.Reverse(b); } SetValue(fi, recvr, BitConverter.ToSingle(b, 0)); } internal override int Size { get { return 4; } } } internal sealed class DoubleNormalizer: Normalizer { internal override void Normalize(FieldInfo fi, object obj, Stream s) { double d = (double) GetValue(fi, obj); byte[] b = BitConverter.GetBytes(d); if (!m_skipNormalize) { Array.Reverse(b); if ((b[0] & 0x80) == 0) { // This is a positive number. // Flip the highest bit b[0] ^= 0x80; } else { // This is a negative number. if (d < 0) { // If all zeroes, means it was a negative zero. // Treat it same as positive zero, so that // the normalized key will compare equal. FlipAllBits(b); } } } // Console.WriteLine("normalized " + fi.FieldType + " " + fi.GetValue(obj) // + " to " + GetString(b)); s.Write(b, 0, b.Length); } internal override void DeNormalize(FieldInfo fi, object recvr, Stream s) { byte[] b = new Byte[8]; s.Read(b, 0, b.Length); if (!m_skipNormalize) { if ((b[0] & 0x80) > 0) { // This is a positive number. // Flip the highest bit b[0] ^= 0x80; } else { // This is a negative number. FlipAllBits(b); } Array.Reverse(b); } SetValue(fi, recvr, BitConverter.ToDouble(b, 0)); } internal override int Size { get { return 8; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FilteredDataSetHelper.cs
- MetadataArtifactLoaderResource.cs
- StreamAsIStream.cs
- ToolBarPanel.cs
- WrappedReader.cs
- Signature.cs
- CompositionCommandSet.cs
- BoundField.cs
- ObjectView.cs
- EditingCoordinator.cs
- RepeatButton.cs
- DataServiceExpressionVisitor.cs
- StubHelpers.cs
- AddInController.cs
- SqlReferenceCollection.cs
- UnsafeNativeMethodsTablet.cs
- XmlReflectionMember.cs
- EncodingTable.cs
- Cloud.cs
- LineServices.cs
- ErrorTableItemStyle.cs
- SelectionProcessor.cs
- UserNamePasswordValidator.cs
- ParserOptions.cs
- ConditionalDesigner.cs
- SqlFacetAttribute.cs
- XmlSchemaInfo.cs
- NotFiniteNumberException.cs
- PropertyOverridesDialog.cs
- UnknownBitmapDecoder.cs
- CommandPlan.cs
- XmlSchemaChoice.cs
- RuntimeComponentFilter.cs
- BaseValidator.cs
- Queue.cs
- PropertyPath.cs
- ResourceManagerWrapper.cs
- InstanceDataCollection.cs
- NamedPipeAppDomainProtocolHandler.cs
- XsltContext.cs
- WorkflowMarkupSerializer.cs
- QueryExtender.cs
- WindowsServiceElement.cs
- BulletDecorator.cs
- ManagementObjectCollection.cs
- PropertyConverter.cs
- DataGridViewRowEventArgs.cs
- ForeignConstraint.cs
- HostingEnvironmentSection.cs
- FunctionImportMapping.cs
- NamedPermissionSet.cs
- ImageList.cs
- PageParser.cs
- ToolStripProgressBar.cs
- SingleObjectCollection.cs
- SoapFault.cs
- HijriCalendar.cs
- SchemaInfo.cs
- MailBnfHelper.cs
- ProcessHostServerConfig.cs
- PackageRelationship.cs
- SessionEndedEventArgs.cs
- FixUp.cs
- HtmlAnchor.cs
- PrintDialog.cs
- Mutex.cs
- XmlNamespaceManager.cs
- PersonalizationEntry.cs
- UIPropertyMetadata.cs
- CompoundFileReference.cs
- WebEncodingValidatorAttribute.cs
- DataGridViewColumnDividerDoubleClickEventArgs.cs
- DataFormats.cs
- XsltOutput.cs
- FormatControl.cs
- infer.cs
- PartManifestEntry.cs
- FrameworkElementFactory.cs
- SubstitutionList.cs
- TraceListener.cs
- NameSpaceEvent.cs
- PrintPreviewDialog.cs
- CacheDependency.cs
- RectangleGeometry.cs
- RegexRunnerFactory.cs
- PlanCompilerUtil.cs
- ArrayConverter.cs
- UserControl.cs
- Brush.cs
- ArglessEventHandlerProxy.cs
- TreeNodeEventArgs.cs
- UpDownEvent.cs
- MarkupCompiler.cs
- Terminate.cs
- ScriptControlDescriptor.cs
- BitmapEffectGroup.cs
- SectionInput.cs
- DataKeyCollection.cs
- ObjectSet.cs
- ProgressBarAutomationPeer.cs