Rewrote the library to use ByteSlice.

This commit is contained in:
Pietro Gagliardi 2018-05-27 15:50:00 -04:00
parent 8231bd337f
commit 4a7e7ed983
3 changed files with 41 additions and 106 deletions

View File

@ -92,7 +92,7 @@ char *sliceAlloc(size_t n)
uintptr_t sliceLookup(char *b)
{
return *(sliceAllocs.lower_bound((uintptr_t) b));
return sliceAllocs.lower_bound((uintptr_t) b)->first;
}
void sliceRetain(char *b)
@ -184,17 +184,6 @@ ByteSlice &ByteSlice::operator=(ByteSlice &&b)
return *this;
}
ByteSlice ByteSlice::Slice(size_t start, size_t end)
{
ByteSlice b;
b.data = this->data + start;
sliceRetain(b.data);
b.len = end - start;
b.cap = this->cap - start;
return b;
}
char *ByteSlice::Data(void)
{
return this->data;
@ -251,6 +240,11 @@ ByteSlice ByteSlice::Append(const ByteSlice &b)
return this->Append(b.data, b.len);
}
ByteSlice ByteSlice::AppendString(const char *str)
{
return this->Append(str, strlen(str));
}
void ByteSlice::CopyFrom(const char *b, size_t n)
{
n = std::min(this->len, n);
@ -262,11 +256,6 @@ void ByteSlice::CopyFrom(const ByteSlice &b)
this->CopyFrom(b.data, b.len);
}
Error *WriteVector(WriteCloser *w, std::vector<char> *v)
{
return w->Write(v->data(), v->size());
}
#define nbuf 1024
Scanner::Scanner(ReadCloser *r)
@ -275,7 +264,7 @@ Scanner::Scanner(ReadCloser *r)
this->buf = new char[nbuf];
this->p = this->buf;
this->n = 0;
this->line = new std::vector<char>;
this->line = ByteSlice(0, nbuf);
this->err = NULL;
}
@ -283,7 +272,6 @@ Scanner::~Scanner(void)
{
if (this->err != NULL)
delete this->err;
delete this->line;
delete[] this->buf;
}
@ -293,7 +281,7 @@ bool Scanner::Scan(void)
if (this->err != NULL)
return false;
this->line->clear();
this->line = this->line.Slice(0, 0);
for (;;) {
if (this->n > 0) {
size_t j;
@ -305,7 +293,7 @@ bool Scanner::Scan(void)
haveline = true;
break;
}
this->line->insert(this->line->end(), this->p, this->p + j);
this->line = this->line.Append(this->p, j);
this->p += j;
this->n -= j;
if (haveline) {
@ -325,14 +313,9 @@ bool Scanner::Scan(void)
}
}
const char *Scanner::Bytes(void) const
ByteSlice Scanner::Bytes(void) const
{
return this->line->data();
}
size_t Scanner::Len(void) const
{
return this->line->size();
return this->line;
}
Error *Scanner::Err(void) const
@ -342,59 +325,24 @@ Error *Scanner::Err(void) const
return NULL;
}
void AppendString(std::vector<char> *v, const char *str)
std::vector<ByteSlice> ByteSliceFields(ByteSlice s)
{
v->insert(v->end(), str, str + strlen(str));
}
std::vector<ByteSlice> ret;
const char *data;
size_t i, j;
Slice::Slice(const char *p, size_t n)
{
this->p = p;
this->n = n;
}
const char *Slice::Data(void) const
{
return this->p;
}
size_t Slice::Len(void) const
{
return this->n;
}
std::vector<Slice *> *TokenizeWhitespace(const char *buf, size_t n)
{
std::vector<Slice *> *ret;
const char *p, *q;
const char *end;
ret = new std::vector<Slice *>;
p = buf;
end = buf + n;
while (p < end) {
if (*p == ' ' || *p == '\t') {
p++;
data = s.Data();
i = 0;
while (i < s.Len()) {
if (data[i] == ' ' || data[i] == '\t') {
i++;
continue;
}
for (q = p; q < end; q++)
if (*q == ' ' || *q == '\t')
for (j = i + 1; j < s.Len(); j++)
if (data[j] == ' ' || data[j] == '\t')
break;
ret->push_back(new Slice(p, q - p));
p = q;
ret.push_back(s.Slice(i, j));
i = j;
}
return ret;
}
void FreeTokenized(std::vector<Slice *> *v)
{
std::for_each(v->begin(), v->end(), [](Slice *s) {
delete s;
});
delete v;
}
void AppendSlice(std::vector<char> *v, Slice *s)
{
v->insert(v->end(), s->Data(), s->Data() + s->Len());
}

View File

@ -12,6 +12,8 @@ extern Error *NewEOF(void);
extern Error *NewErrShortWrite(void);
extern bool IsEOF(Error *e);
// super lightweight (can be passed by value without any data being copied) wrapper around an array of bytes that can be sliced further without copying (std::vector can't do that easily)
// this is modelled after Go's slices
class ByteSlice {
char *data;
size_t len;
@ -37,6 +39,7 @@ public:
ByteSlice Slice(size_t start, size_t end);
ByteSlice Append(const char *b, size_t n);
ByteSlice Append(const ByteSlice &b);
ByteSlice AppendString(const char *str);
void CopyFrom(const char *b, size_t n);
void CopyFrom(const ByteSlice &b);
};
@ -45,49 +48,33 @@ class ReadCloser {
public:
virtual ~ReadCloser(void) = default;
virtual Error *Read(void *buf, size_t n, size_t *actual) = 0;
virtual Error *Read(ByteSlice b, size_t *n) = 0;
};
class WriteCloser {
public:
virtual ~WriteCloser(void) = default;
virtual Error *Write(void *buf, size_t n) = 0;
virtual Error *Write(const ByteSlice b) = 0;
};
extern Error *OpenRead(const char *filename, ReadCloser **r);
extern Error *CreateWrite(const char *filename, WriteCloser **w);
extern Error *WriteVector(WriteCloser *w, std::vector<char> *v);
class Scanner {
ReadCloser *r;
char *buf;
const char *p;
size_t n;
std::vector<char> *line;
ByteSlice line;
Error *err;
public:
Scanner(ReadCloser *r);
~Scanner(void);
bool Scan(void);
const char *Bytes(void) const;
size_t Len(void) const;
ByteSlice Bytes(void) const;
Error *Err(void) const;
};
extern void AppendString(std::vector<char> *v, const char *str);
class Slice {
const char *p;
size_t n;
public:
Slice(const char *p, size_t n);
const char *Data(void) const;
size_t Len(void) const;
};
extern std::vector<Slice *> *TokenizeWhitespace(const char *buf, size_t n);
extern void FreeTokenized(std::vector<Slice *> *v);
extern void AppendSlice(std::vector<char> *v, Slice *s);
extern std::vector<ByteSlice> ByteSliceFields(ByteSlice s);

View File

@ -35,7 +35,7 @@ public:
posixReadCloser(int fd);
virtual ~posixReadCloser(void);
virtual Error *Read(void *buf, size_t n, size_t *actual);
virtual Error *Read(ByteSlice b, size_t *n);
};
posixReadCloser::posixReadCloser(int fd)
@ -48,17 +48,17 @@ posixReadCloser::~posixReadCloser(void)
close(this->fd);
}
Error *posixReadCloser::Read(void *buf, size_t n, size_t *actual)
Error *posixReadCloser::Read(ByteSlice b, size_t *n)
{
ssize_t ret;
*actual = 0;
ret = read(this->fd, buf, n);
*n = 0;
ret = read(this->fd, b.Data(), b.Len());
if (ret < 0)
return new posixError(errno);
if (ret == 0)
return NewEOF();
*actual = ret;
*n = ret;
return NULL;
}
@ -68,7 +68,7 @@ public:
posixWriteCloser(int fd);
virtual ~posixWriteCloser(void);
virtual Error *Write(void *buf, size_t n);
virtual Error *Write(const ByteSlice b);
};
posixWriteCloser::posixWriteCloser(int fd)
@ -81,14 +81,14 @@ posixWriteCloser::~posixWriteCloser(void)
close(this->fd);
}
Error *posixWriteCloser::Write(void *buf, size_t n)
Error *posixWriteCloser::Write(const ByteSlice &b)
{
ssize_t ret;
ret = write(this->fd, buf, n);
ret = write(this->fd, b.Data(), b.Len());
if (ret < 0)
return new posixError(errno);
if (((size_t) ret) != n)
if (((size_t) ret) != b.Len())
return NewErrShortWrite();
return NULL;
}