Beispiel #1
0
        public void parseCanonical(RevWalk walk, byte[] rawTag)
        {
            MutableInteger pos = new MutableInteger();
            int oType;

            pos.value = 53; // "@object $sha1\ntype "
            oType = Constants.decodeTypeString(this, rawTag, (byte)'\n', pos);
            walk.idBuffer.FromString(rawTag, 7);
            @object = walk.lookupAny(walk.idBuffer, oType);

            int p = pos.value += 4; // "tag "
            int nameEnd = RawParseUtils.nextLF(rawTag, p) - 1;
            name = RawParseUtils.decode(Constants.CHARSET, rawTag, p, nameEnd);
            buffer = rawTag;
            flags |= PARSED;
        }
Beispiel #2
0
        public DirCacheTree(byte[] @in, MutableInteger off,
                 DirCacheTree myParent)
        {
            parent = myParent;

            int ptr = RawParseUtils.next(@in, off.value, (byte)'\0');
            int nameLen = ptr - off.value - 1;
            if (nameLen > 0)
            {
                encodedName = new byte[nameLen];
                Array.Copy(@in, off.value, encodedName, 0, nameLen);
            }
            else
                encodedName = NO_NAME;

            entrySpan = RawParseUtils.parseBase10(@in, ptr, off);
            int subcnt = RawParseUtils.parseBase10(@in, off.value, off);
            off.value = RawParseUtils.next(@in, off.value, (byte)'\n');

            if (entrySpan >= 0)
            {
                // Valid trees have a positive entry count and an id of a
                // tree object that should exist in the object database.
                //
                id = ObjectId.FromRaw(@in, off.value);
                off.value += Constants.OBJECT_ID_LENGTH;
            }

            if (subcnt > 0)
            {
                bool alreadySorted = true;
                children = new DirCacheTree[subcnt];
                for (int i = 0; i < subcnt; i++)
                {
                    children[i] = new DirCacheTree(@in, off, this);

                    // C Git's ordering differs from our own; it prefers to
                    // sort by Length first. This sometimes produces a sort
                    // we do not desire. On the other hand it may have been
                    // created by us, and be sorted the way we want.
                    //
                    if (alreadySorted && i > 0
                            && TREE_CMP(children[i - 1], children[i]) > 0)
                        alreadySorted = false;
                }
                if (!alreadySorted)
                    Array.Sort(children, TREE_CMP);
            }
            else
            {
                // Leaf level trees have no children, only (file) entries.
                //
                children = NO_CHILDREN;
            }
            childCnt = subcnt;
        }
Beispiel #3
0
        /// <summary>
        /// Parse an encoded type string into a type constant.
        /// </summary>
        /// <param name="id">
        /// <see cref="ObjectId" /> this type string came from; may be null if 
        /// that is not known at the time the parse is occurring.
        /// </param>
        /// <param name="typeString">string version of the type code.</param>
        /// <param name="endMark">
        /// Character immediately following the type string. Usually ' '
        /// (space) or '\n' (line feed).
        /// </param>
        /// <param name="offset">
        /// Position within <paramref name="typeString"/> where the parse
        /// should start. Updated with the new position (just past
        /// <paramref name="endMark"/> when the parse is successful).
        /// </param>
        /// <returns>
        /// A type code constant (one of <see cref="OBJ_BLOB"/>,
        /// <see cref="OBJ_COMMIT"/>, <see cref="OBJ_TAG"/>, <see cref="OBJ_TREE"/>
        /// </returns>
        /// <exception cref="CorruptObjectException"></exception>
        public static int decodeTypeString(AnyObjectId id, byte[] typeString, byte endMark, MutableInteger offset)
        {
            try
            {
                int position = offset.value;
                switch (typeString[position])
                {
                    case (byte)'b':
                        if (typeString[position + 1] != (byte)'l'
                            || typeString[position + 2] != (byte)'o'
                            || typeString[position + 3] != (byte)'b'
                            || typeString[position + 4] != endMark)
                        {
                            throw new CorruptObjectException(id, "invalid type");
                        }
                        offset.value = position + 5;
                        return OBJ_BLOB;

                    case (byte)'c':
                        if (typeString[position + 1] != (byte)'o'
                                || typeString[position + 2] != (byte)'m'
                                || typeString[position + 3] != (byte)'m'
                                || typeString[position + 4] != (byte)'i'
                                || typeString[position + 5] != (byte)'t'
                                || typeString[position + 6] != endMark)
                        {
                            throw new CorruptObjectException(id, "invalid type");
                        }
                        offset.value = position + 7;
                        return OBJ_COMMIT;

                    case (byte)'t':
                        switch (typeString[position + 1])
                        {
                            case (byte)'a':
                                if (typeString[position + 2] != (byte)'g'
                                    || typeString[position + 3] != endMark)
                                    throw new CorruptObjectException(id, "invalid type");
                                offset.value = position + 4;
                                return OBJ_TAG;

                            case (byte)'r':
                                if (typeString[position + 2] != (byte)'e'
                                        || typeString[position + 3] != (byte)'e'
                                        || typeString[position + 4] != endMark)
                                    throw new CorruptObjectException(id, "invalid type");
                                offset.value = position + 5;
                                return OBJ_TREE;

                            default:
                                throw new CorruptObjectException(id, "invalid type");
                        }

                    default:
                        throw new CorruptObjectException(id, "invalid type");
                }
            }
            catch (IndexOutOfRangeException)
            {
                throw new CorruptObjectException(id, "invalid type");
            }
        }
