Example #1
0
 protected override void Dispose(bool disposing)
 {
     // this is necessary because CanRead/Write/Seek should return false for a closed stream
     this.capabilities = new StreamCapabilities {
         CanTimeout = this.CanTimeout
     };
     base.Dispose(disposing);
 }
Example #2
0
 public TakeStream(Stream stream, long count, bool leaveOpen)
     : base(StreamCapabilities.InferFrom(stream).Intersect(ReadCapabilities), ReadCapabilities)
 {
     this.stream          = stream;
     this.count           = this.remaining = count;
     this.initialPosition = stream.CanSeek ? stream.Position : default(long?);
     this.leaveOpen       = leaveOpen;
 }
Example #3
0
 protected StreamBase(StreamCapabilities currentCapabilities, StreamCapabilities typeCapabilities)
 {
     if (currentCapabilities.Except(typeCapabilities) != StreamCapabilities.None)
     {
         throw new ArgumentException(nameof(currentCapabilities) + " may not exceed " + nameof(typeCapabilities));
     }
     VerifyCapabilities(this.GetType(), typeCapabilities);
     this.capabilities = currentCapabilities;
 }
Example #4
0
        private static void VerifyCapabilities(Type streamType, StreamCapabilities capabilities)
        {
            // safe because Hashtable is safe for multiple concurrent readers and one writer
            var cachedCapabilitiesObj = VerifiedTypeCache[streamType];

            if (cachedCapabilitiesObj != null)
            {
                var cachedCapabilities = (StreamCapabilities)cachedCapabilitiesObj;
                if (cachedCapabilities != capabilities)
                {
                    throw new ArgumentException($"{streamType} was previously validated for the following capabilities: {capabilities}. It cannot be revalidated for a different set of capabilities ({capabilities})");
                }
                return;
            }

            var requiredMethods = new HashSet <MethodInfo>();

            if (capabilities.CanSyncRead)
            {
                requiredMethods.Add(ReadMethod);
            }
            if (capabilities.CanAsyncRead)
            {
                requiredMethods.Add(ReadAsyncMethod);
            }
            if (capabilities.CanSyncWrite)
            {
                requiredMethods.Add(WriteMethod);
                requiredMethods.Add(FlushMethod);
            }
            if (capabilities.CanAsyncWrite)
            {
                requiredMethods.Add(WriteAsyncMethod);
                requiredMethods.Add(FlushAsyncMethod);
            }
            if (capabilities.CanGetLength)
            {
                requiredMethods.Add(GetLengthMethod);
            }
            if (capabilities.CanGetPosition)
            {
                requiredMethods.Add(GetPositionMethod);
            }
            if (capabilities.CanSeek)
            {
                if (capabilities.CanWrite)
                {
                    requiredMethods.Add(SetLengthMethod);
                }
                requiredMethods.Add(SetPositionMethod);
            }
            if (capabilities.CanTimeout)
            {
                if (capabilities.CanRead)
                {
                    requiredMethods.Add(ReadTimeoutProperty.GetMethod);
                    requiredMethods.Add(ReadTimeoutProperty.SetMethod);
                }
                if (capabilities.CanWrite)
                {
                    requiredMethods.Add(WriteTimeoutProperty.GetMethod);
                    requiredMethods.Add(WriteTimeoutProperty.SetMethod);
                }
            }

            var potentialOverrides = new HashSet <MethodInfo>(
                streamType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                .Where(m => m.DeclaringType != typeof(StreamBase))
                );

            var overrides = streamType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                            .Where(m => m.DeclaringType != typeof(StreamBase))
                            .Select(s => s.GetBaseDefinition())
                            .Where(OverridableMethods.Contains);

            foreach (var method in overrides)
            {
                if (!requiredMethods.Remove(method))
                {
                    throw new ArgumentException($"{streamType} override of method {method} does not match the specified capabilities");
                }
            }

            if (requiredMethods.Count > 0)
            {
                var missingMethods = string.Join(", ", requiredMethods);
                throw new ArgumentException($"Type {streamType} is missing the following overrides that are required to implement the provided capabilities: {missingMethods}");
            }

            lock (VerifiedTypeCache.SyncRoot)
            {
                VerifiedTypeCache[streamType] = null;
            }
        }
Example #5
0
 protected StreamBase(StreamCapabilities capabilities)
 {
     VerifyCapabilities(this.GetType(), capabilities);
     this.capabilities = capabilities;
 }
Example #6
0
 public AutoFlushedStream(Stream stream, bool leaveOpen)
     : base(StreamCapabilities.InferFrom(stream).Intersect(BaseCapabilities), BaseCapabilities)
 {
     this.stream    = stream;
     this.leaveOpen = leaveOpen;
 }
Example #7
0
 public ConcatStream(Stream first, Stream second)
     : base(StreamCapabilities.InferFrom(first).Intersect(StreamCapabilities.InferFrom(second)).Intersect(ReadCapabilities), ReadCapabilities)
 {
     this.first  = first;
     this.second = second;
 }