toolkit/components/osfile/modules/ospath_unix.jsm

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /**
     6  * Handling native paths.
     7  *
     8  * This module contains a number of functions destined to simplify
     9  * working with native paths through a cross-platform API. Functions
    10  * of this module will only work with the following assumptions:
    11  *
    12  * - paths are valid;
    13  * - paths are defined with one of the grammars that this module can
    14  *   parse (see later);
    15  * - all path concatenations go through function |join|.
    16  */
    18 "use strict";
    20 // Boilerplate used to be able to import this module both from the main
    21 // thread and from worker threads.
    22 if (typeof Components != "undefined") {
    23   Components.utils.importGlobalProperties(["URL"]);
    24   // Global definition of |exports|, to keep everybody happy.
    25   // In non-main thread, |exports| is provided by the module
    26   // loader.
    27   this.exports = {};
    28 } else if (typeof "module" == "undefined" || typeof "exports" == "undefined") {
    29   throw new Error("Please load this module using require()");
    30 }
    32 let EXPORTED_SYMBOLS = [
    33   "basename",
    34   "dirname",
    35   "join",
    36   "normalize",
    37   "split",
    38   "toFileURI",
    39   "fromFileURI",
    40 ];
    42 /**
    43  * Return the final part of the path.
    44  * The final part of the path is everything after the last "/".
    45  */
    46 let basename = function(path) {
    47   return path.slice(path.lastIndexOf("/") + 1);
    48 };
    49 exports.basename = basename;
    51 /**
    52  * Return the directory part of the path.
    53  * The directory part of the path is everything before the last
    54  * "/". If the last few characters of this part are also "/",
    55  * they are ignored.
    56  *
    57  * If the path contains no directory, return ".".
    58  */
    59 let dirname = function(path) {
    60   let index = path.lastIndexOf("/");
    61   if (index == -1) {
    62     return ".";
    63   }
    64   while (index >= 0 && path[index] == "/") {
    65     --index;
    66   }
    67   return path.slice(0, index + 1);
    68 };
    69 exports.dirname = dirname;
    71 /**
    72  * Join path components.
    73  * This is the recommended manner of getting the path of a file/subdirectory
    74  * in a directory.
    75  *
    76  * Example: Obtaining $TMP/foo/bar in an OS-independent manner
    77  *  var tmpDir = OS.Constants.Path.tmpDir;
    78  *  var path = OS.Path.join(tmpDir, "foo", "bar");
    79  *
    80  * Under Unix, this will return "/tmp/foo/bar".
    81  */
    82 let join = function(...path) {
    83   // If there is a path that starts with a "/", eliminate everything before
    84   let paths = [];
    85   for (let subpath of path) {
    86     if (subpath == null) {
    87       throw new TypeError("invalid path component");
    88     }
    89     if (subpath.length != 0 && subpath[0] == "/") {
    90       paths = [subpath];
    91     } else {
    92       paths.push(subpath);
    93     }
    94   }
    95   return paths.join("/");
    96 };
    97 exports.join = join;
    99 /**
   100  * Normalize a path by removing any unneeded ".", "..", "//".
   101  */
   102 let normalize = function(path) {
   103   let stack = [];
   104   let absolute;
   105   if (path.length >= 0 && path[0] == "/") {
   106     absolute = true;
   107   } else {
   108     absolute = false;
   109   }
   110   path.split("/").forEach(function(v) {
   111     switch (v) {
   112     case "":  case ".":// fallthrough
   113       break;
   114     case "..":
   115       if (stack.length == 0) {
   116         if (absolute) {
   117           throw new Error("Path is ill-formed: attempting to go past root");
   118         } else {
   119           stack.push("..");
   120         }
   121       } else {
   122         if (stack[stack.length - 1] == "..") {
   123           stack.push("..");
   124         } else {
   125           stack.pop();
   126         }
   127       }
   128       break;
   129     default:
   130       stack.push(v);
   131     }
   132   });
   133   let string = stack.join("/");
   134   return absolute ? "/" + string : string;
   135 };
   136 exports.normalize = normalize;
   138 /**
   139  * Return the components of a path.
   140  * You should generally apply this function to a normalized path.
   141  *
   142  * @return {{
   143  *   {bool} absolute |true| if the path is absolute, |false| otherwise
   144  *   {array} components the string components of the path
   145  * }}
   146  *
   147  * Other implementations may add additional OS-specific informations.
   148  */
   149 let split = function(path) {
   150   return {
   151     absolute: path.length && path[0] == "/",
   152     components: path.split("/")
   153   };
   154 };
   155 exports.split = split;
   157 /**
   158  * Returns the file:// URI file path of the given local file path.
   159  */
   160 // The case of %3b is designed to match Services.io, but fundamentally doesn't matter.
   161 let toFileURIExtraEncodings = {';': '%3b', '?': '%3F', "'": '%27', '#': '%23'};
   162 let toFileURI = function toFileURI(path) {
   163   let uri = encodeURI(this.normalize(path));
   165   // add a prefix, and encodeURI doesn't escape a few characters that we do
   166   // want to escape, so fix that up
   167   let prefix = "file://";
   168   uri = prefix + uri.replace(/[;?'#]/g, match => toFileURIExtraEncodings[match]);
   170   return uri;
   171 };
   172 exports.toFileURI = toFileURI;
   174 /**
   175  * Returns the local file path from a given file URI.
   176  */
   177 let fromFileURI = function fromFileURI(uri) {
   178   let url = new URL(uri);
   179   if (url.protocol != 'file:') {
   180     throw new Error("fromFileURI expects a file URI");
   181   }
   182   let path = this.normalize(decodeURIComponent(url.pathname));
   183   return path;
   184 };
   185 exports.fromFileURI = fromFileURI;
   188 //////////// Boilerplate
   189 if (typeof Components != "undefined") {
   190   this.EXPORTED_SYMBOLS = EXPORTED_SYMBOLS;
   191   for (let symbol of EXPORTED_SYMBOLS) {
   192     this[symbol] = exports[symbol];
   193   }
   194 }

mercurial