summaryrefslogtreecommitdiff
path: root/src/dged/s8.c
blob: e641b11a557cb297fa81f7facfbdc53636ce7433 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include "s8.h"

#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct s8 s8new(const char *s, uint32_t len) {
  uint8_t *mem = calloc(len, 1);
  memcpy(mem, s, len);
  return (struct s8){
      .s = mem,
      .l = len,
  };
}

void s8delete(struct s8 s) {
  if (s.s != NULL) {
    free(s.s);
  }
  s.l = 0;
  s.s = NULL;
}

struct s8 s8from_fmt(const char *fmt, ...) {
  va_list args;

  va_start(args, fmt);
  ssize_t len = vsnprintf(NULL, 0, fmt, args);
  va_end(args);

  if (len == -1) {
    return (struct s8){
        .s = NULL,
        .l = 0,
    };
  }

  char *buf = calloc(len + 1, 1);

  va_list args2;
  va_start(args2, fmt);
  vsnprintf(buf, len + 1, fmt, args2);
  va_end(args2);

  return (struct s8){
      .s = (uint8_t *)buf,
      .l = len,
  };
}

bool s8eq(struct s8 s1, struct s8 s2) {
  return s1.l == s2.l && memcmp(s1.s, s2.s, s1.l) == 0;
}

int s8cmp(struct s8 s1, struct s8 s2) {
  if (s1.l < s2.l) {
    int res = memcmp(s1.s, s2.s, s1.l);
    return res == 0 ? -s2.s[s1.l] : res;
  } else if (s2.l < s1.l) {
    int res = memcmp(s1.s, s2.s, s2.l);
    return res == 0 ? s1.s[s2.l] : res;
  }

  return memcmp(s1.s, s2.s, s1.l);
}

char *s8tocstr(struct s8 s) {
  char *cstr = (char *)malloc(s.l + 1);
  memcpy(cstr, s.s, s.l);
  cstr[s.l] = '\0';
  return cstr;
}

bool s8startswith(struct s8 s, struct s8 prefix) {
  if (prefix.l == 0 || prefix.l > s.l) {
    return false;
  }

  return memcmp(s.s, prefix.s, prefix.l) == 0;
}

bool s8endswith(struct s8 s, struct s8 suffix) {
  if (suffix.l > s.l) {
    return false;
  }

  size_t ldiff = s.l - suffix.l;
  return memcmp(s.s + ldiff, suffix.s, suffix.l) == 0;
}

struct s8 s8dup(struct s8 s) {
  struct s8 new = {0};
  new.l = s.l;

  new.s = (uint8_t *)malloc(s.l);
  memcpy(new.s, s.s, s.l);

  return new;
}

bool s8empty(struct s8 s) { return s.s == NULL || s.l == 0; }

bool s8onlyws(struct s8 s) {
  for (size_t i = 0; i < s.l; ++i) {
    if (!isspace(s.s[i])) {
      return false;
    }
  }

  return true;
}