public SecureStream(IClient client)
            : base()
        {
            this.FlushLock = new object();
            this.stream    = new MemoryStream();
            this.Client    = client;

            lock (client.Connection)
            {
                RandomDecimal rnd = new RandomDecimal(DateTime.Now.Millisecond);
                StreamId = rnd.NextDecimal();
                while (client.Connection.Streams.ContainsKey(StreamId))
                {
                    StreamId = rnd.NextDecimal();
                }

                client.Connection.Streams.Add(StreamId, this);
                this.StreamLock = new SyncObject(client);
                client.Connection.SendMessage(new MsgOpenStream(this.StreamId), PacketId.StreamMessages);

                MsgOpenStreamResponse response = StreamLock.Wait <MsgOpenStreamResponse>(default(MsgOpenStreamResponse), 30000);

                if (response == null)
                {
                    throw new TimeoutException("It took too long for the remote host to setup the Stream");
                }

                IsOpen          = true;
                this.StreamLock = new SyncObject(client);
                this.ReadLock   = new SyncObject(client);
            }
        }
        public LockedNodeFileStream(FileStream backingStream, bool poolStreams = true)
        {
            if (this._backingStream is null)
            {
                if (backingStream is null)
                {
                    throw new ArgumentNullException(nameof(backingStream));
                }

                this._backingStream = backingStream;

                if (poolStreams)
                {
                    for (int i = 0; i < StreamPool.Length; i++)
                    {
                        StreamPool[i] = new StreamLock(backingStream);
                    }
                }
            }

            this.PoolStreams = poolStreams;
        }
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (IsClosed)
            {
                return(-1);
            }

            while (stream.Length == 0)
            {
                ReadLock.Wait <object>(null, (uint)this.ReadTimeout);
                ReadLock = new SyncObject(Client);

                //maybe needs to be remove but still... there was a time out set on it
                if (stream.Length == 0)
                {
                    return(0);
                }
                ReadLock = new SyncObject(Client);
            }

            lock (FlushLock)
            {
                stream.Position = 0;
                int read = stream.Read(buffer, offset, count);

                //need a better method soon
                int    size = (int)(stream.Length - stream.Position);
                byte[] temp = new byte[size];
                stream.Read(temp, 0, size);
                this.stream = new MemoryStream();
                this.stream.Write(temp, 0, temp.Length);

                StreamLock.Pulse();
                return(read);
            }
        }
        public byte[] ReadBlock(long offset)
        {
            byte[] bByte;

            FileStream sourceStream;
            StreamLock sl = default;

            if (this.PoolStreams)
            {
                while (!Monitor.TryEnter((sl = StreamPool[StreamPointer++ % StreamPool.Length]).LockObject))
                {
                }
                if (StreamPointer >= StreamPool.Length)
                {
                    StreamPointer = 0;
                }
                sourceStream = sl.Stream;

                //sourceStream = new FileStream(StreamPool[0].Stream.Name, FileMode.Open, FileAccess.Read, FileShare.Read);
            }
            else
            {
                sourceStream = this._backingStream;
            }

            sourceStream.Seek(offset, SeekOrigin.Begin);

            int childCount;

            switch (offset)
            {
            case DiskNode.HEADER_BYTES:
                bByte = new byte[DiskNode.NODE_SIZE + 4];
                sourceStream.Read(bByte, 0, bByte.Length);
                childCount = bByte.GetInt(DiskNode.NODE_SIZE);
                break;

            default:
                bByte = new byte[DiskNode.NODE_SIZE + 2];
                sourceStream.Read(bByte, 0, bByte.Length);
                childCount = bByte.GetShort(DiskNode.NODE_SIZE);
                break;
            }

            if (childCount == 0)
            {
                if (this.PoolStreams)
                {
                    Monitor.Exit(sl.LockObject);
                }

                return(bByte);
            }

            byte[] cByte = new byte[childCount * DiskNode.NEXT_SIZE];

            sourceStream.Read(cByte, 0, cByte.Length);

            if (this.PoolStreams)
            {
                Monitor.Exit(sl.LockObject);
            }

            byte[] toReturn = new byte[bByte.Length + cByte.Length];

            bByte.CopyTo(toReturn, 0);

            cByte.CopyTo(toReturn, DiskNode.NODE_SIZE + (offset == DiskNode.HEADER_BYTES ? 4 : 2));

            return(toReturn);
        }