Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / xsp / System / Web / State / SessionStateItemCollection.cs / 6 / SessionStateItemCollection.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* * SessionStateItemCollection * * Copyright (c) 1998-1999, Microsoft Corporation * */ namespace System.Web.SessionState { using System.IO; using System.Collections; using System.Collections.Specialized; using System.Web.Util; using System.Security; using System.Security.Permissions; [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] public interface ISessionStateItemCollection : ICollection { Object this[String name] { get; set; } Object this[int index] { get; set; } void Remove(String name); void RemoveAt(int index); void Clear(); NameObjectCollectionBase.KeysCollection Keys { get; } bool Dirty { get; set; } } [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] public sealed class SessionStateItemCollection : NameObjectCollectionBase, ISessionStateItemCollection { class KeyedCollection : NameObjectCollectionBase { internal KeyedCollection(int count) : base(count, Misc.CaseInsensitiveInvariantKeyComparer) { } internal Object this[String name] { get { return BaseGet(name); } set { Object oldValue = BaseGet(name); if (oldValue == null && value == null) return; BaseSet(name, value); } } internal Object this[int index] { get { return BaseGet(index); } } internal void Remove(String name) { BaseRemove(name); } internal void RemoveAt(int index) { BaseRemoveAt(index); } internal void Clear() { BaseClear(); } internal string GetKey( int index) { return BaseGetKey(index); } internal bool ContainsKey(string name) { // Please note that we don't expect null value to be inserted. return (BaseGet(name) != null); } } class SerializedItemPosition { int _offset; int _dataLength; internal SerializedItemPosition(int offset, int dataLength) { this._offset = offset; this._dataLength = dataLength; } internal int Offset { get { return _offset; } } internal int DataLength { get { return _dataLength; } } // Mark the item as deserialized by making the offset -1. internal void MarkDeserializedOffset() { _offset = -1; } internal void MarkDeserializedOffsetAndCheck() { if (_offset >= 0) { MarkDeserializedOffset(); } else { Debug.Fail("Offset shouldn't be negative inside MarkDeserializedOffsetAndCheck."); } } internal bool IsDeserialized { get { return _offset < 0; } } } static Hashtable s_immutableTypes; const int NO_NULL_KEY = -1; const int SIZE_OF_INT32 = 4; bool _dirty; KeyedCollection _serializedItems; Stream _stream; int _iLastOffset; object _serializedItemsLock = new object(); public SessionStateItemCollection() : base(Misc.CaseInsensitiveInvariantKeyComparer) { } static SessionStateItemCollection() { Type t; s_immutableTypes = new Hashtable(19); t=typeof(String); s_immutableTypes.Add(t, t); t=typeof(Int32); s_immutableTypes.Add(t, t); t=typeof(Boolean); s_immutableTypes.Add(t, t); t=typeof(DateTime); s_immutableTypes.Add(t, t); t=typeof(Decimal); s_immutableTypes.Add(t, t); t=typeof(Byte); s_immutableTypes.Add(t, t); t=typeof(Char); s_immutableTypes.Add(t, t); t=typeof(Single); s_immutableTypes.Add(t, t); t=typeof(Double); s_immutableTypes.Add(t, t); t=typeof(SByte); s_immutableTypes.Add(t, t); t=typeof(Int16); s_immutableTypes.Add(t, t); t=typeof(Int64); s_immutableTypes.Add(t, t); t=typeof(UInt16); s_immutableTypes.Add(t, t); t=typeof(UInt32); s_immutableTypes.Add(t, t); t=typeof(UInt64); s_immutableTypes.Add(t, t); t=typeof(TimeSpan); s_immutableTypes.Add(t, t); t=typeof(Guid); s_immutableTypes.Add(t, t); t=typeof(IntPtr); s_immutableTypes.Add(t, t); t=typeof(UIntPtr); s_immutableTypes.Add(t, t); } static internal bool IsImmutable(Object o) { return s_immutableTypes[o.GetType()] != null; } internal void DeserializeAllItems() { if (_serializedItems == null) { return; } lock (_serializedItemsLock) { for (int i = 0; i < _serializedItems.Count; i++) { DeserializeItem(_serializedItems.GetKey(i), false); } } } void DeserializeItem(int index) { // No-op if SessionStateItemCollection is not deserialized from a persistent storage. if (_serializedItems == null) { return; } #if DBG // The keys in _serializedItems should match the beginning part of // the list in NameObjectCollectionBase for (int i=0; i < _serializedItems.Count; i++) { Debug.Assert(_serializedItems.GetKey(i) == BaseGetKey(i)); } #endif lock (_serializedItemsLock) { // No-op if the item isn't serialized. if (index >= _serializedItems.Count) { return; } DeserializeItem(_serializedItems.GetKey(index), false); } } [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] [SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.SerializationFormatter)] private object ReadValueFromStreamWithAssert() { return AltSerialization.ReadValueFromStream(new BinaryReader(_stream)); } void DeserializeItem(String name, bool check) { object val; lock (_serializedItemsLock) { if (check) { // No-op if SessionStateItemCollection is not deserialized from a persistent storage, if (_serializedItems == null) { return; } // User is asking for an item we don't have. if (!_serializedItems.ContainsKey(name)) { return; } } Debug.Assert(_serializedItems != null); Debug.Assert(_stream != null); SerializedItemPosition position = (SerializedItemPosition)_serializedItems[name]; if (position.IsDeserialized) { // It has been deserialized already. return; } // Position the stream to the place where the item is stored. _stream.Seek(position.Offset, SeekOrigin.Begin); // Set the value Debug.Trace("SessionStateItemCollection", "Deserialized an item: keyname=" + name); // VSWhidbey 427316: Sandbox Serialization in non full trust cases if (HttpRuntime.NamedPermissionSet != null && HttpRuntime.ProcessRequestInApplicationTrust) { HttpRuntime.NamedPermissionSet.PermitOnly(); } // This deserialization work used to be done in AcquireRequestState event when // there is no user code on the stack. // In whidbey we added this on-demand deserialization for performance reason. However, // in medium and low trust cases the page doesn't have permission to do it. // So we have to assert the permission. // (See VSWhidbey 275003) val = ReadValueFromStreamWithAssert(); BaseSet(name, val); // At the end, mark the item as deserialized by making the offset -1 position.MarkDeserializedOffsetAndCheck(); } } void MarkItemDeserialized(String name) { // No-op if SessionStateItemCollection is not deserialized from a persistent storage, if (_serializedItems == null) { return; } lock (_serializedItemsLock) { // If the serialized collection contains this key, mark it deserialized if (_serializedItems.ContainsKey(name)) { // Mark the item as deserialized by making it -1. ((SerializedItemPosition)_serializedItems[name]).MarkDeserializedOffset(); } } } void MarkItemDeserialized(int index) { // No-op if SessionStateItemCollection is not deserialized from a persistent storage, if (_serializedItems == null) { return; } #if DBG // The keys in _serializedItems should match the beginning part of // the list in NameObjectCollectionBase for (int i=0; i < _serializedItems.Count; i++) { Debug.Assert(_serializedItems.GetKey(i) == BaseGetKey(i)); } #endif lock (_serializedItemsLock) { // No-op if the item isn't serialized. if (index >= _serializedItems.Count) { return; } ((SerializedItemPosition)_serializedItems[index]).MarkDeserializedOffset(); } } public bool Dirty { get {return _dirty;} set {_dirty = value;} } public Object this[String name] { get { DeserializeItem(name, true); Object obj = BaseGet(name); if (obj != null) { if (!IsImmutable(obj)) { // If the item is immutable (e.g. an array), then the caller has the ability to change // its content without calling our setter. So we have to mark the collection // as dirty. Debug.Trace("SessionStateItemCollection", "Setting _dirty to true in get"); _dirty = true; } } return obj; } set { MarkItemDeserialized(name); Debug.Trace("SessionStateItemCollection", "Setting _dirty to true in set"); BaseSet(name, value); _dirty = true; } } public Object this[int index] { get { DeserializeItem(index); Object obj = BaseGet(index); if (obj != null) { if (!IsImmutable(obj)) { Debug.Trace("SessionStateItemCollection", "Setting _dirty to true in get"); _dirty = true; } } return obj; } set { MarkItemDeserialized(index); Debug.Trace("SessionStateItemCollection", "Setting _dirty to true in set"); BaseSet(index, value); _dirty = true; } } public void Remove(String name) { lock (_serializedItemsLock) { if (_serializedItems != null) { _serializedItems.Remove(name); } BaseRemove(name); _dirty = true; } } public void RemoveAt(int index) { lock (_serializedItemsLock) { if (_serializedItems != null && index < _serializedItems.Count) { _serializedItems.RemoveAt(index); } BaseRemoveAt(index); _dirty = true; } } public void Clear() { lock (_serializedItemsLock) { if (_serializedItems != null) { _serializedItems.Clear(); } BaseClear(); _dirty = true; } } public override IEnumerator GetEnumerator() { // Have to deserialize all items; otherwise the enumerator won't // work because we'll keep on changing the collection during // individual item deserialization DeserializeAllItems(); return base.GetEnumerator(); } public override NameObjectCollectionBase.KeysCollection Keys { get { // Unfortunately, we have to deserialize all items first, because // Keys.GetEnumerator might be called and we have the same problem // as in GetEnumerator() above. DeserializeAllItems(); return base.Keys; } } [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] [SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.SerializationFormatter)] private void WriteValueToStreamWithAssert(object value, BinaryWriter writer) { AltSerialization.WriteValueToStream(value, writer); } public void Serialize(BinaryWriter writer) { int count; int i; long iOffsetStart; long iValueStart; string key; object value; long curPos; byte[] buffer = null; Stream baseStream = writer.BaseStream; // VSWhidbey 427316: Sandbox Serialization in non full trust cases if (HttpRuntime.NamedPermissionSet != null && HttpRuntime.ProcessRequestInApplicationTrust) { HttpRuntime.NamedPermissionSet.PermitOnly(); } lock (_serializedItemsLock) { count = Count; writer.Write(count); if (count > 0) { if (BaseGet(null) != null) { // We have a value with a null key. Find its index. for (i = 0; i < count; i++) { key = BaseGetKey(i); if (key == null) { writer.Write(i); break; } } Debug.Assert(i != count); } else { writer.Write(NO_NULL_KEY); } // Write out all the keys. for (i = 0; i < count; i++) { key = BaseGetKey(i); if (key != null) { writer.Write(key); } } // Next, allocate space to store the offset: // - We won't store the offset of first item because it's always zero. // - The offset of an item is counted from the beginning of serialized values // - But we will store the offset of the first byte off the last item because // we need that to calculate the size of the last item. iOffsetStart = baseStream.Position; baseStream.Seek(SIZE_OF_INT32 * count, SeekOrigin.Current); iValueStart = baseStream.Position; for (i = 0; i < count; i++) { // See if that item has not be deserialized yet. if (_serializedItems != null && i < _serializedItems.Count && !((SerializedItemPosition)_serializedItems[i]).IsDeserialized) { SerializedItemPosition position = (SerializedItemPosition)_serializedItems[i]; Debug.Assert(_stream != null); // The item is read as serialized data from a store, and it's still // serialized, meaning no one has referenced it. Just copy // the bytes over. // Move the stream to the serialized data and copy it over to writer _stream.Seek(position.Offset, SeekOrigin.Begin); if (buffer == null || buffer.Length < position.DataLength) { buffer = new Byte[position.DataLength]; } #if DBG int read = #endif _stream.Read(buffer, 0, position.DataLength); #if DBG Debug.Assert(read == position.DataLength); #endif baseStream.Write(buffer, 0, position.DataLength); } else { value = BaseGet(i); WriteValueToStreamWithAssert(value, writer); } curPos = baseStream.Position; // Write the offset baseStream.Seek(i * SIZE_OF_INT32 + iOffsetStart, SeekOrigin.Begin); writer.Write((int)(curPos - iValueStart)); // Move back to current position baseStream.Seek(curPos, SeekOrigin.Begin); Debug.Trace("SessionStateItemCollection", "Serialize: curPost=" + curPos + ", offset= " + (int)(curPos - iValueStart)); } } #if DBG writer.Write((byte)0xff); #endif } } public static SessionStateItemCollection Deserialize(BinaryReader reader) { SessionStateItemCollection d = new SessionStateItemCollection(); int count; int nullKey; String key; int i; byte[] buffer; count = reader.ReadInt32(); if (count > 0) { nullKey = reader.ReadInt32(); d._serializedItems = new KeyedCollection(count); // First, deserialize all the keys for (i = 0; i < count; i++) { if (i == nullKey) { key = null; } else { key = reader.ReadString(); } // Need to set them with null value first, so that // the order of them items is correct. d.BaseSet(key, null); } // Next, deserialize all the offsets // First offset will be 0, and the data length will be the first read offset int offset0 = reader.ReadInt32(); d._serializedItems[d.BaseGetKey(0)] = new SerializedItemPosition(0, offset0); int offset1 = 0; for (i = 1; i < count; i++) { offset1 = reader.ReadInt32(); d._serializedItems[d.BaseGetKey(i)] = new SerializedItemPosition(offset0, offset1 - offset0); offset0 = offset1; } // d._iLastOffset = offset0; Debug.Trace("SessionStateItemCollection", "Deserialize: _iLastOffset= " + d._iLastOffset); // _iLastOffset is the first byte past the last item, which equals // the total length of all serialized data buffer = new byte[d._iLastOffset]; int bytesRead = reader.BaseStream.Read(buffer, 0, d._iLastOffset); if (bytesRead != d._iLastOffset) { throw new HttpException(SR.GetString(SR.Invalid_session_state)); } d._stream = new MemoryStream(buffer); } #if DBG Debug.Assert(reader.ReadByte() == 0xff); #endif d._dirty = false; return d; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* * SessionStateItemCollection * * Copyright (c) 1998-1999, Microsoft Corporation * */ namespace System.Web.SessionState { using System.IO; using System.Collections; using System.Collections.Specialized; using System.Web.Util; using System.Security; using System.Security.Permissions; [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] public interface ISessionStateItemCollection : ICollection { Object this[String name] { get; set; } Object this[int index] { get; set; } void Remove(String name); void RemoveAt(int index); void Clear(); NameObjectCollectionBase.KeysCollection Keys { get; } bool Dirty { get; set; } } [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] public sealed class SessionStateItemCollection : NameObjectCollectionBase, ISessionStateItemCollection { class KeyedCollection : NameObjectCollectionBase { internal KeyedCollection(int count) : base(count, Misc.CaseInsensitiveInvariantKeyComparer) { } internal Object this[String name] { get { return BaseGet(name); } set { Object oldValue = BaseGet(name); if (oldValue == null && value == null) return; BaseSet(name, value); } } internal Object this[int index] { get { return BaseGet(index); } } internal void Remove(String name) { BaseRemove(name); } internal void RemoveAt(int index) { BaseRemoveAt(index); } internal void Clear() { BaseClear(); } internal string GetKey( int index) { return BaseGetKey(index); } internal bool ContainsKey(string name) { // Please note that we don't expect null value to be inserted. return (BaseGet(name) != null); } } class SerializedItemPosition { int _offset; int _dataLength; internal SerializedItemPosition(int offset, int dataLength) { this._offset = offset; this._dataLength = dataLength; } internal int Offset { get { return _offset; } } internal int DataLength { get { return _dataLength; } } // Mark the item as deserialized by making the offset -1. internal void MarkDeserializedOffset() { _offset = -1; } internal void MarkDeserializedOffsetAndCheck() { if (_offset >= 0) { MarkDeserializedOffset(); } else { Debug.Fail("Offset shouldn't be negative inside MarkDeserializedOffsetAndCheck."); } } internal bool IsDeserialized { get { return _offset < 0; } } } static Hashtable s_immutableTypes; const int NO_NULL_KEY = -1; const int SIZE_OF_INT32 = 4; bool _dirty; KeyedCollection _serializedItems; Stream _stream; int _iLastOffset; object _serializedItemsLock = new object(); public SessionStateItemCollection() : base(Misc.CaseInsensitiveInvariantKeyComparer) { } static SessionStateItemCollection() { Type t; s_immutableTypes = new Hashtable(19); t=typeof(String); s_immutableTypes.Add(t, t); t=typeof(Int32); s_immutableTypes.Add(t, t); t=typeof(Boolean); s_immutableTypes.Add(t, t); t=typeof(DateTime); s_immutableTypes.Add(t, t); t=typeof(Decimal); s_immutableTypes.Add(t, t); t=typeof(Byte); s_immutableTypes.Add(t, t); t=typeof(Char); s_immutableTypes.Add(t, t); t=typeof(Single); s_immutableTypes.Add(t, t); t=typeof(Double); s_immutableTypes.Add(t, t); t=typeof(SByte); s_immutableTypes.Add(t, t); t=typeof(Int16); s_immutableTypes.Add(t, t); t=typeof(Int64); s_immutableTypes.Add(t, t); t=typeof(UInt16); s_immutableTypes.Add(t, t); t=typeof(UInt32); s_immutableTypes.Add(t, t); t=typeof(UInt64); s_immutableTypes.Add(t, t); t=typeof(TimeSpan); s_immutableTypes.Add(t, t); t=typeof(Guid); s_immutableTypes.Add(t, t); t=typeof(IntPtr); s_immutableTypes.Add(t, t); t=typeof(UIntPtr); s_immutableTypes.Add(t, t); } static internal bool IsImmutable(Object o) { return s_immutableTypes[o.GetType()] != null; } internal void DeserializeAllItems() { if (_serializedItems == null) { return; } lock (_serializedItemsLock) { for (int i = 0; i < _serializedItems.Count; i++) { DeserializeItem(_serializedItems.GetKey(i), false); } } } void DeserializeItem(int index) { // No-op if SessionStateItemCollection is not deserialized from a persistent storage. if (_serializedItems == null) { return; } #if DBG // The keys in _serializedItems should match the beginning part of // the list in NameObjectCollectionBase for (int i=0; i < _serializedItems.Count; i++) { Debug.Assert(_serializedItems.GetKey(i) == BaseGetKey(i)); } #endif lock (_serializedItemsLock) { // No-op if the item isn't serialized. if (index >= _serializedItems.Count) { return; } DeserializeItem(_serializedItems.GetKey(index), false); } } [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] [SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.SerializationFormatter)] private object ReadValueFromStreamWithAssert() { return AltSerialization.ReadValueFromStream(new BinaryReader(_stream)); } void DeserializeItem(String name, bool check) { object val; lock (_serializedItemsLock) { if (check) { // No-op if SessionStateItemCollection is not deserialized from a persistent storage, if (_serializedItems == null) { return; } // User is asking for an item we don't have. if (!_serializedItems.ContainsKey(name)) { return; } } Debug.Assert(_serializedItems != null); Debug.Assert(_stream != null); SerializedItemPosition position = (SerializedItemPosition)_serializedItems[name]; if (position.IsDeserialized) { // It has been deserialized already. return; } // Position the stream to the place where the item is stored. _stream.Seek(position.Offset, SeekOrigin.Begin); // Set the value Debug.Trace("SessionStateItemCollection", "Deserialized an item: keyname=" + name); // VSWhidbey 427316: Sandbox Serialization in non full trust cases if (HttpRuntime.NamedPermissionSet != null && HttpRuntime.ProcessRequestInApplicationTrust) { HttpRuntime.NamedPermissionSet.PermitOnly(); } // This deserialization work used to be done in AcquireRequestState event when // there is no user code on the stack. // In whidbey we added this on-demand deserialization for performance reason. However, // in medium and low trust cases the page doesn't have permission to do it. // So we have to assert the permission. // (See VSWhidbey 275003) val = ReadValueFromStreamWithAssert(); BaseSet(name, val); // At the end, mark the item as deserialized by making the offset -1 position.MarkDeserializedOffsetAndCheck(); } } void MarkItemDeserialized(String name) { // No-op if SessionStateItemCollection is not deserialized from a persistent storage, if (_serializedItems == null) { return; } lock (_serializedItemsLock) { // If the serialized collection contains this key, mark it deserialized if (_serializedItems.ContainsKey(name)) { // Mark the item as deserialized by making it -1. ((SerializedItemPosition)_serializedItems[name]).MarkDeserializedOffset(); } } } void MarkItemDeserialized(int index) { // No-op if SessionStateItemCollection is not deserialized from a persistent storage, if (_serializedItems == null) { return; } #if DBG // The keys in _serializedItems should match the beginning part of // the list in NameObjectCollectionBase for (int i=0; i < _serializedItems.Count; i++) { Debug.Assert(_serializedItems.GetKey(i) == BaseGetKey(i)); } #endif lock (_serializedItemsLock) { // No-op if the item isn't serialized. if (index >= _serializedItems.Count) { return; } ((SerializedItemPosition)_serializedItems[index]).MarkDeserializedOffset(); } } public bool Dirty { get {return _dirty;} set {_dirty = value;} } public Object this[String name] { get { DeserializeItem(name, true); Object obj = BaseGet(name); if (obj != null) { if (!IsImmutable(obj)) { // If the item is immutable (e.g. an array), then the caller has the ability to change // its content without calling our setter. So we have to mark the collection // as dirty. Debug.Trace("SessionStateItemCollection", "Setting _dirty to true in get"); _dirty = true; } } return obj; } set { MarkItemDeserialized(name); Debug.Trace("SessionStateItemCollection", "Setting _dirty to true in set"); BaseSet(name, value); _dirty = true; } } public Object this[int index] { get { DeserializeItem(index); Object obj = BaseGet(index); if (obj != null) { if (!IsImmutable(obj)) { Debug.Trace("SessionStateItemCollection", "Setting _dirty to true in get"); _dirty = true; } } return obj; } set { MarkItemDeserialized(index); Debug.Trace("SessionStateItemCollection", "Setting _dirty to true in set"); BaseSet(index, value); _dirty = true; } } public void Remove(String name) { lock (_serializedItemsLock) { if (_serializedItems != null) { _serializedItems.Remove(name); } BaseRemove(name); _dirty = true; } } public void RemoveAt(int index) { lock (_serializedItemsLock) { if (_serializedItems != null && index < _serializedItems.Count) { _serializedItems.RemoveAt(index); } BaseRemoveAt(index); _dirty = true; } } public void Clear() { lock (_serializedItemsLock) { if (_serializedItems != null) { _serializedItems.Clear(); } BaseClear(); _dirty = true; } } public override IEnumerator GetEnumerator() { // Have to deserialize all items; otherwise the enumerator won't // work because we'll keep on changing the collection during // individual item deserialization DeserializeAllItems(); return base.GetEnumerator(); } public override NameObjectCollectionBase.KeysCollection Keys { get { // Unfortunately, we have to deserialize all items first, because // Keys.GetEnumerator might be called and we have the same problem // as in GetEnumerator() above. DeserializeAllItems(); return base.Keys; } } [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] [SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.SerializationFormatter)] private void WriteValueToStreamWithAssert(object value, BinaryWriter writer) { AltSerialization.WriteValueToStream(value, writer); } public void Serialize(BinaryWriter writer) { int count; int i; long iOffsetStart; long iValueStart; string key; object value; long curPos; byte[] buffer = null; Stream baseStream = writer.BaseStream; // VSWhidbey 427316: Sandbox Serialization in non full trust cases if (HttpRuntime.NamedPermissionSet != null && HttpRuntime.ProcessRequestInApplicationTrust) { HttpRuntime.NamedPermissionSet.PermitOnly(); } lock (_serializedItemsLock) { count = Count; writer.Write(count); if (count > 0) { if (BaseGet(null) != null) { // We have a value with a null key. Find its index. for (i = 0; i < count; i++) { key = BaseGetKey(i); if (key == null) { writer.Write(i); break; } } Debug.Assert(i != count); } else { writer.Write(NO_NULL_KEY); } // Write out all the keys. for (i = 0; i < count; i++) { key = BaseGetKey(i); if (key != null) { writer.Write(key); } } // Next, allocate space to store the offset: // - We won't store the offset of first item because it's always zero. // - The offset of an item is counted from the beginning of serialized values // - But we will store the offset of the first byte off the last item because // we need that to calculate the size of the last item. iOffsetStart = baseStream.Position; baseStream.Seek(SIZE_OF_INT32 * count, SeekOrigin.Current); iValueStart = baseStream.Position; for (i = 0; i < count; i++) { // See if that item has not be deserialized yet. if (_serializedItems != null && i < _serializedItems.Count && !((SerializedItemPosition)_serializedItems[i]).IsDeserialized) { SerializedItemPosition position = (SerializedItemPosition)_serializedItems[i]; Debug.Assert(_stream != null); // The item is read as serialized data from a store, and it's still // serialized, meaning no one has referenced it. Just copy // the bytes over. // Move the stream to the serialized data and copy it over to writer _stream.Seek(position.Offset, SeekOrigin.Begin); if (buffer == null || buffer.Length < position.DataLength) { buffer = new Byte[position.DataLength]; } #if DBG int read = #endif _stream.Read(buffer, 0, position.DataLength); #if DBG Debug.Assert(read == position.DataLength); #endif baseStream.Write(buffer, 0, position.DataLength); } else { value = BaseGet(i); WriteValueToStreamWithAssert(value, writer); } curPos = baseStream.Position; // Write the offset baseStream.Seek(i * SIZE_OF_INT32 + iOffsetStart, SeekOrigin.Begin); writer.Write((int)(curPos - iValueStart)); // Move back to current position baseStream.Seek(curPos, SeekOrigin.Begin); Debug.Trace("SessionStateItemCollection", "Serialize: curPost=" + curPos + ", offset= " + (int)(curPos - iValueStart)); } } #if DBG writer.Write((byte)0xff); #endif } } public static SessionStateItemCollection Deserialize(BinaryReader reader) { SessionStateItemCollection d = new SessionStateItemCollection(); int count; int nullKey; String key; int i; byte[] buffer; count = reader.ReadInt32(); if (count > 0) { nullKey = reader.ReadInt32(); d._serializedItems = new KeyedCollection(count); // First, deserialize all the keys for (i = 0; i < count; i++) { if (i == nullKey) { key = null; } else { key = reader.ReadString(); } // Need to set them with null value first, so that // the order of them items is correct. d.BaseSet(key, null); } // Next, deserialize all the offsets // First offset will be 0, and the data length will be the first read offset int offset0 = reader.ReadInt32(); d._serializedItems[d.BaseGetKey(0)] = new SerializedItemPosition(0, offset0); int offset1 = 0; for (i = 1; i < count; i++) { offset1 = reader.ReadInt32(); d._serializedItems[d.BaseGetKey(i)] = new SerializedItemPosition(offset0, offset1 - offset0); offset0 = offset1; } // d._iLastOffset = offset0; Debug.Trace("SessionStateItemCollection", "Deserialize: _iLastOffset= " + d._iLastOffset); // _iLastOffset is the first byte past the last item, which equals // the total length of all serialized data buffer = new byte[d._iLastOffset]; int bytesRead = reader.BaseStream.Read(buffer, 0, d._iLastOffset); if (bytesRead != d._iLastOffset) { throw new HttpException(SR.GetString(SR.Invalid_session_state)); } d._stream = new MemoryStream(buffer); } #if DBG Debug.Assert(reader.ReadByte() == 0xff); #endif d._dirty = false; return d; } } } // 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
- TaskFormBase.cs
- MarkerProperties.cs
- PersistenceContextEnlistment.cs
- StateDesigner.TransitionInfo.cs
- FillRuleValidation.cs
- ApplicationInfo.cs
- Vector3DIndependentAnimationStorage.cs
- HiddenFieldPageStatePersister.cs
- VisualBrush.cs
- RequiredAttributeAttribute.cs
- InputScopeNameConverter.cs
- StrokeCollection.cs
- SqlXmlStorage.cs
- GroupBoxAutomationPeer.cs
- OrthographicCamera.cs
- SafeHandles.cs
- DataObjectMethodAttribute.cs
- MetadataArtifactLoaderResource.cs
- EdmTypeAttribute.cs
- DesignerOptionService.cs
- QueryableDataSourceView.cs
- EUCJPEncoding.cs
- RegexFCD.cs
- IUnknownConstantAttribute.cs
- BitmapFrameEncode.cs
- WebFaultException.cs
- MDIControlStrip.cs
- Serializer.cs
- DataGridViewColumnCollection.cs
- XmlArrayItemAttribute.cs
- AspNetSynchronizationContext.cs
- DataBindingList.cs
- EntityDataSourceValidationException.cs
- BufferModesCollection.cs
- JsonObjectDataContract.cs
- ReadOnlyCollectionBase.cs
- PDBReader.cs
- SqlDelegatedTransaction.cs
- SimpleTypeResolver.cs
- DataGridViewColumnCollection.cs
- ContextToken.cs
- ZeroOpNode.cs
- MemberBinding.cs
- XamlLoadErrorInfo.cs
- XmlNamespaceDeclarationsAttribute.cs
- ModuleBuilder.cs
- SqlDataSourceStatusEventArgs.cs
- DetailsViewRowCollection.cs
- PersianCalendar.cs
- SchemaCollectionPreprocessor.cs
- Dictionary.cs
- assemblycache.cs
- CrossContextChannel.cs
- CodeIterationStatement.cs
- FlowDocumentPage.cs
- CFStream.cs
- CategoryNameCollection.cs
- DocumentGridPage.cs
- TemplateLookupAction.cs
- MaskedTextBox.cs
- ApplicationGesture.cs
- HtmlAnchor.cs
- TrustSection.cs
- SafeArchiveContext.cs
- CustomErrorsSection.cs
- PeerChannelListener.cs
- SqlCrossApplyToCrossJoin.cs
- EntityRecordInfo.cs
- ParallelEnumerableWrapper.cs
- SoapAttributeOverrides.cs
- CodeArrayCreateExpression.cs
- Point4D.cs
- DataSourceView.cs
- ScaleTransform3D.cs
- Window.cs
- AdornerHitTestResult.cs
- SelectionPattern.cs
- ThemeInfoAttribute.cs
- X509Chain.cs
- HostSecurityManager.cs
- SqlRecordBuffer.cs
- XPathArrayIterator.cs
- ApplicationDirectory.cs
- HtmlInputPassword.cs
- DataListItemCollection.cs
- SQLDecimal.cs
- BamlLocalizableResourceKey.cs
- DivideByZeroException.cs
- ScriptControlManager.cs
- SID.cs
- HttpHeaderCollection.cs
- HtmlImage.cs
- RefExpr.cs
- SocketInformation.cs
- XPathDescendantIterator.cs
- DiscoveryClientDuplexChannel.cs
- PromptBuilder.cs
- XamlUtilities.cs
- WorkflowInstanceAbortedRecord.cs
- Regex.cs