/// <summary>
        /// Replaces the beginning of path. Modifies original object and returns it.
        /// </summary>
        /// <param name="oldBase"></param>
        /// <param name="newBase"></param>
        /// <returns></returns>
        public AbsoluteCrosspath Rebase(AbsoluteCrosspath oldBase, AbsoluteCrosspath newBase)
        {
            if (directories.Count < oldBase.directories.Count)
            {
                return(this);
            }

            Boolean cantRebase = false;

            using (var myIter = directories.GetEnumerator()) {
                using (var theirsIter = oldBase.directories.GetEnumerator()) {
                    for (int idx = 0; idx < oldBase.directories.Count; idx++)
                    {
                        myIter.MoveNext();
                        theirsIter.MoveNext();
                        if (myIter.Current != theirsIter.Current)
                        {
                            cantRebase = true;
                            break;
                        }
                    }
                }
            }

            if (cantRebase)
            {
                return(this);
            }

            // rebasing
            if (directories.Count == oldBase.directories.Count)
            {
                // full rebase, replacing the whole path
                directories = new LinkedList <String>(newBase.directories);
            }
            else
            {
                for (int idx = 0; idx < oldBase.directories.Count; idx++)
                {
                    directories.RemoveFirst();
                }

                LinkedListNode <String> lln = directories.First;

                foreach (String dir in newBase.directories)
                {
                    directories.AddBefore(lln, dir);
                }
            }

            // rerooting
            if (newBase.Flavor == CrosspathFlavor.Windows)
            {
                WindowsRootDrive = newBase.WindowsRootDrive;
            }

            Flavor = newBase.Flavor;

            return(this);
        }
        internal Boolean EqualsToAbsolute(AbsoluteCrosspath absoluteCrosspath)
        {
            if (WorkingDirectory is null)
            {
                return(false);
            }

            // Do not use base comparer there!
            return(this.ToAbsolutizedString() == absoluteCrosspath.ToAbsolutizedString());
        }
        public static AbsoluteCrosspath FromString(String path, AbsoluteCrosspath workingDir)
        {
            Crosspath xpath = Crosspath.FromString(path);

            if (!(xpath is AbsoluteCrosspath))
            {
                return(((RelativeCrosspath)xpath).Absolutized(workingDir));
            }
            return(xpath as AbsoluteCrosspath);
        }
Exemple #4
0
        /// <summary>
        /// Create a generic Crosspath object, which is actually an
        /// AbsoluteCrosspath or RelativeCrosspath depending on the input string.
        /// </summary>
        /// <param name="path">Any path string.</param>
        /// <returns>Crosspath object.</returns>
        public static Crosspath FromString(String path)
        {
            DetectParams(path, out CrosspathOrigin origin, out CrosspathFlavor flavor, out Char rootDrive);
            Crosspath xpath;

            switch (origin)
            {
            case CrosspathOrigin.Absolute:
                xpath = AbsoluteCrosspath.CreateInstance();
                break;

            case CrosspathOrigin.Relative:
                xpath = RelativeCrosspath.CreateInstance();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            xpath.Origin           = origin;
            xpath.Flavor           = flavor;
            xpath.WindowsRootDrive = rootDrive;
            xpath.SourceString     = path;
            xpath.directories      = new LinkedList <String>();

            // push directories
            String[] parts;
            if (flavor == CrosspathFlavor.Windows)
            {
                if (origin == CrosspathOrigin.Absolute)
                {
                    path = path.Substring(2);
                }

                parts = path.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
            }
            else /* if (Flavor == CrosspathFlavor.FlavorUnix) */
            {
                parts = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            }

            foreach (String part in parts)
            {
                // TODO: check `part` for validity
                xpath.Chdir(part);
            }

            return(xpath);
        }
 /// <summary>
 /// Construct a new AbsoluteCrosspath object from this RelativeCrosspath object and custom working directory.
 /// </summary>
 /// <param name="root">A working directory for this relative path.</param>
 /// <returns>AbsoluteCrosspath</returns>
 public AbsoluteCrosspath Absolutized(AbsoluteCrosspath root)
 {
     return(new AbsoluteCrosspath(root).Append(this));
 }
 public void SetWorkingDirectory(AbsoluteCrosspath workdir)
 {
     this.WorkingDirectory = workdir;
 }
 /// <summary>
 /// Creates a copy of instance.
 /// </summary>
 /// <param name="source">Source RelativeCrosspath object, which will remain untouched.</param>
 public RelativeCrosspath(RelativeCrosspath source) : base(source)
 {
     this.WorkingDirectory = source.WorkingDirectory;
 }
        public static RelativeCrosspath CreateRelativePath(AbsoluteCrosspath xpath, AbsoluteCrosspath workingDirectory, Boolean dontGoOut)
        {
            if (xpath.Flavor != workingDirectory.Flavor)
            {
                throw new PolymorphismException("can relativize only identically-flavored paths");
            }

            if (xpath.Flavor == CrosspathFlavor.Windows && xpath.WindowsRootDrive != workingDirectory.WindowsRootDrive)
            {
                throw new CrosspathLibException("cannot relativize different root drives");
            }

            /*
             * RelativeCrosspath ret = RelativeCrosspath.CreateInstance();
             * ret.Flavor = xpath.Flavor;
             * ret.Origin = CrosspathOrigin.Relative;
             * ret.WindowsRootDrive = xpath.WindowsRootDrive;
             * ret.directories = new LinkedList<String>();
             */
            RelativeCrosspath ret = RelativeCrosspath.FromString("");

            ret.Flavor           = xpath.Flavor;
            ret.WindowsRootDrive = xpath.WindowsRootDrive;
            ret.SetWorkingDirectory(workingDirectory);

            using (var myIter = xpath.directories.GetEnumerator()) {
                using (var theirsIter = workingDirectory.directories.GetEnumerator()) {
                    Boolean myMoved;
                    Boolean theirsMoved;

                    // first find a diverging point
                    while (true)
                    {
                        myMoved     = myIter.MoveNext();
                        theirsMoved = theirsIter.MoveNext();
                        if (!myMoved || !theirsMoved)
                        {
                            break;
                        }
                        if (myIter.Current != theirsIter.Current)
                        {
                            break;
                        }
                    }

                    if (theirsMoved && dontGoOut)
                    {
                        throw new CrosspathLibException("path is outide of working dir");
                    }

                    // then go back from workingDirectory and go forth on xpath

                    for (; theirsMoved; theirsMoved = theirsIter.MoveNext())
                    {
                        ret.Chdir("..");
                    }

                    for (; myMoved; myMoved = myIter.MoveNext())
                    {
                        ret.Chdir(myIter.Current);
                    }
                }
            }

            return(ret);
        }
        public static AbsoluteCrosspath GetCurrentDirectory()
        {
            String pwd = Directory.GetCurrentDirectory();

            return(AbsoluteCrosspath.FromString(pwd));
        }
 /// <summary>
 /// Creates a copy of instance.
 /// </summary>
 /// <param name="source">Source AbsoluteCrosspath object, which will remain untouched.</param>
 public AbsoluteCrosspath(AbsoluteCrosspath source) : base(source)
 {
     // no new fields are introduced
 }
 public RelativeCrosspath Relativized(AbsoluteCrosspath workingDir, Boolean dontGoOut = false)
 {
     return(RelativeCrosspath.CreateRelativePath(this, workingDir, dontGoOut));
 }