Walks a Git tree (directory) in Git sort order. A new iterator instance should be positioned on the first entry, or at eof. Data for the first entry (if not at eof) should be available immediately. Implementors must walk a tree in the Git sort order, which has the following odd sorting: A.c A/c A0c In the second item, A is the name of a subtree and c is a file within that subtree. The other two items are files in the root level tree.
Beispiel #1
0
        /**
         * Enter into the current subtree.
         * <para />
         * If the current entry is a subtree this method arranges for its children
         * to be returned before the next sibling following the subtree is returned.
         *
         * @throws MissingObjectException
         *             a subtree was found, but the subtree object does not exist in
         *             this repository. The repository may be missing objects.
         * @throws IncorrectObjectTypeException
         *             a subtree was found, and the subtree id does not denote a
         *             tree, but instead names some other non-tree type of object.
         *             The repository may have data corruption.
         * @throws CorruptObjectException
         *             the contents of a tree did not appear to be a tree. The
         *             repository may have data corruption.
         * @throws IOException
         *             a loose object or pack file could not be Read.
         */
        public void enterSubtree()
        {
            AbstractTreeIterator ch = CurrentHead;
            var tmp = new AbstractTreeIterator[_trees.Length];

            for (int i = 0; i < _trees.Length; i++)
            {
                AbstractTreeIterator treeIterator = _trees[i];
                AbstractTreeIterator newIterator;

                if (treeIterator.Matches == ch && !treeIterator.eof() && FileMode.Tree == treeIterator.EntryFileMode)
                {
                    newIterator = treeIterator.createSubtreeIterator(_db, _idBuffer, _cursor);
                }
                else
                {
                    newIterator = treeIterator.createEmptyTreeIterator();
                }

                tmp[i] = newIterator;
            }

            _depth++;
            _advance = false;

            Array.Copy(tmp, 0, _trees, 0, _trees.Length);
        }
Beispiel #2
0
        /// <summary>
        /// Obtain the tree iterator for the current entry.
        /// <para />
        /// Entering into (or exiting out of) a subtree causes the current tree
        /// iterator instance to be changed for the nth tree. This allows the tree
        /// iterators to manage only one list of items, with the diving handled by
        /// recursive trees.
        /// </summary>
        /// <typeparam name="T">type of the tree iterator expected by the caller.</typeparam>
        /// <param name="nth">tree to obtain the current iterator of.</param>
        /// <param name="clazz">type of the tree iterator expected by the caller.</param>
        /// <returns>
        /// The current iterator of the requested type; null if the tree
        /// has no entry to match the current path.
        /// </returns>
        public T getTree <T>(int nth, Type clazz)        // [henon] was Class<T> clazz
            where T : AbstractTreeIterator
        {
            AbstractTreeIterator t = _trees[nth];

            return(t.Matches == _currentHead ? (T)t : null);
        }
        /// <summary>
        /// Compare the path of this current entry to another iterator's entry.
        /// </summary>
        /// <param name="treeIterator">
        /// The other iterator to compare the path against.
        /// </param>
        /// <param name="treeIteratorMode">
        /// The other iterator <see cref="FileMode"/> bits.
        /// </param>
        /// <returns>
        /// return -1 if this entry sorts first; 0 if the entries are equal; 1 if
        /// <paramref name="treeIterator"/>'s entry sorts first.
        /// </returns>
        public int pathCompare(AbstractTreeIterator treeIterator, int treeIteratorMode)
        {
            byte[] a    = Path;
            byte[] b    = treeIterator.Path;
            int    aLen = PathLen;
            int    bLen = treeIterator.PathLen;

            // Its common when we are a subtree for both parents to match;
            // when this happens everything in _path[0..cPos] is known to
            // be equal and does not require evaluation again.
            //
            int cPos = AlreadyMatch(this, treeIterator);

            for (; cPos < aLen && cPos < bLen; cPos++)
            {
                int cmp = (a[cPos] & 0xff) - (b[cPos] & 0xff);
                if (cmp != 0)
                {
                    return(cmp);
                }
            }

            if (cPos < aLen)
            {
                return((a[cPos] & 0xff) - LastPathChar(treeIteratorMode));
            }

            if (cPos < bLen)
            {
                return(LastPathChar(Mode) - (b[cPos] & 0xff));
            }

            return(LastPathChar(Mode) - LastPathChar(treeIteratorMode));
        }
