Ejemplo n.º 1
0
        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 {
Ejemplo n.º 2
0
        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));
        }
Ejemplo n.º 3
0
        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));
        }
Ejemplo n.º 4
0
        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);
            }
        }
Ejemplo n.º 5
0
        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())));
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        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);
            }
        }
Ejemplo n.º 8
0
        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");
        }
Ejemplo n.º 9
0
        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));
            }
        }
Ejemplo n.º 10
0
        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);
            }
        }
Ejemplo n.º 11
0
        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);
        }