summaryrefslogtreecommitdiff
path: root/includes/BString.h
blob: dc9fd5dbe6205bdf18964730e98f317f211088b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#pragma once

#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <stdarg.h>
#include <string.h>
#include <stdint.h>
#ifndef __APPLE__
#include <malloc.h>
#endif
#include <stdlib.h>
#include <string>
#include <vector>
#include <algorithm>

#ifdef _MSC_VER
#ifdef _WIN64
typedef __int64    ssize_t;
#else  /* _WIN64 */
typedef _W64 int   ssize_t;
#endif  /* _WIN64 */
#define printfwarning(a, b)
#else
#define printfwarning(a, b) __attribute__((format(printf, a, b)))
#endif

#if defined(_WIN32) && !defined(_MSC_VER)
int vsscanf(const char *, const char *, va_list);
#endif

namespace Balau {

class String : private std::string {
  public:
      String() : std::string() { }
      String(const char * str) : std::string(str ? str : "") { }
      template<size_t L>
      String(const char (&str)[L]) : std::string(str, L - 1) { }
      String(const char * str, size_t n) : std::string(str ? str : "", str ? n : 0) { }
      String(char c) { set("%c", c); }
      String(int32_t i) { set("%" PRIi32, i); }
      String(uint32_t i) { set("%" PRIu32, i); }
      String(int64_t i) { set("%" PRIi64, i); }
      String(uint64_t i) { set("%" PRIu64, i); }
      String(double d) { set("%g", d); }
      String(const String & s) : std::string(s) { }
      String(const std::string & s) : std::string(s) { }
      String(String && s) : std::string(s) { }

    String & set(const char * fmt, va_list) printfwarning(2, 0);
    String & set(const char * fmt, ...) printfwarning(2, 3) { va_list ap; va_start(ap, fmt); set(fmt, ap); va_end(ap); return *this; }
    String & set(const String & fmt, ...) { va_list ap; va_start(ap, fmt); set(fmt.to_charp(), ap); va_end(ap); return *this; }

    String & append(const char * fmt, va_list) printfwarning(2, 0);
    String & append(const char * fmt, ...) printfwarning(2, 3) { va_list ap; va_start(ap, fmt); append(fmt, ap); va_end(ap); return *this; }
    String & append(const String & fmt, ...) { va_list ap; va_start(ap, fmt); append(fmt.to_charp(), ap); va_end(ap); return *this; }

    int scanf(const char * fmt, va_list ap) const { return ::vsscanf(c_str(), fmt, ap); }
    int scanf(const char * fmt, ...) const printfwarning(2, 3) { va_list ap; va_start(ap, fmt); int r = scanf(fmt, ap); va_end(ap); return r; }
    int scanf(const String & fmt, ...) const { va_list ap; va_start(ap, fmt); int r = scanf(fmt.to_charp(), ap); va_end(ap); return r; }

    const char * to_charp(size_t begin = 0) const { return c_str() + begin; }
    String extract(size_t begin = 0, size_t size = static_cast<size_t>(-1)) const { return substr(begin, size); }
    char * strdup(size_t begin = 0, size_t size = static_cast<size_t>(-1)) const {
        if (begin == 0)
            return ::strdup(to_charp());
        else
            return ::strdup(extract(begin, size).to_charp());
    }

    int to_int(int base = 0) const { return strtol(to_charp(), NULL, base); }
    double to_double() const { return strtod(to_charp(), NULL); }
    typedef std::vector<String> List;
    List split(char c);

    size_t strlen() const { return std::string::length(); }
    ssize_t strchr(char c, size_t begin = 0) const { return find(c, begin); }
    ssize_t strrchr(char c) const { return rfind(c); }
    ssize_t strstr(const String & s, size_t begin = 0) const { return find(std::string(s), begin); }
    ssize_t strstr(const char * s, size_t begin = 0) const { return find(std::string(s), begin); }
    int strchrcnt(char) const;

    String ltrim() const { String c = *this; return c.do_ltrim(); }
    String rtrim() const { String c = *this; return c.do_rtrim(); }
    String trim() const { String c = *this; return c.do_trim(); }
    String upper() const { String c = *this; return c.do_upper(); }
    String lower() const { String c = *this; return c.do_lower(); }
    String iconv(const String & from, const String & to) const { String c = *this; c.do_iconv(from.to_charp(), to.to_charp()); return c; }
    String iconv(const char * from, const char * to) const { String c = *this; c.do_iconv(from, to); return c; }
    String replace_all(char from, char to) const { String c = *this; c.do_replace_all(from, to); return c; }

    String & do_ltrim();
    String & do_rtrim();
    String & do_trim() { return do_ltrim().do_rtrim(); }
    String & do_upper();
    String & do_lower();
    String & do_iconv(const String & from, const String & to) { return do_iconv(from.to_charp(), to.to_charp()); }
    String & do_iconv(const char * from, const char * to);
    String & do_replace_all(char from, char to) { std::replace(begin(), end(), from, to); return *this; }

    String & operator=(const String & v) { *((std::string *) this) = std::string::assign(v); return *this; }
    String & operator=(const char * v) { *((std::string *) this) = std::string::assign(v); return *this; }

    String operator+(const String & v) const { String r = *this; r += v; return r; }
    String operator+(const char * v) const { String r = *this; r += v; return r; }
    String & operator+=(const String & v) { *this = std::string::append(v); return *this; }
    String & operator+=(const char * v) { *this = std::string::append(v); return *this; }

    int compare(const String & v) const { return std::string::compare(v); }
    int compare(const char * v) const { return std::string::compare(v); }

    bool operator==(const String & v) const { return compare(v) == 0; }
    bool operator==(const char * v) const { return compare(v) == 0; }
    bool operator!=(const String & v) const { return compare(v) != 0; }
    bool operator!=(const char * v) const { return compare(v) != 0; }
    bool operator<(const String & v) const { return compare(v) < 0; }
    bool operator<(const char * v) const { return compare(v) < 0; }
    bool operator<=(const String & v) const { return compare(v) <= 0; }
    bool operator<=(const char * v) const { return compare(v) <= 0; }
    bool operator>(const String & v) const { return compare(v) > 0; }
    bool operator>(const char * v) const { return compare(v) > 0; }
    bool operator>=(const String & v) const { return compare(v) >= 0; }
    bool operator>=(const char * v) const { return compare(v) >= 0; }

    const char & operator[](ssize_t i) const { if (i < 0) i = strlen() + i; return at(i); }
    char & operator[](ssize_t i) { if (i < 0) i = strlen() + i; return at(i); }

    void reserve(size_t s) { std::string::reserve(s); }

    size_t find_first_of(const String & set, size_t offset = 0) const { return std::string::find_first_of(set, offset); }
    size_t find_last_of(const String & set, size_t offset = 0) const { return std::string::find_last_of(set, offset); }
    size_t find_first_not_of(const String & set, size_t offset = 0) const { return std::string::find_first_not_of(set, offset); }
    size_t find_last_not_of(const String & set, size_t offset = 0) const { return std::string::find_last_not_of(set, offset); }

    bool isEmpty() { return std::string::empty(); }

    std::vector<String> tokenize(const String & delimiters = "&", bool trimEmpty = true);


    using std::string::npos;
    using std::string::size_type;
};

};