libsheepy

C lib for handling text files, strings and json like data structure with an object oriented system
git clone https://spartatek.se/git/libsheepy.git
Log | Files | Refs | README | LICENSE

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 }