Optimized socket library, added generic splitter function
This commit is contained in:
parent
c7c94dc3c3
commit
05387f01fb
2 changed files with 51 additions and 12 deletions
|
@ -65,6 +65,10 @@ std::string uint2string(unsigned int i){
|
||||||
return st.str();
|
return st.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Socket::Buffer::Buffer(){
|
||||||
|
splitter = "\n";
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the amount of elements in the internal std::deque of std::string objects.
|
/// Returns the amount of elements in the internal std::deque of std::string objects.
|
||||||
/// The back is popped as long as it is empty, first - this way this function is
|
/// The back is popped as long as it is empty, first - this way this function is
|
||||||
/// guaranteed to return 0 if the buffer is empty.
|
/// guaranteed to return 0 if the buffer is empty.
|
||||||
|
@ -83,26 +87,58 @@ unsigned int Socket::Buffer::bytes(unsigned int max){
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns how many bytes to read until the next splitter, or 0 if none found.
|
||||||
|
unsigned int Socket::Buffer::bytesToSplit(){
|
||||||
|
unsigned int i = 0;
|
||||||
|
for (std::deque<std::string>::reverse_iterator it = data.rbegin(); it != data.rend(); ++it){
|
||||||
|
i += (*it).size();
|
||||||
|
if ((*it).size() >= splitter.size() && (*it).substr((*it).size()-splitter.size()) == splitter){
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// Appends this string to the internal std::deque of std::string objects.
|
/// Appends this string to the internal std::deque of std::string objects.
|
||||||
/// It is automatically split every BUFFER_BLOCKSIZE bytes.
|
/// It is automatically split every BUFFER_BLOCKSIZE bytes and when the splitter string is encountered.
|
||||||
void Socket::Buffer::append(const std::string &newdata){
|
void Socket::Buffer::append(const std::string &newdata){
|
||||||
append(newdata.c_str(), newdata.size());
|
append(newdata.data(), newdata.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
///Helper function that does a short-circuiting string compare
|
||||||
|
inline bool string_compare(const char *a, const char *b, const size_t len){
|
||||||
|
for (size_t i = 0; i < len; ++i){
|
||||||
|
if (a[i] != b[i]){return false;}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Appends this data block to the internal std::deque of std::string objects.
|
/// Appends this data block to the internal std::deque of std::string objects.
|
||||||
/// It is automatically split every BUFFER_BLOCKSIZE bytes.
|
/// It is automatically split every BUFFER_BLOCKSIZE bytes and when the splitter string is encountered.
|
||||||
void Socket::Buffer::append(const char *newdata, const unsigned int newdatasize){
|
void Socket::Buffer::append(const char *newdata, const unsigned int newdatasize){
|
||||||
unsigned int i = 0, j = 0;
|
uint32_t i = 0;
|
||||||
while (i < newdatasize){
|
while (i < newdatasize){
|
||||||
j = i;
|
uint32_t j = 0;
|
||||||
while (j < newdatasize && j - i <= BUFFER_BLOCKSIZE){
|
if (!splitter.size()){
|
||||||
j++;
|
if (newdatasize - i > BUFFER_BLOCKSIZE){
|
||||||
if (newdata[j - 1] == '\n'){break;}
|
j = BUFFER_BLOCKSIZE;
|
||||||
}
|
|
||||||
if (i != j){
|
|
||||||
data.push_front(std::string(newdata + i, (size_t)(j - i)));
|
|
||||||
i = j;
|
|
||||||
}else{
|
}else{
|
||||||
|
j = newdatasize - i;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
while (j+i < newdatasize && j < BUFFER_BLOCKSIZE){
|
||||||
|
j++;
|
||||||
|
if (j >= splitter.size()){
|
||||||
|
if (string_compare(newdata+i+j-splitter.size(), splitter.data(), splitter.size())){break;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j){
|
||||||
|
data.push_front("");
|
||||||
|
data.front().assign(newdata + i, (size_t)j);
|
||||||
|
i += j;
|
||||||
|
}else{
|
||||||
|
FAIL_MSG("Appended an empty string to buffer: aborting!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,11 @@ namespace Socket{
|
||||||
std::deque<std::string> data;
|
std::deque<std::string> data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
std::string splitter;///<String to automatically split on if encountered. \n by default
|
||||||
|
Buffer();
|
||||||
unsigned int size();
|
unsigned int size();
|
||||||
unsigned int bytes(unsigned int max);
|
unsigned int bytes(unsigned int max);
|
||||||
|
unsigned int bytesToSplit();
|
||||||
void append(const std::string &newdata);
|
void append(const std::string &newdata);
|
||||||
void append(const char *newdata, const unsigned int newdatasize);
|
void append(const char *newdata, const unsigned int newdatasize);
|
||||||
void prepend(const std::string &newdata);
|
void prepend(const std::string &newdata);
|
||||||
|
|
Loading…
Add table
Reference in a new issue