コード例 #1
0
        private int ReadDelimiter(byte[] buffer, int offset, int count)
        {
            Debug.Assert(null != buffer, "null != buffer");
            Debug.Assert(0 <= offset, "0 <= offset");
            Debug.Assert(0 <= count, "0 <= count");
            Debug.Assert(offset + count <= buffer.Length, "offset + count <= buffer.Length");
            int copied = 0;

            string boundary  = null;
            string boundary1 = this.batchBoundary;
            string boundary2 = this.changesetBoundary;

            while ((0 < count) && (0 < this.batchLength) && this.ReadBuffer())
            {
                int boundaryIndex  = 0;
                int boundary1Index = 0;
                int boundary2Index = 0;

                int size = Math.Min(Math.Min(count, this.byteLength), this.batchLength) + this.bytePosition;

                byte[] data = this.byteBuffer;
                for (int i = this.bytePosition; i < size; ++i)
                {
                    byte value = data[i];
                    buffer[offset++] = value;
                    if ((char)value == boundary1[boundary1Index])
                    {
                        if (boundary1.Length == ++boundary1Index)
                        {
                            size    = (1 + i) - boundary1Index;
                            offset -= boundary1Index;
                            Debug.Assert(this.bytePosition <= size, "negative size");
                            break;
                        }
                    }
                    else
                    {
                        boundary1Index = 0;
                    }

                    if ((null != boundary2) && ((char)value == boundary2[boundary2Index]))
                    {
                        if (boundary2.Length == ++boundary2Index)
                        {
                            size    = (1 + i) - boundary2Index;
                            offset -= boundary2Index;
                            Debug.Assert(this.bytePosition <= size, "negative size");
                            break;
                        }
                    }
                    else
                    {
                        boundary2Index = 0;
                    }
                }

                size -= this.bytePosition;
                Debug.Assert(0 <= size, "negative size");

                if (boundary1Index < boundary2Index)
                {
                    boundaryIndex = boundary2Index;
                    boundary      = boundary2;
                }
                else
                {
                    Debug.Assert(null != boundary1, "batch boundary shouldn't be null");
                    boundaryIndex = boundary1Index;
                    boundary      = boundary1;
                }

                if (size == this.batchLength)
                {
                    boundaryIndex = 0;
                }

                if ((0 < boundaryIndex) && (boundary.Length != boundaryIndex))
                {
                    if ((size + copied == boundaryIndex) && (boundaryIndex < this.byteLength))
                    {
                        throw Error.BatchStreamInternalBufferRequestTooSmall();
                    }
                    else
                    {
                        size   -= boundaryIndex;
                        offset -= boundaryIndex;
                    }
                }

                this.totalCount   += size;
                this.bytePosition += size;
                this.byteLength   -= size;
                this.batchLength  -= size;

                count  -= size;
                copied += size;

                if (boundaryIndex > 0 && copied >= 2 && buffer[copied - 2] == '\r' && buffer[copied - 1] == '\n')
                {
                    copied -= 2;
                }

                if (boundary.Length == boundaryIndex)
                {
                    break;
                }
                else if (0 < boundaryIndex)
                {
                    if (boundaryIndex == this.byteLength)
                    {
                        if (0 < this.bytePosition)
                        {
                            Buffer.BlockCopy(data, this.bytePosition, data, 0, this.byteLength);
                            this.bytePosition = 0;
                        }

                        int tmp = this.reader.Read(this.byteBuffer, this.byteLength, this.byteBuffer.Length - this.byteLength);
                        if (null != this.writer)
                        {
                            this.writer.Write(this.byteBuffer, this.byteLength, tmp);
                        }

                        if (0 == tmp)
                        {
                            this.totalCount   += boundaryIndex;
                            this.bytePosition += boundaryIndex;
                            this.byteLength   -= boundaryIndex;
                            this.batchLength  -= boundaryIndex;

                            offset += boundaryIndex;
                            count  -= boundaryIndex;
                            copied += boundaryIndex;
                            break;
                        }

                        this.byteLength += tmp;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return(copied);
        }