/* * Copyright (C) 1996-2018 The Squid Software Foundation and contributors * * Squid software is distributed under GPLv2+ license and includes * contributions from numerous individuals and organizations. * Please see the COPYING and CONTRIBUTORS files for details. */ /* DEBUG: section 67 String */ #include String::String() : size_(0), len_(0), buf_(NULL) { #if DEBUGSTRINGS StringRegistry::Instance().add(this); #endif } String::size_type String::size() const { return len_; } char const * String::rawBuf() const { return buf_; } char const * String::termedBuf() const { return buf_; } char String::operator [](unsigned int aPos) const { assert(aPos < size_); return buf_[aPos]; } /// compare NULL and empty strings because str*cmp() may fail on NULL strings /// and because we need to return consistent results for strncmp(count == 0). bool String::nilCmp(const bool thisIsNilOrEmpty, const bool otherIsNilOrEmpty, int &result) const { if (!thisIsNilOrEmpty && !otherIsNilOrEmpty) return false; // result does not matter if (thisIsNilOrEmpty && otherIsNilOrEmpty) result = 0; else if (thisIsNilOrEmpty) result = -1; else // otherIsNilOrEmpty result = +1; return true; } int String::cmp(char const *aString) const { int result = 0; if (nilCmp(!size(), (!aString || !*aString), result)) return result; return strcmp(termedBuf(), aString); } int String::cmp(char const *aString, String::size_type count) const { int result = 0; if (nilCmp((!size() || !count), (!aString || !*aString || !count), result)) return result; return strncmp(termedBuf(), aString, count); } int String::cmp(String const &aString) const { int result = 0; if (nilCmp(!size(), !aString.size(), result)) return result; return strcmp(termedBuf(), aString.termedBuf()); } int String::caseCmp(char const *aString) const { int result = 0; if (nilCmp(!size(), (!aString || !*aString), result)) return result; return strcasecmp(termedBuf(), aString); } int String::caseCmp(char const *aString, String::size_type count) const { int result = 0; if (nilCmp((!size() || !count), (!aString || !*aString || !count), result)) return result; return strncasecmp(termedBuf(), aString, count); } int String::caseCmp(const String &str) const { return caseCmp(str.rawBuf(),str.size()); } void String::set(char const *loc, char const ch) { if (loc < buf_ || loc > (buf_ + size_) ) return; buf_[loc-buf_] = ch; } void String::cut(String::size_type newLength) { // size_type is size_t, unsigned. No need to check for newLength <0 if (newLength > len_) return; len_ = newLength; // buf_ may be NULL on zero-length strings. if (len_ == 0 && buf_ == NULL) return; buf_[newLength] = '\0'; } void String::cutPointer(char const *loc) { if (loc < buf_ || loc > (buf_ + size_) ) return; len_ = loc-buf_; buf_[len_] = '\0'; } std::ostream & operator<<(std::ostream& os, String const &aString) { os.write(aString.rawBuf(),aString.size()); return os; } bool operator<(const String &a, const String &b) { return a.cmp(b) < 0; }