Imported Upstream version 4.3.2.467

Former-commit-id: 9c2cb47f45fa221e661ab616387c9cda183f283d
This commit is contained in:
Xamarin Public Jenkins
2016-02-22 11:00:01 -05:00
parent f302175246
commit f3e3aab35a
4097 changed files with 122406 additions and 82300 deletions

View File

@@ -18,6 +18,7 @@ namespace System.Security.Claims
{
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
@@ -36,6 +37,9 @@ namespace System.Security.Claims
string m_value;
string m_valueType;
[NonSerialized]
byte[] m_userSerializationData;
Dictionary<string, string> m_properties;
[NonSerialized]
@@ -43,9 +47,48 @@ namespace System.Security.Claims
[NonSerialized]
ClaimsIdentity m_subject;
private enum SerializationMask
{
None = 0,
NameClaimType = 1,
RoleClaimType = 2,
StringType = 4,
Issuer = 8,
OriginalIssuerEqualsIssuer = 16,
OriginalIssuer = 32,
HasProperties = 64,
UserData = 128,
}
#region Claim Constructors
/// <summary>
/// Initializes an instance of <see cref="Claim"/> using a <see cref="BinaryReader"/>.
/// Normally the <see cref="BinaryReader"/> is constructed using the bytes from <see cref="WriteTo(BinaryWriter)"/> and initialized in the same way as the <see cref="BinaryWriter"/>.
/// </summary>
/// <param name="reader">a <see cref="BinaryReader"/> pointing to a <see cref="Claim"/>.</param>
/// <exception cref="ArgumentNullException">if 'reader' is null.</exception>
public Claim(BinaryReader reader)
: this(reader, null)
{
}
/// <summary>
/// Initializes an instance of <see cref="Claim"/> using a <see cref="BinaryReader"/>.
/// Normally the <see cref="BinaryReader"/> is constructed using the bytes from <see cref="WriteTo(BinaryWriter)"/> and initialized in the same way as the <see cref="BinaryWriter"/>.
/// </summary>
/// <param name="reader">a <see cref="BinaryReader"/> pointing to a <see cref="Claim"/>.</param>
/// <param name="subject"> the value for <see cref="Claim.Subject"/>, which is the <see cref="ClaimsIdentity"/> that has these claims.</param>
/// <exception cref="ArgumentNullException">if 'reader' is null.</exception>
public Claim(BinaryReader reader, ClaimsIdentity subject)
{
if (reader == null)
throw new ArgumentNullException("reader");
Initialize(reader, subject);
}
/// <summary>
/// Creates a <see cref="Claim"/> with the specified type and value.
/// </summary>
@@ -203,8 +246,63 @@ namespace System.Security.Claims
}
}
/// <summary>
/// Copy constructor for <see cref="Claim"/>
/// </summary>
/// <param name="other">the <see cref="Claim"/> to copy.</param>
/// <remarks><see cref="Claim.Subject"/>will be set to 'null'.</remarks>
/// <exception cref="ArgumentNullException">if 'other' is null.</exception>
protected Claim(Claim other)
: this(other, (other == null ? (ClaimsIdentity)null : other.m_subject))
{
}
/// <summary>
/// Copy constructor for <see cref="Claim"/>
/// </summary>
/// <param name="other">the <see cref="Claim"/> to copy.</param>
/// <param name="subject">the <see cref="ClaimsIdentity"/> to assign to <see cref="Claim.Subject"/>.</param>
/// <remarks><see cref="Claim.Subject"/>will be set to 'subject'.</remarks>
/// <exception cref="ArgumentNullException">if 'other' is null.</exception>
protected Claim(Claim other, ClaimsIdentity subject)
{
if (other == null)
throw new ArgumentNullException("other");
m_issuer = other.m_issuer;
m_originalIssuer = other.m_originalIssuer;
m_subject = subject;
m_type = other.m_type;
m_value = other.m_value;
m_valueType = other.m_valueType;
if (other.m_properties != null)
{
m_properties = new Dictionary<string, string>();
foreach (var key in other.m_properties.Keys)
{
m_properties.Add(key, other.m_properties[key]);
}
}
if (other.m_userSerializationData != null)
{
m_userSerializationData = other.m_userSerializationData.Clone() as byte[];
}
}
#endregion
/// <summary>
/// Contains any additional data provided by a derived type, typically set when calling <see cref="WriteTo(BinaryWriter, byte[])"/>.</param>
/// </summary>
protected virtual byte[] CustomSerializationData
{
get
{
return m_userSerializationData;
}
}
/// <summary>
/// Gets the issuer of the <see cref="Claim"/>.
/// </summary>
@@ -266,6 +364,7 @@ namespace System.Security.Claims
/// <summary>
/// Gets the claim type of the <see cref="Claim"/>.
/// </summary>
/// <seealso cref="ClaimTypes"/>.
public string Type
{
get { return m_type; }
@@ -282,39 +381,233 @@ namespace System.Security.Claims
/// <summary>
/// Gets the value type of the <see cref="Claim"/>.
/// </summary>
/// <seealso cref="ClaimValueTypes"/>
public string ValueType
{
get { return m_valueType; }
}
/// <summary>
/// Returns a new <see cref="Claim"/> object copied from this object. The subject of the new claim object is set to null.
/// Creates a new instance <see cref="Claim"/> with values copied from this object.
/// </summary>
/// <returns>A new <see cref="Claim"/> object copied from this object.</returns>
/// <remarks>This is a shallow copy operation.</remarks>
public virtual Claim Clone()
{
return Clone((ClaimsIdentity)null);
}
/// <summary>
/// Returns a new <see cref="Claim"/> object copied from this object. The subject of the new claim object is set to identity.
/// Creates a new instance <see cref="Claim"/> with values copied from this object.
/// </summary>
/// <param name="identity">The <see cref="ClaimsIdentity"/> that this <see cref="Claim"/> is associated with.</param>
/// <returns>A new <see cref="Claim"/> object copied from this object.</returns>
/// <remarks>This is a shallow copy operation.</remarks>
/// <param name="identity">the value for <see cref="Claim.Subject"/>, which is the <see cref="ClaimsIdentity"/> that has these claims.
/// <remarks><see cref="Claim.Subject"/> will be set to 'identity'.</remarks>
public virtual Claim Clone(ClaimsIdentity identity)
{
Claim newClaim = new Claim(m_type, m_value, m_valueType, m_issuer, m_originalIssuer, identity);
if (m_properties != null)
return new Claim(this, identity);
}
private void Initialize(BinaryReader reader, ClaimsIdentity subject)
{
if (reader == null)
{
foreach (string key in m_properties.Keys)
throw new ArgumentNullException("reader");
}
m_subject = subject;
SerializationMask mask = (SerializationMask)reader.ReadInt32();
int numPropertiesRead = 1;
int numPropertiesToRead = reader.ReadInt32();
m_value = reader.ReadString();
if ((mask & SerializationMask.NameClaimType) == SerializationMask.NameClaimType)
{
m_type = ClaimsIdentity.DefaultNameClaimType;
}
else if ((mask & SerializationMask.RoleClaimType) == SerializationMask.RoleClaimType)
{
m_type = ClaimsIdentity.DefaultRoleClaimType;
}
else
{
m_type = reader.ReadString();
numPropertiesRead++;
}
if ((mask & SerializationMask.StringType) == SerializationMask.StringType)
{
m_valueType = reader.ReadString();
numPropertiesRead++;
}
else
{
m_valueType = ClaimValueTypes.String;
}
if ((mask & SerializationMask.Issuer) == SerializationMask.Issuer)
{
m_issuer = reader.ReadString();
numPropertiesRead++;
}
else
{
m_issuer = ClaimsIdentity.DefaultIssuer;
}
if ((mask & SerializationMask.OriginalIssuerEqualsIssuer) == SerializationMask.OriginalIssuerEqualsIssuer)
{
m_originalIssuer = m_issuer;
}
else if ((mask & SerializationMask.OriginalIssuer) == SerializationMask.OriginalIssuer)
{
m_originalIssuer = reader.ReadString();
numPropertiesRead++;
}
else
{
m_originalIssuer = ClaimsIdentity.DefaultIssuer;
}
if ((mask & SerializationMask.HasProperties) == SerializationMask.HasProperties)
{
//
int numProperties = reader.ReadInt32();
for (int i = 0; i < numProperties; i++)
{
newClaim.Properties[key] = m_properties[key];
Properties.Add(reader.ReadString(), reader.ReadString());
}
}
return newClaim;
if ((mask & SerializationMask.UserData) == SerializationMask.UserData)
{
//
int cb = reader.ReadInt32();
m_userSerializationData = reader.ReadBytes(cb);
numPropertiesRead++;
}
for (int i = numPropertiesRead; i < numPropertiesToRead; i++)
{
reader.ReadString();
}
}
/// <summary>
/// Serializes using a <see cref="BinaryWriter"/>
/// </summary>
/// <param name="writer">the <see cref="BinaryWriter"/> to use for data storage.</param>
/// <exception cref="ArgumentNullException">if 'writer' is null.</exception>
public virtual void WriteTo(BinaryWriter writer)
{
WriteTo(writer, null);
}
/// <summary>
/// Serializes using a <see cref="BinaryWriter"/>
/// </summary>
/// <param name="writer">the <see cref="BinaryWriter"/> to use for data storage.</param>
/// <param name="userData">additional data provided by derived type.</param>
/// <exception cref="ArgumentNullException">if 'writer' is null.</exception>
protected virtual void WriteTo(BinaryWriter writer, byte[] userData)
{
if (writer == null)
{
throw new ArgumentNullException("writer");
}
//
int numberOfPropertiesWritten = 1;
SerializationMask mask = SerializationMask.None;
if (string.Equals(m_type, ClaimsIdentity.DefaultNameClaimType))
{
mask |= SerializationMask.NameClaimType;
}
else if (string.Equals(m_type, ClaimsIdentity.DefaultRoleClaimType))
{
mask |= SerializationMask.RoleClaimType;
}
else
{
numberOfPropertiesWritten++;
}
if (!string.Equals(m_valueType, ClaimValueTypes.String, StringComparison.Ordinal))
{
numberOfPropertiesWritten++;
mask |= SerializationMask.StringType;
}
if (!string.Equals(m_issuer, ClaimsIdentity.DefaultIssuer, StringComparison.Ordinal))
{
numberOfPropertiesWritten++;
mask |= SerializationMask.Issuer;
}
if (string.Equals(m_originalIssuer, m_issuer, StringComparison.Ordinal))
{
mask |= SerializationMask.OriginalIssuerEqualsIssuer;
}
else if (!string.Equals(m_originalIssuer, ClaimsIdentity.DefaultIssuer, StringComparison.Ordinal))
{
numberOfPropertiesWritten++;
mask |= SerializationMask.OriginalIssuer;
}
if (Properties.Count > 0)
{
numberOfPropertiesWritten++;
mask |= SerializationMask.HasProperties;
}
//
if (userData != null && userData.Length > 0)
{
numberOfPropertiesWritten++;
mask |= SerializationMask.UserData;
}
writer.Write((Int32)mask);
writer.Write((Int32)numberOfPropertiesWritten);
writer.Write(m_value);
if (((mask & SerializationMask.NameClaimType) != SerializationMask.NameClaimType) && ((mask & SerializationMask.RoleClaimType) != SerializationMask.RoleClaimType))
{
writer.Write(m_type);
}
if ((mask & SerializationMask.StringType) == SerializationMask.StringType)
{
writer.Write(m_valueType);
}
if ((mask & SerializationMask.Issuer) == SerializationMask.Issuer)
{
writer.Write(m_issuer);
}
if ((mask & SerializationMask.OriginalIssuer) == SerializationMask.OriginalIssuer)
{
writer.Write(m_originalIssuer);
}
if ((mask & SerializationMask.HasProperties) == SerializationMask.HasProperties)
{
writer.Write(Properties.Count);
foreach (var key in Properties.Keys)
{
writer.Write(key);
writer.Write(Properties[key]);
}
}
if ((mask & SerializationMask.UserData) == SerializationMask.UserData)
{
writer.Write((Int32)userData.Length);
writer.Write(userData);
}
writer.Flush();
}
/// <summary>

View File

@@ -7,7 +7,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
// <OWNER>Brentsch</OWNER>
//
//

View File

@@ -7,7 +7,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// <OWNER>[....]</OWNER>
// <OWNER>Brentsch</OWNER>
//
//

View File

@@ -30,6 +30,22 @@ namespace System.Security.Claims
[ComVisible(true)]
public class ClaimsIdentity : IIdentity
{
private enum SerializationMask
{
None = 0,
AuthenticationType = 1,
BootstrapConext = 2,
NameClaimType = 4,
RoleClaimType = 8,
HasClaims = 16,
HasLabel = 32,
Actor = 64,
UserData = 128,
}
[NonSerialized]
private byte[] m_userSerializationData;
[NonSerialized]
const string PreFix = "System.Security.ClaimsIdentity.";
[NonSerialized]
@@ -333,6 +349,49 @@ namespace System.Security.Claims
}
}
/// Initializes an instance of <see cref="ClaimsIdentity"/> using a <see cref="BinaryReader"/>.
/// Normally the reader is constructed from the bytes returned from <see cref="WriteTo"/>
/// </summary>
/// <param name="reader">a <see cref="BinaryReader"/> pointing to a <see cref="ClaimsIdentity"/>.</param>
/// <exception cref="ArgumentNullException">if 'reader' is null.</exception>
public ClaimsIdentity(BinaryReader reader)
{
if (reader == null)
throw new ArgumentNullException("reader");
Initialize(reader);
}
/// <summary>
/// Copy constructor.
/// </summary>
/// <param name="other"><see cref="ClaimsIdentity"/> to copy.</param>
/// <exception cref="ArgumentNullException">if 'other' is null.</exception>
protected ClaimsIdentity(ClaimsIdentity other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (other.m_actor != null)
{
m_actor = other.m_actor.Clone();
}
m_authenticationType = other.m_authenticationType;
m_bootstrapContext = other.m_bootstrapContext;
m_label = other.m_label;
m_nameType = other.m_nameType;
m_roleType = other.m_roleType;
if (other.m_userSerializationData != null)
{
m_userSerializationData = other.m_userSerializationData.Clone() as byte[];
}
SafeAddClaims(other.m_instanceClaims);
}
/// <summary>
/// Initializes an instance of <see cref="Identity"/> from a serialized stream created via
/// <see cref="ISerializable"/>.
@@ -450,6 +509,17 @@ namespace System.Security.Claims
}
}
/// <summary>
/// Contains any additional data provided by a derived type, typically set when calling <see cref="WriteTo(BinaryWriter, byte[])"/>.</param>
/// </summary>
protected virtual byte[] CustomSerializationData
{
get
{
return m_userSerializationData;
}
}
/// <summary>
/// Allow the association of claims with this instance of <see cref="ClaimsIdentity"/>.
/// The claims will not be serialized or added in Clone(). They will be included in searches, finds and returned from the call to Claims.
@@ -998,6 +1068,203 @@ namespace System.Security.Claims
return false;
}
/// <summary>
/// Initializes from a <see cref="BinaryReader"/>. Normally the reader is initialized in the same as the one passed to <see cref="Serialize(BinaryWriter)"/>
/// </summary>
/// <param name="reader">a <see cref="BinaryReader"/> pointing to a <see cref="ClaimsIdentity"/>.</param>
/// <exception cref="ArgumentNullException">if 'reader' is null.</exception>
private void Initialize(BinaryReader reader)
{
if (reader == null)
{
throw new ArgumentNullException("reader");
}
//
SerializationMask mask = (SerializationMask)reader.ReadInt32();
if ((mask & SerializationMask.AuthenticationType) == SerializationMask.AuthenticationType)
{
m_authenticationType = reader.ReadString();
}
if ((mask & SerializationMask.BootstrapConext) == SerializationMask.BootstrapConext)
{
m_bootstrapContext = reader.ReadString();
}
if ((mask & SerializationMask.NameClaimType) == SerializationMask.NameClaimType)
{
m_nameType = reader.ReadString();
}
else
{
m_nameType = ClaimsIdentity.DefaultNameClaimType;
}
if ((mask & SerializationMask.RoleClaimType) == SerializationMask.RoleClaimType)
{
m_roleType = reader.ReadString();
}
else
{
m_roleType = ClaimsIdentity.DefaultRoleClaimType;
}
if ((mask & SerializationMask.HasClaims) == SerializationMask.HasClaims)
{
//
int numberOfClaims = reader.ReadInt32();
for (int index = 0; index < numberOfClaims; ++index)
{
Claim claim = new Claim(reader, this);
m_instanceClaims.Add(claim);
}
}
}
/// <summary>
/// Provides and extensibility point for derived types to create a custom <see cref="Claim"/>.
/// </summary>
/// <param name="reader">the <see cref="BinaryReader"/>that points at the claim.</param>
/// <returns>a new <see cref="Claim"/>.</returns>
protected virtual Claim CreateClaim(BinaryReader reader)
{
if (reader == null)
{
throw new ArgumentNullException("reader");
}
return new Claim(reader, this);
}
/// <summary>
/// Serializes using a <see cref="BinaryWriter"/>
/// </summary>
/// <param name="writer">the <see cref="BinaryWriter"/> to use for data storage.</param>
/// <exception cref="ArgumentNullException">if 'writer' is null.</exception>
public virtual void WriteTo(BinaryWriter writer)
{
WriteTo(writer, null);
}
/// <summary>
/// Serializes using a <see cref="BinaryWriter"/>
/// </summary>
/// <param name="writer">the <see cref="BinaryWriter"/> to use for data storage.</param>
/// <param name="userData">additional data provided by derived type.</param>
/// <exception cref="ArgumentNullException">if 'writer' is null.</exception>
protected virtual void WriteTo(BinaryWriter writer, byte[] userData)
{
if (writer == null)
{
throw new ArgumentNullException("writer");
}
int numberOfPropertiesWritten = 0;
var mask = SerializationMask.None;
if (m_authenticationType != null)
{
mask |= SerializationMask.AuthenticationType;
numberOfPropertiesWritten++;
}
if (m_bootstrapContext != null)
{
string rawData = m_bootstrapContext as string;
if (rawData != null)
{
mask |= SerializationMask.BootstrapConext;
numberOfPropertiesWritten++;
}
}
if (!string.Equals(m_nameType, ClaimsIdentity.DefaultNameClaimType, StringComparison.Ordinal))
{
mask |= SerializationMask.NameClaimType;
numberOfPropertiesWritten++;
}
if (!string.Equals(m_roleType, ClaimsIdentity.DefaultRoleClaimType, StringComparison.Ordinal))
{
mask |= SerializationMask.RoleClaimType;
numberOfPropertiesWritten++;
}
if (!string.IsNullOrWhiteSpace(m_label))
{
mask |= SerializationMask.HasLabel;
numberOfPropertiesWritten++;
}
if (m_instanceClaims.Count > 0)
{
mask |= SerializationMask.HasClaims;
numberOfPropertiesWritten++;
}
if (m_actor != null)
{
mask |= SerializationMask.Actor;
numberOfPropertiesWritten++;
}
if (userData != null && userData.Length > 0)
{
numberOfPropertiesWritten++;
mask |= SerializationMask.UserData;
}
writer.Write((Int32)mask);
writer.Write((Int32)numberOfPropertiesWritten);
if ((mask & SerializationMask.AuthenticationType) == SerializationMask.AuthenticationType)
{
writer.Write(m_authenticationType);
}
if ((mask & SerializationMask.BootstrapConext) == SerializationMask.BootstrapConext)
{
writer.Write(m_bootstrapContext as string);
}
if ((mask & SerializationMask.NameClaimType) == SerializationMask.NameClaimType)
{
writer.Write(m_nameType);
}
if ((mask & SerializationMask.RoleClaimType) == SerializationMask.RoleClaimType)
{
writer.Write(m_roleType);
}
if ((mask & SerializationMask.HasLabel) == SerializationMask.HasLabel)
{
writer.Write(m_label);
}
if ((mask & SerializationMask.HasClaims) == SerializationMask.HasClaims)
{
writer.Write((Int32)m_instanceClaims.Count);
foreach (var claim in m_instanceClaims)
{
claim.WriteTo(writer);
}
}
if ((mask & SerializationMask.Actor) == SerializationMask.Actor)
{
m_actor.WriteTo(writer);
}
if ((mask & SerializationMask.UserData) == SerializationMask.UserData)
{
writer.Write((Int32)userData.Length);
writer.Write(userData);
}
writer.Flush();
}
// <param name="useContext"></param> The reason for this param is due to WindowsIdentity deciding to have an
// api that doesn't pass the context to its internal constructor.
[SecurityCritical]

