Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / Net / System / Net / Cache / _SingleItemRequestCache.cs / 1 / _SingleItemRequestCache.cs
/*++ Copyright (c) Microsoft Corporation Module Name: _SingleItemRequestCache.cs Abstract: Request Caching subsystem capable of caching one file at a time. Used by, for example, auto-proxy script downloading. Author: Justin Brown - Aug 2, 2004 Revision History: --*/ namespace System.Net.Cache { using System; using System.Net; using System.Diagnostics; using System.Text; using System.IO; using System.Collections.Specialized; using System.Threading; using System.Collections; internal class SingleItemRequestCache : #if !FEATURE_PAL Microsoft.Win32.WinInetCache #else RequestCache #endif { bool _UseWinInet; FrozenCacheEntry _Entry; private sealed class FrozenCacheEntry: RequestCacheEntry { byte[] _StreamBytes; string _Key; public FrozenCacheEntry(string key, RequestCacheEntry entry, Stream stream): this(key, entry, GetBytes(stream)) { } public FrozenCacheEntry(string key, RequestCacheEntry entry, byte[] streamBytes): base() { _Key = key; _StreamBytes = streamBytes; IsPrivateEntry = entry.IsPrivateEntry; StreamSize = entry.StreamSize; ExpiresUtc = entry.ExpiresUtc; HitCount = entry.HitCount; LastAccessedUtc = entry.LastAccessedUtc; entry.LastModifiedUtc = entry.LastModifiedUtc; LastSynchronizedUtc = entry.LastSynchronizedUtc; MaxStale = entry.MaxStale; UsageCount = entry.UsageCount; IsPartialEntry = entry.IsPartialEntry; EntryMetadata = entry.EntryMetadata; SystemMetadata = entry.SystemMetadata; } static byte[] GetBytes(Stream stream) { byte[] bytes; bool resize = false; if (stream.CanSeek) bytes = new byte[stream.Length]; else { resize = true; bytes = new byte[4096*2]; } int offset = 0; while (true) { int read = stream.Read(bytes, offset, bytes.Length-offset); if (read == 0) break; if ((offset+=read) == bytes.Length && resize) { byte[] newBytes = new byte[bytes.Length+4096*2]; Buffer.BlockCopy(bytes, 0, newBytes, 0, offset); bytes = newBytes; } } if (resize) { byte[] newBytes = new byte[offset]; Buffer.BlockCopy(bytes, 0, newBytes, 0, offset); bytes = newBytes; } return bytes; } public static FrozenCacheEntry Create(FrozenCacheEntry clonedObject) { return (object)clonedObject == (object)null? null: (FrozenCacheEntry) clonedObject.MemberwiseClone(); } public byte[] StreamBytes { get {return _StreamBytes;}} public string Key { get {return _Key;}} } internal SingleItemRequestCache(bool useWinInet) : #if !FEATURE_PAL base(true, true, false) #else base(true, true) #endif { _UseWinInet = useWinInet; } // Returns a read data stream and metadata associated with a cached entry. // Returns Stream.Null if there is no entry found. //An opened cache entry be preserved until the stream is closed. // internal override Stream Retrieve(string key, out RequestCacheEntry cacheEntry) { Stream result; if (!TryRetrieve(key, out cacheEntry, out result)) { FileNotFoundException fileNotFoundException = new FileNotFoundException(null, key); throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, fileNotFoundException.Message), fileNotFoundException); } return result; } // Returns a write cache stream associated with the string Key. // Passed parameters allow cache to update an entry metadata accordingly. //The commit operation should happen on the stream closure. // internal override Stream Store(string key, long contentLength, DateTime expiresUtc, DateTime lastModifiedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata) { Stream result; if (!TryStore(key, contentLength, expiresUtc, lastModifiedUtc, maxStale, entryMetadata, systemMetadata, out result)) { FileNotFoundException fileNotFoundException = new FileNotFoundException(null, key); throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, fileNotFoundException.Message), fileNotFoundException); } return result; } // // Removes an entry from the cache. // internal override void Remove(string key) { if (!TryRemove(key)) { FileNotFoundException fileNotFoundException = new FileNotFoundException(null, key); throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, fileNotFoundException.Message), fileNotFoundException); } } // // Updates only metadata associated with a cached entry. // internal override void Update(string key, DateTime expiresUtc, DateTime lastModifiedUtc, DateTime lastSynchronizedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata) { if (!TryUpdate(key, expiresUtc, lastModifiedUtc, lastSynchronizedUtc, maxStale, entryMetadata, systemMetadata)) { FileNotFoundException fileNotFoundException = new FileNotFoundException(null, key); throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, fileNotFoundException.Message), fileNotFoundException); } } internal override bool TryRetrieve(string key, out RequestCacheEntry cacheEntry, out Stream readStream) { if (key == null) throw new ArgumentNullException("key"); FrozenCacheEntry chkEntry = _Entry; cacheEntry = null; readStream = null; if (chkEntry == null || chkEntry.Key != key) { #if !FEATURE_PAL Stream realCacheStream; RequestCacheEntry realCacheEntry; if (!_UseWinInet || !base.TryRetrieve(key, out realCacheEntry, out realCacheStream)) return false; chkEntry = new FrozenCacheEntry(key, realCacheEntry, realCacheStream); // Relasing the WinInet entry earlier because we don't forward metadata-only updates ot it. realCacheStream.Close(); _Entry = chkEntry; #else return false; #endif } cacheEntry = FrozenCacheEntry.Create(chkEntry); readStream = new ReadOnlyStream(chkEntry.StreamBytes); return true; } internal override bool TryStore(string key, long contentLength, DateTime expiresUtc, DateTime lastModifiedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata, out Stream writeStream) { if (key == null) throw new ArgumentNullException("key"); RequestCacheEntry requestCacheEntry = new RequestCacheEntry(); requestCacheEntry.IsPrivateEntry = this.IsPrivateCache; requestCacheEntry.StreamSize = contentLength; requestCacheEntry.ExpiresUtc = expiresUtc; requestCacheEntry.LastModifiedUtc = lastModifiedUtc; requestCacheEntry.LastAccessedUtc = DateTime.UtcNow; requestCacheEntry.LastSynchronizedUtc = DateTime.UtcNow; requestCacheEntry.MaxStale = maxStale; requestCacheEntry.HitCount = 0; requestCacheEntry.UsageCount = 0; requestCacheEntry.IsPartialEntry = false; requestCacheEntry.EntryMetadata = entryMetadata; requestCacheEntry.SystemMetadata = systemMetadata; writeStream = null; Stream realWriteStream = null; #if !FEATURE_PAL if (_UseWinInet) { base.TryStore(key, contentLength, expiresUtc, lastModifiedUtc, maxStale, entryMetadata, systemMetadata, out realWriteStream); } #endif writeStream = new WriteOnlyStream(key, this, requestCacheEntry, realWriteStream); return true; } private void Commit(string key, RequestCacheEntry tempEntry, byte[] allBytes) { FrozenCacheEntry chkEntry = new FrozenCacheEntry(key, tempEntry, allBytes); _Entry = chkEntry; } internal override bool TryRemove(string key) { if (key == null) throw new ArgumentNullException("key"); #if !FEATURE_PAL if (_UseWinInet) { base.TryRemove(key); } #endif FrozenCacheEntry chkEntry = _Entry; if (chkEntry != null && chkEntry.Key == key) _Entry = null; return true; } internal override bool TryUpdate(string key, DateTime expiresUtc, DateTime lastModifiedUtc, DateTime lastSynchronizedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata) { if (key == null) throw new ArgumentNullException("key"); FrozenCacheEntry chkEntry = FrozenCacheEntry.Create(_Entry); // // This class does not forward metadata updates to WinInet to simplify the design and avoid interlocked ops // if (chkEntry == null || chkEntry.Key != key) return true; chkEntry.ExpiresUtc = expiresUtc; chkEntry.LastModifiedUtc = lastModifiedUtc; chkEntry.LastSynchronizedUtc = lastSynchronizedUtc; chkEntry.MaxStale = maxStale; chkEntry.EntryMetadata = entryMetadata; chkEntry.SystemMetadata = systemMetadata; _Entry = chkEntry; return true; } // // We've chosen to no forward to WinInet metadata-only updates // Hence our entries are never locked and this method does nothing // internal override void UnlockEntry(Stream stream) { } // // // internal class ReadOnlyStream : Stream { private byte[] _Bytes; private int _Offset; private bool _Disposed; private int _ReadTimeout; private int _WriteTimeout; internal ReadOnlyStream(byte[] bytes): base() { _Bytes = bytes; _Offset = 0; _Disposed = false; _ReadTimeout = _WriteTimeout = -1; } public override bool CanRead {get {return true;}} public override bool CanSeek {get {return true;}} public override bool CanTimeout {get {return true;}} public override bool CanWrite {get {return false;}} public override long Length {get {return _Bytes.Length;}} public override long Position { get {return _Offset;} set { if (value < 0 || value > (long)_Bytes.Length) throw new ArgumentOutOfRangeException("value"); _Offset = (int)value; } } public override int ReadTimeout { get {return _ReadTimeout;} set { if (value<=0 && value!=System.Threading.Timeout.Infinite) throw new ArgumentOutOfRangeException(SR.GetString(SR.net_io_timeout_use_gt_zero)); _ReadTimeout = value; } } public override int WriteTimeout { get {return _WriteTimeout;} set { if (value<=0 && value!=System.Threading.Timeout.Infinite) throw new ArgumentOutOfRangeException(SR.GetString(SR.net_io_timeout_use_gt_zero)); _WriteTimeout = value; } } public override void Flush() {} public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state) { int result = Read(buffer, offset, count); LazyAsyncResult ar = new LazyAsyncResult(null, state, callback); ar.InvokeCallback(result); return ar; } public override int EndRead(IAsyncResult asyncResult) { if (asyncResult == null) throw new ArgumentNullException("asyncResult"); LazyAsyncResult ar = (LazyAsyncResult) asyncResult; if (ar.EndCalled) throw new InvalidOperationException(SR.GetString(SR.net_io_invalidendcall, "EndRead")); ar.EndCalled = true; return (int)ar.InternalWaitForCompletion(); } public override int Read(byte[] buffer, int offset, int count) { if (_Disposed) throw new ObjectDisposedException(GetType().Name); if (buffer==null) throw new ArgumentNullException("buffer"); if (offset<0 || offset>buffer.Length) throw new ArgumentOutOfRangeException("offset"); if (count<0 || count>buffer.Length-offset) throw new ArgumentOutOfRangeException("count"); if (_Offset == _Bytes.Length) return 0; int chkOffset = (int)_Offset; count = Math.Min(count, _Bytes.Length - chkOffset); System.Buffer.BlockCopy(_Bytes, chkOffset, buffer, offset, count); chkOffset += count; _Offset = chkOffset; return count; } public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) { throw new NotSupportedException(SR.GetString(SR.net_readonlystream)); } public override void EndWrite(IAsyncResult asyncResult) { throw new NotSupportedException(SR.GetString(SR.net_readonlystream)); } public override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(SR.GetString(SR.net_readonlystream)); } public override long Seek(long offset, SeekOrigin origin) { switch (origin) { case SeekOrigin.Begin: return Position = offset; case SeekOrigin.Current: return Position += offset; ///case SeekOrigin.End: return Position = _Bytes.Length-offset; default: throw new ArgumentException(SR.GetString(SR.net_invalid_enum, "SeekOrigin"), "origin"); } } public override void SetLength(long length) { throw new NotSupportedException(SR.GetString(SR.net_readonlystream)); } protected override void Dispose(bool disposing) { try { _Disposed = true; } finally { base.Dispose(disposing); } } internal byte[] Buffer { get { return _Bytes; } } } // // // private class WriteOnlyStream: Stream { private string _Key; private SingleItemRequestCache _Cache; private RequestCacheEntry _TempEntry; private Stream _RealStream; private long _TotalSize; private ArrayList _Buffers; private bool _Disposed; private int _ReadTimeout; private int _WriteTimeout; public WriteOnlyStream(string key, SingleItemRequestCache cache, RequestCacheEntry cacheEntry, Stream realWriteStream) { _Key = key; _Cache = cache; _TempEntry = cacheEntry; _RealStream = realWriteStream; _Buffers = new ArrayList(); } public override bool CanRead {get {return false;}} public override bool CanSeek {get {return false;}} public override bool CanTimeout {get {return true;}} public override bool CanWrite {get {return true;}} public override long Length {get {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));}} public override long Position { get {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));} set {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));} } public override int ReadTimeout { get {return _ReadTimeout;} set { if (value<=0 && value!=System.Threading.Timeout.Infinite) throw new ArgumentOutOfRangeException(SR.GetString(SR.net_io_timeout_use_gt_zero)); _ReadTimeout = value; } } public override int WriteTimeout { get {return _WriteTimeout;} set { if (value<=0 && value!=System.Threading.Timeout.Infinite) throw new ArgumentOutOfRangeException(SR.GetString(SR.net_io_timeout_use_gt_zero)); _WriteTimeout = value; } } public override void Flush() {} public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state) {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));} public override int EndRead(IAsyncResult asyncResult) {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));} public override int Read(byte[] buffer, int offset, int count) {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));} public override long Seek(long offset, SeekOrigin origin) {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));} public override void SetLength(long length) {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));} public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, Object state) { Write(buffer, offset, count); LazyAsyncResult ar = new LazyAsyncResult(null, state, callback); ar.InvokeCallback(null); return ar; } public override void EndWrite(IAsyncResult asyncResult) { if (asyncResult == null) throw new ArgumentNullException("asyncResult"); LazyAsyncResult ar = (LazyAsyncResult) asyncResult; if (ar.EndCalled) throw new InvalidOperationException(SR.GetString(SR.net_io_invalidendcall, "EndWrite")); ar.EndCalled = true; ar.InternalWaitForCompletion(); } public override void Write(byte[] buffer, int offset, int count) { if (_Disposed) throw new ObjectDisposedException(GetType().Name); if (buffer==null) throw new ArgumentNullException("buffer"); if (offset<0 || offset>buffer.Length) throw new ArgumentOutOfRangeException("offset"); if (count<0 || count>buffer.Length-offset) throw new ArgumentOutOfRangeException("count"); if (_RealStream != null) try { _RealStream.Write(buffer, offset, count); } catch { _RealStream.Close(); _RealStream = null; } byte[] chunk = new byte[count]; System.Buffer.BlockCopy(buffer, offset, chunk, 0, count); _Buffers.Add(chunk); _TotalSize += count; } protected override void Dispose(bool disposing) { _Disposed = true; base.Dispose(disposing); // Do we mean to do this here???? if (disposing) { if (_RealStream != null) try { _RealStream.Close(); } catch { } byte[] allBytes = new byte[_TotalSize]; int offset = 0; for (int i = 0; i < _Buffers.Count; ++i) { byte[] buffer = (byte[])_Buffers[i]; Buffer.BlockCopy(buffer, 0, allBytes, offset, buffer.Length); offset += buffer.Length; } _Cache.Commit(_Key, _TempEntry, allBytes); } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. /*++ Copyright (c) Microsoft Corporation Module Name: _SingleItemRequestCache.cs Abstract: Request Caching subsystem capable of caching one file at a time. Used by, for example, auto-proxy script downloading. Author: Justin Brown - Aug 2, 2004 Revision History: --*/ namespace System.Net.Cache { using System; using System.Net; using System.Diagnostics; using System.Text; using System.IO; using System.Collections.Specialized; using System.Threading; using System.Collections; internal class SingleItemRequestCache : #if !FEATURE_PAL Microsoft.Win32.WinInetCache #else RequestCache #endif { bool _UseWinInet; FrozenCacheEntry _Entry; private sealed class FrozenCacheEntry: RequestCacheEntry { byte[] _StreamBytes; string _Key; public FrozenCacheEntry(string key, RequestCacheEntry entry, Stream stream): this(key, entry, GetBytes(stream)) { } public FrozenCacheEntry(string key, RequestCacheEntry entry, byte[] streamBytes): base() { _Key = key; _StreamBytes = streamBytes; IsPrivateEntry = entry.IsPrivateEntry; StreamSize = entry.StreamSize; ExpiresUtc = entry.ExpiresUtc; HitCount = entry.HitCount; LastAccessedUtc = entry.LastAccessedUtc; entry.LastModifiedUtc = entry.LastModifiedUtc; LastSynchronizedUtc = entry.LastSynchronizedUtc; MaxStale = entry.MaxStale; UsageCount = entry.UsageCount; IsPartialEntry = entry.IsPartialEntry; EntryMetadata = entry.EntryMetadata; SystemMetadata = entry.SystemMetadata; } static byte[] GetBytes(Stream stream) { byte[] bytes; bool resize = false; if (stream.CanSeek) bytes = new byte[stream.Length]; else { resize = true; bytes = new byte[4096*2]; } int offset = 0; while (true) { int read = stream.Read(bytes, offset, bytes.Length-offset); if (read == 0) break; if ((offset+=read) == bytes.Length && resize) { byte[] newBytes = new byte[bytes.Length+4096*2]; Buffer.BlockCopy(bytes, 0, newBytes, 0, offset); bytes = newBytes; } } if (resize) { byte[] newBytes = new byte[offset]; Buffer.BlockCopy(bytes, 0, newBytes, 0, offset); bytes = newBytes; } return bytes; } public static FrozenCacheEntry Create(FrozenCacheEntry clonedObject) { return (object)clonedObject == (object)null? null: (FrozenCacheEntry) clonedObject.MemberwiseClone(); } public byte[] StreamBytes { get {return _StreamBytes;}} public string Key { get {return _Key;}} } internal SingleItemRequestCache(bool useWinInet) : #if !FEATURE_PAL base(true, true, false) #else base(true, true) #endif { _UseWinInet = useWinInet; } // Returns a read data stream and metadata associated with a cached entry. // Returns Stream.Null if there is no entry found. // An opened cache entry be preserved until the stream is closed. // internal override Stream Retrieve(string key, out RequestCacheEntry cacheEntry) { Stream result; if (!TryRetrieve(key, out cacheEntry, out result)) { FileNotFoundException fileNotFoundException = new FileNotFoundException(null, key); throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, fileNotFoundException.Message), fileNotFoundException); } return result; } // Returns a write cache stream associated with the string Key. // Passed parameters allow cache to update an entry metadata accordingly. //The commit operation should happen on the stream closure. // internal override Stream Store(string key, long contentLength, DateTime expiresUtc, DateTime lastModifiedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata) { Stream result; if (!TryStore(key, contentLength, expiresUtc, lastModifiedUtc, maxStale, entryMetadata, systemMetadata, out result)) { FileNotFoundException fileNotFoundException = new FileNotFoundException(null, key); throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, fileNotFoundException.Message), fileNotFoundException); } return result; } // // Removes an entry from the cache. // internal override void Remove(string key) { if (!TryRemove(key)) { FileNotFoundException fileNotFoundException = new FileNotFoundException(null, key); throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, fileNotFoundException.Message), fileNotFoundException); } } // // Updates only metadata associated with a cached entry. // internal override void Update(string key, DateTime expiresUtc, DateTime lastModifiedUtc, DateTime lastSynchronizedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata) { if (!TryUpdate(key, expiresUtc, lastModifiedUtc, lastSynchronizedUtc, maxStale, entryMetadata, systemMetadata)) { FileNotFoundException fileNotFoundException = new FileNotFoundException(null, key); throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, fileNotFoundException.Message), fileNotFoundException); } } internal override bool TryRetrieve(string key, out RequestCacheEntry cacheEntry, out Stream readStream) { if (key == null) throw new ArgumentNullException("key"); FrozenCacheEntry chkEntry = _Entry; cacheEntry = null; readStream = null; if (chkEntry == null || chkEntry.Key != key) { #if !FEATURE_PAL Stream realCacheStream; RequestCacheEntry realCacheEntry; if (!_UseWinInet || !base.TryRetrieve(key, out realCacheEntry, out realCacheStream)) return false; chkEntry = new FrozenCacheEntry(key, realCacheEntry, realCacheStream); // Relasing the WinInet entry earlier because we don't forward metadata-only updates ot it. realCacheStream.Close(); _Entry = chkEntry; #else return false; #endif } cacheEntry = FrozenCacheEntry.Create(chkEntry); readStream = new ReadOnlyStream(chkEntry.StreamBytes); return true; } internal override bool TryStore(string key, long contentLength, DateTime expiresUtc, DateTime lastModifiedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata, out Stream writeStream) { if (key == null) throw new ArgumentNullException("key"); RequestCacheEntry requestCacheEntry = new RequestCacheEntry(); requestCacheEntry.IsPrivateEntry = this.IsPrivateCache; requestCacheEntry.StreamSize = contentLength; requestCacheEntry.ExpiresUtc = expiresUtc; requestCacheEntry.LastModifiedUtc = lastModifiedUtc; requestCacheEntry.LastAccessedUtc = DateTime.UtcNow; requestCacheEntry.LastSynchronizedUtc = DateTime.UtcNow; requestCacheEntry.MaxStale = maxStale; requestCacheEntry.HitCount = 0; requestCacheEntry.UsageCount = 0; requestCacheEntry.IsPartialEntry = false; requestCacheEntry.EntryMetadata = entryMetadata; requestCacheEntry.SystemMetadata = systemMetadata; writeStream = null; Stream realWriteStream = null; #if !FEATURE_PAL if (_UseWinInet) { base.TryStore(key, contentLength, expiresUtc, lastModifiedUtc, maxStale, entryMetadata, systemMetadata, out realWriteStream); } #endif writeStream = new WriteOnlyStream(key, this, requestCacheEntry, realWriteStream); return true; } private void Commit(string key, RequestCacheEntry tempEntry, byte[] allBytes) { FrozenCacheEntry chkEntry = new FrozenCacheEntry(key, tempEntry, allBytes); _Entry = chkEntry; } internal override bool TryRemove(string key) { if (key == null) throw new ArgumentNullException("key"); #if !FEATURE_PAL if (_UseWinInet) { base.TryRemove(key); } #endif FrozenCacheEntry chkEntry = _Entry; if (chkEntry != null && chkEntry.Key == key) _Entry = null; return true; } internal override bool TryUpdate(string key, DateTime expiresUtc, DateTime lastModifiedUtc, DateTime lastSynchronizedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata) { if (key == null) throw new ArgumentNullException("key"); FrozenCacheEntry chkEntry = FrozenCacheEntry.Create(_Entry); // // This class does not forward metadata updates to WinInet to simplify the design and avoid interlocked ops // if (chkEntry == null || chkEntry.Key != key) return true; chkEntry.ExpiresUtc = expiresUtc; chkEntry.LastModifiedUtc = lastModifiedUtc; chkEntry.LastSynchronizedUtc = lastSynchronizedUtc; chkEntry.MaxStale = maxStale; chkEntry.EntryMetadata = entryMetadata; chkEntry.SystemMetadata = systemMetadata; _Entry = chkEntry; return true; } // // We've chosen to no forward to WinInet metadata-only updates // Hence our entries are never locked and this method does nothing // internal override void UnlockEntry(Stream stream) { } // // // internal class ReadOnlyStream : Stream { private byte[] _Bytes; private int _Offset; private bool _Disposed; private int _ReadTimeout; private int _WriteTimeout; internal ReadOnlyStream(byte[] bytes): base() { _Bytes = bytes; _Offset = 0; _Disposed = false; _ReadTimeout = _WriteTimeout = -1; } public override bool CanRead {get {return true;}} public override bool CanSeek {get {return true;}} public override bool CanTimeout {get {return true;}} public override bool CanWrite {get {return false;}} public override long Length {get {return _Bytes.Length;}} public override long Position { get {return _Offset;} set { if (value < 0 || value > (long)_Bytes.Length) throw new ArgumentOutOfRangeException("value"); _Offset = (int)value; } } public override int ReadTimeout { get {return _ReadTimeout;} set { if (value<=0 && value!=System.Threading.Timeout.Infinite) throw new ArgumentOutOfRangeException(SR.GetString(SR.net_io_timeout_use_gt_zero)); _ReadTimeout = value; } } public override int WriteTimeout { get {return _WriteTimeout;} set { if (value<=0 && value!=System.Threading.Timeout.Infinite) throw new ArgumentOutOfRangeException(SR.GetString(SR.net_io_timeout_use_gt_zero)); _WriteTimeout = value; } } public override void Flush() {} public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state) { int result = Read(buffer, offset, count); LazyAsyncResult ar = new LazyAsyncResult(null, state, callback); ar.InvokeCallback(result); return ar; } public override int EndRead(IAsyncResult asyncResult) { if (asyncResult == null) throw new ArgumentNullException("asyncResult"); LazyAsyncResult ar = (LazyAsyncResult) asyncResult; if (ar.EndCalled) throw new InvalidOperationException(SR.GetString(SR.net_io_invalidendcall, "EndRead")); ar.EndCalled = true; return (int)ar.InternalWaitForCompletion(); } public override int Read(byte[] buffer, int offset, int count) { if (_Disposed) throw new ObjectDisposedException(GetType().Name); if (buffer==null) throw new ArgumentNullException("buffer"); if (offset<0 || offset>buffer.Length) throw new ArgumentOutOfRangeException("offset"); if (count<0 || count>buffer.Length-offset) throw new ArgumentOutOfRangeException("count"); if (_Offset == _Bytes.Length) return 0; int chkOffset = (int)_Offset; count = Math.Min(count, _Bytes.Length - chkOffset); System.Buffer.BlockCopy(_Bytes, chkOffset, buffer, offset, count); chkOffset += count; _Offset = chkOffset; return count; } public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) { throw new NotSupportedException(SR.GetString(SR.net_readonlystream)); } public override void EndWrite(IAsyncResult asyncResult) { throw new NotSupportedException(SR.GetString(SR.net_readonlystream)); } public override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(SR.GetString(SR.net_readonlystream)); } public override long Seek(long offset, SeekOrigin origin) { switch (origin) { case SeekOrigin.Begin: return Position = offset; case SeekOrigin.Current: return Position += offset; ///case SeekOrigin.End: return Position = _Bytes.Length-offset; default: throw new ArgumentException(SR.GetString(SR.net_invalid_enum, "SeekOrigin"), "origin"); } } public override void SetLength(long length) { throw new NotSupportedException(SR.GetString(SR.net_readonlystream)); } protected override void Dispose(bool disposing) { try { _Disposed = true; } finally { base.Dispose(disposing); } } internal byte[] Buffer { get { return _Bytes; } } } // // // private class WriteOnlyStream: Stream { private string _Key; private SingleItemRequestCache _Cache; private RequestCacheEntry _TempEntry; private Stream _RealStream; private long _TotalSize; private ArrayList _Buffers; private bool _Disposed; private int _ReadTimeout; private int _WriteTimeout; public WriteOnlyStream(string key, SingleItemRequestCache cache, RequestCacheEntry cacheEntry, Stream realWriteStream) { _Key = key; _Cache = cache; _TempEntry = cacheEntry; _RealStream = realWriteStream; _Buffers = new ArrayList(); } public override bool CanRead {get {return false;}} public override bool CanSeek {get {return false;}} public override bool CanTimeout {get {return true;}} public override bool CanWrite {get {return true;}} public override long Length {get {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));}} public override long Position { get {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));} set {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));} } public override int ReadTimeout { get {return _ReadTimeout;} set { if (value<=0 && value!=System.Threading.Timeout.Infinite) throw new ArgumentOutOfRangeException(SR.GetString(SR.net_io_timeout_use_gt_zero)); _ReadTimeout = value; } } public override int WriteTimeout { get {return _WriteTimeout;} set { if (value<=0 && value!=System.Threading.Timeout.Infinite) throw new ArgumentOutOfRangeException(SR.GetString(SR.net_io_timeout_use_gt_zero)); _WriteTimeout = value; } } public override void Flush() {} public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state) {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));} public override int EndRead(IAsyncResult asyncResult) {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));} public override int Read(byte[] buffer, int offset, int count) {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));} public override long Seek(long offset, SeekOrigin origin) {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));} public override void SetLength(long length) {throw new NotSupportedException(SR.GetString(SR.net_writeonlystream));} public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, Object state) { Write(buffer, offset, count); LazyAsyncResult ar = new LazyAsyncResult(null, state, callback); ar.InvokeCallback(null); return ar; } public override void EndWrite(IAsyncResult asyncResult) { if (asyncResult == null) throw new ArgumentNullException("asyncResult"); LazyAsyncResult ar = (LazyAsyncResult) asyncResult; if (ar.EndCalled) throw new InvalidOperationException(SR.GetString(SR.net_io_invalidendcall, "EndWrite")); ar.EndCalled = true; ar.InternalWaitForCompletion(); } public override void Write(byte[] buffer, int offset, int count) { if (_Disposed) throw new ObjectDisposedException(GetType().Name); if (buffer==null) throw new ArgumentNullException("buffer"); if (offset<0 || offset>buffer.Length) throw new ArgumentOutOfRangeException("offset"); if (count<0 || count>buffer.Length-offset) throw new ArgumentOutOfRangeException("count"); if (_RealStream != null) try { _RealStream.Write(buffer, offset, count); } catch { _RealStream.Close(); _RealStream = null; } byte[] chunk = new byte[count]; System.Buffer.BlockCopy(buffer, offset, chunk, 0, count); _Buffers.Add(chunk); _TotalSize += count; } protected override void Dispose(bool disposing) { _Disposed = true; base.Dispose(disposing); // Do we mean to do this here???? if (disposing) { if (_RealStream != null) try { _RealStream.Close(); } catch { } byte[] allBytes = new byte[_TotalSize]; int offset = 0; for (int i = 0; i < _Buffers.Count; ++i) { byte[] buffer = (byte[])_Buffers[i]; Buffer.BlockCopy(buffer, 0, allBytes, offset, buffer.Length); offset += buffer.Length; } _Cache.Commit(_Key, _TempEntry, allBytes); } } } } } // 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
- FixedDSBuilder.cs
- Bidi.cs
- PlanCompilerUtil.cs
- Stream.cs
- DataGridViewRow.cs
- URI.cs
- LineProperties.cs
- IOException.cs
- MetaData.cs
- AppearanceEditorPart.cs
- FileSecurity.cs
- EntitySqlQueryBuilder.cs
- WebPartAuthorizationEventArgs.cs
- AssemblyAssociatedContentFileAttribute.cs
- SurrogateDataContract.cs
- OptionUsage.cs
- AutomationElementIdentifiers.cs
- ArrayMergeHelper.cs
- ActivatedMessageQueue.cs
- PathGradientBrush.cs
- XmlBoundElement.cs
- HuffmanTree.cs
- UInt16Converter.cs
- TagPrefixInfo.cs
- CompositeTypefaceMetrics.cs
- MessageAction.cs
- TransactionManager.cs
- _ProxyChain.cs
- ImportCatalogPart.cs
- LoopExpression.cs
- TemplateBindingExtension.cs
- SvcMapFile.cs
- ActivityTypeDesigner.xaml.cs
- ServiceModelSectionGroup.cs
- RenamedEventArgs.cs
- HtmlTableRowCollection.cs
- CodePageUtils.cs
- RankException.cs
- MenuItemStyle.cs
- XXXInfos.cs
- FixedStringLookup.cs
- AutoCompleteStringCollection.cs
- EdmItemError.cs
- TouchesOverProperty.cs
- SingleConverter.cs
- FileBasedResourceGroveler.cs
- WebEvents.cs
- ResponseStream.cs
- UidManager.cs
- SmtpNetworkElement.cs
- FileUtil.cs
- ImageCreator.cs
- GetReadStreamResult.cs
- LineServices.cs
- BufferedGraphics.cs
- WindowsToolbarItemAsMenuItem.cs
- EntityRecordInfo.cs
- XmlQueryTypeFactory.cs
- HttpRequestCacheValidator.cs
- HandlerFactoryWrapper.cs
- ScanQueryOperator.cs
- ConfigXmlText.cs
- GcSettings.cs
- XmlSchemaAnnotated.cs
- CollectionView.cs
- ProcessHostConfigUtils.cs
- StackBuilderSink.cs
- DynamicFilter.cs
- SrgsRule.cs
- MediaContextNotificationWindow.cs
- OleDragDropHandler.cs
- NameObjectCollectionBase.cs
- DataColumnCollection.cs
- AssemblyUtil.cs
- DescendentsWalker.cs
- sqlinternaltransaction.cs
- BrowserCapabilitiesFactoryBase.cs
- SingleAnimationUsingKeyFrames.cs
- NextPreviousPagerField.cs
- OLEDB_Util.cs
- EventRouteFactory.cs
- FocusTracker.cs
- GraphicsState.cs
- GeneratedCodeAttribute.cs
- ParentUndoUnit.cs
- Matrix.cs
- SspiHelper.cs
- XmlQueryType.cs
- ModulesEntry.cs
- XmlJsonWriter.cs
- Cursors.cs
- WCFModelStrings.Designer.cs
- Encoder.cs
- ImportOptions.cs
- XPathParser.cs
- XmlDataSourceNodeDescriptor.cs
- BrowserCapabilitiesFactory.cs
- InputProcessorProfilesLoader.cs
- PropertyKey.cs
- MyContact.cs