修改工单流程页面,订单列表增加工单按钮
This commit is contained in:
1 parent
f9dcae4610
commit
10bb0803d9
44 files changed
+5920
-1291
No files matched your search
@@ -0,0 +1,179 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace LaunchDarkly.EventSource
|
||||
{
|
||||
/// <summary>
|
||||
/// Internal implementation of a buffered text line parser for UTF-8 data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This is used as follows. 1. The caller puts some data into the byte buffer. 2. The caller
|
||||
/// calls ScanToEndOfLine; if it returns true, the <c>lineOut</c> parameter is set to point
|
||||
/// to the content of the line (not including the line ending character(s)). If it returns
|
||||
/// false, put more data into the buffer and try again.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Since in UTF-8 all multi-byte characters use values greater than 127 for all of their
|
||||
/// bytes, this logic doesn't need to do any UTF-8 decoding or even know how many bytes are
|
||||
/// in a character; it just looks for the line-ending sequences CR, LF, or CR+LF.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
internal struct ByteArrayLineScanner
|
||||
{
|
||||
private readonly byte[] _buffer;
|
||||
private readonly int _capacity;
|
||||
private int _count;
|
||||
private int _startPos;
|
||||
|
||||
public byte[] Buffer => _buffer;
|
||||
public int Capacity => _capacity;
|
||||
public int Count => _count;
|
||||
public int Available => _capacity - _count;
|
||||
|
||||
private MemoryStream _partialLine;
|
||||
|
||||
public ByteArrayLineScanner(int capacity)
|
||||
{
|
||||
_buffer = new byte[capacity];
|
||||
_capacity = capacity;
|
||||
_count = 0;
|
||||
_partialLine = null;
|
||||
_startPos = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The caller calls this method after having already added <c>count</c> more bytes at the
|
||||
/// end of the buffer. We do it this way instead of having an <c>AddBytes(byte[], int)</c>
|
||||
/// method because we don't want to allocate a second buffer just to be the destination for
|
||||
/// a read operation.
|
||||
/// </summary>
|
||||
/// <param name="count">number of bytes added</param>
|
||||
public void AddedBytes(int count)
|
||||
{
|
||||
_count += count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for the next line ending and, if successful, provides the line data.
|
||||
/// </summary>
|
||||
/// <param name="lineOut">if successful, this is set to point to the bytes for the line
|
||||
/// <i>not</i> including any CR/LF; whenever possible this is a reference to the underlying
|
||||
/// buffer, not a copy, so the caller should read/copy it before doing anything else to the
|
||||
/// buffer</param>
|
||||
/// <returns>true if a full line was read, false if we need more data first</returns>
|
||||
public bool ScanToEndOfLine(out Utf8ByteSpan lineOut)
|
||||
{
|
||||
if (_startPos == _count)
|
||||
{
|
||||
_startPos = _count = 0;
|
||||
lineOut = new Utf8ByteSpan();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_startPos == 0 && _partialLine != null && _partialLine.Position > 0
|
||||
&& _partialLine.GetBuffer()[_partialLine.Position - 1] == '\r')
|
||||
{
|
||||
// This is an edge case where the very last byte we previously saw was a CR, and we didn't know
|
||||
// whether the next byte would be LF or not, but we had to dump the buffer into _partialLine
|
||||
// because it was completely full. So, now we can return the line that's already in _partialLine,
|
||||
// but if the first byte in the buffer is LF we should skip past it.
|
||||
if (_buffer[_startPos] == '\n')
|
||||
{
|
||||
_startPos++;
|
||||
}
|
||||
lineOut = new Utf8ByteSpan(_partialLine.GetBuffer(), 0,
|
||||
(int)_partialLine.Position - 1); // don't include the CR
|
||||
_partialLine = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
int startedAt = _startPos, pos = _startPos;
|
||||
|
||||
while (pos < _count)
|
||||
{
|
||||
var b = _buffer[pos];
|
||||
if (b == '\n') // LF by itself terminates a line
|
||||
{
|
||||
_startPos = pos + 1; // next line will start after the LF
|
||||
break;
|
||||
}
|
||||
if (b == '\r')
|
||||
{
|
||||
if (pos < (_count - 1))
|
||||
{
|
||||
_startPos = pos + 1; // next line will start after the CR--
|
||||
if (_buffer[pos + 1] == '\n') // --unless there was an LF right after that
|
||||
{
|
||||
_startPos++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// CR by itself and CR+LF are both valid line endings in SSE, so if the very
|
||||
// last character we saw was a CR, we can't know when the line is fully read
|
||||
// until we've gotten more data. So we'll need to treat this as an incomplete
|
||||
// line.
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (pos == _count) // we didn't find a line terminator
|
||||
{
|
||||
lineOut = new Utf8ByteSpan();
|
||||
if (_count < _capacity)
|
||||
{
|
||||
// There's still room in the buffer, so we'll re-scan the line once they add more bytes
|
||||
return false;
|
||||
}
|
||||
// We need to dump the incomplete line into _partialLine so we can make room in the buffer
|
||||
var partialCount = pos - _startPos;
|
||||
if (_partialLine is null)
|
||||
{
|
||||
_partialLine = new MemoryStream(partialCount);
|
||||
}
|
||||
_partialLine.Write(_buffer, _startPos, partialCount);
|
||||
|
||||
// Clear the main buffer
|
||||
_startPos = _count = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_partialLine != null && _partialLine.Position > 0)
|
||||
{
|
||||
_partialLine.Write(_buffer, startedAt, pos - startedAt);
|
||||
lineOut = new Utf8ByteSpan(_partialLine.GetBuffer(), 0, (int)_partialLine.Position);
|
||||
_partialLine = null;
|
||||
|
||||
// If there are still bytes in the main buffer, move them over to make more room. It's
|
||||
// safe for us to do this before the caller has looked at lineOut, because lineOut is now
|
||||
// a reference to the separate _partialLine buffer, not to the main buffer.
|
||||
if (_startPos < _count)
|
||||
{
|
||||
System.Buffer.BlockCopy(_buffer, _startPos, _buffer, 0, _count - _startPos);
|
||||
}
|
||||
_count -= _startPos;
|
||||
_startPos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lineOut = new Utf8ByteSpan(_buffer, startedAt, pos - startedAt);
|
||||
if (_startPos == _count)
|
||||
{
|
||||
// If we've scanned all the data in the buffer, reset _startPos and _count to indicate
|
||||
// that the entire buffer is available for the next read. It's safe for us to do this
|
||||
// before the caller has looked at lineOut, because we're not actually modifying any
|
||||
// bytes in the buffer. It's the caller's responsibility not to modify the buffer
|
||||
// until it has already done whatever needs to be done with the lineOut data.
|
||||
_startPos = _count = 0;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user