1/*
2 * Copyright (c) 2014-2019 Pavel Kalvoda <me@pavelkalvoda.com>
3 *
4 * libcbor is free software; you can redistribute it and/or modify
5 * it under the terms of the MIT license. See LICENSE for details.
6 */
7
8#include "ints.h"
9
10cbor_int_width cbor_int_get_width(const cbor_item_t *item) {
11  assert(cbor_is_int(item));
12  return item->metadata.int_metadata.width;
13}
14
15uint8_t cbor_get_uint8(const cbor_item_t *item) {
16  assert(cbor_is_int(item));
17  assert(cbor_int_get_width(item) == CBOR_INT_8);
18  return *item->data;
19}
20
21uint16_t cbor_get_uint16(const cbor_item_t *item) {
22  assert(cbor_is_int(item));
23  assert(cbor_int_get_width(item) == CBOR_INT_16);
24  return *(uint16_t *)item->data;
25}
26
27uint32_t cbor_get_uint32(const cbor_item_t *item) {
28  assert(cbor_is_int(item));
29  assert(cbor_int_get_width(item) == CBOR_INT_32);
30  return *(uint32_t *)item->data;
31}
32
33uint64_t cbor_get_uint64(const cbor_item_t *item) {
34  assert(cbor_is_int(item));
35  assert(cbor_int_get_width(item) == CBOR_INT_64);
36  return *(uint64_t *)item->data;
37}
38
39uint64_t cbor_get_int(const cbor_item_t *item) {
40  assert(cbor_is_int(item));
41  switch (cbor_int_get_width(item)) {
42    case CBOR_INT_8:
43      return cbor_get_uint8(item);
44    case CBOR_INT_16:
45      return cbor_get_uint16(item);
46    case CBOR_INT_32:
47      return cbor_get_uint32(item);
48    case CBOR_INT_64:
49      return cbor_get_uint64(item);
50  }
51  // TODO: This should be handled in a default branch
52  return 0xDEADBEEF; /* Compiler complaints */
53}
54
55void cbor_set_uint8(cbor_item_t *item, uint8_t value) {
56  assert(cbor_is_int(item));
57  assert(cbor_int_get_width(item) == CBOR_INT_8);
58  *item->data = value;
59}
60
61void cbor_set_uint16(cbor_item_t *item, uint16_t value) {
62  assert(cbor_is_int(item));
63  assert(cbor_int_get_width(item) == CBOR_INT_16);
64  *(uint16_t *)item->data = value;
65}
66
67void cbor_set_uint32(cbor_item_t *item, uint32_t value) {
68  assert(cbor_is_int(item));
69  assert(cbor_int_get_width(item) == CBOR_INT_32);
70  *(uint32_t *)item->data = value;
71}
72
73void cbor_set_uint64(cbor_item_t *item, uint64_t value) {
74  assert(cbor_is_int(item));
75  assert(cbor_int_get_width(item) == CBOR_INT_64);
76  *(uint64_t *)item->data = value;
77}
78
79void cbor_mark_uint(cbor_item_t *item) {
80  assert(cbor_is_int(item));
81  item->type = CBOR_TYPE_UINT;
82}
83
84void cbor_mark_negint(cbor_item_t *item) {
85  assert(cbor_is_int(item));
86  item->type = CBOR_TYPE_NEGINT;
87}
88
89cbor_item_t *cbor_new_int8() {
90  cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 1);
91  _CBOR_NOTNULL(item);
92  *item = (cbor_item_t){.data = (unsigned char *)item + sizeof(cbor_item_t),
93                        .refcount = 1,
94                        .metadata = {.int_metadata = {.width = CBOR_INT_8}},
95                        .type = CBOR_TYPE_UINT};
96  return item;
97}
98
99cbor_item_t *cbor_new_int16() {
100  cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 2);
101  _CBOR_NOTNULL(item);
102  *item = (cbor_item_t){.data = (unsigned char *)item + sizeof(cbor_item_t),
103                        .refcount = 1,
104                        .metadata = {.int_metadata = {.width = CBOR_INT_16}},
105                        .type = CBOR_TYPE_UINT};
106  return item;
107}
108
109cbor_item_t *cbor_new_int32() {
110  cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4);
111  _CBOR_NOTNULL(item);
112  *item = (cbor_item_t){.data = (unsigned char *)item + sizeof(cbor_item_t),
113                        .refcount = 1,
114                        .metadata = {.int_metadata = {.width = CBOR_INT_32}},
115                        .type = CBOR_TYPE_UINT};
116  return item;
117}
118
119cbor_item_t *cbor_new_int64() {
120  cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 8);
121  _CBOR_NOTNULL(item);
122  *item = (cbor_item_t){.data = (unsigned char *)item + sizeof(cbor_item_t),
123                        .refcount = 1,
124                        .metadata = {.int_metadata = {.width = CBOR_INT_64}},
125                        .type = CBOR_TYPE_UINT};
126  return item;
127}
128
129cbor_item_t *cbor_build_uint8(uint8_t value) {
130  cbor_item_t *item = cbor_new_int8();
131  _CBOR_NOTNULL(item);
132  cbor_set_uint8(item, value);
133  cbor_mark_uint(item);
134  return item;
135}
136
137cbor_item_t *cbor_build_uint16(uint16_t value) {
138  cbor_item_t *item = cbor_new_int16();
139  _CBOR_NOTNULL(item);
140  cbor_set_uint16(item, value);
141  cbor_mark_uint(item);
142  return item;
143}
144
145cbor_item_t *cbor_build_uint32(uint32_t value) {
146  cbor_item_t *item = cbor_new_int32();
147  _CBOR_NOTNULL(item);
148  cbor_set_uint32(item, value);
149  cbor_mark_uint(item);
150  return item;
151}
152
153cbor_item_t *cbor_build_uint64(uint64_t value) {
154  cbor_item_t *item = cbor_new_int64();
155  _CBOR_NOTNULL(item);
156  cbor_set_uint64(item, value);
157  cbor_mark_uint(item);
158  return item;
159}
160
161cbor_item_t *cbor_build_negint8(uint8_t value) {
162  cbor_item_t *item = cbor_new_int8();
163  _CBOR_NOTNULL(item);
164  cbor_set_uint8(item, value);
165  cbor_mark_negint(item);
166  return item;
167}
168
169cbor_item_t *cbor_build_negint16(uint16_t value) {
170  cbor_item_t *item = cbor_new_int16();
171  _CBOR_NOTNULL(item);
172  cbor_set_uint16(item, value);
173  cbor_mark_negint(item);
174  return item;
175}
176
177cbor_item_t *cbor_build_negint32(uint32_t value) {
178  cbor_item_t *item = cbor_new_int32();
179  _CBOR_NOTNULL(item);
180  cbor_set_uint32(item, value);
181  cbor_mark_negint(item);
182  return item;
183}
184
185cbor_item_t *cbor_build_negint64(uint64_t value) {
186  cbor_item_t *item = cbor_new_int64();
187  _CBOR_NOTNULL(item);
188  cbor_set_uint64(item, value);
189  cbor_mark_negint(item);
190  return item;
191}
192