Example #1
0
        public IEnumerable <byte> GetBoundaryWithoutLeadingCRLF()
        {
            var rawBoundary = GetBoundary();
            var result      = new Couchbase.Lite.Util.ArraySegment <Byte>(rawBoundary, 2, rawBoundary.Length - 2);

            return(result);
        }
        public void AppendData(IEnumerable<byte> newData)
        {
            if (newData == null) {
                return;
            }

            var data = newData.ToArray();
            if (_buffer == null || data.Length == 0) {
                return;
            }

            _buffer.AddRange(data);

            MultipartReader.MultipartReaderState nextState;
            do {
                nextState = MultipartReader.MultipartReaderState.Uninitialized;
                var bufLen = _buffer.Count;
                switch (state) {
                    case MultipartReader.MultipartReaderState.AtStart:
                        // The entire message might start with a boundary without a leading CRLF.
                        var boundaryWithoutLeadingCRLF = TrimmedBoundary.ToArray();
                        if (bufLen >= boundaryWithoutLeadingCRLF.Length) {
                            // if (Arrays.equals(buffer.toByteArray(), boundaryWithoutLeadingCRLF)) {
                            if (Memcmp(_buffer.ToArray(), boundaryWithoutLeadingCRLF, boundaryWithoutLeadingCRLF.Length)) {
                                DeleteUpThrough(boundaryWithoutLeadingCRLF.Length);
                                nextState = MultipartReader.MultipartReaderState.InHeaders;
                            } else {
                                nextState = MultipartReader.MultipartReaderState.InPrologue;
                            }
                        }
                        break;
                    case MultipartReader.MultipartReaderState.InPrologue:
                    case MultipartReader.MultipartReaderState.InBody:
                        // Look for the next part boundary in the data we just added and the ending bytes of
                        // the previous data (in case the boundary string is split across calls)
                        if (bufLen < _boundary.Length) {
                            break;
                        }

                        var start = Math.Max(0, bufLen - data.Length - _boundary.Length);
                        var r = SearchFor(_boundary, start);

                        if (r.Length > 0) {
                            if (state == MultipartReader.MultipartReaderState.InBody) {
                                var dataToAppend = new byte[r.Location];
                                Array.Copy(_buffer.ToArray(), 0, dataToAppend, 0, dataToAppend.Length);
                                _readerDelegate.AppendToPart(dataToAppend);
                                _readerDelegate.FinishedPart();
                            }

                            DeleteUpThrough(r.Location + r.Length);
                            nextState = MultipartReader.MultipartReaderState.InHeaders;
                        } else {
                            TrimBuffer();
                        }
                        break;
                    case MultipartReader.MultipartReaderState.InHeaders:
                        // First check for the end-of-message string ("--" after separator):
                        if (bufLen >= 2 && Memcmp(_buffer.ToArray(), EOM_BYTES, 2)) {
                            state = MultipartReader.MultipartReaderState.AtEnd;
                            Close();
                            return;
                        }
                        // Otherwise look for two CRLFs that delimit the end of the headers:
                        var headerEnd = SearchFor(CRLF_CRLF, 0);
                        if (headerEnd.Length > 0) {
                            var headersBytes = new Couchbase.Lite.Util.ArraySegment<Byte>(_buffer.ToArray(), 0, headerEnd.Location); // <-- better?
                            var headersString = Encoding.UTF8.GetString(headersBytes.ToArray());
                            ParseHeaders(headersString);
                            DeleteUpThrough(headerEnd.Location + headerEnd.Length);
                            _readerDelegate.StartedPart(_headers);
                            nextState = MultipartReader.MultipartReaderState.InBody;
                        }
                        break;
                    default:
                        throw new InvalidOperationException("Unexpected data after end of MIME body");

                }

                if (nextState != MultipartReader.MultipartReaderState.Uninitialized) {
                    state = nextState;
                }
            } while (nextState != MultipartReader.MultipartReaderState.Uninitialized && _buffer.Count > 0);
        }
