aboutsummaryrefslogtreecommitdiff
path: root/tests/hex.h
blob: e6a2a07e6a66098e9d4f7016a5052f2acdbdec3a (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
/*
* Copyright (c) 2024 Vaughn Nugent
*
* Package: noscrypt
* File: hex.h
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or  (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with noscrypt. If not, see http://www.gnu.org/licenses/.
*/


#ifndef HEX_HELPERS_H
#define HEX_HELPERS_H

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <nc-util.h>

/* Deferred list of span_t to be freed on exit */
static span_t _hdeferList[20];
static size_t _hdeferListIndex = 0;

/* 
	Allocates a span_t and decodes the hexadecimal string into it's binary
	representation. The string must be a valid hexadecimal string and the length
	and may not be NULL. The length may be known at compile time and can be used
    to assert the length of the string literal.
	@param hexLiteral The hexadecimal string to decode
	@param strLen The length of the string
*/
#define FromHexString(str, len) _fromHexString(str, sizeof(str) - 1); STATIC_ASSERT(sizeof(str)/2 == len && len > 0, "Invalid length hex string literal");

static span_t __allocHexBytes(size_t length)
{
	span_t hexBytes;

	length /= 2;

	hexBytes.data = malloc(length);

	if(!hexBytes.data)
	{
		return hexBytes;
	}

	hexBytes.size = length;
	/* add new value to deferred cleanup list */
	_hdeferList[_hdeferListIndex++] = hexBytes;
	return hexBytes;
}

static span_t _fromHexString(const char* hexLiteral, uint32_t strLen)
{
	span_t hexBytes;
	size_t i;

	if(!hexLiteral)
	{
		return hexBytes;
	}

	/* alloc the raw bytes */
	hexBytes = __allocHexBytes(strLen);

	/* read every 2 chars into  */
	for (i = 0; i < strLen; i += 2)
	{
		/* slice string into smaller 2 char strings then parse */
		char byteString[3] = { '\0' };

		byteString[0] = hexLiteral[i];
		byteString[1] = hexLiteral[i + 1];

		hexBytes.data[i / 2] = (uint8_t)strtol(byteString, NULL, 16);
	}
	
	return hexBytes;
}

/*
	Frees all the span_t that were allocated by the 
	FromHexString function. To be called at the end of 
	the program.
*/
static void FreeHexBytes(void)
{
	while(_hdeferListIndex > 0)
	{
		free(_hdeferList[--_hdeferListIndex].data);
		memset(&_hdeferList[_hdeferListIndex], 0, sizeof(span_t));
	}
}

/*
* Prints the value of the buffer as a hexadecimal string
* @param bytes The buffer to print
* @param len The length of the buffer
*/
static void PrintHexRaw(void* bytes, size_t len)
{
	size_t i;
	for (i = 0; i < len; i++)
	{
		printf("%02x", ((uint8_t*)bytes)[i]);
	}

	puts("\n");
}

/*
* Prints the value of the span_t as a hexadecimal string
* @param hexBytes A pointer to the span_t structure to print the value of
*/
static void PrintHexBytes(span_t hexBytes)
{
	if (!hexBytes.data)
	{
		puts("NULL");
	}
	else
	{
		PrintHexRaw(hexBytes.data, hexBytes.size);
	}
}


#endif /* !HEX_HELPERS_H */