stringUtils.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_BASE_TF_STRING_UTILS_H
25 #define PXR_BASE_TF_STRING_UTILS_H
26 
30 
31 #include "pxr/pxr.h"
32 
34 #include "pxr/base/arch/inttypes.h"
35 #include "pxr/base/tf/api.h"
36 #include "pxr/base/tf/enum.h"
37 
38 #include <cstdarg>
39 #include <cstring>
40 #include <list>
41 #include <set>
42 #include <sstream>
43 #include <string>
44 #include <type_traits>
45 #include <vector>
46 
47 PXR_NAMESPACE_OPEN_SCOPE
48 
49 class TfToken;
50 
53 
71 TF_API
72 std::string TfStringPrintf(const char *fmt, ...)
73 #ifndef doxygen
75 #endif /* doxygen */
76  ;
77 
87 TF_API
88 std::string TfVStringPrintf(const std::string& fmt, va_list ap);
89 
91 
92 TF_API
93 std::string TfVStringPrintf(const char *fmt, va_list ap)
94 #ifndef doxygen
96 #endif /* doxygen */
97  ;
98 
102 inline std::string TfSafeString(const char* ptr) {
103  return ptr ? std::string(ptr) : std::string();
104 }
105 
107 inline std::string TfIntToString(int i) {
108  return TfStringPrintf("%d", i);
109 }
110 
130 TF_API double TfStringToDouble(const std::string& txt);
131 
133 TF_API double TfStringToDouble(const char *text);
134 
136 TF_API double TfStringToDouble(const char *text, int len);
137 
149 TF_API
150 long TfStringToLong(const std::string &txt, bool *outOfRange=NULL);
151 
153 
154 TF_API
155 long TfStringToLong(const char *txt, bool *outOfRange=NULL);
156 
167 TF_API
168 unsigned long TfStringToULong(const std::string &txt, bool *outOfRange=NULL);
169 
171 
172 TF_API
173 unsigned long TfStringToULong(const char *txt, bool *outOfRange=NULL);
174 
186 TF_API
187 int64_t TfStringToInt64(const std::string &txt, bool *outOfRange=NULL);
188 
190 TF_API
191 int64_t TfStringToInt64(const char *txt, bool *outOfRange=NULL);
192 
203 TF_API
204 uint64_t TfStringToUInt64(const std::string &txt, bool *outOfRange=NULL);
205 
207 TF_API
208 uint64_t TfStringToUInt64(const char *txt, bool *outOfRange=NULL);
209 
210 inline bool
211 Tf_StringStartsWithImpl(char const *s, size_t slen,
212  char const *prefix, size_t prelen)
213 {
214  return slen >= prelen && strncmp(s, prefix, prelen) == 0;
215 }
216 
218 inline bool
219 TfStringStartsWith(const std::string& s, const char *prefix)
220 {
221  return Tf_StringStartsWithImpl(
222  s.c_str(), s.length(), prefix, strlen(prefix));
223 }
224 
226 inline bool
227 TfStringStartsWith(const std::string& s, const std::string& prefix) {
228  return TfStringStartsWith(s, prefix.c_str());
229 }
230 
231 inline bool
232 Tf_StringEndsWithImpl(char const *s, size_t slen,
233  char const *suffix, size_t suflen)
234 {
235  return slen >= suflen && strcmp(s + (slen - suflen), suffix) == 0;
236 }
237 
239 inline bool TfStringEndsWith(const std::string& s, const char *suffix)
240 {
241  return Tf_StringEndsWithImpl(s.c_str(), s.length(),
242  suffix, strlen(suffix));
243 }
244 
246 inline bool
247 TfStringEndsWith(const std::string& s, const std::string& suffix)
248 {
249  return TfStringEndsWith(s, suffix.c_str());
250 }
251 
253 // \ingroup group_tf_String
254 TF_API
255 bool TfStringContains(const std::string& s, const char *substring);
256 
258 inline bool
259 TfStringContains(const std::string &s, const std::string &substring) {
260  return TfStringContains(s, substring.c_str());
261 }
262 
264 TF_API
265 bool TfStringContains(const std::string &s, const TfToken& substring);
266 
268 TF_API
269 std::string TfStringToLower(const std::string& source);
270 
272 TF_API
273 std::string TfStringToUpper(const std::string& source);
274 
277 TF_API
278 std::string TfStringCapitalize(const std::string& source);
279 
284 TF_API
285 std::string TfStringTrimLeft(const std::string& s,
286  const char* trimChars = " \n\t\r");
287 
292 TF_API
293 std::string TfStringTrimRight(const std::string& s,
294  const char* trimChars = " \n\t\r");
295 
301 TF_API
302 std::string TfStringTrim(const std::string& s,
303  const char* trimChars = " \n\t\r");
304 
310 TF_API
311 std::string TfStringGetCommonPrefix(std::string a, std::string b);
312 
318 TF_API
319 std::string TfStringGetSuffix(const std::string& name, char delimiter = '.');
320 
327 TF_API
328 std::string TfStringGetBeforeSuffix(const std::string& name, char delimiter = '.');
329 
331 TF_API
332 std::string TfGetBaseName(const std::string& fileName);
333 
341 TF_API
342 std::string TfGetPathName(const std::string& fileName);
343 
349 TF_API
350 std::string TfStringReplace(const std::string& source, const std::string& from,
351  const std::string& to);
352 
358 template <class ForwardIterator>
359 std::string TfStringJoin(
360  ForwardIterator begin, ForwardIterator end,
361  const char* separator = " ")
362 {
363  if (begin == end)
364  return std::string();
365 
366  size_t distance = std::distance(begin, end);
367  if (distance == 1)
368  return *begin;
369 
370  std::string retVal;
371 
372  size_t sum = 0;
373  ForwardIterator i = begin;
374  for (i = begin; i != end; ++i)
375  sum += i->size();
376  retVal.reserve(sum + strlen(separator) * (distance - 1));
377 
378  i = begin;
379  retVal.append(*i);
380  while (++i != end) {
381  retVal.append(separator);
382  retVal.append(*i);
383  }
384 
385  return retVal;
386 }
387 
392 TF_API
393 std::string TfStringJoin(const std::vector<std::string>& strings,
394  const char* separator = " ");
395 
400 TF_API
401 std::string TfStringJoin(const std::set<std::string>& strings,
402  const char* separator = " ");
403 
409 TF_API
410 std::vector<std::string> TfStringSplit(std::string const &src,
411  std::string const &separator);
412 
422 TF_API
423 std::vector<std::string> TfStringTokenize(const std::string& source,
424  const char* delimiters = " \t\n");
425 
429 TF_API
430 std::set<std::string> TfStringTokenizeToSet(const std::string& source,
431  const char* delimiters = " \t\n");
432 
442 TF_API
443 std::vector<std::string>
444 TfQuotedStringTokenize(const std::string& source,
445  const char* delimiters = " \t\n",
446  std::string *errors = NULL);
447 
458 TF_API
459 std::vector<std::string>
460 TfMatchedStringTokenize(const std::string& source,
461  char openDelimiter,
462  char closeDelimiter,
463  char escapeCharacter = '\0',
464  std::string *errors = NULL);
465 
472 inline
473 std::vector<std::string>
474 TfMatchedStringTokenize(const std::string& source,
475  char openDelimiter,
476  char closeDelimiter,
477  std::string *errors)
478 {
479  return TfMatchedStringTokenize(source, openDelimiter,
480  closeDelimiter, '\0', errors);
481 }
482 
512  inline bool operator()(const std::string &lhs,
513  const std::string &rhs) const {
514  // Check first chars first. By far, it is most common that these
515  // characters are letters of the same case that differ, or of different
516  // case that differ. It is very rare that we have to account for
517  // different cases, or numerical comparisons, so we special-case this
518  // first.
519  char l = lhs.c_str()[0], r = rhs.c_str()[0];
520  if (((l & ~0x20) != (r & ~0x20)) & bool(l & r & ~0x3f)) {
521  // This bit about add 5 mod 32 makes it so that '_' sorts less than
522  // all letters, which preserves existing behavior.
523  return ((l + 5) & 31) < ((r + 5) & 31);
524  }
525  else {
526  return _LessImpl(lhs, rhs);
527  }
528  }
529 private:
530  TF_API bool _LessImpl(const std::string &lhs,
531  const std::string &rhs) const;
532 };
533 
539 template <typename T>
540 typename std::enable_if<!std::is_enum<T>::value, std::string>::type
541 TfStringify(const T& v)
542 {
543  std::ostringstream stream;
544  stream << v;
545  return stream.str();
546 }
547 
549 template <typename T>
550 typename std::enable_if<std::is_enum<T>::value, std::string>::type
551 TfStringify(const T& v)
552 {
553  return TfEnum::GetName(v);
554 }
555 
557 TF_API std::string TfStringify(bool v);
559 TF_API std::string TfStringify(std::string const&);
561 TF_API std::string TfStringify(float);
563 TF_API std::string TfStringify(double);
564 
571 TF_API bool TfDoubleToString(
572  double d, char* buffer, int len, bool emitTrailingZero);
573 
579  explicit TfStreamFloat(float f) : value(f) {}
580  float value;
581 };
582 
583 TF_API std::ostream& operator<<(std::ostream& o, TfStreamFloat t);
584 
590  explicit TfStreamDouble(double d) : value(d) {}
591  double value;
592 };
593 
594 TF_API std::ostream& operator<<(std::ostream& o, TfStreamDouble t);
595 
601 template <typename T>
602 T
603 TfUnstringify(const std::string &instring, bool* status = NULL)
604 {
605  T v = T();
606  std::istringstream stream(instring);
607  stream >> v;
608  if (status && !stream)
609  *status = false;
610  return v;
611 }
612 
614 template <>
615 TF_API
616 bool TfUnstringify(const std::string &instring, bool* status);
618 template <>
619 TF_API
620 std::string TfUnstringify(const std::string &instring, bool* status);
621 
627 TF_API
628 std::string TfStringGlobToRegex(const std::string& s);
629 
656 //
661 TF_API std::string TfEscapeString(const std::string &in);
662 TF_API void TfEscapeStringReplaceChar(const char** in, char** out);
663 
674 TF_API
675 std::string TfStringCatPaths( const std::string &prefix,
676  const std::string &suffix );
677 
683 inline bool
684 TfIsValidIdentifier(std::string const &identifier)
685 {
686  char const *p = identifier.c_str();
687  auto letter = [](unsigned c) { return ((c-'A') < 26) || ((c-'a') < 26); };
688  auto number = [](unsigned c) { return (c-'0') < 10; };
689  auto under = [](unsigned c) { return c == '_'; };
690  unsigned x = *p;
691  if (!x || number(x)) {
692  return false;
693  }
694  while (letter(x) || number(x) || under(x)) {
695  x = *p++;
696  };
697  return x == 0;
698 }
699 
702 TF_API
703 std::string
704 TfMakeValidIdentifier(const std::string &in);
705 
710 TF_API
711 std::string TfGetXmlEscapedString(const std::string &in);
712 
714 
715 PXR_NAMESPACE_CLOSE_SCOPE
716 
717 #endif // PXR_BASE_TF_STRING_UTILS_H
TF_API std::string TfGetXmlEscapedString(const std::string &in)
Escapes characters in in so that they are valid XML.
TF_API std::string TfStringPrintf(const char *fmt,...)
Returns a string formed by a printf()-like specification.
TF_API unsigned long TfStringToULong(const std::string &txt, bool *outOfRange=NULL)
Convert a sequence of digits in txt to an unsigned long value.
std::string TfSafeString(const char *ptr)
Safely create a std::string from a (possibly NULL) char*.
Definition: stringUtils.h:102
bool TfStringEndsWith(const std::string &s, const char *suffix)
Returns true if s ends with suffix.
Definition: stringUtils.h:239
Provides dictionary ordering binary predicate function on strings.
Definition: stringUtils.h:499
TF_API long TfStringToLong(const std::string &txt, bool *outOfRange=NULL)
Convert a sequence of digits in txt to a long int value.
TF_API std::string TfStringGetBeforeSuffix(const std::string &name, char delimiter='.')
Returns everything up to the suffix of a string.
TF_API std::vector< std::string > TfStringSplit(std::string const &src, std::string const &separator)
Breaks the given string apart, returning a vector of strings.
TF_API std::string TfStringTrimRight(const std::string &s, const char *trimChars=" \n\t\r")
Trims characters (by default, whitespace) from the right.
Define function attributes.
bool TfStringStartsWith(const std::string &s, const char *prefix)
Returns true if s starts with prefix.
Definition: stringUtils.h:219
TF_API std::set< std::string > TfStringTokenizeToSet(const std::string &source, const char *delimiters=" \t\n")
Breaks the given string apart, returning a set of strings.
TF_API double TfStringToDouble(const std::string &txt)
Converts text string to double.
TF_API std::string TfStringGlobToRegex(const std::string &s)
Returns a string with glob characters converted to their regular expression equivalents.
TF_API std::string TfMakeValidIdentifier(const std::string &in)
Produce a valid identifier (see TfIsValidIdentifier) from in by replacing invalid characters with '_'...
TF_API std::string TfStringToLower(const std::string &source)
Makes all characters in source lowercase, and returns the result.
TF_API std::string TfStringTrim(const std::string &s, const char *trimChars=" \n\t\r")
Trims characters (by default, whitespace) from the beginning and end of string.
TF_API std::vector< std::string > TfQuotedStringTokenize(const std::string &source, const char *delimiters=" \t\n", std::string *errors=NULL)
Breaks the given quoted string apart, returning a vector of strings.
TF_API bool TfDoubleToString(double d, char *buffer, int len, bool emitTrailingZero)
Writes the string representation of d to buffer of length len.
std::string TfIntToString(int i)
Returns the given integer as a string.
Definition: stringUtils.h:107
TF_API std::vector< std::string > TfMatchedStringTokenize(const std::string &source, char openDelimiter, char closeDelimiter, char escapeCharacter='\0', std::string *errors=NULL)
Breaks the given string apart by matching delimiters.
A type which offers streaming for floats in a canonical format that can safely roundtrip with the min...
Definition: stringUtils.h:578
static TF_API std::string GetName(TfEnum val)
Returns the name associated with an enumerated value.
bool operator()(const std::string &lhs, const std::string &rhs) const
Return true if lhs is less than rhs in dictionary order.
Definition: stringUtils.h:512
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:87
TF_API std::string TfVStringPrintf(const std::string &fmt, va_list ap)
Returns a string formed by a printf()-like specification.
TF_API uint64_t TfStringToUInt64(const std::string &txt, bool *outOfRange=NULL)
Convert a sequence of digits in txt to a uint64_t value.
#define ARCH_PRINTF_FUNCTION(_fmt, _firstArg)
Macro used to indicate a function takes a printf-like specification.
Definition: attributes.h:51
TF_API bool TfStringContains(const std::string &s, const char *substring)
Returns true if s contains substring.
std::string TfStringJoin(ForwardIterator begin, ForwardIterator end, const char *separator=" ")
Concatenates the strings (begin, end), with default separator.
Definition: stringUtils.h:359
TF_API std::string TfStringGetSuffix(const std::string &name, char delimiter='.')
Returns the suffix of a string.
TF_API std::string TfStringCapitalize(const std::string &source)
Returns a copy of the source string with only its first character capitalized.
Define integral types.
GF_API std::ostream & operator<<(std::ostream &, const GfBBox3d &)
Output a GfBBox3d using the format [(range) matrix zeroArea].
TF_API std::string TfStringToUpper(const std::string &source)
Makes all characters in source uppercase, and returns the result.
TF_API std::string TfStringGetCommonPrefix(std::string a, std::string b)
Returns the common prefix of the input strings, if any.
A type which offers streaming for doubles in a canonical format that can safely roundtrip with the mi...
Definition: stringUtils.h:589
T TfUnstringify(const std::string &instring, bool *status=NULL)
Convert a string to an arbitrary type.
Definition: stringUtils.h:603
TF_API std::string TfGetBaseName(const std::string &fileName)
Returns the base name of a file (final component of the path).
bool TfIsValidIdentifier(std::string const &identifier)
Test whether identifier is valid.
Definition: stringUtils.h:684
std::enable_if<!std::is_enum< T >::value, std::string >::type TfStringify(const T &v)
Convert an arbitrary type into a string.
Definition: stringUtils.h:541
TF_API std::vector< std::string > TfStringTokenize(const std::string &source, const char *delimiters=" \t\n")
Breaks the given string apart, returning a vector of strings.
TF_API int64_t TfStringToInt64(const std::string &txt, bool *outOfRange=NULL)
Convert a sequence of digits in txt to an int64_t value.
TF_API std::string TfStringReplace(const std::string &source, const std::string &from, const std::string &to)
Replaces all occurrences of string from with to in source.
TF_API std::string TfStringTrimLeft(const std::string &s, const char *trimChars=" \n\t\r")
Trims characters (by default, whitespace) from the left.
TF_API std::string TfStringCatPaths(const std::string &prefix, const std::string &suffix)
Concatenate two strings containing '/' and '..' tokens like a file path or scope name.
TF_API std::string TfEscapeString(const std::string &in)
Process escape sequences in ANSI C string constants.
TF_API std::string TfGetPathName(const std::string &fileName)
Returns the path component of a file (complement of TfGetBaseName()).