diff options
Diffstat (limited to 'generic/String.cpp')
-rw-r--r-- | generic/String.cpp | 358 |
1 files changed, 358 insertions, 0 deletions
diff --git a/generic/String.cpp b/generic/String.cpp new file mode 100644 index 0000000..d6a1e01 --- /dev/null +++ b/generic/String.cpp @@ -0,0 +1,358 @@ +#include <iostream.h> +#include <string.h> +#include <stdarg.h> +#include "String.h" +#include "Exceptions.h" +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#define _(x) x +#endif + +extern "C" { + double dateCalc(char *, char *); + int isDateArgument(char *); +} + +char String::t[BUFSIZ + 1]; + +String::String(const String & s) : str(Base::strdup(s.str)), siz(s.siz) { } + +String::String(char c) : siz(1) { + char * t = (char *) malloc(2); + + sprintf(t, "%c", c); + str = t; +} + +String::String(const char * s) : str(s ? Base::strdup(s) : Base::strdup("")) { + siz = ::strlen(str); +} + +String::String(int hs, const char * s) : str(s ? Base::strdup(s) : Base::strdup("")), siz(hs) { } + +String::String(int i) { + char t[20]; + + sprintf(t, "%i", i); + str = Base::strdup(t); + siz = ::strlen(str); +} + +String::String(unsigned int i) { + char t[20]; + + sprintf(t, "%u", i); + str = Base::strdup(t); + siz = ::strlen(str); +} + +#ifdef USE_LONGLONG +String::String(long long l) { + char t[40]; + + sprintf(t, "%lld", l); + str = Base::strdup(t); + siz = ::strlen(str); +} + +String::String(unsigned long long l) { + char t[40]; + + sprintf(t, "%llu", l); + str = Base::strdup(t); + siz = ::strlen(str); +} +#endif + +String::String(double d) { + char t[30]; + + sprintf(t, "%g", d); + str = Base::strdup(t); + siz = ::strlen(str); +} + +String::~String() { + free(str); +} + +const char * String::set(const char * s, ...) { + va_list ap; + +/* This causes a warning: cannot pass objects of type `const String' through `...' + but it is not really a problem. */ + va_start(ap, s); + vsnprintf(t, BUFSIZ, s, ap); + free(str); + str = Base::strdup(t); + va_end(ap); + siz = ::strlen(str); + return t; +} + +const char * String::set(const String & s, ...) { + va_list ap; + + va_start(ap, s); + vsnprintf(t, BUFSIZ, s.str, ap); + free(str); + str = Base::strdup(t); + va_end(ap); + siz = ::strlen(str); + return t; +} + +const char * String::to_charp(size_t from, ssize_t to) const { + if (to < 0) { + strncpy(t, &(str[from]), BUFSIZ); + } else { + if (((size_t) to) >= siz) { + to = siz - 1; + } + + if ((((size_t) to) - from) > BUFSIZ) { + from -= (to - from) - BUFSIZ; + } + + if (((size_t) to) >= from) { + size_t i; + for (i = 0; i <= ((size_t) to) - from; i++) { + t[i] = str[i + from]; + } + t[i] = '\0'; + } else { + t[0] = '\0'; + } + } + return t; +} + +String String::extract(size_t from, ssize_t to) const { + return String(to_charp(from, to)); +} + +char * String::strdup(size_t from, ssize_t to) const { + return Base::strdup(to_charp(from, to)); +} + +int String::to_int(void) const { + int r; + + sscanf(str, "%i", &r); + return r; +} + +double String::to_double(void) const { + double r; + + sscanf(str, "%lf", &r); + return r; +} + +String & String::operator=(const String & s) { + if (str != s.str) { + // On évite l'autodestruction... + free(str); + str = s.strdup(); + siz = s.siz; + } + return *this; +} + +String String::operator+(const String & s) const { + char * t = (char *) malloc(s.siz + siz + 1), * u; + String o; + + strcpy((u = t), str); + u += siz; + strcpy(u, s.str); + o = String(siz + s.siz, t); + free(t); + return o; +} + +String & String::operator+=(const String & s) { + char * t = (char *) malloc(s.siz + siz + 1), * u; + + strcpy((u = t), str); + u += siz; + strcat(u, s.str); + free(str); + str = t; + siz += s.siz; + return (*this); +} + +ostream & operator<<(ostream & os, const String & s) { + return (os << s.to_charp()); +} + +istream & operator>>(istream & is, String & s) { + char c = 0; + + s.set(""); + + while (!is.eof()) { + c = is.get(); + if (c == '\n') return is; + if (c == '\r') continue; + s += c; + } + + return is; +} + +bool String::operator!=(const String & s) const { + return (strcmp(str, s.str) != 0); +} + +bool String::operator==(const String & s) const { + return (strcmp(str, s.str) == 0); +} + +bool String::operator<=(const String & s) const { + return (strcmp(str, s.str) <= 0); +} + +bool String::operator>=(const String & s) const { + return (strcmp(str, s.str) >= 0); +} + +bool String::operator<(const String & s) const { + return (strcmp(str, s.str) < 0); +} + +bool String::operator>(const String & s) const { + return (strcmp(str, s.str) > 0); +} + +size_t String::strlen() const { + return (siz); +} + +char String::operator[](size_t i) const { + if (i >= siz) { + return 0; + } else { + return str[i]; + } +} + +ssize_t String::strchr(char c, size_t from) const { + for (size_t i = from; i < siz; i++) { + if (str[i] == c) return i; + } + + return -1; +} + +ssize_t String::strrchr(char c) const { + for (size_t i = siz - 1; i >= 0; i--) { + if (str[i] == c) return i; + } + + return -1; +} + +ssize_t String::strstr(const String & s) const { + char * p = ::strstr(str, s.str); + + if (p) { + return p - str; + } else { + return -1; + } +} + +int String::strchrcnt(char c) const { + size_t i, cnt = 0; + for (i = 0; i < siz; i++) { + if (str[i] == c) cnt++; + } + + return cnt; +} + +String String::to_sqldate(void) const { +/* DD/MM/YYYY ==> YYYYMMMDD */ + return (is_date() ? extract(6, 9) + extract(3, 4) + extract(0, 1) : ""); +} + +String String::to_sqltime(void) const { +/* h:m ==> h * 60 + m */ + int p = strchr(':'); + return (is_time() ? String(extract(0, p - 1).to_int() * 60 + extract(p + 1).to_int()) : ""); +} + +String String::from_sqldate(void) const { +/* YYYYMMDD ==> DD/MM/YYYY */ + return ((strlen() == 8) && is_number() ? extract(6, 7) + '/' + extract(4, 5) + '/' + extract(0, 3) : ""); +} + +String String::from_sqltime(void) const { +/* t ==> (t / 60):(t % 60) */ + int t = to_int(); + return (is_number() ? String((int) (t / 60)) + ':' + (t % 60) : ""); +} + +bool String::is_date(void) const { +/* 'DD/MM/YYYY' + 0123456789 */ + + if (strlen() != 10) return false; + if ((str[2] != '/') || (str[5] != '/') || + (!extract(0, 1).is_number()) || + (!extract(3, 4).is_number()) || + (!extract(6, 9).is_number())) { + return (isDateArgument(to_sqldate().str)); + } + + return true; +} + +double String::datedif(const String & s) const { + double r; + if (is_date() && s.is_date()) { + r = dateCalc(str, s.str); + return r < 0 ? -r : r; + } + + return -1; +} + +bool String::is_number(void) const { + for (size_t i = ((str[0] == '-') ? 1 : 0); i < siz; i++) { + if ((str[i] > '9') || (str[i] < '0')) return false; + } + return true; +} + +bool String::is_float(void) const { + bool seendot = false; + + for (size_t i = ((str[0] == '-') ? 1 : 0); i < siz; i++) { + if ((str[i] > '9') || (str[i] < '0')) { + if ((str[i] == '.') && !seendot) { + seendot = true; + } else { + return false; + } + } + } + + return true; +} + +bool String::is_time(void) const { + int p = strchr(':'); + + if (p == -1) return false; + + // On accepte les heures sous le format xxxxxx:yy pour pouvoir indiquer des durées. + + if ((!extract(0, p - 1).is_number()) || (!extract(p + 1).is_number())) + return false; + + return (extract(p + 1).to_int() < 60) ? true : false; +} |