summaryrefslogtreecommitdiff
path: root/BSON-lib/bson_util.c
blob: 6734b29ef6d232fe51984235c0ee8e9e70235c4d (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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include "bson_util.h"

void write_int32_le(uint8_t *bytes, int32_t value, size_t *position) {
  int i = 0;
  for (i = 0; i < SIZE_INT32; i++) {
    bytes[(*position)++] = (uint8_t)value & 0x000000FF;
    value >>= 8;
  }
}

void write_int64_le(uint8_t *bytes, int64_t value, size_t *position) {
  int i = 0;
  for (i = 0; i < SIZE_INT64; i++) {
    bytes[(*position)++] = (uint8_t)value & 0x000000FFull;
    value >>= 8;
  }
}

void write_double_le(uint8_t *bytes, double value, size_t *position) {
  union doubleUnion_t {
    double value;
    uint64_t intValue;
  };
  union doubleUnion_t unionVal;
  unionVal.value = value;
  int i = 0;
  for (i = 0; i < SIZE_DOUBLE; i++) {
    bytes[(*position)++] = (uint8_t)unionVal.intValue & 0x000000FFull;
    unionVal.intValue >>= 8;
  }
}

int32_t read_int32_le(uint8_t **bytes) {
  int32_t value = 0;
  int i = 0;
  for (i = SIZE_INT32 - 1; i >= 0; i--) {
    value <<= 8;
    value += (*bytes)[i];
  }
  (*bytes) += SIZE_INT32;
  return value;
}

int64_t read_int64_le(uint8_t **bytes) {
  int64_t value = 0;
  int i = 0;
  for (i = SIZE_INT64 - 1; i >= 0; i--) {
    value <<= 8;
    value += (*bytes)[i];
  }
  (*bytes) += SIZE_INT64;
  return value;
}

double read_double_le(uint8_t **bytes) {
  union doubleUnion_t {
    double value;
    uint64_t intValue;
  };
  union doubleUnion_t unionVal;
  unionVal.intValue = 0;
  int i = 0;
  for (i = SIZE_DOUBLE - 1; i >= 0; i--) {
    unionVal.intValue <<= 8;
    unionVal.intValue += (*bytes)[i];
  }
  (*bytes) += SIZE_DOUBLE;
  return unionVal.value;
}

size_t read_string_len(char **output, const uint8_t **data, size_t *dataSize) {
  size_t i = 0;
  for (i = 0; i < *dataSize; i++) {
    if ((*data)[i] == 0x00) {
      break;
    }
  }
  if (i == *dataSize) {
    // '\0' is not found
    return 0;
  }

  *output = byte_array_to_bson_string((uint8_t *)*data, i);

  // add 1 since we also consumed '\0' at the end
  size_t bytesRead = i + 1;
  (*data) += bytesRead;
  *dataSize -= bytesRead;
  return bytesRead;
}

uint8_t *string_to_byte_array(char *stringVal) {
  size_t length = strlen(stringVal);
  uint8_t *bytes = malloc(length + 1);
  int i = 0;
  for (i = 0; i < length; i++) {
    bytes[i] = (uint8_t)stringVal[i];
  }
  bytes[length] = 0x00;
  return bytes;
}

size_t c_string_length(uint8_t *value) {
  size_t length = 0;
  while (value[length] != 0x00) {
    length++;
  }
  return length;
}

char *byte_array_to_string(uint8_t *bytes) {
  size_t length = c_string_length(bytes);
  return byte_array_to_bson_string(bytes, length);
}

char *byte_array_to_bson_string(uint8_t *bytes, size_t length) {
  char *stringVal = malloc(sizeof(char) * (length + 1));
  
  int i = 0;
  for (i = 0; i < length; i++) {
    stringVal[i] = (char)(bytes[i] & 0xFF);
  }
  stringVal[length] = 0x00;
  return stringVal;
}

uint8_t *index_to_key(size_t index) {
  size_t length = digits(index);
  uint8_t *bytes = malloc(length);
  size_t modValue = index;
  int i = 0;
  for (i = (int)length - 1; i >= 0; i--) {
    //Convert digit to UTF-8
    bytes[i] = 0x30 + (modValue % 10);
    modValue /= 10;
  }
  return bytes;
}

size_t object_key_size(char *key) {
  return strlen(key) + 1;
}

size_t array_key_size(size_t index) {
  //One byte for each decimal digit in index plus null character
  return digits(index) + 1;
}

size_t digits(size_t value) {
  size_t modValue = value;
  size_t numDigits = 1;
  while (modValue >= 10) {
    numDigits++;
    modValue /= 10;
  }
  return numDigits;
}