Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Common / internal / materialization / recordstate.cs / 1305376 / recordstate.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
//-----------------------------------------------------------------------------
using System.Collections.Generic;
using System.Data.Metadata.Edm;
using System.Linq;
using System.Linq.Expressions;
namespace System.Data.Common.Internal.Materialization
{
///
/// The RecordState class is responsible for tracking state about a record
/// that should be returned from a data reader.
///
internal class RecordState
{
#region state
///
/// Where to find the static information about this record
///
private readonly RecordStateFactory RecordStateFactory;
///
/// The coordinator factory (essentially, the reader) that we're a part of.
///
internal readonly CoordinatorFactory CoordinatorFactory;
///
/// True when the record is supposed to be null. (Null Structured Types...)
///
private bool _pendingIsNull;
private bool _currentIsNull;
///
/// An EntityRecordInfo, with EntityKey and EntitySet populated; set
/// by the GatherData expression.
///
private EntityRecordInfo _currentEntityRecordInfo;
private EntityRecordInfo _pendingEntityRecordInfo;
///
/// The column values; set by the GatherData expression. Really ought
/// to be in the Shaper.State.
///
internal object[] CurrentColumnValues;
internal object[] PendingColumnValues;
#endregion
#region constructor
internal RecordState(RecordStateFactory recordStateFactory, CoordinatorFactory coordinatorFactory)
{
this.RecordStateFactory = recordStateFactory;
this.CoordinatorFactory = coordinatorFactory;
this.CurrentColumnValues = new object[RecordStateFactory.ColumnCount];
this.PendingColumnValues = new object[RecordStateFactory.ColumnCount];
}
#endregion
#region "public" surface area
///
/// Move the PendingValues to the CurrentValues for this record and all nested
/// records. We keep the pending values separate from the current ones because
/// we may have a nested reader in the middle, and while we're reading forward
/// on the nested reader we we'll blast over the pending values.
///
/// This should be called as part of the data reader's Read() method.
///
internal void AcceptPendingValues()
{
object[] temp = CurrentColumnValues;
CurrentColumnValues = PendingColumnValues;
PendingColumnValues = temp;
_currentEntityRecordInfo = _pendingEntityRecordInfo;
_pendingEntityRecordInfo = null;
_currentIsNull = _pendingIsNull;
//
if (RecordStateFactory.HasNestedColumns)
{
for (int ordinal = 0; ordinal < CurrentColumnValues.Length; ordinal++)
{
if (RecordStateFactory.IsColumnNested[ordinal])
{
RecordState recordState = CurrentColumnValues[ordinal] as RecordState;
if (null != recordState)
{
recordState.AcceptPendingValues();
}
}
}
}
}
///
/// Return the number of columns
///
internal int ColumnCount
{
get { return RecordStateFactory.ColumnCount; }
}
///
/// Return the DataRecordInfo for this record; if we had an EntityRecordInfo
/// set, then return it otherwise return the static one from the factory.
///
internal DataRecordInfo DataRecordInfo
{
get
{
DataRecordInfo result = _currentEntityRecordInfo;
if (null == result)
{
result = RecordStateFactory.DataRecordInfo;
}
return result;
}
}
///
/// Is the record NULL?
///
internal bool IsNull
{
get { return _currentIsNull; }
}
///
/// Implementation of DataReader's GetBytes method
///
internal long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length)
{
byte[] byteValue = (byte[])CurrentColumnValues[ordinal];
int valueLength = byteValue.Length;
int sourceOffset = (int)dataOffset;
int byteCount = valueLength - sourceOffset;
if (null != buffer)
{
byteCount = Math.Min(byteCount, length);
if (0 < byteCount)
{
Buffer.BlockCopy(byteValue, sourceOffset, buffer, bufferOffset, byteCount);
}
}
return Math.Max(0, byteCount);
}
///
/// Implementation of DataReader's GetChars method
///
internal long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length)
{
string stringValue = CurrentColumnValues[ordinal] as string;
char[] charValue;
if (stringValue != null)
{
charValue = stringValue.ToCharArray();
}
else
{
charValue = (char[])CurrentColumnValues[ordinal];
}
int valueLength = charValue.Length;
int sourceOffset = (int)dataOffset;
int charCount = valueLength - sourceOffset;
if (null != buffer)
{
charCount = Math.Min(charCount, length);
if (0 < charCount)
{
Buffer.BlockCopy(charValue, sourceOffset * System.Text.UnicodeEncoding.CharSize,
buffer, bufferOffset * System.Text.UnicodeEncoding.CharSize,
charCount * System.Text.UnicodeEncoding.CharSize);
}
}
return Math.Max(0, charCount);
}
///
/// Return the name of the column at the ordinal specified.
///
internal string GetName(int ordinal)
{
// Some folks are picky about the exception we throw
if (ordinal < 0 || ordinal >= RecordStateFactory.ColumnCount)
{
throw EntityUtil.ArgumentOutOfRange("ordinal");
}
return RecordStateFactory.ColumnNames[ordinal];
}
///
/// This is where the GetOrdinal method for DbDataReader/DbDataRecord end up.
///
internal int GetOrdinal(string name)
{
return RecordStateFactory.FieldNameLookup.GetOrdinal(name);
}
///
/// Return the type of the column at the ordinal specified.
///
internal TypeUsage GetTypeUsage(int ordinal)
{
return RecordStateFactory.TypeUsages[ordinal];
}
///
/// Returns true when the column at the ordinal specified is
/// a record or reader column that requires special handling.
///
internal bool IsNestedObject(int ordinal)
{
return RecordStateFactory.IsColumnNested[ordinal];
}
///
/// Called whenever we hand this record state out as the default state for
/// a data reader; we will have already handled any existing data back to
/// the previous group of records (that is, we couldn't be using it from two
/// distinct readers at the same time).
///
internal void ResetToDefaultState()
{
_currentEntityRecordInfo = null;
}
#endregion
#region called from Shaper's Element Expression
///
/// Called from the Element expression on the Coordinator to gather all
/// the data for the record; we just turn around and call the expression
/// we build on the RecordStateFactory.
///
internal RecordState GatherData(Shaper shaper)
{
RecordStateFactory.GatherData(shaper);
_pendingIsNull = false;
return this;
}
///
/// Called by the GatherData expression to set the data for the
/// specified column value
///
internal bool SetColumnValue(int ordinal, object value)
{
PendingColumnValues[ordinal] = value;
return true;
}
///
/// Called by the GatherData expression to set the data for the
/// EntityRecordInfo
///
internal bool SetEntityRecordInfo(EntityKey entityKey, EntitySet entitySet)
{
_pendingEntityRecordInfo = new EntityRecordInfo(this.RecordStateFactory.DataRecordInfo, entityKey, entitySet);
return true;
}
///
/// Called from the Element expression on the Coordinator to indicate that
/// the record should be NULL.
///
internal RecordState SetNullRecord(Shaper shaper)
{
//
for (int i = 0; i < PendingColumnValues.Length; i++)
{
PendingColumnValues[i] = DBNull.Value;
}
_pendingEntityRecordInfo = null; // the default is already setup correctly on the record state factory
_pendingIsNull = true;
return this;
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DoubleAnimationUsingKeyFrames.cs
- FileLevelControlBuilderAttribute.cs
- WebPartActionVerb.cs
- AppDomainAttributes.cs
- hwndwrapper.cs
- SequenceRangeCollection.cs
- CipherData.cs
- ListControlConvertEventArgs.cs
- ExpressionsCollectionConverter.cs
- ColorMap.cs
- CommandID.cs
- FileRecordSequence.cs
- Rights.cs
- ConnectionOrientedTransportManager.cs
- SqlNodeAnnotations.cs
- DockingAttribute.cs
- DomainUpDown.cs
- InkCanvasAutomationPeer.cs
- ClientFormsAuthenticationCredentials.cs
- BuildDependencySet.cs
- UiaCoreApi.cs
- InvariantComparer.cs
- AvtEvent.cs
- RestHandler.cs
- ObfuscationAttribute.cs
- CqlQuery.cs
- Trace.cs
- UriSection.cs
- ColorConvertedBitmapExtension.cs
- TimeoutException.cs
- DataRelationPropertyDescriptor.cs
- CodeTypeReference.cs
- PerformanceCounterPermissionAttribute.cs
- HtmlInputImage.cs
- DesignTimeTemplateParser.cs
- SmtpDigestAuthenticationModule.cs
- ToolStripContainer.cs
- SimpleApplicationHost.cs
- StrokeNodeEnumerator.cs
- Camera.cs
- HandoffBehavior.cs
- UpdateProgress.cs
- NullableDoubleSumAggregationOperator.cs
- ServiceBusyException.cs
- TableStyle.cs
- TreeNode.cs
- EntityDataSourceContextCreatingEventArgs.cs
- SchemaElementDecl.cs
- RequestUriProcessor.cs
- DeferredReference.cs
- SmtpAuthenticationManager.cs
- Profiler.cs
- SubclassTypeValidatorAttribute.cs
- MailMessageEventArgs.cs
- CodeMethodMap.cs
- TextEditorTables.cs
- ErrorProvider.cs
- FastEncoderWindow.cs
- TemplateField.cs
- WizardPanel.cs
- SerializationInfoEnumerator.cs
- DbgUtil.cs
- OAVariantLib.cs
- SafeHandles.cs
- NamespaceCollection.cs
- PtsPage.cs
- BamlLocalizableResourceKey.cs
- ImagingCache.cs
- HealthMonitoringSectionHelper.cs
- SoapEnvelopeProcessingElement.cs
- RoleGroup.cs
- AssemblyCacheEntry.cs
- AttributeUsageAttribute.cs
- CroppedBitmap.cs
- Vars.cs
- SafeSecurityHelper.cs
- ExceptionDetail.cs
- Base64Encoder.cs
- Calendar.cs
- XmlSchemaComplexType.cs
- AssemblyCache.cs
- EventLogTraceListener.cs
- FrameworkPropertyMetadata.cs
- QueryIntervalOp.cs
- RuntimeArgumentHandle.cs
- FrameworkTemplate.cs
- ADMembershipProvider.cs
- Task.cs
- _BufferOffsetSize.cs
- ToolStripArrowRenderEventArgs.cs
- SkinBuilder.cs
- Expander.cs
- EditorPart.cs
- DispatchWrapper.cs
- EntryPointNotFoundException.cs
- storepermissionattribute.cs
- _TLSstream.cs
- DataBoundLiteralControl.cs
- SafeCryptoHandles.cs
- DataGridViewHeaderCell.cs