Beispiel #4
0
        /**
         * Reset this walker to run over a single existing tree.
         *
         * @param id
         *            the tree we need to parse. The walker will execute over this
         *            single tree if the reset is successful.
         * @throws MissingObjectException
         *             the given tree object does not exist in this repository.
         * @throws IncorrectObjectTypeException
         *             the given object id does not denote a tree, but instead names
         *             some other non-tree type of object. Note that commits are not
         *             trees, even if they are sometimes called a "tree-ish".
         * @throws CorruptObjectException
         *             the object claimed to be a tree, but its contents did not
         *             appear to be a tree. The repository may have data corruption.
         * @throws IOException
         *             a loose object or pack file could not be Read.
         */
        public void reset(AnyObjectId id)
        {
            if (_trees.Length == 1)
            {
                AbstractTreeIterator iterator = _trees[0];
                while (iterator.Parent != null)
                {
                    iterator = iterator.Parent;
                }

                CanonicalTreeParser oParse = (iterator as CanonicalTreeParser);
                if (oParse != null)
                {
                    iterator.Matches    = null;
                    iterator.MatchShift = 0;

                    oParse.reset(_db, id, _cursor);
                    _trees[0] = iterator;
                }
                else
                {
                    _trees[0] = ParserFor(id);
                }
            }
            else
            {
                _trees = new AbstractTreeIterator[] { ParserFor(id) };
            }

            _advance = false;
            _depth   = 0;
        }
Beispiel #5
0
        /**
         * Get the current entry's name within its parent tree.
         * <para />
         * This method is not very efficient and is primarily meant for debugging
         * and  output generation. Applications should try to avoid calling it,
         * and if invoked do so only once per interesting entry, where the name is
         * absolutely required for correct function.
         *
         * @return name of the current entry within the parent tree (or directory).
         *         The name never includes a '/'.
         */
        public string getNameString()
        {
            AbstractTreeIterator t = _currentHead;
            int off = t.PathOffset;
            int end = t.PathLen;

            return(RawParseUtils.decode(Constants.CHARSET, t.Path, off, end));
        }
Beispiel #6
0
 /// <summary>
 /// Compare the path of this current entry to another iterator's entry.
 /// </summary>
 /// <param name="treeIterator">
 /// The other iterator to compare the path against.
 /// </param>
 /// <returns>
 /// return -1 if this entry sorts first; 0 if the entries are equal; 1 if
 /// <paramref name="treeIterator"/>'s entry sorts first.
 /// </returns>
 public int pathCompare(AbstractTreeIterator treeIterator)
 {
     if (treeIterator == null)
     {
         throw new ArgumentNullException("treeIterator");
     }
     return(pathCompare(treeIterator, treeIterator.Mode));
 }
Beispiel #7
0
 /// <summary>
 /// Check if the current entry of both iterators has the same id.
 /// <para />
 /// This method is faster than <see cref="getEntryObjectId()"/>as it does not
 /// require copying the bytes out of the buffers. A direct <see cref="idBuffer"/>
 /// compare operation is performed.
 /// </summary>
 /// <param name="otherIterator">the other iterator to test against.</param>
 /// <returns>
 /// true if both iterators have the same object id; false otherwise.
 /// </returns>
 public virtual bool idEqual(AbstractTreeIterator otherIterator)
 {
     if (otherIterator == null)
     {
         throw new ArgumentNullException("otherIterator");
     }
     return(ObjectId.Equals(idBuffer(), idOffset(), otherIterator.idBuffer(), otherIterator.idOffset()));
 }
Beispiel #8
0
 public static string pathOf(AbstractTreeIterator t)
 {
     if (t == null)
     {
         throw new ArgumentNullException("t");
     }
     return(RawParseUtils.decode(Constants.CHARSET, t.Path, 0, t.PathLen));
 }
Beispiel #9
0
        /**
         * Get the current entry's complete path as a UTF-8 byte array.
         *
         * @return complete path of the current entry, from the root of the
         *         repository. If the current entry is in a subtree there will be at
         *         least one '/' in the returned string.
         */
        public byte[] getRawPath()
        {
            AbstractTreeIterator treeIterator = CurrentHead;
            int newPathLen = treeIterator.PathLen;
            var rawPath    = new byte[newPathLen];

            Array.Copy(treeIterator.Path, 0, rawPath, 0, newPathLen);
            return(rawPath);
        }
