Skip to content

Commit

Permalink
refactor fastring & fastream
Browse files Browse the repository at this point in the history
  • Loading branch information
idealvin committed Nov 23, 2023
1 parent 1ccb883 commit d4c8350
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 44 deletions.
28 changes: 14 additions & 14 deletions include/co/fast.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,6 @@ class __coapi stream {
_p = cap > 0 ? (char*)co::alloc(cap) : 0;
}

stream(char* p, size_t cap, size_t size) noexcept
: _cap(cap), _size(size), _p(p) {
}

~stream() { this->reset(); }

stream(const stream&) = delete;
Expand All @@ -146,6 +142,7 @@ class __coapi stream {
return *this;
}

char* data() noexcept { return _p; }
const char* data() const noexcept { return _p; }
size_t size() const noexcept { return _size; }
bool empty() const noexcept { return _size == 0; }
Expand All @@ -159,30 +156,33 @@ class __coapi stream {
}

const char* c_str() const {
((stream*)this)->reserve(_size + 1);
if (_p[_size] != '\0') _p[_size] = '\0';
return _p;
if (_p) {
assert(_size < _cap);
if (_p[_size] != '\0') _p[_size] = '\0';
return _p;
}
return "";
}

char& back() { return _p[_size - 1]; }
const char& back() const { return ((stream*)this)->back(); }
const char& back() const { return _p[_size - 1]; }

char& front() { return _p[0]; }
const char& front() const { return ((stream*)this)->front(); }
const char& front() const { return _p[0]; }

char& operator[](size_t i) { return _p[i]; }
const char& operator[](size_t i) const { return ((stream*)this)->operator[](i); }
const char& operator[](size_t i) const { return _p[i]; }

// resize only, will not fill the expanded memory with zeros
void resize(size_t n) {
this->reserve(n);
this->reserve(n + 1);
_size = n;
}