Beispiel #4
0
        /**
         * Parse a name line (e.g. author, committer, tagger) into a PersonIdent.
         * <p>
         * When passing in a value for <code>nameB</code> callers should use the
         * return value of {@link #author(byte[], int)} or
         * {@link #committer(byte[], int)}, as these methods provide the proper
         * position within the buffer.
         *
         * @param raw
         *            the buffer to parse character data from.
         * @param nameB
         *            first position of the identity information. This should be the
         *            first position after the space which delimits the header field
         *            name (e.g. "author" or "committer") from the rest of the
         *            identity line.
         * @return the parsed identity. Never null.
         */
        public static PersonIdent parsePersonIdent(byte[] raw, int nameB)
        {
            Encoding cs = parseEncoding(raw);
            int emailB = nextLF(raw, nameB, (byte)'<');
            int emailE = nextLF(raw, emailB, (byte)'>');

            string name = decode(cs, raw, nameB, emailB - 2);
            string email = decode(cs, raw, emailB, emailE - 1);

            MutableInteger ptrout = new MutableInteger();
            long when = parseLongBase10(raw, emailE + 1, ptrout);
            int tz = parseTimeZoneOffset(raw, ptrout.value);

            return new PersonIdent(name, email, when, tz);
        }
Beispiel #5
0
        /**
         * Parse a base 10 numeric from a sequence of ASCII digits into a long.
         * <p>
         * Digit sequences can begin with an optional run of spaces before the
         * sequence, and may start with a '+' or a '-' to indicate sign position.
         * Any other characters will cause the method to stop and return the current
         * result to the caller.
         *
         * @param b
         *            buffer to scan.
         * @param ptr
         *            position within buffer to start parsing digits at.
         * @param ptrResult
         *            optional location to return the new ptr value through. If null
         *            the ptr value will be discarded.
         * @return the value at this location; 0 if the location is not a valid
         *         numeric.
         */
        public static long parseLongBase10(byte[] b, int ptr, MutableInteger ptrResult)
        {
            long r = 0;
            int sign = 0;
            try
            {
                int sz = b.Length;
                while (ptr < sz && b[ptr] == ' ')
                    ptr++;
                if (ptr >= sz)
                    return 0;

                switch (b[ptr])
                {
                    case (byte)'-':
                        sign = -1;
                        ptr++;
                        break;
                    case (byte)'+':
                        ptr++;
                        break;
                }

                while (ptr < sz)
                {
                    int v = b[ptr]-(byte)'0';
                    if (v < 0)
                        break;
                    r = (r * 10) + v;
                    ptr++;
                }
            }
            catch (IndexOutOfRangeException e)
            {
                // Not a valid digit.
            }
            if (ptrResult != null)
                ptrResult.value = ptr;
            return sign < 0 ? -r : r;
        }