Beispiel #10
0
        /**
         * Advance this walker to the next relevant entry.
         *
         * @return true if there is an entry available; false if all entries have
         *         been walked and the walk of this set of tree iterators is over.
         * @throws MissingObjectException
         *             {@link #isRecursive()} was enabled, a subtree was found, but
         *             the subtree object does not exist in this repository. The
         *             repository may be missing objects.
         * @throws IncorrectObjectTypeException
         *             {@link #isRecursive()} was enabled, a subtree was found, and
         *             the subtree id does not denote a tree, but instead names some
         *             other non-tree type of object. The repository may have data
         *             corruption.
         * @throws CorruptObjectException
         *             the contents of a tree did not appear to be a tree. The
         *             repository may have data corruption.
         * @throws IOException
         *             a loose object or pack file could not be Read.
         */
        public bool next()
        {
            try
            {
                if (_advance)
                {
                    _advance      = false;
                    _postChildren = false;
                    popEntriesEqual();
                }

                while (true)
                {
                    AbstractTreeIterator t = min();
                    if (t.eof())
                    {
                        if (_depth > 0)
                        {
                            ExitSubtree();
                            if (PostOrderTraversal)
                            {
                                _advance      = true;
                                _postChildren = true;
                                return(true);
                            }
                            popEntriesEqual();
                            continue;
                        }
                        return(false);
                    }

                    _currentHead = t;
                    if (!_filter.include(this))
                    {
                        skipEntriesEqual();
                        continue;
                    }

                    if (Recursive && FileMode.Tree == t.EntryFileMode)
                    {
                        enterSubtree();
                        continue;
                    }

                    _advance = true;
                    return(true);
                }
            }
            catch (StopWalkException)
            {
                foreach (AbstractTreeIterator t in _trees)
                {
                    t.stopWalk();
                }
                return(false);
            }
        }
Beispiel #11
0
        /// <summary>
        /// Set path buffer capacity to the specified size
        /// </summary>
        /// <param name="capacity">the new size</param>
        /// <param name="length">the amount of bytes to copy</param>
        private void SetPathCapacity(int capacity, int length)
        {
            var oldPath = Path;
            var newPath = new byte[capacity];

            Array.Copy(oldPath, 0, newPath, 0, length);

            for (AbstractTreeIterator p = this; p != null && p.Path == oldPath; p = p._parent)
            {
                p.Path = newPath;
            }
        }
Beispiel #12
0
        /**
         * Obtain the ObjectId for the current entry.
         * <para />
         * Every tree supplies an object id, even if the tree does not contain the
         * current entry. In the latter case {@link ObjectId#zeroId()} is supplied.
         * <para />
         * Applications should try to use {@link #idEqual(int, int)} when possible
         * as it avoids conversion overheads.
         *
         * @param out
         *            buffer to copy the object id into.
         * @param nth
         *            tree to obtain the object identifier from.
         * @see #idEqual(int, int)
         */
        public void getObjectId(MutableObjectId @out, int nth)
        {
            AbstractTreeIterator t = _trees[nth];

            if (t.Matches == _currentHead)
            {
                t.getEntryObjectId(@out);
            }
            else
            {
                @out.Clear();
            }
        }
Beispiel #13
0
        /**
         * Add an already created tree iterator for walking.
         * <para />
         * The position of this tree is returned to the caller, in case the caller
         * has lost track of the order they added the trees into the walker.
         * <para />
         * The tree which the iterator operates on must have the same root as
         * existing trees in the walk.
         *
         * @param parentIterator
         *            an iterator to walk over. The iterator should be new, with no
         *            parent, and should still be positioned before the first entry.
         *            The tree which the iterator operates on must have the same root
         *            as other trees in the walk.
         *
         * @return position of this tree within the walker.
         * @throws CorruptObjectException
         *             the iterator was unable to obtain its first entry, due to
         *             possible data corruption within the backing data store.
         */
        public int addTree(AbstractTreeIterator parentIterator)
        {
            int n        = _trees.Length;
            var newTrees = new AbstractTreeIterator[n + 1];

            Array.Copy(_trees, 0, newTrees, 0, n);
            newTrees[n]               = parentIterator;
            parentIterator.Matches    = null;
            parentIterator.MatchShift = 0;

            _trees = newTrees;
            return(n);
        }
