1*10ff414cSEd Maste /*
2*10ff414cSEd Maste  * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3*10ff414cSEd Maste  *
4*10ff414cSEd Maste  * libcbor is free software; you can redistribute it and/or modify
5*10ff414cSEd Maste  * it under the terms of the MIT license. See LICENSE for details.
6*10ff414cSEd Maste  */
7*10ff414cSEd Maste 
8*10ff414cSEd Maste #include "encoders.h"
9*10ff414cSEd Maste #include <string.h>
10*10ff414cSEd Maste 
11*10ff414cSEd Maste size_t _cbor_encode_uint8(uint8_t value, unsigned char *buffer,
12*10ff414cSEd Maste                           size_t buffer_size, uint8_t offset) {
13*10ff414cSEd Maste   if (value <= 23) {
14*10ff414cSEd Maste     if (buffer_size >= 1) {
15*10ff414cSEd Maste       buffer[0] = value + offset;
16*10ff414cSEd Maste       return 1;
17*10ff414cSEd Maste     }
18*10ff414cSEd Maste   } else {
19*10ff414cSEd Maste     if (buffer_size >= 2) {
20*10ff414cSEd Maste       buffer[0] = 0x18 + offset;
21*10ff414cSEd Maste       buffer[1] = value;
22*10ff414cSEd Maste       return 2;
23*10ff414cSEd Maste     }
24*10ff414cSEd Maste   }
25*10ff414cSEd Maste   return 0;
26*10ff414cSEd Maste }
27*10ff414cSEd Maste 
28*10ff414cSEd Maste size_t _cbor_encode_uint16(uint16_t value, unsigned char *buffer,
29*10ff414cSEd Maste                            size_t buffer_size, uint8_t offset) {
30*10ff414cSEd Maste   if (buffer_size >= 3) {
31*10ff414cSEd Maste     buffer[0] = 0x19 + offset;
32*10ff414cSEd Maste 
33*10ff414cSEd Maste #ifdef IS_BIG_ENDIAN
34*10ff414cSEd Maste     memcpy(buffer + 1, &value, 2);
35*10ff414cSEd Maste #else
36*10ff414cSEd Maste     buffer[1] = value >> 8;
37*10ff414cSEd Maste     buffer[2] = value;
38*10ff414cSEd Maste #endif
39*10ff414cSEd Maste 
40*10ff414cSEd Maste     return 3;
41*10ff414cSEd Maste   } else
42*10ff414cSEd Maste     return 0;
43*10ff414cSEd Maste }
44*10ff414cSEd Maste 
45*10ff414cSEd Maste size_t _cbor_encode_uint32(uint32_t value, unsigned char *buffer,
46*10ff414cSEd Maste                            size_t buffer_size, uint8_t offset) {
47*10ff414cSEd Maste   if (buffer_size >= 5) {
48*10ff414cSEd Maste     buffer[0] = 0x1A + offset;
49*10ff414cSEd Maste 
50*10ff414cSEd Maste #ifdef IS_BIG_ENDIAN
51*10ff414cSEd Maste     memcpy(buffer + 1, &value, 4);
52*10ff414cSEd Maste #else
53*10ff414cSEd Maste     buffer[1] = value >> 24;
54*10ff414cSEd Maste     buffer[2] = value >> 16;
55*10ff414cSEd Maste     buffer[3] = value >> 8;
56*10ff414cSEd Maste     buffer[4] = value;
57*10ff414cSEd Maste #endif
58*10ff414cSEd Maste 
59*10ff414cSEd Maste     return 5;
60*10ff414cSEd Maste   } else
61*10ff414cSEd Maste     return 0;
62*10ff414cSEd Maste }
63*10ff414cSEd Maste 
64*10ff414cSEd Maste size_t _cbor_encode_uint64(uint64_t value, unsigned char *buffer,
65*10ff414cSEd Maste                            size_t buffer_size, uint8_t offset) {
66*10ff414cSEd Maste   if (buffer_size >= 9) {
67*10ff414cSEd Maste     buffer[0] = 0x1B + offset;
68*10ff414cSEd Maste 
69*10ff414cSEd Maste #ifdef IS_BIG_ENDIAN
70*10ff414cSEd Maste     memcpy(buffer + 1, &value, 8);
71*10ff414cSEd Maste #else
72*10ff414cSEd Maste     buffer[1] = value >> 56;
73*10ff414cSEd Maste     buffer[2] = value >> 48;
74*10ff414cSEd Maste     buffer[3] = value >> 40;
75*10ff414cSEd Maste     buffer[4] = value >> 32;
76*10ff414cSEd Maste     buffer[5] = value >> 24;
77*10ff414cSEd Maste     buffer[6] = value >> 16;
78*10ff414cSEd Maste     buffer[7] = value >> 8;
79*10ff414cSEd Maste     buffer[8] = value;
80*10ff414cSEd Maste #endif
81*10ff414cSEd Maste 
82*10ff414cSEd Maste     return 9;
83*10ff414cSEd Maste   } else
84*10ff414cSEd Maste     return 0;
85*10ff414cSEd Maste }
86*10ff414cSEd Maste 
87*10ff414cSEd Maste size_t _cbor_encode_uint(uint64_t value, unsigned char *buffer,
88*10ff414cSEd Maste                          size_t buffer_size, uint8_t offset) {
89*10ff414cSEd Maste   if (value <= UINT16_MAX)
90*10ff414cSEd Maste     if (value <= UINT8_MAX)
91*10ff414cSEd Maste       return _cbor_encode_uint8((uint8_t)value, buffer, buffer_size, offset);
92*10ff414cSEd Maste     else
93*10ff414cSEd Maste       return _cbor_encode_uint16((uint16_t)value, buffer, buffer_size, offset);
94*10ff414cSEd Maste   else if (value <= UINT32_MAX)
95*10ff414cSEd Maste     return _cbor_encode_uint32((uint32_t)value, buffer, buffer_size, offset);
96*10ff414cSEd Maste   else
97*10ff414cSEd Maste     return _cbor_encode_uint64((uint64_t)value, buffer, buffer_size, offset);
98*10ff414cSEd Maste }
99