may have gotten the gremlin; was an interaction that separate used to handle, but...
authorChris Koeritz <fred@gruntose.com>
Tue, 2 Oct 2012 17:40:26 +0000 (13:40 -0400)
committerChris Koeritz <fred@gruntose.com>
Tue, 2 Oct 2012 17:40:26 +0000 (13:40 -0400)
where one cannot tell that the path given to separate was rooted if one just gets a list of
components.  that's why we used to treat the top-level dir as its own component, but that also
isn't very helpful or sensible.  so now separate and join both have a rooted parameter; separate
reports if the path was rooted, and join needs to know that so it can recreate the original
path.

nucleus/library/filesystem/directory.cpp
nucleus/library/filesystem/directory_tree.cpp
nucleus/library/filesystem/filename.cpp
nucleus/library/filesystem/filename.h
nucleus/library/filesystem/heavy_file_ops.cpp
nucleus/library/tests_filesystem/test_filename.cpp
octopi/library/tentacles/file_transfer_tentacle.cpp

index 8e7789521e434281fb47837dcea7477efc403d1e..5a056f7af1f49c17490656f08fc1bcc9df799ad9 100644 (file)
@@ -259,12 +259,13 @@ bool directory::recursive_create(const astring &directory_name)
   FUNCDEF("recursive_create");
   filename dir(directory_name);
   string_array pieces;