View File

@@ -36,6 +36,16 @@ namespace System.Security.Claims
[ComVisible(true)]
public class ClaimsPrincipal : IPrincipal
{
private enum SerializationMask
{
None = 0,
HasIdentities = 1,
UserData = 2
}
[NonSerialized]
private byte[] m_userSerializationData;
[NonSerialized]
const string PreFix = "System.Security.ClaimsPrincipal.";
[NonSerialized]
@@ -230,6 +240,21 @@ namespace System.Security.Claims
}
}
/// <summary>
/// Initializes an instance of <see cref="ClaimsPrincipal"/> using a <see cref="BinaryReader"/>.
/// Normally the <see cref="BinaryReader"/> is constructed using the bytes from <see cref="WriteTo(BinaryWriter)"/> and initialized in the same way as the <see cref="BinaryWriter"/>.
/// </summary>
/// <param name="reader">a <see cref="BinaryReader"/> pointing to a <see cref="ClaimsPrincipal"/>.</param>
/// <exception cref="ArgumentNullException">if 'reader' is null.</exception>
public ClaimsPrincipal(BinaryReader reader)
{
if (reader == null)
throw new ArgumentNullException("reader");
Initialize(reader);
}
[SecurityCritical]
protected ClaimsPrincipal(SerializationInfo info, StreamingContext context)
{
@@ -241,6 +266,41 @@ namespace System.Security.Claims
Deserialize(info, context);
}
/// <summary>
/// Contains any additional data provided by derived type, typically set when calling <see cref="WriteTo(BinaryWriter, byte[])"/>.</param>
/// </summary>
protected virtual byte[] CustomSerializationData
{
get
{
return m_userSerializationData;
}
}
/// <summary>
/// Creates a new instance of <see cref="ClaimsPrincipal"/> with values copied from this object.
/// </summary>
public virtual ClaimsPrincipal Clone()
{
return new ClaimsPrincipal(this);
}
/// <summary>
/// Provides and extensibility point for derived types to create a custom <see cref="ClaimsIdentity"/>.
/// </summary>
/// <param name="reader">the <see cref="BinaryReader"/>that points at the claim.</param>
/// <exception cref="ArgumentNullException">if 'reader' is null.</exception>
/// <returns>a new <see cref="ClaimsIdentity"/>.</returns>
protected virtual ClaimsIdentity CreateClaimsIdentity(BinaryReader reader)
{
if (reader == null)
{
throw new ArgumentNullException("reader");
}
return new ClaimsIdentity(reader);
}
#endregion ClaimsPrincipal Constructors
[OnSerializing()]
@@ -717,6 +777,104 @@ namespace System.Security.Claims
return false;
}
/// <summary>
/// Initializes from a <see cref="BinaryReader"/>. Normally the reader is initialized with the results from <see cref="WriteTo(BinaryWriter)"/>
/// Normally the <see cref="BinaryReader"/> is initialized in the same way as the <see cref="BinaryWriter"/> passed to <see cref="WriteTo(BinaryWriter)"/>.
/// </summary>
/// <param name="reader">a <see cref="BinaryReader"/> pointing to a <see cref="ClaimsPrincipal"/>.</param>
/// <exception cref="ArgumentNullException">if 'reader' is null.</exception>
private void Initialize(BinaryReader reader)
{
if (reader == null)
{
throw new ArgumentNullException("reader");
}
SerializationMask mask = (SerializationMask)reader.ReadInt32();
int numPropertiesToRead = reader.ReadInt32();
int numPropertiesRead = 0;
if ((mask & SerializationMask.HasIdentities) == SerializationMask.HasIdentities)
{
numPropertiesRead++;
int numberOfIdentities = reader.ReadInt32();
for (int index = 0; index < numberOfIdentities; ++index)
{
// directly add to m_identities as that is what we serialized from
m_identities.Add(CreateClaimsIdentity(reader));
}
}
if ((mask & SerializationMask.UserData) == SerializationMask.UserData)
{
//
int cb = reader.ReadInt32();
m_userSerializationData = reader.ReadBytes(cb);
numPropertiesRead++;
}
for (int i = numPropertiesRead; i < numPropertiesToRead; i++)
{
reader.ReadString();
}
}
/// <summary>
/// Serializes using a <see cref="BinaryWriter"/>
/// </summary>
/// <exception cref="ArgumentNullException">if 'writer' is null.</exception>
public virtual void WriteTo(BinaryWriter writer)
{
WriteTo(writer, null);
}
/// <summary>
/// Serializes using a <see cref="BinaryWriter"/>
/// </summary>
/// <param name="writer">the <see cref="BinaryWriter"/> to use for data storage.</param>
/// <param name="userData">additional data provided by derived type.</param>
/// <exception cref="ArgumentNullException">if 'writer' is null.</exception>
protected virtual void WriteTo(BinaryWriter writer, byte[] userData)
{
if (writer == null)
{
throw new ArgumentNullException("writer");
}
int numberOfPropertiesWritten = 0;
var mask = SerializationMask.None;
if (m_identities.Count > 0)
{
mask |= SerializationMask.HasIdentities;
numberOfPropertiesWritten++;
}
if (userData != null && userData.Length > 0)
{
numberOfPropertiesWritten++;
mask |= SerializationMask.UserData;
}
writer.Write((Int32)mask);
writer.Write((Int32)numberOfPropertiesWritten);
if ((mask & SerializationMask.HasIdentities) == SerializationMask.HasIdentities)
{
writer.Write(m_identities.Count);
foreach (var identity in m_identities)
{
identity.WriteTo(writer);
}
}
if ((mask & SerializationMask.UserData) == SerializationMask.UserData)
{
writer.Write((Int32)userData.Length);
writer.Write(userData);
}
writer.Flush();
}
}
}