Beispiel #6
0
        /**
         * Parse a base 10 numeric from a sequence of ASCII digits into an int.
         * <p>
         * Digit sequences can begin with an optional run of spaces before the
         * sequence, and may start with a '+' or a '-' to indicate sign position.
         * Any other characters will cause the method to stop and return the current
         * result to the caller.
         *
         * @param b
         *            buffer to scan.
         * @param ptr
         *            position within buffer to start parsing digits at.
         * @param ptrResult
         *            optional location to return the new ptr value through. If null
         *            the ptr value will be discarded.
         * @return the value at this location; 0 if the location is not a valid
         *         numeric.
         */
        public static int parseBase10(byte[] b, int ptr, MutableInteger ptrResult)
        {
            int r = 0;
            int sign = 0;
            try
            {
                int sz = b.Length;
                while (ptr < sz && b[ptr] == ' ')
                    ptr++;
                if (ptr >= sz)
                    return 0;

                switch (b[ptr])
                {
                    case ((byte)'-'):
                        sign = -1;
                        ptr++;
                        break;
                    case ((byte)'+'):
                        ptr++;
                        break;
                }

                while (ptr < sz)
                {
                    byte d = b[ptr];
                    if ((d < (byte)'0') || (d > (byte)'9'))
                        break;
                    r = r * 10 + (d - (byte)'0');
                    ptr++;
                }
            }
            catch (IndexOutOfRangeException)
            {
                // Not a valid digit.
            }
            if (ptrResult != null)
                ptrResult.value = ptr;
            return sign < 0 ? -r : r;
        }
Beispiel #7
0
        /**
         * Parse a name data (e.g. as within a reflog) into a PersonIdent.
         * <para />
         * When passing in a value for <code>nameB</code> callers should use the
         * return value of {@link #author(byte[], int)} or
         * {@link #committer(byte[], int)}, as these methods provide the proper
         * position within the buffer.
         *
         * @param raw
         *            the buffer to parse character data from.
         * @param nameB
         *            first position of the identity information. This should be the
         *            first position After the space which delimits the header field
         *            name (e.g. "author" or "committer") from the rest of the
         *            identity line.
         * @return the parsed identity. Never null.
         */
        public static PersonIdent parsePersonIdentOnly(byte[] raw, int nameB)
        {
            int stop = nextLF(raw, nameB);
            int emailB = nextLF(raw, nameB, (byte)'<');
            int emailE = nextLF(raw, emailB, (byte)'>');
            string name;
            string email;
            if (emailE < stop)
            {
                email = decode(raw, emailB, emailE - 1);
            }
            else
            {
                email = "invalid";
            }
            if (emailB < stop)
                name = decode(raw, nameB, emailB - 2);
            else
                name = decode(raw, nameB, stop);

            MutableInteger ptrout = new MutableInteger();
            long when;
            int tz;
            if (emailE < stop)
            {
                when = parseLongBase10(raw, emailE + 1, ptrout);
                tz = parseTimeZoneOffset(raw, ptrout.value);
            }
            else
            {
                when = 0;
                tz = 0;
            }
            return new PersonIdent(name, email, when, tz);
        }
Beispiel #8
0
        public virtual void parseHeader()
        {
            // Parse "@@ -236,9 +236,9 @@ protected boolean"
            //
            byte[] buf = _file.Buffer;
            var ptr = new MutableInteger
                        {
                            value = RawParseUtils.nextLF(buf, _startOffset, (byte)' ')
                        };

            _oldImage.StartLine = -1 * RawParseUtils.parseBase10(buf, ptr.value, ptr);

            _oldImage.LineCount = buf[ptr.value] == ',' ? RawParseUtils.parseBase10(buf, ptr.value + 1, ptr) : 1;
            NewStartLine = RawParseUtils.parseBase10(buf, ptr.value + 1, ptr);
            NewLineCount = buf[ptr.value] == ',' ? RawParseUtils.parseBase10(buf, ptr.value + 1, ptr) : 1;
        }
Beispiel #9
0
	    public void parseHeader()
        {
		    // Parse "@@ -236,9 +236,9 @@ protected boolean"
		    //
		    byte[] buf = file.buf;
		    MutableInteger ptr = new MutableInteger();
		    ptr.value = RawParseUtils.nextLF(buf, startOffset, (byte)' ');
		    old.startLine = -RawParseUtils.parseBase10(buf, ptr.value, ptr);
		    if (buf[ptr.value] == ',')
			    old.lineCount = RawParseUtils.parseBase10(buf, ptr.value + 1, ptr);
		    else
			    old.lineCount = 1;

		    newStartLine = RawParseUtils.parseBase10(buf, ptr.value + 1, ptr);
		    if (buf[ptr.value] == ',')
			    newLineCount = RawParseUtils.parseBase10(buf, ptr.value + 1, ptr);
		    else
			    newLineCount = 1;
	    }
