LCOV - code coverage report
Current view: top level - shared - tools.cpp (source / functions) Coverage Total Hit
Test: Libprimis Test Coverage Lines: 88.2 % 102 90
Test Date: 2026-04-10 06:41:26 Functions: 93.3 % 15 14

            Line data    Source code
       1              : // implementation of generic tools
       2              : 
       3              : #include <cstring>
       4              : #include <functional>
       5              : #include <string>
       6              : #include <algorithm>
       7              : #include <array>
       8              : 
       9              : #include <SDL.h>
      10              : #include <zlib.h>
      11              : 
      12              : #include "../libprimis-headers/tools.h"
      13              : #include "../libprimis-headers/geom.h"
      14              : 
      15              : #include "stream.h"
      16              : 
      17              : ////////////////////////// strings ////////////////////////////////////////
      18              : 
      19            6 : char *tempformatstring(const char *fmt, ...)
      20              : {
      21              :     static std::array<string, 4> tmpstr;
      22              :     static int tmpidx = 0;
      23            6 :     tmpidx = (tmpidx+1)%4;
      24              : 
      25              :     va_list v;
      26            6 :     va_start(v, fmt);
      27            6 :     vformatstring(tmpstr[tmpidx], fmt, v);
      28            6 :     va_end(v);
      29              : 
      30            6 :     return tmpstr[tmpidx];
      31              : }
      32              : 
      33              : ////////////////////////// bit packing ////////////////////////////////////
      34              : 
      35              : // these functions are useful for packing ints/chars into smaller chunks, which
      36              : // is useful for reducing file save sizes
      37              : 
      38              : // note that the parent put*_ template functions is not defined here but in tools.h
      39              : 
      40              : //*             signed integers            *//
      41           13 : void putint(ucharbuf &p, int n)
      42              : {
      43           13 :     putint_(p, n);
      44           13 : }
      45              : 
      46              : //Stores the passed integer into a uchar array, by splitting it into four bytes.
      47            2 : void putint(std::vector<uchar> &p, int n)
      48              : {
      49            2 :     p.push_back((n >> 24) & 0xFF);
      50            2 :     p.push_back((n >> 16) & 0xFF);
      51            2 :     p.push_back((n >> 8 ) & 0xFF);
      52            2 :     p.push_back(n & 0xFF);
      53            2 : }
      54              : 
      55              : //Removes the last four values from the uchar array, returning its int representation.
      56            2 : int getint(std::vector<uchar> &p)
      57              : {
      58            2 :     int a = 0;
      59            2 :     a += static_cast<int>(p.back());
      60            2 :     p.pop_back();
      61            2 :     a += static_cast<int>(p.back()) << 8;
      62            2 :     p.pop_back();
      63            2 :     a += static_cast<int>(p.back()) << 16;
      64            2 :     p.pop_back();
      65            2 :     a += static_cast<int>(p.back()) << 24;
      66            2 :     p.pop_back();
      67            2 :     return a;
      68              : }
      69              : 
      70              : //Stores the passed float into a uchar array, by splitting it into four bytes.
      71            2 : void putfloat(std::vector<uchar> &p, float n)
      72              : {
      73              :     uchar arr[sizeof(float)];
      74            2 :     std::memcpy(arr, &n, sizeof(float));
      75           10 :     for(unsigned long i = 0; i < sizeof(float); ++i)
      76              :     {
      77            8 :         p.push_back(arr[sizeof(float)-i-1]);
      78              :     }
      79            2 : }
      80              : 
      81              : //Removes the last four values from the uchar array, returning its float representation.
      82            2 : float getfloat(std::vector<uchar> &p)
      83              : {
      84              :     uchar arr[sizeof(float)];
      85           10 :     for(unsigned long i = 0; i < sizeof(float); ++i)
      86              :     {
      87            8 :         arr[i] = p.back();
      88            8 :         p.pop_back();
      89              :     }
      90            2 :     float n = 0.f;
      91            2 :     std::memcpy(&n, arr, sizeof(float));
      92            2 :     return n;
      93              : }
      94              : 
      95              : 
      96           13 : int getint(ucharbuf &p)
      97              : {
      98           13 :     int c = static_cast<char>(p.get());
      99           13 :     if(c == -128)
     100              :     {
     101            1 :         int n = p.get();
     102            1 :         n |= static_cast<char>(p.get()) << 8;
     103            1 :         return n;
     104              :     }
     105           12 :     else if(c == -127)
     106              :     {
     107            1 :         int n = p.get();
     108            1 :         n |= p.get() << 8;
     109            1 :         n |= p.get() << 16;
     110            1 :         return n|(p.get()<<24);
     111              :     }
     112              :     else
     113              :     {
     114           11 :         return c;
     115              :     }
     116              : }
     117              : 
     118              : //*             unisigned integers            *//
     119              : // much smaller encoding for unsigned integers up to 28 bits, but can handle signed
     120              : 
     121            4 : void putuint(ucharbuf &p, int n)
     122              : {
     123            4 :     putuint_(p, n);
     124            4 : }
     125              : 
     126            4 : int getuint(ucharbuf &p)
     127              : {
     128            4 :     int n = p.get();
     129            4 :     if(n & 0x80)
     130              :     {
     131            3 :         n += (p.get() << 7) - 0x80;
     132            3 :         if(n & (1<<14))
     133              :         {
     134            2 :             n += (p.get() << 14) - (1<<14);
     135              :         }
     136            3 :         if(n & (1<<21))
     137              :         {
     138            1 :             n += (p.get() << 21) - (1<<21);
     139              :         }
     140            3 :         if(n & (1<<28))
     141              :         {
     142            1 :             n |= ~0U<<28;
     143              :         }
     144              :     }
     145            4 :     return n;
     146              : }
     147              : 
     148              : //*             floats            *//
     149            2 : void putfloat(ucharbuf &p, float f)
     150              : {
     151            2 :     putfloat_(p, f);
     152            2 : }
     153              : 
     154            2 : float getfloat(ucharbuf &p)
     155              : {
     156              :     float f;
     157            2 :     p.get(reinterpret_cast<uchar *>(&f), sizeof(float));
     158            2 :     return f;
     159              : }
     160              : 
     161              : //*             strings            *//
     162            2 : void sendstring(const char *t, ucharbuf &p)
     163              : {
     164            2 :     sendstring_(t, p);
     165            2 : }
     166            0 : void sendstring(const char *t, std::vector<uchar> &p)
     167              : {
     168            0 :     sendstring_(t, p);
     169            0 : }
     170              : 
     171            2 : void getstring(char *text, ucharbuf &p, size_t len)
     172              : {
     173            2 :     char *t = text;
     174              :     do
     175              :     {
     176           10 :         if(t >= &text[len])
     177              :         {
     178            0 :             text[len-1] = 0;
     179            0 :             return;
     180              :         }
     181           10 :         if(!p.remaining())
     182              :         {
     183            0 :             *t = 0;
     184            0 :             return;
     185              :         }
     186           10 :         *t = getint(p);
     187           10 :     } while(*t++);
     188              : }
     189              : 
     190            5 : void filtertext(char *dst, const char *src, bool whitespace, bool forcespace, size_t len)
     191              : {
     192           37 :     for(int c = static_cast<uchar>(*src); c; c = static_cast<uchar>(*++src))
     193              :     {
     194           33 :         if(c == '\f')
     195              :         {
     196            3 :             if(!*++src)
     197              :             {
     198            0 :                 break;
     199              :             }
     200            3 :             continue;
     201              :         }
     202           30 :         if(!iscubeprint(c))
     203              :         {
     204            0 :             if(!iscubespace(c) || !whitespace)
     205              :             {
     206            0 :                 continue;
     207              :             }
     208            0 :             if(forcespace)
     209              :             {
     210            0 :                 c = ' ';
     211              :             }
     212              :         }
     213           30 :         *dst++ = c;
     214           30 :         if(!--len)
     215              :         {
     216            1 :             break;
     217              :         }
     218              :     }
     219            5 :     *dst = '\0';
     220            5 : }
        

Generated by: LCOV version 2.0-1