-  dir.separate(pieces);
+  bool rooted;
+  dir.separate(rooted, pieces);
   for (int i = 0; i < pieces.length(); i++) {
     // check each location along the way.
     string_array partial = pieces.subarray(0, i);
     filename curr;
-    curr.join(partial);  // this is our current location.
+    curr.join(rooted, partial);  // this is our current location.
     // make sure, if we see a drive letter component, that we call it
     // a proper directory name.
     if (curr.raw()[curr.raw().end()] == ':')
index 68b82b7fc7d3cdbf41e27182acf178596f6a0d86..bf554db17b3f289210780fd387c9a342ab5e9193 100644 (file)
@@ -274,7 +274,8 @@ bool directory_tree::jump_to(dir_tree_iterator &scanning,
 {
   FUNCDEF("jump_to");
   string_array pieces;
-  filename(sub_path).separate(pieces);
+  bool rooted;
+  filename(sub_path).separate(rooted, pieces);
   for (int i = 0; i < pieces.length(); i++) {
     filename_tree *curr = dynamic_cast<filename_tree *>(scanning.current());
 #ifdef DEBUG_DIRECTORY_TREE
@@ -282,7 +283,7 @@ bool directory_tree::jump_to(dir_tree_iterator &scanning,
 #endif
     string_array sub_pieces = pieces.subarray(i, i);
     filename curr_path;
-    curr_path.join(sub_pieces);
+    curr_path.join(rooted, sub_pieces);
     curr_path = filename(curr->_dirname.raw() + filename::default_separator()
         + curr_path.raw());
 #ifdef DEBUG_DIRECTORY_TREE
@@ -583,7 +584,8 @@ bool directory_tree::compare_trees(const directory_tree &source,
   int source_pieces = 0;
   {
     string_array temp;
-    filename(real_source_start).separate(temp);
+    bool rooted_source;
+    filename(real_source_start).separate(rooted_source, temp);
     source_pieces = temp.length();
   }
 
@@ -597,7 +599,8 @@ bool directory_tree::compare_trees(const directory_tree &source,
 #endif
 
     string_array pieces;
-    curr.separate(pieces);  // get the components of the current location.
+    bool curr_rooted;
+    curr.separate(curr_rooted, pieces);  // get the components of the current location.
 #ifdef DEBUG_DIRECTORY_TREE
     LOG(astring("name in pieces:") + pieces.text_form());
 #endif
@@ -605,7 +608,8 @@ bool directory_tree::compare_trees(const directory_tree &source,
       // snap the root components out of there.
 
     filename corresponding_name;
-    corresponding_name.join(pieces);
+//hmmm: is that right decision?
+    corresponding_name.join(false, pieces);
 #ifdef DEBUG_DIRECTORY_TREE
     LOG(astring("computed target name as: ") + corresponding_name);
 #endif
@@ -715,13 +719,15 @@ outcome directory_tree::find_common_root(const astring &finding, bool exists,
 
   // break up the path into pieces.
   pieces.reset();
-  adding.separate(pieces);
+  bool rooted;
+  adding.separate(rooted, pieces);
 
   // break up our root into pieces; we must take off components that are
   // already in the root.
   string_array root_pieces;
+  bool root_rooted;
   filename temp_file(path());
-  temp_file.separate(root_pieces);
+  temp_file.separate(root_rooted, root_pieces);
 
   // locate the last place where the path we were given touches our tree.
   // it could be totally new, partially new, or already contained.
@@ -866,7 +872,8 @@ outcome directory_tree::add_path(const astring &new_item, bool just_size)
 #endif
       // handle the case for files now that we have our proper node.
       string_array partial_pieces;
-      filename(reassembled).separate(partial_pieces);
+      bool partial_rooted;
+      filename(reassembled).separate(partial_rooted, partial_pieces);
       int levels_missing = pieces.length() - partial_pieces.length();
 
       // we loop over all the pieces that were missing in between the last
index adca7e99dcee76d0d31b12f473c455897d594d95..a77035baeabb3f795ad586b79ba471da3c62e0f9 100644 (file)
@@ -425,11 +425,12 @@ bool filename::unpack(byte_array &packed_form)
   return true;
 }
 
-void filename::separate(string_array &pieces) const
+void filename::separate(bool &rooted, string_array &pieces) const
 {
   pieces.reset();
   const astring &raw_form = raw();
   astring accumulator;  // holds the names we find.
+  rooted = raw_form.length() && separator(raw_form[0]);
   for (int i = 0; i < raw_form.length(); i++) {
     if (separator(raw_form[i])) {
       // this is a separator character, so eat it and add the accumulated
@@ -445,9 +446,10 @@ void filename::separate(string_array &pieces) const
   if (accumulator.length()) pieces += accumulator;
 }
 
-void filename::join(const string_array &pieces)
+void filename::join(bool rooted, const string_array &pieces)
 {
   astring constructed_name;  // we'll make a filename here.
+  if (rooted) constructed_name += DEFAULT_SEPARATOR;
   for (int i = 0; i < pieces.length(); i++) {
     constructed_name += pieces[i];
     if (!i || (i != pieces.length() - 1))
@@ -459,8 +461,13 @@ void filename::join(const string_array &pieces)
 bool filename::base_compare_prefix(const filename &to_compare,
     string_array &first, string_array &second)
 {
-  separate(first);
-  to_compare.separate(second);
+  bool first_rooted;
+  separate(first_rooted, first);
+  bool second_rooted;
+  to_compare.separate(second_rooted, second);
+  if (first_rooted != second_rooted) {
+    return false;
+  }
   // that case should never be allowed, since there are some bits missing
   // in the name to be compared.
   if (first.length() > second.length())
@@ -509,8 +516,10 @@ bool filename::compare_prefix(const filename &to_compare)
 bool filename::base_compare_suffix(const filename &to_compare,
     string_array &first, string_array &second)
 {
-  separate(first);
-  to_compare.separate(second);
+  bool first_rooted;
+  separate(first_rooted, first);
+  bool second_rooted;
+  to_compare.separate(second_rooted, second);
   // that case should never be allowed, since there are some bits missing
   // in the name to be compared.
   if (first.length() > second.length())
index 9c4eb56beb7b9a582f70e5881dbba7951fcbf9b3..940b6c037cfc717005a149ddc7c34a7bbfa2abc7 100644 (file)
@@ -185,20 +185,19 @@ public:
     the file to be created or accessed).  the "replacement" is used as the
     character that is substituted instead of illegal characters. */
 
-  void separate(structures::string_array &pieces) const;
+  void separate(bool &rooted, structures::string_array &pieces) const;
     //!< breaks the filename into its component parts.
-    /*!< this returns an array containing the component names.  the last
-    component, unless the filename held is actually a directory, should be the
-    name of the file.
-//hmmm: what does this mean, below?
-  if the first character is a directory, then the first
-    component will be empty. */
-
-  void join(const structures::string_array &pieces);
+    /*!< this returns an array containing the component names for the path in
+    this filename object.  if the "rooted" flag is set to true, then the path
+    was absolute (i.e. started at '/' in unix.  this notion is not needed for
+    dos/windoze, as the first component will be something like 'a:'). */
+
+  void join(bool rooted, const structures::string_array &pieces);
     //!< undoes a separate() operation to get the filename back.
     /*!< "this" is set to a filename made from each of the "pieces".  if there
-    are any directory separators inside the pieces, then they will be removed
-    by canonicalize(). */
+    are any directory separators inside the pieces themselves, then they will
+    be removed by canonicalize().  if separate() said the path was rooted,
+    then join needs to be told that. */
 
   // these implement the packing functionality.
   virtual void pack(basis::byte_array &packed_form) const;
index 0900b4328b9b52d5f4129b0d0158597d59421430..05da6a992b58f267540ebceb8577098aba0e99ef 100644 (file)
@@ -176,7 +176,11 @@ outcome heavy_file_operations::write_file_chunk(const astring &target,
   if (byte_start < 0) return BAD_INPUT;
 
   filename targ_name(target);
-  if (!directory::recursive_create(targ_name.dirname().raw())) {
+  astring targ_dir = targ_name.dirname().raw();
+#ifdef DEBUG_HEAVY_FILE_OPS
+  LOG(astring("creating target's directory: ") + targ_name.dirname().raw());
+#endif
+  if (!directory::recursive_create(targ_dir)) {
     LOG(astring("failed to create directory: ") + targ_name.dirname().raw());
     return TARGET_DIR_ERROR;
   }
index e237777788847890d54eaa60eeffee91fa797de7..6fa80759ceac3b118a564f0ab4a5a9697a3b3e7c 100644 (file)
@@ -59,7 +59,9 @@ int test_filename::execute()
     astring GROUP = "separate-- ";
     filename turkey("/omega/ralph/turkey/buzzard.txt");
     string_array pieces;
-    turkey.separate(pieces);
+    bool rooted;
+    turkey.separate(rooted, pieces);
+    ASSERT_TRUE(rooted, GROUP + "the rooted value is erreonous.");
     ASSERT_TRUE(pieces[0].equal_to("omega"), GROUP + "the first piece didn't match.");
     ASSERT_TRUE(pieces[1].equal_to("ralph"), GROUP + "the second piece didn't match.");
     ASSERT_TRUE(pieces[2].equal_to("turkey"), GROUP + "the third piece didn't match.");
index c004b07740ee7de1ad6b3e48ccb9e431ae16ab67..068e59fb31493a2fd780307cda29cb0004f0f9f2 100644 (file)
@@ -138,7 +138,8 @@ public:
   astring translate(const astring &source_path) const {
     FUNCDEF("translate");
     string_array pieces;
-    filename(source_path).separate(pieces);
+    bool rooted;
+    filename(source_path).separate(rooted, pieces);
     astring source_mapping = pieces[0];
     pieces.zap(0, 0);  // remove source part.
 
@@ -466,13 +467,14 @@ outcome file_transfer_tentacle::handle_tree_compare_request
   // get the mapping from the specified location on this side.
   filename splitting(req._src_root);
   string_array pieces;
-  splitting.separate(pieces);
+  bool rooted;
+  splitting.separate(rooted, pieces);
   astring source_mapping = pieces[0];
 
   // patch the name up to find the sub_path for the source.
   filename source_start;
   pieces.zap(0, 0);
-  source_start.join(pieces);
+  source_start.join(rooted, pieces);
 
   // locate the allowed transfer depot for the mapping they provided.
   file_transfer_record *mapping_record
@@ -698,6 +700,7 @@ outcome file_transfer_tentacle::handle_storage_response
 
     astring full_file = resp._dest_root + filename::default_separator()
         + recorded_info->secondary();
+LOG(astring("telling it to write to fullfile: ") + full_file);
 
     outcome ret = heavy_file_operations::write_file_chunk(full_file,
         found._byte_start, to_write);