1 /*=========================================================================== 2 * 3 * PUBLIC DOMAIN NOTICE 4 * National Center for Biotechnology Information 5 * 6 * This software/database is a "United States Government Work" under the 7 * terms of the United States Copyright Act. It was written as part of 8 * the author's official duties as a United States Government employee and 9 * thus cannot be copyrighted. This software/database is freely available 10 * to the public for use. The National Library of Medicine and the U.S. 11 * Government have not placed any restriction on its use or reproduction. 12 * 13 * Although all reasonable efforts have been taken to ensure the accuracy 14 * and reliability of the software and data, the NLM and the U.S. 15 * Government do not and cannot warrant the performance or results that 16 * may be obtained by using this software or data. The NLM and the U.S. 17 * Government disclaim all warranties, express or implied, including 18 * warranties of performance, merchantability or fitness for any particular 19 * purpose. 20 * 21 * Please cite the author in any work or product based on this material. 22 * 23 * =========================================================================== 24 * 25 */ 26 27 #ifndef _h_klib_data_buffer 28 #define _h_klib_data_buffer 29 30 #ifndef _h_klib_extern_ 31 #include <klib/extern.h> 32 #endif 33 34 #ifndef _h_klib_defs_ 35 #include <klib/defs.h> 36 #endif 37 38 #ifdef __cplusplus 39 extern "C" { 40 #endif 41 42 43 /*-------------------------------------------------------------------------- 44 * KDataBuffer 45 * simple, open structure to reference an opaque data buffer 46 * 47 * "base" - pointer to first byte of buffer 48 * 49 * "elem_bits" - size of buffer element datatype in bits 50 * 51 * "elem_count" - size of buffer in elements 52 * 53 * "bit_offset" [ DEFAULT ZERO ] - offset from "base" 54 * to first bit of buffer, always 0 when "elem_bits" % 8 == 0 55 * bits are left-packed, i.e.: 56 * 57 * bit_offset | starting bit 58 * ============+============= 59 * 0 | 7 60 * 1 | 6 61 * 2 | 5 62 * ... 63 * 6 | 1 64 * 7 | 0 65 * 66 * NB - there may be limits to the total number of bits within the buffer 67 * that may be determined by architecture or runtime environment. 68 */ 69 typedef struct KDataBuffer KDataBuffer; 70 struct KDataBuffer 71 { 72 const void *ignore; 73 void *base; 74 uint64_t elem_bits; 75 uint64_t elem_count; 76 uint8_t bit_offset; 77 }; 78 79 80 /* Bits 81 * return buffer size in bits 82 */ 83 #define KDataBufferBits( self ) \ 84 ((((bitsz_t)((const KDataBuffer *)(self))->elem_bits) * ((const KDataBuffer *)(self))->elem_count)) 85 86 /* Bytes 87 * returns buffer size in bytes 88 */ 89 #define KDataBufferBytes( self ) \ 90 ((size_t)((KDataBufferBits(self) + 7) >> 3)) 91 92 93 /* Make 94 * create a new empty buffer 95 * 96 * "buffer" [ OUT ] - pointer to structure to initialize 97 * 98 * "elem_bits" [ IN ] - the number of bits in each element 99 * 100 * "elem_capacity" [ IN ] - the minimum number of elements to be allocated 101 */ 102 KLIB_EXTERN rc_t CC KDataBufferMake ( KDataBuffer *buffer, 103 uint64_t elem_bits, uint64_t elem_capacity ); 104 105 106 /* MakeBytes 107 * MakeBits 108 * create a new empty buffer with default element size 109 */ 110 #define KDataBufferMakeBytes( buffer, bytes ) \ 111 KDataBufferMake ( buffer, 8, bytes ) 112 #define KDataBufferMakeBits( buffer, bits ) \ 113 KDataBufferMake ( buffer, 1, bits ) 114 115 /* Sub 116 * create a sub-range reference to an existing buffer 117 * 118 * "sub" [ OUT ] - pointer to subrange structure 119 * 120 * "start" [ IN ] - element offset of subrange from start of "self". 121 * if given start >= self->elem_count, the resultant subrange 122 * will have an element count of 0. 123 * 124 * "count" [ IN, DEFAULT UINT64_MAX ] - number of elements of subrange. 125 * when given count exceeds buffer size, the actual count is calculated to be 126 * all remaining count in "self" from "start". otherwise, the 127 * requested count will be limited to the actual count available 128 * in "self". 129 */ 130 KLIB_EXTERN rc_t CC KDataBufferSub ( const KDataBuffer *self, 131 KDataBuffer *sub, uint64_t start, uint64_t count ); 132 133 134 /* MakeWritable 135 * make a writable copy of the buffer, copying contents if needed. 136 * 137 * "writable" [ OUT ] - pointer to the structure to initialize 138 * 139 * The usage pattern is: 140 * KDataBuffer buffer; 141 * ... 142 * initialize buffer 143 * do stuff which might make it shared 144 * (like pass it to a function that might retain it) 145 * ... 146 * KDataBuffer writable; 147 * rc_t rc = KDataBufferMakeWritable(&buffer, &writable); 148 * 149 * if (rc == 0) { 150 * / * until you whack the old one KDataBufferWritable(&writable) might be false! * / 151 * KDataBufferWhack(&buffer); 152 * buffer = writable; 153 * ... 154 * do whatever you want with buffer because it is now writable (not shared) 155 * ... 156 * } 157 * KDataBufferWhack(&buffer); 158 */ 159 KLIB_EXTERN rc_t CC KDataBufferMakeWritable ( const KDataBuffer *self, KDataBuffer *writable ); 160 161 162 /* Whack 163 * release memory associated with a buffer. 164 */ 165 KLIB_EXTERN rc_t CC KDataBufferWhack ( KDataBuffer *self ); 166 167 168 /* Resize 169 * make a buffer bigger or smaller. 170 * can fail if not enough memory. 171 * can fail if not writable. 172 * 173 * "new_count" [ IN ] - new number of elements 174 */ 175 KLIB_EXTERN rc_t CC KDataBufferResize ( KDataBuffer *self, uint64_t new_count ); 176 177 178 /* Cast 179 * create a new data-buffer with a different element size 180 * won't increase the total number of bits 181 * 182 * "cast" [ OUT ] - newly typed buffer 183 * 184 * "new_elem_bits" [ IN ] - new element size in bits 185 * 186 * "can_shrink" [ IN ] - when true allow 187 * KDataBufferBits ( cast ) < KDataBufferBits ( self ) 188 */ 189 KLIB_EXTERN rc_t CC KDataBufferCast ( const KDataBuffer *self, 190 KDataBuffer *cast, uint64_t new_elem_bits, bool can_shrink ); 191 192 193 /* Writable 194 * returns true if buffer is valid and writable 195 */ 196 KLIB_EXTERN bool CC KDataBufferWritable ( const KDataBuffer *self ); 197 198 199 /* CheckIntegrity 200 * performs some level of integrity checking on buffer structure 201 */ 202 KLIB_EXTERN rc_t CC KDataBufferCheckIntegrity ( const KDataBuffer *self ); 203 204 205 /* Wipe 206 * overwrite allocated memory 207 */ 208 KLIB_EXTERN rc_t CC KDataBufferWipe ( KDataBuffer * self ); 209 210 211 /* WipeNWhack 212 * wipes and releases memory associated with a buffer. 213 */ 214 KLIB_EXTERN rc_t CC KDataBufferWipeNWhack ( KDataBuffer * self ); 215 216 217 /* WipeResize 218 * make a buffer bigger or smaller. 219 * can fail if not enough memory. 220 * can fail if not writable. 221 * wipes memory before release or reallocation 222 * 223 * "new_count" [ IN ] - new number of elements 224 */ 225 KLIB_EXTERN rc_t CC KDataBufferWipeResize ( KDataBuffer * self, uint64_t new_count ); 226 227 228 #ifdef __cplusplus 229 } 230 #endif 231 232 #endif /* _h_klib_data_buffer_ */ 233