LCOV - code coverage report
Current view: top level - src - pino.c (source / functions) Coverage Total Hit
Test: pino Coverage Report Lines: 90.2 % 92 83
Test Date: 2026-01-22 09:45:38 Functions: 100.0 % 12 12
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              :  * libpino - pino.c
       3              :  *
       4              :  * This file is part of libpino.
       5              :  *
       6              :  * Author: Go Kudo <zeriyoshi@gmail.com>
       7              :  * SPDX-License-Identifier: MIT
       8              :  */
       9              : 
      10              : #include <stdbool.h>
      11              : #include <stddef.h>
      12              : #include <stdint.h>
      13              : #include <stdio.h>
      14              : 
      15              : #include <pino.h>
      16              : #include <pino/handler.h>
      17              : 
      18              : #include "internal/common.h"
      19              : 
      20         1007 : static inline pino_t *pino_create(pino_magic_safe_t magic, pino_handler_t *handler, size_t size)
      21              : {
      22              :     pino_t *pino;
      23              : 
      24         1007 :     pino = pmalloc(sizeof(pino_t));
      25         1007 :     if (!pino) {
      26            0 :         return NULL;
      27              :     }
      28              : 
      29         1007 :     pmemcpy(pino->magic, magic, sizeof(pino_magic_t));
      30         1007 :     pino->magic[sizeof(pino_magic_t)] = '\0';
      31         1007 :     pino->static_fields_size = handler->static_fields_size;
      32         1007 :     pino->static_fields = pcalloc(1, pino->static_fields_size);
      33              : 
      34         1007 :     if (!pino->static_fields) {
      35            0 :         pfree(pino);
      36              : 
      37            0 :         return NULL;
      38              :     }
      39              : 
      40         1007 :     pino->handler = handler;
      41         1007 :     pino->this = handler->create(size, pino->static_fields);
      42         1007 :     if (!pino->this) {
      43            1 :         pfree(pino->static_fields);
      44            1 :         pfree(pino);
      45            1 :         return NULL;
      46              :     }
      47              : 
      48         1006 :     return pino;
      49              : }
      50              : 
      51           18 : extern bool pino_init(void)
      52              : {
      53           18 :     return pino_handler_init(HANDLER_STEP);
      54              : }
      55              : 
      56           18 : extern void pino_free(void)
      57              : {
      58           18 :     pino_handler_free();
      59           18 : }
      60              : 
      61            3 : extern size_t pino_serialize_size(const pino_t *pino)
      62              : {
      63              :     size_t handler_size, total_size;
      64              : 
      65            3 :     if (!pino || !pino->handler || !pino->handler->serialize_size) {
      66            1 :         return 0;
      67              :     }
      68              : 
      69            2 :     handler_size = pino->handler->serialize_size(pino->this, pino->static_fields);
      70            2 :     if (handler_size > SIZE_MAX - sizeof(pino_magic_t) - sizeof(pino_static_fields_size_t) - pino->static_fields_size) {
      71            0 :         return 0;
      72              :     }
      73              : 
      74            2 :     total_size = handler_size + sizeof(pino_magic_t) + sizeof(pino_static_fields_size_t) + pino->static_fields_size;
      75              : 
      76            2 :     return total_size;
      77              : }
      78              : 
      79            3 : extern bool pino_serialize(const pino_t *pino, void *dest)
      80              : {
      81            3 :     if (!pino || !dest || !pino->handler || !pino->handler->serialize) {
      82            1 :         return false;
      83              :     }
      84              : 
      85            2 :     pmemcpy(dest, pino->magic, sizeof(pino_magic_t));
      86            2 :     pmemcpy_n2l(((char *)dest) + sizeof(pino_magic_t), &pino->static_fields_size, sizeof(pino_static_fields_size_t));
      87              : 
      88              :     /* fields always use LE */
      89            2 :     pmemcpy(((char *)dest) + sizeof(pino_magic_t) + sizeof(pino_static_fields_size_t), pino->static_fields,
      90              :             pino->static_fields_size);
      91              : 
      92            2 :     return pino->handler->serialize(pino->this, pino->static_fields,
      93            2 :                                     ((char *)dest) + sizeof(pino_magic_t) + sizeof(pino_static_fields_size_t) +
      94            2 :                                         pino->handler->static_fields_size);
      95              : }
      96              : 
      97            9 : extern pino_t *pino_unserialize(const void *src, size_t size)
      98              : {
      99              :     pino_t *pino;
     100              :     pino_handler_t *handler;
     101              :     pino_magic_safe_t magic;
     102              :     pino_static_fields_size_t fields_size;
     103              : 
     104            9 :     if (!src) {
     105            1 :         return NULL;
     106              :     }
     107              : 
     108            8 :     if (size < sizeof(pino_magic_t) + sizeof(pino_static_fields_size_t)) {
     109            2 :         return NULL;
     110              :     }
     111              : 
     112            6 :     pmemcpy(magic, src, sizeof(pino_magic_t));
     113            6 :     pmemcpy_l2n(&fields_size, ((char *)src) + sizeof(pino_magic_t), sizeof(pino_static_fields_size_t));
     114              : 
     115            6 :     if (size < sizeof(pino_magic_t) + sizeof(pino_static_fields_size_t) + fields_size) {
     116            1 :         return NULL;
     117              :     }
     118              : 
     119            5 :     handler = pino_handler_find(magic);
     120            5 :     if (!handler) {
     121            2 :         return NULL;
     122              :     }
     123              : 
     124            3 :     pino = pino_create(magic, handler, size - sizeof(pino_magic_t) - sizeof(pino_static_fields_size_t) - fields_size);
     125            3 :     if (!pino) {
     126            0 :         return NULL;
     127              :     }
     128              : 
     129              :     /* always LE */
     130            3 :     pmemcpy(pino->static_fields, ((char *)src) + sizeof(pino_magic_t) + sizeof(pino_static_fields_size_t), fields_size);
     131            3 :     if (!handler->unserialize(pino->this, pino->static_fields,
     132            3 :                               ((char *)src) + sizeof(pino_magic_t) + sizeof(pino_static_fields_size_t) + fields_size,
     133              :                               size)) {
     134            1 :         pino_destroy(pino);
     135            1 :         return NULL;
     136              :     }
     137              : 
     138            2 :     return pino;
     139              : }
     140              : 
     141         1008 : extern pino_t *pino_pack(pino_magic_safe_t magic, const void *src, size_t size)
     142              : {
     143              :     pino_t *pino;
     144              :     pino_handler_t *handler;
     145              : 
     146         1008 :     handler = pino_handler_find(magic);
     147         1008 :     if (!handler) {
     148            4 :         return NULL;
     149              :     }
     150              : 
     151         1004 :     pino = pino_create(magic, handler, size);
     152         1004 :     if (!pino) {
     153            1 :         return NULL;
     154              :     }
     155              : 
     156         1003 :     if (!handler->pack(pino->this, pino->static_fields, src, size)) {
     157            0 :         pino_destroy(pino);
     158            0 :         return NULL;
     159              :     }
     160              : 
     161         1003 :     return pino;
     162              : }
     163              : 
     164            5 : extern size_t pino_unpack_size(const pino_t *pino)
     165              : {
     166            5 :     if (!pino || !pino->handler || !pino->handler->unpack_size) {
     167            0 :         return 0;
     168              :     }
     169              : 
     170            5 :     return pino->handler->unpack_size(pino->this, pino->static_fields);
     171              : }
     172              : 
     173            4 : extern bool pino_unpack(const pino_t *pino, void *dest)
     174              : {
     175            4 :     if (!pino || !dest || !pino->handler || !pino->handler->unpack) {
     176            0 :         return false;
     177              :     }
     178              : 
     179            4 :     return pino->handler->unpack(pino->this, pino->static_fields, dest);
     180              : }
     181              : 
     182         1007 : extern void pino_destroy(pino_t *pino)
     183              : {
     184         1007 :     if (!pino) {
     185            1 :         return;
     186              :     }
     187              : 
     188         1006 :     if (pino->this) {
     189         1006 :         pino->handler->destroy(pino->this, pino->static_fields);
     190              :     }
     191              : 
     192         1006 :     if (pino->static_fields) {
     193         1006 :         pfree(pino->static_fields);
     194              :     }
     195              : 
     196         1006 :     pfree(pino);
     197              : }
     198              : 
     199            1 : extern uint32_t pino_version_id()
     200              : {
     201            1 :     return (uint32_t)PINO_VERSION_ID;
     202              : }
     203              : 
     204            1 : extern pino_buildtime_t pino_buildtime()
     205              : {
     206            1 :     return (pino_buildtime_t)PINO_BUILDTIME;
     207              : }
        

Generated by: LCOV version 2.0-1