Logo Search packages:      
Sourcecode: ardour version File versions  Download package

std::string Glib::build_path ( const std::string &  separator,
const Glib::ArrayHandle< std::string > &  elements 
)

Creates a path from a series of elements using separator as the separator between elements.

At the boundary between two elements, any trailing occurrences of separator in the first element, or leading occurrences of separator in the second element are removed and exactly one copy of the separator is inserted.

Empty elements are ignored.

The number of leading copies of the separator on the result is the same as the number of leading copies of the separator on the first non-empty element.

The number of trailing copies of the separator on the result is the same as the number of trailing copies of the separator on the last non-empty element. (Determination of the number of trailing copies is done without stripping leading copies, so if the separator is "ABA", "ABABA" has 1 trailing copy.)

However, if there is only a single non-empty element, and there are no characters in that element not part of the leading or trailing separators, then the result is exactly the original value of that element.

Other than for determination of the number of leading and trailing copies of the separator, elements consisting only of copies of the separator are ignored.

Parameters:
separator A string used to separate the elements of the path.
elements A container holding the elements of the path to build. Any STL compatible container type is accepted.
Returns:
The resulting path.

Definition at line 160 of file miscutils.cc.

References Glib::ArrayHandle< T, Tr >::data(), and Glib::ArrayHandle< T, Tr >::size().

Referenced by Glib::build_filename().

{
  std::string result;
  result.reserve(256); //TODO: Explain why this magic number is useful. murrayc

  const char *const sep = separator.c_str();
  const size_t seplen   = separator.length();

  bool is_first     = true;
  bool have_leading = false;
  const char* single_element = 0;
  const char* last_trailing  = 0;

  const char *const *const elements_begin = elements.data();
  const char *const *const elements_end   = elements_begin + elements.size();

  for(const char *const * pelement = elements_begin; pelement != elements_end; ++pelement)
  {
    const char* start = *pelement;

    if(*start == '\0')
      continue; // ignore empty elements

    if(seplen != 0)
    {
      while(strncmp(start, sep, seplen) == 0)
        start += seplen;
    }

    const char* end = start + strlen(start);

    if(seplen != 0)
    {
      while(end >= start + seplen && strncmp(end - seplen, sep, seplen) == 0)
        end -= seplen;

      last_trailing = end;

      while(last_trailing >= *pelement + seplen && strncmp(last_trailing - seplen, sep, seplen) == 0)
        last_trailing -= seplen;

      if(!have_leading)
      {
        // If the leading and trailing separator strings are in the
        // same element and overlap, the result is exactly that element.
        //
        if(last_trailing <= start)
          single_element = *pelement;

        result.append(*pelement, start);
        have_leading = true;
      }
      else
        single_element = 0;
    }

    if(end == start)
      continue;

    if(!is_first)
      result += separator;

    result.append(start, end);
    is_first = false;
  }

  if(single_element)
    result = single_element;
  else if(last_trailing)
    result += last_trailing;

  return result;
}


Generated by  Doxygen 1.6.0   Back to index