diff options
author | Rohan Jain <rohanj@google.com> | 2016-09-14 09:07:53 -0800 |
---|---|---|
committer | TensorFlower Gardener <gardener@tensorflow.org> | 2016-09-14 10:22:05 -0700 |
commit | 857fc259445fbff9a23ba1723d7f617ff40fbf05 (patch) | |
tree | 91fd4ac2e3cf08c172abc2e298a9aedf95dcf615 /tensorflow/core/lib/io/path.cc | |
parent | 7794f94cbe28db421a27afac95bfc780fd10be4d (diff) |
Adding io::CleanPath in path.h to clean up paths. Also made TranslateName call CleanPath so that all paths are clean before doing file system ops.
Change: 133140241
Diffstat (limited to 'tensorflow/core/lib/io/path.cc')
-rw-r--r-- | tensorflow/core/lib/io/path.cc | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/tensorflow/core/lib/io/path.cc b/tensorflow/core/lib/io/path.cc index 107bd5e56a..c59d6d1893 100644 --- a/tensorflow/core/lib/io/path.cc +++ b/tensorflow/core/lib/io/path.cc @@ -101,5 +101,86 @@ StringPiece Extension(StringPiece path) { return internal::SplitBasename(path).second; } +string CleanPath(StringPiece unclean_path) { + string path = unclean_path.ToString(); + const char *src = path.c_str(); + string::iterator dst = path.begin(); + + // Check for absolute path and determine initial backtrack limit. + const bool is_absolute_path = *src == '/'; + if (is_absolute_path) { + *dst++ = *src++; + while (*src == '/') ++src; + } + string::const_iterator backtrack_limit = dst; + + // Process all parts + while (*src) { + bool parsed = false; + + if (src[0] == '.') { + // 1dot ".<whateverisnext>", check for END or SEP. + if (src[1] == '/' || !src[1]) { + if (*++src) { + ++src; + } + parsed = true; + } else if (src[1] == '.' && (src[2] == '/' || !src[2])) { + // 2dot END or SEP (".." | "../<whateverisnext>"). + src += 2; + if (dst != backtrack_limit) { + // We can backtrack the previous part + for (--dst; dst != backtrack_limit && dst[-1] != '/'; --dst) { + // Empty. + } + } else if (!is_absolute_path) { + // Failed to backtrack and we can't skip it either. Rewind and copy. + src -= 2; + *dst++ = *src++; + *dst++ = *src++; + if (*src) { + *dst++ = *src; + } + // We can never backtrack over a copied "../" part so set new limit. + backtrack_limit = dst; + } + if (*src) { + ++src; + } + parsed = true; + } + } + + // If not parsed, copy entire part until the next SEP or EOS. + if (!parsed) { + while (*src && *src != '/') { + *dst++ = *src++; + } + if (*src) { + *dst++ = *src++; + } + } + + // Skip consecutive SEP occurrences + while (*src == '/') { + ++src; + } + } + + // Calculate and check the length of the cleaned path. + int path_length = dst - path.begin(); + if (path_length != 0) { + // Remove trailing '/' except if it is root path ("/" ==> path_length := 1) + if (path_length > 1 && path[path_length - 1] == '/') { + --path_length; + } + path.resize(path_length); + } else { + // The cleaned path is empty; assign "." as per the spec. + path.assign(1, '.'); + } + return path; +} + } // namespace io } // namespace tensorflow |