// resize and fill the expanded memory with character @c
void resize(size_t n, char c) {
if (_size < n) {
this->reserve(n);
this->reserve(n + 1);
memset(_p + _size, c, n - _size);
}
_size = n;
Expand All @@ -204,9 +204,9 @@ class __coapi stream {
}

void ensure(size_t n) {
if (_cap < _size + n) {
if (_cap < _size + n + 1) {
const size_t cap = _cap;
_cap += ((_cap >> 1) + n);
_cap += ((_cap >> 1) + n + 1);
_p = (char*) co::realloc(_p, cap, _cap); assert(_p);
}
}
Expand Down
7 changes: 2 additions & 5 deletions include/co/fastream.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ class __coapi fastream : public fast::stream {
return this->append_nomchk(s.data(), s.size());
}

// append the fastream itself is ok
fastream& append(const fastream& s) {
if (&s != this) return this->append_nomchk(s.data(), s.size());
this->reserve(_size << 1);
this->reserve((_size << 1) + !!_size);
memcpy(_p + _size, _p, _size); // append itself
_size <<= 1;
return *this;
Expand All @@ -69,10 +70,6 @@ class __coapi fastream : public fast::stream {
return (fastream&) fast::stream::append(n, c);
}

fastream& append(char c, size_t n) {
return this->append(n, c);
}

fastream& append(char c) {
return (fastream&) fast::stream::append(c);
}
Expand Down
34 changes: 13 additions & 21 deletions include/co/fastring.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,15 @@ class __coapi fastring : public fast::stream {
: fast::stream(cap) {
}

// @p: memory allocated by co::alloc()
fastring(char* p, size_t cap, size_t size) noexcept
: fast::stream(p, cap, size) {
}

~fastring() = default;

fastring(size_t n, char c)
: fast::stream(n, n) {
: fast::stream(n + 1, n) {
memset(_p, c, n);
}

fastring(char c, size_t n) : fastring(n, c) {}

fastring(const void* s, size_t n)
: fast::stream(n, n) {
: fast::stream(n + !!n, n) {
memcpy(_p, s, n);
}

Expand Down Expand Up @@ -93,6 +86,13 @@ class __coapi fastring : public fast::stream {
return *this;
}

fastring& assign(size_t n, char c) {
this->reserve(n + 1);
memset(_p, c, n);
_size = n;
return *this;
}

template<typename S>
fastring& assign(S&& s) {
return this->operator=(std::forward<S>(s));
Expand All @@ -118,7 +118,7 @@ class __coapi fastring : public fast::stream {

fastring& append(const fastring& s) {
if (&s != this) return this->append_nomchk(s.data(), s.size());
this->reserve(_size << 1);
this->reserve((_size << 1) + !!_size);
memcpy(_p + _size, _p, _size); // append itself
_size <<= 1;
return *this;
Expand All @@ -132,10 +132,6 @@ class __coapi fastring : public fast::stream {
return (fastring&) fast::stream::append(n, c);
}

fastring& append(char c, size_t n) {
return this->append(n, c);
}

fastring& append(char c) {
return (fastring&) fast::stream::append(c);
}
Expand Down Expand Up @@ -439,15 +435,11 @@ class __coapi fastring : public fast::stream {
fastring& toupper();

fastring lower() const {
fastring s(*this);
s.tolower();
return s;
fastring s(*this); s.tolower(); return s;
}

fastring upper() const {
fastring s(*this);
s.toupper();
return s;
fastring s(*this); s.toupper(); return s;
}

fastring substr(size_t pos) const {
Expand Down Expand Up @@ -693,7 +685,7 @@ class __coapi fastring : public fast::stream {
fastring& _assign(const void* s, size_t n) {
_size = n;
if (n > 0) {
this->reserve(n);
this->reserve(n + 1);
memcpy(_p, s, n);
}
return *this;
Expand Down
2 changes: 1 addition & 1 deletion src/fastring.cc
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ fastring& fastring::replace(const char* sub, size_t n, const char* to, size_t m,
if (!p) return *this;

const char* const e = _p + _size;
fastring s(_size);
fastring s(_size + 1);

do {
s.append(from, p - from).append(to, m);
Expand Down
12 changes: 10 additions & 2 deletions unitest/fastream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ DEF_test(fastream) {
EXPECT_EQ(fs.size(), 1);
fs.clear();
EXPECT_EQ(fs.size(), 0);

fs.reset();
EXPECT_EQ(fs.capacity(), 0);
}

DEF_case(cat) {
Expand Down Expand Up @@ -157,9 +160,14 @@ DEF_test(fastream) {
fs.clear();
fs << fs;
EXPECT_EQ(fs.str(), "");
fs << "x";

fs.reset();
fs << "xx";
EXPECT_EQ(fs.capacity(), 3);

fs << fs;
EXPECT_EQ(fs.str(), "xx");
EXPECT_EQ(fs.str(), "xxxx");
EXPECT_EQ(fs.capacity(), 5);
}

DEF_case(ptr) {
Expand Down
67 changes: 66 additions & 1 deletion unitest/fastring.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ DEF_test(fastring) {
{
fastring s(4, 'x');
EXPECT_EQ(s.size(), 4);
EXPECT_EQ(s.capacity(), 5);
EXPECT_EQ(s, "xxxx");
}
{
Expand All @@ -29,11 +30,13 @@ DEF_test(fastring) {
fastring s("helloworld", 5);
EXPECT_EQ(s.size(), 5);
EXPECT_EQ(s, "hello");
EXPECT_LT(s.size(), s.capacity());
}
{
fastring s("helloworld");
EXPECT_EQ(s.size(), 10);
EXPECT_EQ(s, "helloworld");
EXPECT_LT(s.size(), s.capacity());
}
}

Expand Down Expand Up @@ -91,9 +94,10 @@ DEF_test(fastring) {
s.append(s);
EXPECT_EQ(s, "");

s.append('x', 3);
s.append(3, 'x');
EXPECT_EQ(s.size(), 3);
EXPECT_EQ(s, "xxx");
EXPECT_LT(s.size(), s.capacity());

s.append(s); // append self
EXPECT_EQ(s, "xxxxxx");
Expand Down Expand Up @@ -156,6 +160,12 @@ DEF_test(fastring) {

s = s.c_str() + 1;
EXPECT_EQ(s, "345");

s.assign(3, '0');
EXPECT_EQ(s, "000");

s.assign(31, '0');
EXPECT_EQ(s, fastring(31, '0'));
}

DEF_case(cat) {
Expand All @@ -165,6 +175,60 @@ DEF_test(fastring) {
EXPECT_EQ(s.cat(' ', "hello ", false), "123 hello false");
}

DEF_case(c_str) {
{
fastring s;
EXPECT_EQ(fastring(s.c_str()), "");
}
{
fastring s("xxx", 3);
EXPECT_LT(s.size(), s.capacity());
const char* p = s.data();
EXPECT_EQ(p, s.c_str())

fastring x(7, 'x');
EXPECT_LT(x.size(), x.capacity());

s.assign(x.data(), x.size());
EXPECT_LT(s.size(), s.capacity());
EXPECT_EQ(s, "xxxxxxx");
EXPECT_EQ(s.capacity(), 8);

s.append('x');
EXPECT_LT(s.size(), s.capacity());
p = s.data();
EXPECT_EQ(p, s.c_str())

s.append(s.capacity() - s.size(), 'x');
EXPECT_LT(s.size(), s.capacity());
p = s.data();
EXPECT_EQ(p, s.c_str())

x.assign(s.capacity() - s.size() + 3, 'x');
s.append(x.data(), x.size());
EXPECT_LT(s.size(), s.capacity());
p = s.data();
EXPECT_EQ(p, s.c_str());
}
{
const char* p;
fastring s;
s << false;
EXPECT_LT(s.size(), s.capacity());

s.reset();
s << 1234567;
EXPECT_LT(s.size(), s.capacity());

s.reset();
s << 3.1415926;
EXPECT_LT(s.size(), s.capacity());

p = s.data();
EXPECT_EQ(p, s.c_str());
}
}

DEF_case(operator<<) {
fastring s;
{
Expand Down Expand Up @@ -543,6 +607,7 @@ DEF_test(fastring) {
fastring s(256);
(s = "hello world").shrink();
EXPECT_LT(s.capacity(), 256);
EXPECT_EQ(s.capacity(), 12);
EXPECT_EQ(s, "hello world");
}

Expand Down

0 comments on commit d4c8350

Please sign in to comment.