/* * tardy - a tar post-processor * Copyright (C) 1991-1995, 1998, 1999, 2002, 2004 Peter Miller; * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * * MANIFEST: interface definition for common/str.cc */ #ifndef COMMON_RCSTRING_H #define COMMON_RCSTRING_H #include #include #include typedef unsigned long str_hash_ty; typedef struct string_ty string_ty; struct string_ty { str_hash_ty str_hash; string_ty *str_next; long str_references; size_t str_length; char str_text[1]; }; void str_initialize(void); string_ty *str_from_c(const char *); string_ty *str_n_from_c(const char *, size_t); string_ty *str_copy(string_ty *); void str_free(string_ty *); string_ty *str_catenate(string_ty *, string_ty *); string_ty *str_cat_three(string_ty *, string_ty *, string_ty *); int str_bool(string_ty *); string_ty *str_upcase(string_ty *); string_ty *str_downcase(string_ty *); void str_dump(void); string_ty *str_field(string_ty *str, int sep, int fldnum); void slow_to_fast(char **, string_ty **, size_t); string_ty *str_format(char *, ...) ATTR_PRINTF(1, 2); string_ty *str_vformat(char *, va_list); inline bool str_equal(string_ty *s1, string_ty *s2) { return (s1 == s2); } /** * The rcstring class is used to represent a reference counted string * class. It has optinal string equality time charactgerstics. */ class rcstring { public: ~rcstring() { if (p) str_free(p); } rcstring() { p = 0; } rcstring(const rcstring &arg) : p(str_copy(arg.p)) {} rcstring(const char *arg) : p(str_from_c(arg)) {} rcstring(const char *arg, size_t len) : p(str_n_from_c(arg, len)) {} rcstring &operator = (const rcstring &arg) { if (p) str_free(p); arg.bind(); p = str_copy(arg.p); return *this; } const char *to_c_string() const { bind(); return p->str_text; } operator const char * () const { return to_c_string(); } size_t length() const { bind(); return p->str_length; } str_hash_ty hash() const { bind(); return p->str_hash; } int operator[] (int n) const { if (n < 0) return 0; bind(); if (n >= (int)p->str_length) return 0; return (unsigned char)p->str_text[n]; } rcstring &operator += (const rcstring &arg) { bind(); arg.bind(); string_ty *tmp = str_catenate(p, arg.p); str_free(p); p = tmp; return *this; } friend bool operator == (const rcstring &, const rcstring &); friend bool operator != (const rcstring &, const rcstring &); friend bool operator < (const rcstring &, const rcstring &); friend bool operator <= (const rcstring &, const rcstring &); friend bool operator > (const rcstring &, const rcstring &); friend bool operator >= (const rcstring &, const rcstring &); friend rcstring operator + (const rcstring &, const rcstring &); private: mutable string_ty *p; void bind() const { if (!p) p = str_from_c(""); } }; inline bool operator == (const rcstring &lhs, const rcstring &rhs) { lhs.bind(); rhs.bind(); return str_equal(lhs.p, rhs.p); } inline bool operator == (const rcstring &lhs, const char *rhs) { return (lhs == rcstring(rhs)); } inline bool operator == (const char *lhs, const rcstring &rhs) { return (rcstring(lhs) == rhs); } inline bool operator != (const rcstring &lhs, const rcstring &rhs) { lhs.bind(); rhs.bind(); return !str_equal(lhs.p, rhs.p); } inline bool operator != (const rcstring &lhs, const char *rhs) { return (lhs != rcstring(rhs)); } inline bool operator != (const char *lhs, const rcstring &rhs) { return (rcstring(lhs) != rhs); } bool operator < (const rcstring &, const rcstring &); bool operator <= (const rcstring &, const rcstring &); bool operator > (const rcstring &, const rcstring &); bool operator >= (const rcstring &, const rcstring &); inline rcstring operator + (const rcstring &lhs, const rcstring &rhs) { lhs.bind(); rhs.bind(); rcstring result; result.p = str_catenate(lhs.p, rhs.p); return result; } #endif /* COMMON_RCSTRING_H */