private protected void ParseLineToPeel(BucketBytes line, ref GitRefPeel?last, int idLength) { if (char.IsLetterOrDigit((char)line[0]) && line.Length > idLength + 1) { if (GitId.TryParse(line.Slice(0, idLength), out var oid)) { string name = line.Slice(idLength + 1).Trim().ToUTF8String(); if (GitReference.ValidName(name, false)) { _peelRefs ![name] = last = new GitRefPeel {
protected override BucketBytes ConvertData(ref BucketBytes sourceData, bool final) { buffer ??= new byte[1024]; int i; int nb = 0; for (i = 0; i < sourceData.Length && nb + 4 < buffer.Length; i++) { byte b = sourceData[i]; sbyte sb = (b < base64Reversemap.Length) ? base64Reversemap[b] : (sbyte)-3; if (sb < 0) { if (sb == -1 || char.IsWhiteSpace((char)b)) { continue; // Newlines, Whitespace and '=' are skipped } else { throw new BucketException($"Unexpected base64 character 0x{b:x} '{(char)b}' in {Name} bucket"); } } bits |= (uint)sb << (6 * (3 - state)); if (state < 3) { state++; continue; } state = 0; for (int d = 2; d >= 0; d--) { buffer[nb++] = (byte)((bits >> 8 * d) & 0xFF); } bits = 0; } if (final && state > 0) { for (int d = 0; d <= 2; d++) { if (d + 1 < state) { buffer[nb++] = (byte)((bits >> 16 - 8 * d) & 0xFF); } } state = 0; } if (i > 0) // Pass EOF through unchanged { sourceData = sourceData.Slice(i); } return(new BucketBytes(buffer, 0, nb)); }
protected override BucketBytes ConvertData(ref BucketBytes sourceData, bool final) { buffer ??= new byte[1024]; int i; int nb = 0; for (i = 0; i < sourceData.Length && nb + 5 < buffer.Length; i++) { byte b = sourceData[i]; bits |= (uint)b << (8 * (2 - state)); if (state < 2) { state++; continue; } state = 0; for (int d = 3; d >= 0; d--) { buffer[nb++] = base64Map[(bits >> 6 * d) & 0x3F]; } nl += 1; if (_wrapLines && nl >= 19) { buffer[nb++] = (byte)'\r'; buffer[nb++] = (byte)'\n'; nl = 0; } bits = 0; } if (final && state > 0) { for (int d = 0; d < 4; d++) { if (d <= state) { buffer[nb++] = base64Map[(bits >> 18 - 6 * d) & 0x3F]; } else if (_addPadding) { buffer[nb++] = (byte)'='; } } state = 0; } if (i > 0) // Pass EOF through unchanged { sourceData = sourceData.Slice(i); } return(new BucketBytes(buffer, 0, nb)); }
async Task <BucketBytes> DoRead(int requested) { if (_unread.Length == 0 && !_readEof) { await ReadFromStream().ConfigureAwait(false); } if (_unread.Length > 0) { var bb = _unread.Slice(0, Math.Min(requested, _unread.Length)); _unread = _unread.Slice(bb.Length); return(bb); } else { _readEof = true; return(BucketBytes.Eof); } }
public async Task NormalizeBucketToUtf8(Encoding enc) { var data = Enumerable.Range(0, byte.MaxValue).Select(x => ANSI.GetChars(new byte[] { (byte)x })[0]).ToArray(); var encodedBytes = (enc.GetPreamble().AsBucket() + enc.GetBytes(data).AsBucket()).ToArray(); using var b = encodedBytes.AsBucket(); // This wil test the peaking var bb = await b.NormalizeToUtf8().ReadFullAsync(1024); Assert.AreEqual(Escape(new String(data)), Escape(bb.ToUTF8String()), Escape(new String(encodedBytes.Select(x => (char)x).ToArray()))); if (enc is UnicodeEncoding u && !u.GetPreamble().Any()) { return; // Unicode without preamble not detectable without scan via .Peek() } // This will check the byte reading BucketBytes ec = encodedBytes; bb = await(ec.Slice(0, 1).ToArray().AsBucket() + ec.Slice(1).ToArray().AsBucket()).NormalizeToUtf8().ReadFullAsync(1024); Assert.AreEqual(Escape(new String(data)), Escape(bb.ToUTF8String()), Escape(new String(encodedBytes.Select(x => (char)x).ToArray()))); }
public override async ValueTask <BucketBytes> ReadAsync(int requested = int.MaxValue) { if (!_remaining.IsEmpty) { var r = _remaining.Slice(0, Math.Min(requested, _remaining.Length)); _remaining = _remaining.Slice(r.Length); _position += r.Length; return(r); } while (_skipFirst > 0) { var skipped = await Inner.ReadSkipAsync(_skipFirst).ConfigureAwait(false); _skipFirst -= (int)skipped; } do { if (_readLeft.IsEmpty) { _readLeft = await Inner.ReadAsync(ConvertRequested(requested)).ConfigureAwait(false); } _remaining = ConvertData(ref _readLeft, _readLeft.IsEof); if (!_remaining.IsEmpty) { var r = _remaining.Slice(0, Math.Min(requested, _remaining.Length)); _remaining = _remaining.Slice(r.Length); _position += r.Length; return(r); } }while (!_readLeft.IsEof); return(BucketBytes.Eof); }
public override async ValueTask <BucketBytes> ReadAsync(int requested = int.MaxValue) { if (_remaining.Length == 0) { #if !NETFRAMEWORK int n = await _stream.ReadAsync(_buffer).ConfigureAwait(false); #else int n = await _stream.ReadAsync(_buffer, 0, _buffer.Length).ConfigureAwait(false); #endif _remaining = new BucketBytes(_buffer, 0, n); } if (_remaining.Length > 0) { var r = _remaining.Slice(0, Math.Min(requested, _remaining.Length)); _remaining = _remaining.Slice(r.Length); return(r); } else { return(BucketBytes.Eof); } }
public void BytesEmptyEof() { Assert.IsTrue(BucketBytes.Eof.IsEof, "BucketBytes.Eof.IsEof = true"); Assert.IsFalse(BucketBytes.Empty.IsEof, "BucketBytes.Eof.IsEof = false"); Assert.IsFalse(BucketBytes.Eof.Equals(BucketBytes.Empty), "BucketBytes.Eof != BucketBytes.Empty"); //Assert.IsFalse(BucketBytes.Empty.IsEof, "BucketBytes.Eof.IsEof = false"); Assert.IsTrue(BucketBytes.Eof.Trim().IsEof, "Trimmed still eof"); Assert.IsFalse(BucketBytes.Empty.Trim().IsEof, "Trimmed not eof"); BucketBytes bEmpty = Array.Empty <byte>(); Assert.IsTrue(bEmpty.IsEmpty, "Empty"); Assert.IsFalse(bEmpty.IsEof, "Not EOF"); Assert.IsTrue(BucketBytes.Empty.Slice(0, 0).IsEmpty, "Empty"); Assert.IsTrue(BucketBytes.Eof.Slice(0, 0).IsEmpty, "Empty"); Assert.IsFalse(BucketBytes.Empty.Slice(0, 0).IsEof, "Eof"); Assert.IsTrue(BucketBytes.Eof.Slice(0, 0).IsEof, "Eof"); Assert.IsTrue(bEmpty.Slice(0, 0).IsEmpty, "Empty"); Assert.IsFalse(bEmpty.IsEof, "Not EOF"); }
public override async ValueTask <BucketBytes> ReadAsync(int requested = int.MaxValue) { if (requested > _buffer.Length) { requested = _buffer.Length; } if (!_bbLeft.IsEmpty || !_bbRight.IsEmpty) { if (_bbLeft.IsEmpty && !_bbLeft.IsEof) { _bbLeft = await Left.ReadAsync(Math.Max(_bbRight.Length, 1)).ConfigureAwait(false); } if (_bbRight.IsEmpty && !_bbRight.IsEof) { _bbRight = await Right.ReadAsync(Math.Max(_bbRight.Length, 1)).ConfigureAwait(false); } } else { _bbLeft = await Left.ReadAsync(requested).ConfigureAwait(false); _bbRight = await Right.ReadAsync(_bbLeft.IsEmpty?requested : _bbLeft.Length).ConfigureAwait(false); } if (_bbLeft.IsEof) { if (_bbRight.IsEof) { return(BucketBytes.Eof); } // Assume left is all 0, so we can return right if (requested >= _bbRight.Length) { var r = _bbRight; _bbRight = BucketBytes.Empty; return(r); } else { var r = _bbRight.Slice(0, requested); _bbRight = _bbRight.Slice(requested); return(r); } } else if (_bbRight.IsEof) { // Assume right is all 0, so we can return left if (requested >= _bbLeft.Length) { var r = _bbLeft; _bbLeft = BucketBytes.Empty; return(r); } else { var r = _bbLeft.Slice(0, requested); _bbLeft = _bbLeft.Slice(requested); return(r); } } else { int got = Process(); if (got == _bbLeft.Length) { _bbLeft = BucketBytes.Empty; } else { _bbLeft = _bbLeft.Slice(got); } if (got == _bbRight.Length) { _bbRight = BucketBytes.Empty; } else { _bbRight = _bbRight.Slice(got); } return(new BucketBytes(_buffer, 0, got)); } }
public override async ValueTask <BucketBytes> ReadAsync(int requested = int.MaxValue) { int rq = _by2 ? (requested + 1) & ~1 : requested; while (_remaining.IsEmpty) { BucketBytes bb; if (_toConvert == null) { bb = await Inner.ReadAsync(rq).ConfigureAwait(false); if (bb.IsEof) { return(bb); } if (_position == 0 && !_preampbleScanned && _sourceEncoding.GetPreamble() is byte[] preample && preample.Length > 0) { _preampbleScanned = true; int len = Math.Min(preample.Length, bb.Length); if (bb.Span.Slice(0, len).SequenceEqual(preample.AsSpan().Slice(0, len))) { bool isMatch = true; while (len < preample.Length && isMatch) { byte?b = await Inner.ReadByteAsync().ConfigureAwait(false); if (b is null) { _toConvert = bb.ToArray(); isMatch = false; break; } bb = bb.ToArray().ArrayAppend(b.Value); len++; if (!bb.Span.Slice(0, len).SequenceEqual(preample.AsSpan().Slice(0, len))) { isMatch = false; } } if (isMatch) { bb = bb.Slice(preample.Length); } } if (bb.Length == 0) { continue; } } } else { bb = _toConvert; _toConvert = null; } #if !NETFRAMEWORK _decoder.Convert(bb.Span, new Span <char>(_charBuffer, _toEncode, _charBuffer.Length - _toEncode), false, out var bytesUsed, out var charsDecoded, out var completed); #else var(arr, offs) = bb.ExpandToArray(); _decoder.Convert(arr, offs, bb.Length, _charBuffer, _toEncode, _charBuffer.Length - _toEncode, false, out var bytesUsed, out var charsDecoded, out var completed); #endif charsDecoded += _toEncode; _toEncode = 0; if (bytesUsed < bb.Length) { _toConvert = bb.Slice(bytesUsed).ToArray(); } _encoder.Convert(_charBuffer, 0, charsDecoded, _utfBuffer, 0, _utfBuffer.Length, false, out var charsEncoded, out var utfBytesUsed, out var utfCompleted); if (charsEncoded < charsDecoded) { _toEncode = charsDecoded - charsEncoded; for (int i = 0; i < _toEncode; i++) { _charBuffer[i] = _charBuffer[i + charsDecoded]; } } else { _toEncode = 0; } _remaining = new BucketBytes(_utfBuffer, 0, utfBytesUsed); } if (!_remaining.IsEmpty) { requested = Math.Min(requested, _remaining.Length); var r = _remaining.Slice(0, requested); _remaining = _remaining.Slice(requested); _position += requested; return(r); } else { return(BucketBytes.Eof); } }
internal static bool TryReadRefFile(string path, string?prefix, [NotNullWhen(true)] out string?result) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } #pragma warning disable CA1031 // Do not catch general exception types try { using var f = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete, 512); byte[] buf = new byte[512]; int n = f.Read(buf, 0, buf.Length); if (buf.Length > 0 && n < buf.Length && n >= (prefix?.Length ?? 0)) { BucketEol eol = BucketEol.None; if (buf.Length > 2 && buf[buf.Length - 1] == '\n') { if (buf[buf.Length - 2] == '\r') { eol = BucketEol.CRLF; } else { eol = BucketEol.LF; } } else if (buf[buf.Length - 1] == '\r') { eol = BucketEol.CR; } else if (buf[buf.Length - 1] == '\n') { eol = BucketEol.LF; } else if (buf[buf.Length - 1] == '\0') { eol = BucketEol.Zero; } BucketBytes bb = new BucketBytes(buf, 0, n); if (prefix != null) { var p = bb.Slice(0, prefix.Length).ToUTF8String(); if (prefix != p) { result = null; return(false); } bb = bb.Slice(p.Length); } result = bb.ToUTF8String(eol); return(true); } } catch (IOException) { } catch (NotSupportedException) { } catch (SystemException) { } #pragma warning restore CA1031 // Do not catch general exception types result = null; return(false); }