Example #3
0
        public void AppendData(IEnumerable <byte> newData)
        {
            var data = newData.ToArray();

            if (buffer == null)
            {
                return;
            }

            if (data.Length == 0)
            {
                return;
            }

            buffer.AddRange(data);

            MultipartReader.MultipartReaderState nextState;
            do
            {
                nextState = MultipartReader.MultipartReaderState.Uninitialized;
                var bufLen = buffer.Count;
                switch (state)
                {
                case MultipartReader.MultipartReaderState.AtStart:
                {
                    // Log.d(Database.TAG, "appendData.  bufLen: " + bufLen);
                    // The entire message might start with a boundary without a leading CRLF.
                    var boundaryWithoutLeadingCRLF = GetBoundaryWithoutLeadingCRLF().ToArray();
                    if (bufLen >= boundaryWithoutLeadingCRLF.Length)
                    {
                        // if (Arrays.equals(buffer.toByteArray(), boundaryWithoutLeadingCRLF)) {
                        if (Memcmp(buffer.ToArray(), boundaryWithoutLeadingCRLF, boundaryWithoutLeadingCRLF.Length))
                        {
                            DeleteUpThrough(boundaryWithoutLeadingCRLF.Length);
                            nextState = MultipartReader.MultipartReaderState.InHeaders;
                        }
                        else
                        {
                            nextState = MultipartReader.MultipartReaderState.InPrologue;
                        }
                    }
                    break;
                }

                case MultipartReader.MultipartReaderState.InPrologue:
                case MultipartReader.MultipartReaderState.InBody:
                {
                    // Look for the next part boundary in the data we just added and the ending bytes of
                    // the previous data (in case the boundary string is split across calls)
                    if (bufLen < boundary.Length)
                    {
                        break;
                    }

                    var start = Math.Max(0, bufLen - data.Length - boundary.Length);
                    var r     = SearchFor(boundary, start);

                    if (r.GetLength() > 0)
                    {
                        if (state == MultipartReader.MultipartReaderState.InBody)
                        {
                            var dataToAppend = new byte[r.GetLocation()];
                            Array.Copy(buffer.ToArray(), 0, dataToAppend, 0, dataToAppend.Length);
                            readerDelegate.AppendToPart(dataToAppend);
                            readerDelegate.FinishedPart();
                        }
                        DeleteUpThrough(r.GetLocation() + r.GetLength());
                        nextState = MultipartReader.MultipartReaderState.InHeaders;
                    }
                    else
                    {
                        TrimBuffer();
                    }
                    break;
                }

                case MultipartReader.MultipartReaderState.InHeaders:
                {
                    // First check for the end-of-message string ("--" after separator):
                    if (bufLen >= 2 && Memcmp(buffer.ToArray(), EOMBytes(), 2))
                    {
                        state = MultipartReader.MultipartReaderState.AtEnd;
                        Close();
                        return;
                    }
                    // Otherwise look for two CRLFs that delimit the end of the headers:
                    var r = SearchFor(kCRLFCRLF, 0);
                    if (r.GetLength() > 0)
                    {
                        var headersBytes  = new Couchbase.Lite.Util.ArraySegment <Byte>(buffer.ToArray(), 0, r.GetLocation());       // <-- better?
                        var headersString = Encoding.UTF8.GetString(headersBytes.ToArray());
                        ParseHeaders(headersString);
                        DeleteUpThrough(r.GetLocation() + r.GetLength());
                        readerDelegate.StartedPart(headers);
                        nextState = MultipartReader.MultipartReaderState.InBody;
                    }
                    break;
                }

                default:
                {
                    throw new InvalidOperationException("Unexpected data after end of MIME body");
                }
                }
                if (nextState != MultipartReader.MultipartReaderState.Uninitialized)
                {
                    state = nextState;
                }
            }while (nextState != MultipartReader.MultipartReaderState.Uninitialized && buffer.Count > 0);
        }
 public IEnumerable<byte> GetBoundaryWithoutLeadingCRLF()
 {
     var rawBoundary = GetBoundary();
     var result = new Couchbase.Lite.Util.ArraySegment<Byte>(rawBoundary, 2, rawBoundary.Length - 2);
     return result;
 }