iPXE
base16.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <stdint.h>
27 #include <stdio.h>
28 #include <errno.h>
29 #include <assert.h>
30 #include <ipxe/string.h>
31 #include <ipxe/vsprintf.h>
32 #include <ipxe/base16.h>
33 
34 /** @file
35  *
36  * Base16 encoding
37  *
38  */
39 
40 /**
41  * Encode hexadecimal string (with optional byte separator character)
42  *
43  * @v separator Byte separator character, or 0 for no separator
44  * @v raw Raw data
45  * @v raw_len Length of raw data
46  * @v data Buffer
47  * @v len Length of buffer
48  * @ret len Encoded length
49  */
50 size_t hex_encode ( char separator, const void *raw, size_t raw_len,
51  char *data, size_t len ) {
52  const uint8_t *bytes = raw;
53  const char delimiter[2] = { separator, '\0' };
54  size_t used = 0;
55  unsigned int i;
56 
57  if ( len )
58  data[0] = 0; /* Ensure that a terminating NUL exists */
59  for ( i = 0 ; i < raw_len ; i++ ) {
60  used += ssnprintf ( ( data + used ), ( len - used ),
61  "%s%02x", ( used ? delimiter : "" ),
62  bytes[i] );
63  }
64  return used;
65 }
66 
67 /**
68  * Decode hexadecimal string (with optional byte separator character)
69  *
70  * @v separator Byte separator character, or 0 for no separator
71  * @v encoded Encoded string
72  * @v data Buffer
73  * @v len Length of buffer
74  * @ret len Length of data, or negative error
75  */
76 int hex_decode ( char separator, const char *encoded, void *data, size_t len ) {
77  uint8_t *out = data;
78  unsigned int count = 0;
79  unsigned int sixteens;
80  unsigned int units;
81  int optional;
82 
83  /* Strip out optionality flag from separator character */
84  optional = ( separator & HEX_DECODE_OPTIONAL );
85  separator &= ~HEX_DECODE_OPTIONAL;
86 
87  /* Decode string */
88  while ( *encoded ) {
89 
90  /* Check separator, if applicable */
91  if ( count && separator ) {
92  if ( *encoded == separator ) {
93  encoded++;
94  } else if ( ! optional ) {
95  return -EINVAL;
96  }
97  }
98 
99  /* Extract digits. Note that either digit may be NUL,
100  * which would be interpreted as an invalid value by
101  * digit_value(); there is therefore no need for an
102  * explicit end-of-string check.
103  */
104  sixteens = digit_value ( *(encoded++) );
105  if ( sixteens >= 16 )
106  return -EINVAL;
107  units = digit_value ( *(encoded++) );
108  if ( units >= 16 )
109  return -EINVAL;
110 
111  /* Store result */
112  if ( count < len )
113  out[count] = ( ( sixteens << 4 ) | units );
114  count++;
115 
116  }
117  return count;
118 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
Error codes.
printf() and friends
unsigned int digit_value(unsigned int character)
Calculate digit value.
Definition: string.c:413
__be32 out[4]
Definition: CIB_PRM.h:36
int ssnprintf(char *buf, ssize_t ssize, const char *fmt,...)
Version of vsnprintf() that accepts a signed buffer size.
Definition: vsprintf.c:420
Assertions.
#define HEX_DECODE_OPTIONAL
Treat separator as optional while decoding.
Definition: base16.h:16
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
int hex_decode(char separator, const char *encoded, void *data, size_t len)
Decode hexadecimal string (with optional byte separator character)
Definition: base16.c:76
static size_t raw_len
Definition: base16.h:53
unsigned char uint8_t
Definition: stdint.h:10
size_t hex_encode(char separator, const void *raw, size_t raw_len, char *data, size_t len)
Encode hexadecimal string (with optional byte separator character)
Definition: base16.c:50
uint32_t len
Length.
Definition: ena.h:14
uint16_t count
Number of entries.
Definition: ena.h:22
uint8_t data[48]
Additional event data.
Definition: ena.h:22
__be32 raw[7]
Definition: CIB_PRM.h:28
uint8_t bytes[64]
Definition: ib_mad.h:16
String functions.
Base16 encoding.