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