mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 02:46:29 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			118 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
 | |
| // vim:sw=2:ai
 | |
| 
 | |
| /*
 | |
|  * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
 | |
|  * See COPYRIGHT.txt for details.
 | |
|  */
 | |
| 
 | |
| #ifndef DENA_STRING_BUFFER_HPP
 | |
| #define DENA_STRING_BUFFER_HPP
 | |
| 
 | |
| #include <vector>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| 
 | |
| #include "util.hpp"
 | |
| #include "allocator.hpp"
 | |
| #include "fatal.hpp"
 | |
| 
 | |
| namespace dena {
 | |
| 
 | |
| struct string_buffer : private noncopyable {
 | |
|   string_buffer() : buffer(0), begin_offset(0), end_offset(0), alloc_size(0) { }
 | |
|   ~string_buffer() {
 | |
|     DENA_FREE(buffer);
 | |
|   }
 | |
|   const char *begin() const {
 | |
|     return buffer + begin_offset;
 | |
|   }
 | |
|   const char *end() const {
 | |
|     return buffer + end_offset;
 | |
|   }
 | |
|   char *begin() {
 | |
|     return buffer + begin_offset;
 | |
|   }
 | |
|   char *end() {
 | |
|     return buffer + end_offset;
 | |
|   }
 | |
|   size_t size() const {
 | |
|     return end_offset - begin_offset;
 | |
|   }
 | |
|   void clear() {
 | |
|     begin_offset = end_offset = 0;
 | |
|   }
 | |
|   void resize(size_t len) {
 | |
|     if (size() < len) {
 | |
|       reserve(len);
 | |
|       memset(buffer + end_offset, 0, len - size());
 | |
|     }
 | |
|     end_offset = begin_offset + len;
 | |
|   }
 | |
|   void reserve(size_t len) {
 | |
|     if (alloc_size >= begin_offset + len) {
 | |
|       return;
 | |
|     }
 | |
|     size_t asz = alloc_size;
 | |
|     while (asz < begin_offset + len) {
 | |
|       if (asz == 0) {
 | |
| 	asz = 16;
 | |
|       }
 | |
|       const size_t asz_n = asz << 1;
 | |
|       if (asz_n < asz) {
 | |
| 	fatal_abort("string_buffer::resize() overflow");
 | |
|       }
 | |
|       asz = asz_n;
 | |
|     }
 | |
|     void *const p = DENA_REALLOC(buffer, asz);
 | |
|     if (p == 0) {
 | |
|       fatal_abort("string_buffer::resize() realloc");
 | |
|     }
 | |
|     buffer = static_cast<char *>(p);
 | |
|     alloc_size = asz;
 | |
|   }
 | |
|   void erase_front(size_t len) {
 | |
|     if (len >= size()) {
 | |
|       clear();
 | |
|     } else {
 | |
|       begin_offset += len;
 | |
|     }
 | |
|   }
 | |
|   char *make_space(size_t len) {
 | |
|     reserve(size() + len);
 | |
|     return buffer + end_offset;
 | |
|   }
 | |
|   void space_wrote(size_t len) {
 | |
|     len = std::min(len, alloc_size - end_offset);
 | |
|     end_offset += len;
 | |
|   }
 | |
|   template <size_t N>
 | |
|   void append_literal(const char (& str)[N]) {
 | |
|     append(str, str + N - 1);
 | |
|   }
 | |
|   void append(const char *start, const char *finish) {
 | |
|     const size_t len = finish - start;
 | |
|     reserve(size() + len);
 | |
|     memcpy(buffer + end_offset, start, len);
 | |
|     end_offset += len;
 | |
|   }
 | |
|   void append_2(const char *s1, const char *f1, const char *s2,
 | |
|     const char *f2) {
 | |
|     const size_t l1 = f1 - s1;
 | |
|     const size_t l2 = f2 - s2;
 | |
|     reserve(end_offset + l1 + l2);
 | |
|     memcpy(buffer + end_offset, s1, l1);
 | |
|     memcpy(buffer + end_offset + l1, s2, l2);
 | |
|     end_offset += l1 + l2;
 | |
|   }
 | |
|  private:
 | |
|   char *buffer;
 | |
|   size_t begin_offset;
 | |
|   size_t end_offset;
 | |
|   size_t alloc_size;
 | |
| };
 | |
| 
 | |
| };
 | |
| 
 | |
| #endif
 | |
| 
 | 
