add packaging
[platform/upstream/nettle.git] / base16-decode.c
1 /* base16-encode.c
2  *
3  * Hex decoding.
4  */
5
6 /* nettle, low-level cryptographics library
7  *
8  * Copyright (C) 2002 Niels Möller
9  *  
10  * The nettle library is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation; either version 2.1 of the License, or (at your
13  * option) any later version.
14  * 
15  * The nettle library is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
18  * License for more details.
19  * 
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with the nettle library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23  * MA 02111-1301, USA.
24  */
25  
26 #if HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <assert.h>
31 #include <stdlib.h>
32
33 #include "base16.h"
34
35 void
36 base16_decode_init(struct base16_decode_ctx *ctx)
37 {
38   ctx->word = ctx->bits = 0;
39 }
40
41 enum { HEX_INVALID = -1, HEX_SPACE=-2 };
42
43 static const signed char
44 hex_decode_table[0x80] =
45   {
46     -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -1, -1, -2, -1, -1, 
47     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
48     -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
49      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
50     -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
51     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
52     -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
53     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
54   };
55
56 /* Decodes a single byte. Returns amount of output (0 or 1), or -1 on
57  * errors. */
58 int
59 base16_decode_single(struct base16_decode_ctx *ctx,
60                      uint8_t *dst,
61                      uint8_t src)
62 {
63   int digit;
64
65   if (src >= 0x80)
66     return -1;
67
68   digit = hex_decode_table[src];
69   switch (digit)
70     {
71     case -1:
72       return -1;
73     case -2:
74       return 0;
75     default:
76       assert(digit >= 0);
77       assert(digit < 0x10);
78
79       if (ctx->bits)
80         {
81           *dst = (ctx->word << 4) | digit;
82           ctx->bits = 0;
83           return 1;
84         }
85       else
86         {
87           ctx->word = digit;
88           ctx->bits = 4;
89           return 0;
90         }
91     }
92 }
93
94 int
95 base16_decode_update(struct base16_decode_ctx *ctx,
96                      unsigned *dst_length,
97                      uint8_t *dst,
98                      unsigned src_length,
99                      const uint8_t *src)
100 {
101   unsigned done;
102   unsigned i;
103
104   assert(*dst_length >= BASE16_DECODE_LENGTH(src_length));
105   
106   for (i = 0, done = 0; i<src_length; i++)
107     switch(base16_decode_single(ctx, dst + done, src[i]))
108       {
109       case -1:
110         return 0;
111       case 1:
112         done++;
113         /* Fall through */
114       case 0:
115         break;
116       default:
117         abort();
118       }
119   
120   assert(done <= BASE16_DECODE_LENGTH(src_length));
121
122   *dst_length = done;
123   return 1;
124 }
125
126 int
127 base16_decode_final(struct base16_decode_ctx *ctx)
128 {
129   return ctx->bits == 0;
130 }