nostrdb

an unfairly fast embedded nostr database backed by lmdb
git clone git://jb55.com/nostrdb
Log | Files | Refs | Submodules | README | LICENSE

fileio.c (4816B)


      1 #include <string.h>
      2 #include <stdio.h>
      3 
      4 /* Ensures portable headers are included such as inline. */
      5 #include "config.h"
      6 #include "fileio.h"
      7 #include "pstrutil.h"
      8 
      9 char *fb_copy_path_n(const char *path, size_t len)
     10 {
     11     size_t n;
     12     char *s;
     13 
     14     n = strnlen(path, len);
     15     if ((s = malloc(n + 1))) {
     16         memcpy(s, path, n);
     17         s[n] = '\0';
     18     }
     19     return s;
     20 }
     21 
     22 char *fb_copy_path(const char *path)
     23 {
     24     size_t n;
     25     char *s;
     26 
     27     n = strlen(path);
     28     if ((s = malloc(n + 1))) {
     29         memcpy(s, path, n);
     30         s[n] = '\0';
     31     }
     32     return s;
     33 }
     34 
     35 size_t fb_chomp(const char *path, size_t len, const char *ext)
     36 {
     37     size_t ext_len = ext ? strlen(ext) : 0;
     38     if (len > ext_len && 0 == strncmp(path + len - ext_len, ext, ext_len)) {
     39         len -= ext_len;
     40     }
     41     return len;
     42 }
     43 
     44 char *fb_create_join_path_n(const char *prefix, size_t prefix_len,
     45         const char *suffix, size_t suffix_len, const char *ext, int path_sep)
     46 {
     47     char *path;
     48     size_t ext_len = ext ? strlen(ext) : 0;
     49     size_t n;
     50 
     51     if (!prefix ||
     52             (suffix_len > 0 && (suffix[0] == '/' || suffix[0] == '\\')) ||
     53             (suffix_len > 1 && suffix[1] == ':')) {
     54         prefix_len = 0;
     55     }
     56     if (path_sep && (prefix_len == 0 ||
     57             (prefix[prefix_len - 1] == '/' || prefix[prefix_len - 1] == '\\'))) {
     58         path_sep = 0;
     59     }
     60     path = malloc(prefix_len + !!path_sep + suffix_len + ext_len + 1);
     61     if (!path) {
     62         return 0;
     63     }
     64     n = 0;
     65     if (prefix_len > 0) {
     66         memcpy(path, prefix, prefix_len);
     67         n += prefix_len;
     68     }
     69     if (path_sep) {
     70         path[n++] = '/';
     71     }
     72     memcpy(path + n, suffix, suffix_len);
     73     n += suffix_len;
     74     memcpy(path + n, ext, ext_len);
     75     n += ext_len;
     76     path[n] = '\0';
     77     return path;
     78 }
     79 
     80 char *fb_create_join_path(const char *prefix, const char *suffix, const char *ext, int path_sep)
     81 {
     82     return fb_create_join_path_n(prefix, prefix ? strlen(prefix) : 0,
     83             suffix, suffix ? strlen(suffix) : 0, ext, path_sep);
     84 }
     85 
     86 char *fb_create_path_ext_n(const char *path, size_t path_len, const char *ext)
     87 {
     88     return fb_create_join_path_n(0, 0, path, path_len, ext, 0);
     89 }
     90 
     91 char *fb_create_path_ext(const char *path, const char *ext)
     92 {
     93     return fb_create_join_path(0, path, ext, 0);
     94 }
     95 
     96 char *fb_create_make_path_n(const char *path, size_t len)
     97 {
     98     size_t i, j, n;
     99     char *s;
    100 
    101     if (len == 1 && (path[0] == ' ' || path[0] == '\\')) {
    102         if (!(s = malloc(3))) {
    103             return 0;
    104         }
    105         s[0] = '\\';
    106         s[1] = path[0];
    107         s[2] = '\0';
    108         return s;
    109     }
    110     if (len <= 1) {
    111         return fb_copy_path_n(path, len);
    112     }
    113     for (i = 0, n = len; i < len - 1; ++i) {
    114         if (path[i] == '\\' && path[i + 1] == ' ') {
    115             ++n;
    116         }
    117         n += path[i] == ' ';
    118     }
    119     n += path[i] == ' ';
    120     if (!(s = malloc(n + 1))) {
    121         return 0;
    122     }
    123     for (i = 0, j = 0; i < len - 1; ++i, ++j) {
    124         if (path[i] == '\\' && path[i + 1] == ' ') {
    125             s[j++] = '\\';
    126         }
    127         if (path[i] == ' ') {
    128             s[j++] = '\\';
    129         }
    130         s[j] = path[i];
    131     }
    132     if (path[i] == ' ') {
    133         s[j++] = '\\';
    134     }
    135     s[j++] = path[i];
    136     s[j] = 0;
    137     return s;
    138 }
    139 
    140 char *fb_create_make_path(const char *path)
    141 {
    142     return fb_create_make_path_n(path, strlen(path));
    143 }
    144 
    145 size_t fb_find_basename(const char *path, size_t len)
    146 {
    147     char *p = (char *)path;
    148 
    149     p += len;
    150     while(p != path) {
    151         --p;
    152         if (*p == '/' || *p == '\\') {
    153             ++p;
    154             break;
    155         }
    156     }
    157     return (size_t)(p - path);
    158 }
    159 
    160 char *fb_create_basename(const char *path, size_t len, const char *ext)
    161 {
    162     size_t pos;
    163     char *s;
    164 
    165     pos = fb_find_basename(path, len);
    166     path += pos;
    167     len -= pos;
    168     len = fb_chomp(path, len, ext);
    169     if ((s = malloc(len + 1))) {
    170         memcpy(s, path, len);
    171         s[len] = '\0';
    172     }
    173     return s;
    174 }
    175 
    176 char *fb_read_file(const char *filename, size_t max_size, size_t *size_out)
    177 {
    178     FILE *fp;
    179     long k;
    180     size_t size, pos, n, _out;
    181     char *buf;
    182 
    183     size_out = size_out ? size_out : &_out;
    184 
    185     fp = fopen(filename, "rb");
    186     size = 0;
    187     buf = 0;
    188 
    189     if (!fp) {
    190         goto fail;
    191     }
    192     fseek(fp, 0L, SEEK_END);
    193     k = ftell(fp);
    194     if (k < 0) goto fail;
    195     size = (size_t)k;
    196     *size_out = size;
    197     if (max_size > 0 && size > max_size) {
    198         goto fail;
    199     }
    200     rewind(fp);
    201     buf = malloc(size ? size : 1);
    202     if (!buf) {
    203         goto fail;
    204     }
    205     pos = 0;
    206     while ((n = fread(buf + pos, 1, size - pos, fp))) {
    207         pos += n;
    208     }
    209     if (pos != size) {
    210         goto fail;
    211     }
    212     fclose(fp);
    213     *size_out = size;
    214     return buf;
    215 
    216 fail:
    217     if (fp) {
    218         fclose(fp);
    219     }
    220     if (buf) {
    221         free(buf);
    222     }
    223     *size_out = size;
    224     return 0;
    225 }