1 /* 2 Copyright (c) 2003, 2021, Oracle and/or its affiliates. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License, version 2.0, 6 as published by the Free Software Foundation. 7 8 This program is also distributed with certain software (including 9 but not limited to OpenSSL) that is licensed under separate terms, 10 as designated in a particular file or component or in included license 11 documentation. The authors of MySQL hereby grant you an additional 12 permission to link the program and your derivative works with the 13 separately licensed software that they have included with MySQL. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License, version 2.0, for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software 22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 */ 24 25 #ifndef __BUFFER_HPP_INCLUDED__ 26 #define __BUFFER_HPP_INCLUDED__ 27 28 #include <ndb_global.h> 29 30 /* This class represents a buffer of binary data, where you can append 31 * data at the end, and later read the entire bunch. 32 * It will take care of the hairy details of realloc()ing the space 33 * for you 34 */ 35 class UtilBuffer { 36 public: UtilBuffer()37 UtilBuffer() { data = NULL; len = 0; alloc_size = 0; }; ~UtilBuffer()38 ~UtilBuffer() { if(data) free(data); data = NULL; len = 0; alloc_size = 0; }; 39 40 reallocate(size_t newsize)41 int reallocate(size_t newsize) { 42 if(newsize < len) { 43 errno = EINVAL; 44 return -1; 45 } 46 void *newdata; 47 if((newdata = realloc(data, newsize)) == NULL) { 48 errno = ENOMEM; 49 return -1; 50 } 51 alloc_size = newsize; 52 data = newdata; 53 return 0; 54 }; 55 grow(size_t l)56 int grow(size_t l) { 57 if(l > alloc_size) 58 return reallocate(l); 59 return 0; 60 }; 61 append(const void * d,size_t l)62 int append(const void *d, size_t l) { 63 int ret; 64 ret = grow(len+l); 65 if(ret != 0) 66 return ret; 67 68 memcpy((char *)data+len, d, l); 69 len+=l; 70 71 return 0; 72 }; 73 append(size_t l)74 void * append(size_t l){ 75 if(grow(len+l) != 0) 76 return 0; 77 78 void * ret = (char*)data+len; 79 len += l; 80 return ret; 81 } 82 assign(const void * d,size_t l)83 int assign(const void * d, size_t l) { 84 /* Free the old data only after copying, in case d==data. */ 85 void *old_data= data; 86 data = NULL; 87 len = 0; 88 alloc_size = 0; 89 int ret= append(d, l); 90 if (old_data) 91 free(old_data); 92 return ret; 93 } 94 clear()95 void clear() { 96 len = 0; 97 } 98 length() const99 int length() const { assert(Uint64(len) == Uint32(len)); return (int)len; } 100 get_data() const101 void *get_data() const { return data; } 102 empty() const103 bool empty () const { return len == 0; } 104 equal(const UtilBuffer & cmp) const105 bool equal(const UtilBuffer &cmp) const { 106 if(len==0 && cmp.len==0) 107 return true; 108 else if(len!=cmp.len) 109 return false; 110 else 111 return (memcmp(get_data(), cmp.get_data(), len) == 0); 112 } 113 assign(const UtilBuffer & buf)114 int assign(const UtilBuffer& buf) { 115 int ret = 0; 116 if(this != &buf) { 117 ret = assign(buf.get_data(), buf.length()); 118 } 119 return ret; 120 } 121 private: 122 void *data; /* Pointer to data storage */ 123 size_t len; /* Size of the stored data */ 124 size_t alloc_size; /* Size of the allocated space, 125 * i.e. len can grow to this size */ 126 }; 127 128 #endif /* !__BUFFER_HPP_INCLUDED__ */ 129