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
		Add a link
		
	
		Reference in a new issue