static void _writeEnumeratorToEnd <T>(Stream stream,
                                              IEnumerator enumerator, ObjectToBytesConverter <T> converter,
                                              bool validityCheck)
        {
            var lengthPos = stream.Position;

            stream.WriteInt32(0);
            stream.WriteInt32(0);
            stream.WriteInt64(0);

            int len = 0;

            do
            {
                if (enumerator.Current != null)
                {
                    len += stream.WriteObject((T)enumerator.Current, converter, validityCheck);
                }
            }while (enumerator.MoveNext());

            var endPos = stream.Position;

            stream.SeekTo(lengthPos);
            stream.WriteInt32(len);
            stream.WriteInt32(len);
            stream.SeekTo(endPos);
        }
Beispiel #2
0
 public static int WriteObject <T>(this Stream stream, T obj, ObjectToBytesConverter <T> converter, bool validityCheck = true)
 {
     return(stream.WriteByteArray(converter(obj), validityCheck));
 }
        /// <summary>
        /// Writes a set of objects, each of them fetched from an enumerator, to this stream.
        /// </summary>
        /// <param name="stream">A <see cref="System.IO.Stream"/>.</param>
        /// <param name="enumerator">An enumerator used to get each object.</param>
        /// <param name="mode">Indicates whether to override existing list or create a new list in the stream.</param>
        /// <param name="converter">A delegate used to convert each item in the list to a byte array.</param>
        /// <param name="validityCheck">Indicates whether to write a validity-check countersign before the list in the stream.</param>
        public static void WriteObjects <T>(this Stream stream, IEnumerator enumerator, WritingMode mode,
                                            ObjectToBytesConverter <T> converter, bool validityCheck = true)
        {
            if (mode == WritingMode.New)
            {
                if (validityCheck)
                {
                    stream.WriteCheckCode((Int64)29);
                }

                if (enumerator.MoveNext())
                {
                    _writeEnumeratorToEnd(stream, enumerator, converter, validityCheck);
                }
                else
                {
                    stream.WriteInt32(0);
                    stream.WriteInt32(0);
                    stream.WriteInt64(0);
                }
            }
            else
            {
                if (!validityCheck || stream.Check((Int64)29))
                {
                    int  i        = 0;
                    bool moreObjs = enumerator.MoveNext();
                    if (!moreObjs)
                    {
                        stream.SkipInt32();
                        stream.WriteInt32(0);
                        var next = stream.ReadInt64();
                        stream.WriteInt64(-Math.Abs(next));
                        return;
                    }

                    while (moreObjs)
                    {
                        var len  = stream.ReadInt32();
                        var olen = len;

                        var usedLenPos = stream.Position;
                        var usedLen    = stream.ReadInt32();

                        var nextPtrPos = stream.Position;
                        var next       = stream.ReadInt64();

                        int objLen;
                        for (; len > 0 && moreObjs; len -= objLen, i++)
                        {
                            var b = converter((T)enumerator.Current);
                            objLen = stream._byteArrayOccupancy(b, validityCheck);

                            if (objLen > len)
                            {
                                break;
                            }
                            else
                            {
                                stream.WriteByteArray(b, validityCheck);
                                moreObjs = enumerator.MoveNext();
                            }
                        }

                        var nUsedLen = olen - len;

                        var currPos = stream.Position;
                        stream.SeekTo(usedLenPos);
                        stream.WriteInt32(nUsedLen);
                        stream.SeekTo(currPos);

                        if (moreObjs)
                        {
                            if (next == 0)
                            {
                                stream.SeekTo(nextPtrPos);
                                stream.WriteInt64(stream.Length);
                                stream.SeekToEnd();

                                _writeEnumeratorToEnd(stream, enumerator, converter, validityCheck);
                                break;
                            }
                            else
                            {
                                if (next < 0)
                                {
                                    stream.SeekTo(nextPtrPos);
                                    next = -next;
                                    stream.WriteInt64(next);
                                }
                                stream.SeekTo(next);
                            }
                        }
                        else
                        {
                            if (next != 0)
                            {
                                currPos = stream.Position;
                                stream.SeekTo(nextPtrPos);
                                stream.WriteInt64(-Math.Abs(next));
                                stream.SeekTo(currPos);
                                break;
                            }
                        }
                    }
                }
                else
                {
                    throw new InvalidDataException(IOResources.ERR_StreamExtension_DataIrrecognizable);
                }
            }
        }