aboutsummaryrefslogtreecommitdiff
path: root/libk/string.h
blob: 7c0afb9f837e550ab67ce433c208073b89434703 (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
#pragma once
#include <types.h>

extern "C" {
void* memcpy(void* dstptr, const void* srcptr, size_t n);
void* memset(void* bufptr, int value, size_t n);
void* memmove(void* dstptr, const void* srcptr, size_t n);
int memcmp(const void* aptr, const void* bptr, size_t n);
}

/**
 * Calculate the length of the string (in bytes) pointed to by str, excluding
 * the terminating null character.
 */
constexpr size_t strlen(const char* str) {
  size_t len = 0;
  while (str[len] != '\0') ++len;
  return len;
}

/**
 * Reverse array in place
 */
constexpr void reverse(char s[], size_t strlen) {
  int i, j;
  char c;

  for (i = 0, j = strlen - 1; i < j; i++, j--) {
    c = s[i];
    s[i] = s[j];
    s[j] = c;
  }
}

class ViewIterator {
public:
  char next() { return buffer[reverse ? pos-- : pos++]; }
  operator bool() const { return reverse ? (pos >= 0) : (pos < length); }

  explicit ViewIterator(const char* b, size_t l, bool r = false) : buffer(b), length(l), reverse(r) {
    if (reverse) pos = length - 1;
  };

private:
  ssize_t pos = 0;
  const char* const buffer;  // const pointer to const char*
  const size_t length;
  const bool reverse;
};

class StringView {
public:
  StringView(const char* d) : buffer{d}, m_length{strlen(d)} {}
  StringView(const char* d, size_t l) : buffer{d}, m_length{l} {}

  auto begin() const { return ViewIterator(buffer, m_length); }

private:
  const char* const buffer;
  const size_t m_length;
};

class IntegerView {
public:
  struct HexFormat_int32 {
    int32_t n;
  };
  struct HexFormat_uint32 {
    uint32_t n;
  };

  IntegerView(int32_t n);
  IntegerView(uint32_t n);
  IntegerView(HexFormat_int32 f);
  IntegerView(HexFormat_uint32 f);

  auto begin() const { return ViewIterator(buffer, length, true); }

private:
  char buffer[32];
  size_t length = 0;
};

using hex = IntegerView::HexFormat_int32;
using uhex = IntegerView::HexFormat_uint32;

// using hex_addr = IntegerView::HexFormat<uint64_t>;  // TODO causes crash