Beispiel #14
0
        public virtual void popEntriesEqual()
        {
            AbstractTreeIterator ch = _currentHead;

            for (int i = 0; i < _trees.Length; i++)
            {
                AbstractTreeIterator t = _trees[i];
                if (t.Matches == ch)
                {
                    t.next(1);
                    t.Matches = null;
                }
            }
        }
Beispiel #15
0
 /// <summary>
 /// Create an iterator for a subtree of an existing iterator.
 /// </summary>
 /// <param name="p">parent tree iterator.</param>
 protected AbstractTreeIterator(AbstractTreeIterator p)
 {
     _parent    = p;
     Path       = p.Path;
     PathOffset = p.PathLen + 1;
     try
     {
         Path[PathOffset - 1] = (byte)'/';
     }
     catch (IndexOutOfRangeException)
     {
         growPath(p.PathLen);
         Path[PathOffset - 1] = (byte)'/';
     }
 }
Beispiel #16
0
        public virtual void skipEntriesEqual()
        {
            AbstractTreeIterator ch = _currentHead;

            for (int i = 0; i < _trees.Length; i++)
            {
                AbstractTreeIterator t = _trees[i];
                if (t.Matches != ch)
                {
                    continue;
                }

                t.skip();
                t.Matches = null;
            }
        }
Beispiel #17
0
        /**
         * Add an already created tree iterator for walking.
         * <para />
         * The position of this tree is returned to the caller, in case the caller
         * has lost track of the order they added the trees into the walker.
         * <para />
         * The tree which the iterator operates on must have the same root as
         * existing trees in the walk.
         *
         * @param parentIterator
         *            an iterator to walk over. The iterator should be new, with no
         *            parent, and should still be positioned before the first entry.
         *            The tree which the iterator operates on must have the same root
         *            as other trees in the walk.
         *
         * @return position of this tree within the walker.
         * @throws CorruptObjectException
         *             the iterator was unable to obtain its first entry, due to
         *             possible data corruption within the backing data store.
         */
        public int addTree(AbstractTreeIterator parentIterator)
        {
            if (parentIterator == null)
            {
                throw new ArgumentNullException("parentIterator");
            }
            int n        = _trees.Length;
            var newTrees = new AbstractTreeIterator[n + 1];

            Array.Copy(_trees, 0, newTrees, 0, n);
            newTrees[n]               = parentIterator;
            parentIterator.Matches    = null;
            parentIterator.MatchShift = 0;

            _trees = newTrees;
            return(n);
        }
