/// <summary>
        /// Reads the current value of <see cref="Cursor"/>.
        /// </summary>
        /// <param name="itemValue">A <see cref="ResourcePoolItem{MemoryStream}"/> that provides
        /// streams used for deserializing the value.</param>
        /// <param name="valueBuffer">Outputs the <see cref="DataBuffer"/> value read.</param>
        /// <returns>The <see cref="Int32"/> length of the cursor read.</returns>
        public int ReadCursor(ResourcePoolItem <MemoryStream> itemValue, out DataBuffer valueBuffer)
        {
            var valueStream = itemValue.Item;

            valueBuffer = SerializingObjectStorage.GetReadBuffer(valueStream);
            var results = Cursor.Get(valueBuffer, true);

            if (results < 0)
            {
                return(results);
            }
            var bfExcessValue = SerializingObjectStorage.GetExcessBuffer(valueStream, valueBuffer, results);

            if (!bfExcessValue.IsEmpty)
            {
                var len = valueBuffer.Length;
                valueBuffer = bfExcessValue;
                if (!Storage.Storage.SupportsIncompleteReads)
                {
                    bfExcessValue = bfExcessValue.RestrictOffset(len);
                    results       = Cursor.Get(len, bfExcessValue, false);
                    if (results >= 0)
                    {
                        results += len;
                    }
                }
                else
                {
                    results = Cursor.Get(0, bfExcessValue, false);
                }
            }
            return(results);
        }
예제 #2
0
        /// <summary>
        ///     <para>Initializes a new instance of the <see cref="ObjectListForSingles{T, THeader}"/> class
        ///		for an existing list.</para>
        /// </summary>
        /// <param name="storage">
        ///     <para>The <see cref="SerializingObjectStorage"/> containing the list.</para>
        /// </param>
        /// <param name="keySpace">
        ///     <para>The <see cref="DataBuffer"/> keyspace the list is stored in.</para>
        /// </param>
        /// <param name="key">
        ///     <para>The single <see cref="StorageKey"/> all the binary entries are
        /// stored under.</para>
        /// </param>
        /// <param name="buffer">
        ///		<para><see cref="DataBuffer"/> that holds the entire list. If
        ///		<see cref="DataBuffer.IsEmpty"/> is true, then the list is read
        ///		from <paramref name="storage"/>.</para>
        /// </param>
        /// <param name="creator">
        ///     <para>The <see cref="Func{T}"/> that produces new <typeparamref name="T"/>
        ///		instances for deserialization.</para>
        /// </param>
        /// <param name="headerCreator">
        ///     <para>The <see cref="Func{THeader}"/> that produces new <typeparamref name="THeader"/>
        ///		instances for deserialization.</para>
        /// </param>
        public ObjectListForSingles(SerializingObjectStorage storage, DataBuffer keySpace,
                                    StorageKey key, DataBuffer buffer, Func <T> creator, Func <THeader> headerCreator)
            : this(storage, keySpace, key, creator)
        {
            ArraySegment <byte> seg;

            if (buffer.IsEmpty)
            {
                _stream = _pooled.Item;
                buffer  = SerializingObjectStorage.GetReadBuffer(_stream);
                var entryLen = storage.Storage.Get(keySpace, key, buffer);
                if (entryLen < 0)
                {
                    throw new ApplicationException(string.Format(
                                                       "No list found for key space '{0}', key '{1}'",
                                                       keySpace, key));
                }
                var bfExcess = SerializingObjectStorage.GetExcessBuffer(_stream, buffer,
                                                                        entryLen);
                if (bfExcess.IsEmpty)
                {
                    buffer = buffer.Restrict(entryLen);
                }
                else
                {
                    if (storage.Storage.SupportsIncompleteReads)
                    {
                        storage.Storage.Get(keySpace, key, buffer.Length,
                                            bfExcess.RestrictOffset(buffer.Length));
                    }
                    else
                    {
                        storage.Storage.Get(keySpace, key, 0, bfExcess);
                    }
                    buffer = bfExcess;
                }
                seg = buffer.ByteArraySegmentValue;
            }
            else
            {
                _pooled.Dispose();
                _pooled = null;
                seg     = buffer.ByteArraySegmentValue;
                _stream = new MemoryStream(seg.Array, seg.Offset, seg.Count);
            }
            var ticks = BitConverter.ToInt64(seg.Array, seg.Offset);

            // expires listed first, since SetExpires can change it by itself
            // and this way it doesn't have to worry about future changes
            // to header
            Expires          = new DateTime(ticks);
            _stream.Position = sizeof(long);
            _header          = headerCreator();
            Serializer.Deserialize(_stream, _header);
            _headerLength = _stream.Position;
        }