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); }
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; }