diff --git a/src/machinery/pathname.cpp b/src/machinery/pathname.cpp index 69330b1..892a717 100644 --- a/src/machinery/pathname.cpp +++ b/src/machinery/pathname.cpp @@ -1,4 +1,4 @@ -/* Copyright 2015, Michele Santullo +/* Copyright 2016, Michele Santullo * This file is part of "dindexer". * * "dindexer" is free software: you can redistribute it and/or modify @@ -20,12 +20,40 @@ #include #include #include +#include namespace mchlib { const std::string PathName::m_empty_str(""); namespace { std::string get_joint_atoms ( const StringPool& parPool, bool parAbs, std::size_t parSkipRight=0 ); + std::size_t calc_join_size ( const StringPool& parPool, bool parAbs, std::size_t parSkipRight=0 ); + std::size_t get_adjusted_atom_count ( const StringPool& parPool, std::size_t parSkipRight ); + + std::size_t get_adjusted_atom_count (const StringPool& parPool, std::size_t parSkipRight) { + const auto orig_atom_count = parPool.size(); + const auto atom_count = (parSkipRight >= orig_atom_count ? 0 : orig_atom_count - parSkipRight); + return atom_count; + } + + std::size_t calc_join_size (const StringPool& parPool, bool parAbs, std::size_t parSkipRight) { + const auto atom_count = get_adjusted_atom_count(parPool, parSkipRight); + if (not atom_count) { + if (parPool.empty() and parAbs) { + return 1; + } + else { + return 0; + } + } + + std::size_t reserve = (parAbs ? 1 : 0); + for (std::size_t z = 0; z < atom_count; ++z) { + reserve += parPool[z].size(); + } + reserve += atom_count - 1; + return reserve; + } std::size_t count_grouped (boost::string_ref parIn, char parDelim) { std::size_t retval = 0; @@ -55,32 +83,30 @@ namespace mchlib { } std::string get_joint_atoms (const StringPool& parPool, bool parAbs, std::size_t parSkipRight) { - const auto orig_atom_count = parPool.size(); - const auto atom_count = (parSkipRight >= orig_atom_count ? 0 : orig_atom_count - parSkipRight); - if (not atom_count) { - if (parPool.empty() and parAbs) { + const auto reserve = calc_join_size(parPool, parAbs, parSkipRight); + switch (reserve) { + case 0: + //reserve 0 means the resulting string is empty + return std::string(""); + case 1: + //when reserve is 1 and we're talking about an absolute path, + //the resulting string can only be "/" + if (parAbs) { return std::string("/"); } - else { - return std::string(""); - } - } - - std::size_t reserve = (parAbs ? 1 : 0); - for (std::size_t z = 0; z < atom_count; ++z) { - reserve += parPool[z].size(); - } - reserve += atom_count - 1; + }; std::string out; out.reserve(reserve); const char* slash = (parAbs ? "/" : ""); + const auto atom_count = get_adjusted_atom_count(parPool, parSkipRight); for (std::size_t z = 0; z < atom_count; ++z) { out += slash; const auto& curr_itm = parPool[z]; out.insert(out.end(), curr_itm.begin(), curr_itm.end()); slash = "/"; } + assert(reserve == out.size()); return std::move(out); } } //unnamed namespace @@ -210,4 +236,8 @@ namespace mchlib { } return true; } + + std::size_t PathName::str_path_size() const { + return calc_join_size(m_pool, is_absolute()); + } } //namespace mchlib diff --git a/src/machinery/pathname.hpp b/src/machinery/pathname.hpp index 365dc97..14d607b 100644 --- a/src/machinery/pathname.hpp +++ b/src/machinery/pathname.hpp @@ -1,4 +1,4 @@ -/* Copyright 2015, Michele Santullo +/* Copyright 2016, Michele Santullo * This file is part of "dindexer". * * "dindexer" is free software: you can redistribute it and/or modify @@ -35,6 +35,7 @@ namespace mchlib { bool is_absolute ( void ) const { return m_absolute; } std::string path ( void ) const; + std::size_t str_path_size ( void ) const; const std::string& original_path ( void ) const { return (m_original_path ? *m_original_path : m_empty_str); } std::size_t atom_count ( void ) const; const boost::string_ref operator[] ( std::size_t parIndex ) const;