forked from hxim/paq8px
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathString.cpp
121 lines (107 loc) · 2.62 KB
/
String.cpp
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
#include <string.h>
#include "Utils.hpp"
#include "String.hpp"
#ifndef NDEBUG
void String::chk_consistency() const {
for (uint32_t i = 0; i < size() - 1; i++) {
if ((*this)[i] == 0) {
quit("Internal error - string consistency check failed (1).");
}
}
if (((*this)[size() - 1]) != 0) {
quit("Internal error - string consistency check failed (2).");
}
}
#endif
void String::appendIntRecursive(uint64_t x) {
if( x <= 9 ) {
pushBack('0' + char(x));
} else {
const uint64_t rem = x % 10;
x = x / 10;
if( x != 0 ) {
appendIntRecursive(x);
}
pushBack('0' + char(rem));
}
}
const char* String::c_str() const {
return &(*this)[0];
}
uint64_t String::strsize() const {
chk_consistency();
assert(size() > 0);
return size() - 1;
}
void String::operator=(const char *s) {
resize(strlen(s) + 1);
memcpy(&(*this)[0], s, size());
chk_consistency();
}
void String::operator+=(const char *s) {
const uint64_t pos = size();
const uint64_t len = strlen(s);
resize(pos + len);
memcpy(&(*this)[pos - 1], s, len + 1);
chk_consistency();
}
void String::operator+=(char c) {
popBack(); //Remove NUL
pushBack(c);
pushBack(0); //Append NUL
chk_consistency();
}
void String::operator+=(uint64_t x) {
popBack(); //Remove NUL
if( x == 0 ) {
pushBack('0');
} else {
appendIntRecursive(x);
}
pushBack(0); //Append NUL
chk_consistency();
}
bool String::endsWith(const char *ending) const {
const uint64_t endingSize = strlen(ending);
if( endingSize > strsize()) {
return false;
}
const int cmp = memcmp(ending, &(*this)[strsize() - endingSize], endingSize);
return (cmp == 0);
}
void String::stripEnd(uint64_t count) {
assert(strsize() >= count);
const uint64_t newSize = strsize() - count;
resize(newSize);
pushBack(0); //Append NUL
chk_consistency();
}
bool String::beginsWith(const char *beginning) const {
const uint64_t beginningSize = strlen(beginning);
if( beginningSize > strsize()) {
return false;
}
const int cmp = memcmp(beginning, &(*this)[0], beginningSize);
return (cmp == 0);
}
void String::stripStart(uint64_t count) {
assert(strsize() >= count);
const uint64_t newSize = strsize() - count;
memmove(&(*this)[0], &(*this)[count], newSize);
resize(newSize);
pushBack(0); //Append NUL
chk_consistency();
}
int String::findLast(char c) const{
uint64_t i = strsize();
while( i-- > 0 ) {
if((*this)[i] == c ) {
return static_cast<int>(i);
}
}
return -1; //not found
}
String::String(const char *s) : Array<char>(strlen(s) + 1) {
memcpy(&(*this)[0], s, size());
chk_consistency();
}