libsheepyCSmallContainer.c (10773B)
1 // MIT License 2 // 3 // Copyright (c) 2026 Remy Noulin 4 // 5 // Permission is hereby granted, free of charge, to any person obtaining a copy 6 // of this software and associated documentation files (the "Software"), to deal 7 // in the Software without restriction, including without limitation the rights 8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 // copies of the Software, and to permit persons to whom the Software is 10 // furnished to do so, subject to the following conditions: 11 // 12 // The above copyright notice and this permission notice shall be included in all 13 // copies or substantial portions of the Software. 14 // 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 // SOFTWARE. 22 23 #include "../libsheepyObject.h" 24 #include "libsheepyCSmallContainer.h" 25 #include "libsheepyCSmallContainerInternal.h" 26 27 #define internal static 28 29 #include <stdlib.h> 30 #include <stdint.h> 31 #include <string.h> 32 #include <stdio.h> 33 34 void initiateSmallContainer(smallContainert *self); 35 void registerMethodsSmallContainer(smallContainerFunctionst *f); 36 void initiateAllocateSmallContainer(smallContainert **self); 37 void finalizeRecycleSmallContainer(void *arg UNUSED); 38 void finalizeSmallContainer(void); 39 smallContainert* allocSmallContainer(void *data); 40 void cleanUpSmallContainerTerminateG(smallContainert **val); 41 void cleanUpSmallContainerFreeLocalG(smallContainert *val); 42 void cleanUpSmallContainerFreeG(smallContainert **val); 43 void cleanUpSmallContainerFinishG(smallContainert **val); 44 internal void freeSmallContainer(smallContainert *self); 45 internal void terminateSmallContainer(smallContainert **self); 46 #if (NFreeStackCheck) 47 internal void finishSmallContainer(smallContainert **self); 48 #else 49 internal void finishSmallContainer(smallContainert **self); 50 #endif 51 internal const char* helpSmallContainer(smallContainert UNUSED *self); 52 internal char* toStringSmallContainer(smallContainert *self); 53 internal smallContainert* duplicateSmallContainer(smallContainert *self); 54 internal smallContainert* setClassDataFreeSmallContainer(smallContainert *self, dataFreeSmallContainerFt free); 55 internal smallContainert* setObjectDataFreeSmallContainer(smallContainert *self, dataFreeSmallContainerFt free); 56 internal smallContainert* setClassDataToStringSmallContainer(smallContainert *self, dataToStringSmallContainerFt toString); 57 internal smallContainert* setObjectDataToStringSmallContainer(smallContainert *self, dataToStringSmallContainerFt toString); 58 internal smallContainert* setClassDataDuplicateSmallContainer(smallContainert *self, dataDuplicateSmallContainerFt duplicate); 59 internal smallContainert* setObjectDataDuplicateSmallContainer(smallContainert *self, dataDuplicateSmallContainerFt duplicate); 60 internal void smashSmallContainer(smallContainert **self); 61 internal void* getSmallContainer(smallContainert *self); 62 internal smallContainert* setSmallContainer(smallContainert *self, void *data); 63 smallContainert* duplicateSmallContainerG (smallContainert *self); 64 void* getSmallContainerG(smallContainert *self, void* retType UNUSED, int64_t index UNUSED); 65 smallContainert* setSmallContainerG(smallContainert *self, void *data); 66 67 void initiateSmallContainer(smallContainert *self) { 68 69 self->type = "smallContainer"; 70 if (!smallContainerF) { 71 isError(smallContainerF, malloc(sizeof(smallContainerFunctionst))) { 72 self->f = NULL; 73 return; 74 } 75 registerMethodsSmallContainer(smallContainerF); 76 } 77 self->f = smallContainerF;; 78 79 self->data = NULL; 80 self->dataFree = NULL; 81 self->dataToString = NULL; 82 self->dataDuplicate = NULL; 83 } 84 85 void registerMethodsSmallContainer(smallContainerFunctionst *f) { 86 87 f->free = freeSmallContainer; 88 f->terminate = terminateSmallContainer; 89 f->finish = finishSmallContainer; 90 f->toString = toStringSmallContainer; 91 f->duplicate = duplicateSmallContainer; 92 f->help = helpSmallContainer; 93 f->dataFree = NULL; 94 f->setClassDataFree = setClassDataFreeSmallContainer; 95 f->setObjectDataFree = setObjectDataFreeSmallContainer; 96 f->dataToString = NULL; 97 f->setClassDataToString = setClassDataToStringSmallContainer; 98 f->setObjectDataToString = setObjectDataToStringSmallContainer; 99 f->dataDuplicate = NULL; 100 f->setClassDataDuplicate = setClassDataDuplicateSmallContainer; 101 f->setObjectDataDuplicate = setObjectDataDuplicateSmallContainer; 102 f->smash = smashSmallContainer; 103 f->get = getSmallContainer; 104 f->set = setSmallContainer; 105 } 106 107 void initiateAllocateSmallContainer(smallContainert **self) { 108 109 if (self) { 110 #if (recycleContainers) 111 initAllocateRecycle(smallContainert); 112 #else 113 isError(*self, malloc(sizeof(smallContainert))) 114 return; 115 #endif 116 if (*self) { 117 initiateSmallContainer(*self); 118 if (!(*self)->f) { 119 finishSmallContainer(self); 120 } 121 } 122 } 123 } 124 125 void finalizeRecycleSmallContainer(void *arg UNUSED) { 126 127 #if (recycleContainers) 128 finalizeRecycle 129 #endif 130 // recycleContainers 131 } 132 133 void finalizeSmallContainer(void) { 134 135 if (smallContainerF) { 136 free(smallContainerF); 137 smallContainerF = NULL; 138 } 139 finalizeRecycleSmallContainer(NULL); 140 } 141 142 smallContainert* allocSmallContainer(void *data) { 143 smallContainert *r = NULL; 144 145 initiateAllocateSmallContainer(&r); 146 if (!r) { 147 return(NULL); 148 } 149 r->data = allocSContainer(data); 150 return(r); 151 } 152 153 void cleanUpSmallContainerTerminateG(smallContainert **val) { 154 155 terminateO(*val); 156 } 157 158 void cleanUpSmallContainerFreeLocalG(smallContainert *val) { 159 160 freeO(val); 161 } 162 163 void cleanUpSmallContainerFreeG(smallContainert **val) { 164 165 freeO(*val); 166 } 167 168 void cleanUpSmallContainerFinishG(smallContainert **val) { 169 170 finishO(*val); 171 } 172 173 internal void freeSmallContainer(smallContainert *self) { 174 175 if (self->data) { 176 // free with sContainert free function 177 if (self->data->free) { 178 self->data->free(self->data->data); 179 } 180 else if (self->dataFree) { 181 self->dataFree(self->data->data); 182 } 183 else if (self->f->dataFree) { 184 self->f->dataFree(self->data->data); 185 } 186 free(self->data); 187 self->data = NULL; 188 } 189 return; 190 } 191 192 internal void terminateSmallContainer(smallContainert **self) { 193 194 freeSmallContainer(*self); 195 finishSmallContainer(self); 196 } 197 198 #if (NFreeStackCheck) 199 internal void finishSmallContainer(smallContainert **self) { 200 201 register u64 rsp asm("rsp"); 202 if ((u64)*self > rsp) { 203 logW("Probably trying to free a smallContainer on stack: "BLD PRIx64 RST" sp: "BLD PRIx64 RST, *self, rsp); 204 logBtrace; 205 } 206 else { 207 #if (recycleContainers) 208 finishRecycle 209 #else 210 free(*self); 211 #endif 212 // recycleContainers 213 *self = NULL; 214 } 215 } 216 217 #else 218 // #if NFreeStackCheck 219 internal void finishSmallContainer(smallContainert **self) { 220 221 #if (recycleContainers) 222 finishRecycle 223 #else 224 free(*self); 225 #endif 226 // recycleContainers 227 *self = NULL; 228 } 229 230 #endif 231 // #if NFreeStackCheck 232 233 internal const char* helpSmallContainer(smallContainert UNUSED *self) { 234 235 return(helpTextSmallContainer); 236 } 237 238 239 internal char* toStringSmallContainer(smallContainert *self) { 240 241 if (!self->data) { 242 return(NULL); 243 } 244 if (self->dataToString) { 245 return(self->dataToString(self->data->data)); 246 } 247 if (self->f->dataToString) { 248 return(self->f->dataToString(self->data->data)); 249 } 250 return(strdup("<data smallContainer>")); 251 } 252 253 internal smallContainert* duplicateSmallContainer(smallContainert *self) { 254 255 createAllocateSmallContainer(dup); 256 if (!dup) { 257 return(NULL); 258 } 259 if (self->data) { 260 isError(dup->data, allocSContainer(NULL)) return(NULL); 261 if (self->dataDuplicate) { 262 dup->data->data = self->dataDuplicate(self->data->data); 263 } 264 else if (self->f->dataDuplicate) { 265 dup->data->data = self->f->dataDuplicate(self->data->data); 266 } 267 dup->data->free = self->data->free; 268 } 269 dup->dataFree = self->dataFree; 270 dup->dataToString = self->dataToString; 271 dup->dataDuplicate = self->dataDuplicate; 272 return(dup); 273 } 274 275 internal smallContainert* setClassDataFreeSmallContainer(smallContainert *self, dataFreeSmallContainerFt free) { 276 277 self->f->dataFree = free; 278 if (self->data) { 279 self->data->free = (freeSContainerFt)free;; 280 } 281 return(self); 282 } 283 284 internal smallContainert* setObjectDataFreeSmallContainer(smallContainert *self, dataFreeSmallContainerFt free) { 285 286 self->dataFree = free; 287 if (self->data) { 288 self->data->free = (freeSContainerFt)free;; 289 } 290 return(self); 291 } 292 293 internal smallContainert* setClassDataToStringSmallContainer(smallContainert *self, dataToStringSmallContainerFt toString) { 294 295 self->f->dataToString = toString; 296 return(self); 297 } 298 299 internal smallContainert* setObjectDataToStringSmallContainer(smallContainert *self, dataToStringSmallContainerFt toString) { 300 301 self->dataToString = toString; 302 return(self); 303 } 304 305 internal smallContainert* setClassDataDuplicateSmallContainer(smallContainert *self, dataDuplicateSmallContainerFt duplicate) { 306 307 self->f->dataDuplicate = duplicate; 308 return(self); 309 } 310 311 internal smallContainert* setObjectDataDuplicateSmallContainer(smallContainert *self, dataDuplicateSmallContainerFt duplicate) { 312 313 self->dataDuplicate = duplicate; 314 return(self); 315 } 316 317 internal void smashSmallContainer(smallContainert **self) { 318 319 if ((*self)->data) { 320 free((*self)->data); 321 } 322 finishSmallContainer(self); 323 } 324 325 internal void* getSmallContainer(smallContainert *self) { 326 327 if (!self->data) { 328 return(NULL); 329 } 330 return(self->data->data); 331 } 332 333 internal smallContainert* setSmallContainer(smallContainert *self, void *data) { 334 335 if (!self->data) { 336 isError(self->data, allocSContainer(data)) return(NULL); 337 if (self->f->dataFree) { 338 // set free function from class 339 self->data->free = (freeSContainerFt)self->f->dataFree; 340 } 341 } 342 else { 343 self->data->data = data; 344 } 345 return(self); 346 } 347 348 smallContainert* duplicateSmallContainerG (smallContainert *self) { 349 350 return(self->f->duplicate(self)); 351 } 352 353 void freeSmallContainerG(smallContainert *self) {self->f->free(self);} 354 355 void* getSmallContainerG(smallContainert *self, void* retType UNUSED, int64_t index UNUSED) { 356 357 return(self->f->get(self)); 358 } 359 360 smallContainert* setSmallContainerG(smallContainert *self, void *data) { 361 362 return(self->f->set(self, data)); 363 }