Beispiel #18
0
        /**
         * Test if the supplied path matches (being suffix of) the current entry's
         * path.
         * <para />
         * This method tests that the supplied path is exactly equal to the current
         * entry, or is relative to one of entry's parent directories. It is faster
         * to use this method then to use {@link #getPathString()} to first Create
         * a String object, then test <code>endsWith</code> or some other type of
         * string match function.
         *
         * @param p
         *            path buffer to test.
         * @param pLen
         *            number of bytes from <code>buf</code> to test.
         * @return true if p is suffix of the current path;
         *         false if otherwise
         */
        public bool isPathSuffix(byte[] p, int pLen)
        {
            AbstractTreeIterator t = _currentHead;

            byte[] c    = t.Path;
            int    cLen = t.PathLen;
            int    ci;

            for (ci = 1; ci < cLen && ci < pLen; ci++)
            {
                if (c[cLen - ci] != p[pLen - ci])
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #19
0
 /// <summary>
 /// Create an iterator for a subtree of an existing iterator.
 /// </summary>
 /// <param name="p">parent tree iterator.</param>
 protected AbstractTreeIterator(AbstractTreeIterator p)
 {
     if (p == null)
     {
         throw new ArgumentNullException("p");
     }
     _parent    = p;
     Path       = p.Path;
     PathOffset = p.PathLen + 1;
     try
     {
         Path[PathOffset - 1] = (byte)'/';
     }
     catch (IndexOutOfRangeException)
     {
         growPath(p.PathLen);
         Path[PathOffset - 1] = (byte)'/';
     }
 }
Beispiel #20
0
        /**
         * Test if the supplied path matches the current entry's path.
         * <para />
         * This method tests that the supplied path is exactly equal to the current
         * entry, or is one of its parent directories. It is faster to use this
         * method then to use {@link #getPathString()} to first Create a string
         * object, then test <code>startsWith</code> or some other type of string
         * match function.
         *
         * @param p
         *            path buffer to test. Callers should ensure the path does not
         *            end with '/' prior to invocation.
         * @param pLen
         *            number of bytes from <code>buf</code> to test.
         * @return &lt; 0 if p is before the current path; 0 if p matches the current
         *         path; 1 if the current path is past p and p will never match
         *         again on this tree walk.
         */
        public int isPathPrefix(byte[] p, int pLen)
        {
            if (p == null)
            {
                throw new ArgumentNullException("p");
            }
            AbstractTreeIterator t = _currentHead;

            byte[] c    = t.Path;
            int    cLen = t.PathLen;
            int    ci;

            for (ci = 0; ci < cLen && ci < pLen; ci++)
            {
                int cValue = (c[ci] & 0xff) - (p[ci] & 0xff);
                if (cValue != 0)
                {
                    return(cValue);
                }
            }

            if (ci < cLen)
            {
                // Ran out of pattern but we still had current data.
                // If c[ci] == '/' then pattern matches the subtree.
                // Otherwise we cannot be certain so we return -1.
                //
                return(c[ci] == '/' ? 0 : -1);
            }

            if (ci < pLen)
            {
                // Ran out of current, but we still have pattern data.
                // If p[ci] == '/' then pattern matches this subtree,
                // otherwise we cannot be certain so we return -1.
                //
                return(p[ci] == '/' ? 0 : -1);
            }

            // Both strings are identical.
            //
            return(0);
        }
Beispiel #21
0
        /// <summary>
        /// Create a new iterator with no parent and a prefix.
        ///
        /// The prefix path supplied is inserted in front of all paths generated by
        /// this iterator. It is intended to be used when an iterator is being
        /// created for a subsection of an overall repository and needs to be
        /// combined with other iterators that are created to run over the entire
        /// repository namespace.
        /// </summary>
        /// <param name="prefix">
        /// position of this iterator in the repository tree. The value
        /// may be null or the empty array to indicate the prefix is the
        /// root of the repository. A trailing slash ('/') is
        /// automatically appended if the prefix does not end in '/'.
        /// </param>
        protected AbstractTreeIterator(byte[] prefix)
        {
            _parent = null;

            if (prefix != null && prefix.Length > 0)
            {
                PathLen = prefix.Length;
                Path    = new byte[Math.Max(DEFAULT_PATH_SIZE, PathLen + 1)];
                Array.Copy(prefix, 0, Path, 0, PathLen);
                if (Path[PathLen - 1] != (byte)'/')
                {
                    Path[PathLen++] = (byte)'/';
                }
                PathOffset = PathLen;
            }
            else
            {
                Path       = new byte[DEFAULT_PATH_SIZE];
                PathOffset = 0;
            }
        }
Beispiel #22
0
        private static int AlreadyMatch(AbstractTreeIterator a, AbstractTreeIterator b)
        {
            while (true)
            {
                AbstractTreeIterator ap = a._parent;
                AbstractTreeIterator bp = b._parent;

                if (ap == null || bp == null)
                {
                    return(0);
                }

                if (ap.Matches == bp.Matches)
                {
                    return(a.PathOffset);
                }

                a = ap;
                b = bp;
            }
        }
Beispiel #23
0
        /**
         * Compare two tree's current ObjectId values for equality.
         *
         * @param nthA
         *            first tree to compare the object id from.
         * @param nthB
         *            second tree to compare the object id from.
         * @return result of
         *         <code>getObjectId(nthA).Equals(getObjectId(nthB))</code>.
         * @see #getObjectId(int)
         */
        public bool idEqual(int nthA, int nthB)
        {
            AbstractTreeIterator ch = _currentHead;
            AbstractTreeIterator a  = _trees[nthA];
            AbstractTreeIterator b  = _trees[nthB];

            if (a.Matches == ch && b.Matches == ch)
            {
                return(a.idEqual(b));
            }

            if (a.Matches != ch && b.Matches != ch)
            {
                // If neither tree matches the current path node then neither
                // tree has this entry. In such case the ObjectId is zero(),
                // and zero() is always equal to zero().
                //
                return(true);
            }

            return(false);
        }
Beispiel #24
0
        /**
         * Test if the supplied path matches (being suffix of) the current entry's
         * path.
         * <para />
         * This method tests that the supplied path is exactly equal to the current
         * entry, or is relative to one of entry's parent directories. It is faster
         * to use this method then to use {@link #getPathString()} to first Create
         * a String object, then test <code>endsWith</code> or some other type of
         * string match function.
         *
         * @param p
         *            path buffer to test.
         * @param pLen
         *            number of bytes from <code>buf</code> to test.
         * @return true if p is suffix of the current path;
         *         false if otherwise
         */
        public bool isPathSuffix(byte[] p, int pLen)
        {
            if (p == null)
            {
                throw new ArgumentNullException("p");
            }
            AbstractTreeIterator t = _currentHead;

            byte[] c    = t.Path;
            int    cLen = t.PathLen;
            int    ci;

            for (ci = 1; ci < cLen && ci < pLen; ci++)
            {
                if (c[cLen - ci] != p[pLen - ci])
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #25
0
        public virtual AbstractTreeIterator min()
        {
            int i = 0;
            AbstractTreeIterator minRef = _trees[i];

            while (minRef.eof() && ++i < _trees.Length)
            {
                minRef = _trees[i];
            }

            if (minRef.eof())
            {
                return(minRef);
            }

            minRef.Matches = minRef;
            while (++i < _trees.Length)
            {
                AbstractTreeIterator t = _trees[i];
                if (t.eof())
                {
                    continue;
                }

                int cmp = t.pathCompare(minRef);
                if (cmp < 0)
                {
                    t.Matches = t;
                    minRef    = t;
                }
                else if (cmp == 0)
                {
                    t.Matches = minRef;
                }
            }

            return(minRef);
        }
Beispiel #26
0
        private void ExitSubtree()
        {
            _depth--;
            for (int i = 0; i < _trees.Length; i++)
            {
                _trees[i] = _trees[i].Parent;
            }

            AbstractTreeIterator minRef = null;

            foreach (AbstractTreeIterator t in _trees)
            {
                if (t.Matches != t)
                {
                    continue;
                }

                if (minRef == null || t.pathCompare(minRef) < 0)
                {
                    minRef = t;
                }
            }
            _currentHead = minRef;
        }
 /// <summary>
 /// Check if the current entry of both iterators has the same id.
 /// <para />
 /// This method is faster than <see cref="getEntryObjectId()"/>as it does not
 /// require copying the bytes out of the buffers. A direct <see cref="idBuffer"/>
 /// compare operation is performed.
 /// </summary>
 /// <param name="otherIterator">the other iterator to test against.</param>
 /// <returns>
 /// true if both iterators have the same object id; false otherwise.
 /// </returns>
 public virtual bool idEqual(AbstractTreeIterator otherIterator)
 {
     if (otherIterator == null)
         throw new ArgumentNullException ("otherIterator");
     return ObjectId.Equals(idBuffer(), idOffset(), otherIterator.idBuffer(), otherIterator.idOffset());
 }
 /// <summary>
 /// Create an iterator for a subtree of an existing iterator.
 /// </summary>
 /// <param name="p">parent tree iterator.</param>
 protected AbstractTreeIterator(AbstractTreeIterator p)
 {
     _parent = p;
     Path = p.Path;
     PathOffset = p.PathLen + 1;
     try
     {
         Path[PathOffset - 1] = (byte)'/';
     }
     catch (IndexOutOfRangeException)
     {
         growPath(p.PathLen);
         Path[PathOffset - 1] = (byte)'/';
     }
 }
 /// <summary>
 /// Check if the current entry of both iterators has the same id.
 /// <para />
 /// This method is faster than <see cref="getEntryObjectId()"/>as it does not
 /// require copying the bytes out of the buffers. A direct <see cref="idBuffer"/>
 /// compare operation is performed.
 /// </summary>
 /// <param name="otherIterator">the other iterator to test against.</param>
 /// <returns>
 /// true if both iterators have the same object id; false otherwise.
 /// </returns>
 public virtual bool idEqual(AbstractTreeIterator otherIterator)
 {
     return ObjectId.Equals(idBuffer(), idOffset(), otherIterator.idBuffer(), otherIterator.idOffset());
 }
Beispiel #30
0
 /// <summary>
 /// Create an iterator for a subtree of an existing iterator.
 /// The caller is responsible for setting up the path of the child iterator.
 /// </summary>
 /// <param name="p">parent tree iterator.</param>
 /// <param name="childPath">
 /// Path array to be used by the child iterator. This path must
 /// contain the path from the top of the walk to the first child
 /// and must end with a '/'.
 /// </param>
 /// <param name="childPathOffset">
 /// position within <code>childPath</code> where the child can
 /// insert its data. The value at
 /// <code>childPath[childPathOffset-1]</code> must be '/'.
 /// </param>
 protected AbstractTreeIterator(AbstractTreeIterator p, byte[] childPath, int childPathOffset)
 {
     _parent    = p;
     Path       = childPath;
     PathOffset = childPathOffset;
 }
Beispiel #31
0
 private static string NameOf(AbstractTreeIterator i)
 {
     return RawParseUtils.decode(Constants.CHARSET, i.Path, 0, i.PathLen);
 }
 /// <summary>
 /// Compare the path of this current entry to another iterator's entry.
 /// </summary>
 /// <param name="treeIterator">
 /// The other iterator to compare the path against.
 /// </param>
 /// <returns>
 /// return -1 if this entry sorts first; 0 if the entries are equal; 1 if
 /// <paramref name="treeIterator"/>'s entry sorts first.
 /// </returns>
 public int pathCompare(AbstractTreeIterator treeIterator)
 {
     return pathCompare(treeIterator, treeIterator.Mode);
 }
 /// <summary>
 /// Create a new iterator with no parent.
 /// </summary>
 protected AbstractTreeIterator()
 {
     _parent = null;
     Path = new byte[DEFAULT_PATH_SIZE];
     PathOffset = 0;
 }
Beispiel #34
0
 private CanonicalTreeParser(AbstractTreeIterator p)
     : base(p)
 {
 }
        /// <summary>
        /// Compare the path of this current entry to another iterator's entry.
        /// </summary>
        /// <param name="treeIterator">
        /// The other iterator to compare the path against.
        /// </param>
        /// <param name="treeIteratorMode">
        /// The other iterator <see cref="FileMode"/> bits.
        /// </param>
        /// <returns>
        /// return -1 if this entry sorts first; 0 if the entries are equal; 1 if
        /// <paramref name="treeIterator"/>'s entry sorts first.
        /// </returns>
        public int pathCompare(AbstractTreeIterator treeIterator, int treeIteratorMode)
        {
            if (treeIterator == null)
                throw new ArgumentNullException ("treeIterator");
            byte[] a = Path;
            byte[] b = treeIterator.Path;
            int aLen = PathLen;
            int bLen = treeIterator.PathLen;

            // Its common when we are a subtree for both parents to match;
            // when this happens everything in _path[0..cPos] is known to
            // be equal and does not require evaluation again.
            //
            int cPos = AlreadyMatch(this, treeIterator);

            for (; cPos < aLen && cPos < bLen; cPos++)
            {
                int cmp = (a[cPos] & 0xff) - (b[cPos] & 0xff);
                if (cmp != 0)
                {
                    return cmp;
                }
            }

            if (cPos < aLen)
            {
                return (a[cPos] & 0xff) - LastPathChar(treeIteratorMode);
            }

            if (cPos < bLen)
            {
                return LastPathChar(Mode) - (b[cPos] & 0xff);
            }

            return LastPathChar(Mode) - LastPathChar(treeIteratorMode);
        }
        private static int AlreadyMatch(AbstractTreeIterator a, AbstractTreeIterator b)
        {
            while (true)
            {
                AbstractTreeIterator ap = a._parent;
                AbstractTreeIterator bp = b._parent;

                if (ap == null || bp == null)
                {
                    return 0;
                }

                if (ap.Matches == bp.Matches)
                {
                    return a.PathOffset;
                }

                a = ap;
                b = bp;
            }
        }
Beispiel #37
0
 /// <summary>
 /// Check if the current entry of both iterators has the same id.
 /// <para />
 /// This method is faster than <see cref="getEntryObjectId()"/>as it does not
 /// require copying the bytes out of the buffers. A direct <see cref="idBuffer"/>
 /// compare operation is performed.
 /// </summary>
 /// <param name="otherIterator">the other iterator to test against.</param>
 /// <returns>
 /// true if both iterators have the same object id; false otherwise.
 /// </returns>
 public virtual bool idEqual(AbstractTreeIterator otherIterator)
 {
     return(ObjectId.Equals(idBuffer(), idOffset(), otherIterator.idBuffer(), otherIterator.idOffset()));
 }
 private CanonicalTreeParser(AbstractTreeIterator p)
     : base(p)
 {
 }
 /// <summary>
 /// Create an iterator for a subtree of an existing iterator. 
 /// The caller is responsible for setting up the path of the child iterator.
 /// </summary>
 /// <param name="p">parent tree iterator.</param>
 /// <param name="childPath">
 /// Path array to be used by the child iterator. This path must
 /// contain the path from the top of the walk to the first child
 /// and must end with a '/'.
 /// </param>
 /// <param name="childPathOffset">
 /// position within <code>childPath</code> where the child can
 /// insert its data. The value at
 /// <code>childPath[childPathOffset-1]</code> must be '/'.
 /// </param>
 protected AbstractTreeIterator(AbstractTreeIterator p, byte[] childPath, int childPathOffset)
 {
     _parent = p;
     Path = childPath;
     PathOffset = childPathOffset;
 }
 /// <summary>
 /// Create an iterator for a subtree of an existing iterator.
 /// </summary>
 /// <param name="p">parent tree iterator.</param>
 protected AbstractTreeIterator(AbstractTreeIterator p)
 {
     if (p == null)
         throw new ArgumentNullException ("p");
     _parent = p;
     Path = p.Path;
     PathOffset = p.PathLen + 1;
     try
     {
         Path[PathOffset - 1] = (byte)'/';
     }
     catch (IndexOutOfRangeException)
     {
         growPath(p.PathLen);
         Path[PathOffset - 1] = (byte)'/';
     }
 }
        /// <summary>
        /// Create a new iterator with no parent and a prefix.
        /// 
        /// The prefix path supplied is inserted in front of all paths generated by
        /// this iterator. It is intended to be used when an iterator is being
        /// created for a subsection of an overall repository and needs to be
        /// combined with other iterators that are created to run over the entire
        /// repository namespace.
        /// </summary>
        /// <param name="prefix">
        /// position of this iterator in the repository tree. The value
        /// may be null or the empty array to indicate the prefix is the
        /// root of the repository. A trailing slash ('/') is
        /// automatically appended if the prefix does not end in '/'.
        /// </param>
        protected AbstractTreeIterator(byte[] prefix)
        {
            _parent = null;

            if (prefix != null && prefix.Length > 0)
            {
                PathLen = prefix.Length;
                Path = new byte[Math.Max(DEFAULT_PATH_SIZE, PathLen + 1)];
                Array.Copy(prefix, 0, Path, 0, PathLen);
                if (Path[PathLen - 1] != (byte)'/')
                {
                    Path[PathLen++] = (byte)'/';
                }
                PathOffset = PathLen;
            }
            else
            {
                Path = new byte[DEFAULT_PATH_SIZE];
                PathOffset = 0;
            }
        }
Beispiel #42
0
 /// <summary>
 /// Create a new iterator with no parent.
 /// </summary>
 protected AbstractTreeIterator()
 {
     _parent    = null;
     Path       = new byte[DEFAULT_PATH_SIZE];
     PathOffset = 0;
 }
 /// <summary>
 /// Compare the path of this current entry to another iterator's entry.
 /// </summary>
 /// <param name="treeIterator">
 /// The other iterator to compare the path against.
 /// </param>
 /// <returns>
 /// return -1 if this entry sorts first; 0 if the entries are equal; 1 if
 /// <paramref name="treeIterator"/>'s entry sorts first.
 /// </returns>
 public int pathCompare(AbstractTreeIterator treeIterator)
 {
     if (treeIterator == null)
         throw new ArgumentNullException ("treeIterator");
     return pathCompare(treeIterator, treeIterator.Mode);
 }