From: Chris Koeritz Date: Tue, 2 Oct 2012 17:40:26 +0000 (-0400) Subject: may have gotten the gremlin; was an interaction that separate used to handle, but... X-Git-Tag: 2.140.90~1205 X-Git-Url: https://feistymeow.org/gitweb/?p=feisty_meow.git;a=commitdiff_plain;h=1d0e3f784ca8c86185013026e8500f8460aefe8e may have gotten the gremlin; was an interaction that separate used to handle, but in ugly way, 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. --- diff --git a/nucleus/library/filesystem/directory.cpp b/nucleus/library/filesystem/directory.cpp index 8e778952..5a056f7a 100644 --- a/nucleus/library/filesystem/directory.cpp +++ b/nucleus/library/filesystem/directory.cpp @@ -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()] == ':') diff --git a/nucleus/library/filesystem/directory_tree.cpp b/nucleus/library/filesystem/directory_tree.cpp index 68b82b7f..bf554db1 100644 --- a/nucleus/library/filesystem/directory_tree.cpp +++ b/nucleus/library/filesystem/directory_tree.cpp @@ -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(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 diff --git a/nucleus/library/filesystem/filename.cpp b/nucleus/library/filesystem/filename.cpp index adca7e99..a77035ba 100644 --- a/nucleus/library/filesystem/filename.cpp +++ b/nucleus/library/filesystem/filename.cpp @@ -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()) diff --git a/nucleus/library/filesystem/filename.h b/nucleus/library/filesystem/filename.h index 9c4eb56b..940b6c03 100644 --- a/nucleus/library/filesystem/filename.h +++ b/nucleus/library/filesystem/filename.h @@ -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; diff --git a/nucleus/library/filesystem/heavy_file_ops.cpp b/nucleus/library/filesystem/heavy_file_ops.cpp index 0900b432..05da6a99 100644 --- a/nucleus/library/filesystem/heavy_file_ops.cpp +++ b/nucleus/library/filesystem/heavy_file_ops.cpp @@ -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; } diff --git a/nucleus/library/tests_filesystem/test_filename.cpp b/nucleus/library/tests_filesystem/test_filename.cpp index e2377777..6fa80759 100644 --- a/nucleus/library/tests_filesystem/test_filename.cpp +++ b/nucleus/library/tests_filesystem/test_filename.cpp @@ -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."); diff --git a/octopi/library/tentacles/file_transfer_tentacle.cpp b/octopi/library/tentacles/file_transfer_tentacle.cpp index c004b077..068e59fb 100644 --- a/octopi/library/tentacles/file_transfer_tentacle.cpp +++ b/octopi/library/tentacles/file_transfer_tentacle.cpp @@ -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);