Beispiel #10
0
        public void parseCanonical(RevWalk walk, byte[] rawTag)
        {
            var pos = new MutableInteger { value = 53 };

            int oType = Constants.decodeTypeString(this, rawTag, (byte)'\n', pos);
            walk.IdBuffer.FromString(rawTag, 7);
            _object = walk.lookupAny(walk.IdBuffer, oType);

            int p = pos.value += 4; // "tag "
            int nameEnd = RawParseUtils.nextLF(rawTag, p) - 1;
            _name = RawParseUtils.decode(Constants.CHARSET, rawTag, p, nameEnd);

            if (walk.isRetainBody())
                _buffer = rawTag;
            Flags |= PARSED;
        }
        private UnpackedObjectLoader(byte[] compressed, AnyObjectId id)
        {
            // Try to determine if this is a legacy format loose object or
            // a new style loose object. The legacy format was completely
            // compressed with zlib so the first byte must be 0x78 (15-bit
            // window size, deflated) and the first 16 bit word must be
            // evenly divisible by 31. Otherwise its a new style loose
            // object.
            //
            Inflater inflater = InflaterCache.Instance.get();
            try
            {
                int fb = compressed[0] & 0xff;
                if (fb == 0x78 && (((fb << 8) | compressed[1] & 0xff) % 31) == 0)
                {
                    inflater.SetInput(compressed);
                    var hdr = new byte[64];
                    int avail = 0;
                    while (!inflater.IsFinished && avail < hdr.Length)
                    {
                        try
                        {
                            avail += inflater.Inflate(hdr, avail, hdr.Length - avail);
                        }
                        catch (IOException dfe)
                        {
                            var coe = new CorruptObjectException(id, "bad stream", dfe);
                            //inflater.end();
                            throw coe;
                        }
                    }

                    if (avail < 5)
                    {
                        throw new CorruptObjectException(id, "no header");
                    }

                    var p = new MutableInteger();
                    _objectType = Constants.decodeTypeString(id, hdr, (byte)' ', p);
                    _objectSize = RawParseUtils.parseBase10(hdr, p.value, p);

                    if (_objectSize < 0)
                    {
                        throw new CorruptObjectException(id, "negative size");
                    }

                    if (hdr[p.value++] != 0)
                    {
                        throw new CorruptObjectException(id, "garbage after size");
                    }

                    _bytes = new byte[_objectSize];

                    if (p.value < avail)
                    {
                        Array.Copy(hdr, p.value, _bytes, 0, avail - p.value);
                    }

                    Decompress(id, inflater, avail - p.value);
                }
                else
                {
                    int p = 0;
                    int c = compressed[p++] & 0xff;
                    int typeCode = (c >> 4) & 7;
                    int size = c & 15;
                    int shift = 4;
                    while ((c & 0x80) != 0)
                    {
                        c = compressed[p++] & 0xff;
                        size += (c & 0x7f) << shift;
                        shift += 7;
                    }

                    switch (typeCode)
                    {
                        case Constants.OBJ_COMMIT:
                        case Constants.OBJ_TREE:
                        case Constants.OBJ_BLOB:
                        case Constants.OBJ_TAG:
                            _objectType = typeCode;
                            break;

                        default:
                            throw new CorruptObjectException(id, "invalid type");
                    }

                    _objectSize = size;
                    _bytes = new byte[_objectSize];
                    inflater.SetInput(compressed, p, compressed.Length - p);
                    Decompress(id, inflater, 0);
                }
            }
            finally
            {
                InflaterCache.Instance.release(inflater);
            }
        }
        public override void parseHeader()
        {
            // Parse "@@@ -55,12 -163,13 +163,15 @@@ protected boolean"
            //
            byte[] buf = File.Buffer;
            var ptr = new MutableInteger
                        {
                            value = RawParseUtils.nextLF(buf, StartOffset, (byte)' ')
                        };

            _old.ForEach(coi =>
                            {
                                coi.StartLine = -1 * RawParseUtils.parseBase10(Buffer, ptr.value, ptr);
                                coi.LineCount = buf[ptr.value] == ',' ?
                                    RawParseUtils.parseBase10(buf, ptr.value + 1, ptr) : 1;
                            });

            NewStartLine = RawParseUtils.parseBase10(buf, ptr.value + 1, ptr);
            NewLineCount = buf[ptr.value] == ',' ? RawParseUtils.parseBase10(buf, ptr.value + 1, ptr) : 1;
        }