documented fix
[gnutls.git] / lib / gnutls_num.c
blob6c7d968e632fa80025a714e785b51fab8a651c12
1 /*
2 * Copyright (C) 2000-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* This file contains the functions needed for 64 bit integer support in
24 * TLS, and functions which ease the access to TLS vectors (data of given size).
27 #include <gnutls_int.h>
28 #include <gnutls_num.h>
29 #include <gnutls_errors.h>
31 #include <byteswap.h>
33 /* This function will add one to uint64 x.
34 * Returns 0 on success, or -1 if the uint64 max limit
35 * has been reached.
37 int
38 _gnutls_uint64pp (uint64 * x)
40 register int i, y = 0;
42 for (i = 7; i >= 0; i--)
44 y = 0;
45 if (x->i[i] == 0xff)
47 x->i[i] = 0;
48 y = 1;
50 else
51 x->i[i]++;
53 if (y == 0)
54 break;
56 if (y != 0)
57 return -1; /* over 64 bits! WOW */
59 return 0;
62 /* This function will add one to uint48 x.
63 * Returns 0 on success, or -1 if the uint48 max limit
64 * has been reached.
66 int
67 _gnutls_uint48pp (uint64 * x)
69 register int i, y = 0;
71 for (i = 7; i >= 3; i--)
73 y = 0;
74 if (x->i[i] == 0xff)
76 x->i[i] = 0;
77 y = 1;
79 else
80 x->i[i]++;
82 if (y == 0)
83 break;
85 if (y != 0)
86 return -1; /* over 48 bits */
88 return 0;
91 uint32_t
92 _gnutls_uint24touint32 (uint24 num)
94 uint32_t ret = 0;
96 ((uint8_t *) & ret)[1] = num.pint[0];
97 ((uint8_t *) & ret)[2] = num.pint[1];
98 ((uint8_t *) & ret)[3] = num.pint[2];
99 return ret;
102 uint24
103 _gnutls_uint32touint24 (uint32_t num)
105 uint24 ret;
107 ret.pint[0] = ((uint8_t *) & num)[1];
108 ret.pint[1] = ((uint8_t *) & num)[2];
109 ret.pint[2] = ((uint8_t *) & num)[3];
110 return ret;
114 /* data should be at least 3 bytes */
115 uint32_t
116 _gnutls_read_uint24 (const uint8_t * data)
118 uint32_t res;
119 uint24 num;
121 num.pint[0] = data[0];
122 num.pint[1] = data[1];
123 num.pint[2] = data[2];
125 res = _gnutls_uint24touint32 (num);
126 #ifndef WORDS_BIGENDIAN
127 res = bswap_32 (res);
128 #endif
129 return res;
132 void
133 _gnutls_write_uint64 (uint64_t num, uint8_t * data)
135 #ifndef WORDS_BIGENDIAN
136 num = bswap_64 (num);
137 #endif
138 memcpy(data, &num, 8);
141 void
142 _gnutls_write_uint24 (uint32_t num, uint8_t * data)
144 uint24 tmp;
146 #ifndef WORDS_BIGENDIAN
147 num = bswap_32 (num);
148 #endif
149 tmp = _gnutls_uint32touint24 (num);
151 data[0] = tmp.pint[0];
152 data[1] = tmp.pint[1];
153 data[2] = tmp.pint[2];
156 uint32_t
157 _gnutls_read_uint32 (const uint8_t * data)
159 uint32_t res;
161 memcpy (&res, data, sizeof (uint32_t));
162 #ifndef WORDS_BIGENDIAN
163 res = bswap_32 (res);
164 #endif
165 return res;
168 void
169 _gnutls_write_uint32 (uint32_t num, uint8_t * data)
172 #ifndef WORDS_BIGENDIAN
173 num = bswap_32 (num);
174 #endif
175 memcpy (data, &num, sizeof (uint32_t));
178 uint16_t
179 _gnutls_read_uint16 (const uint8_t * data)
181 uint16_t res;
182 memcpy (&res, data, sizeof (uint16_t));
183 #ifndef WORDS_BIGENDIAN
184 res = bswap_16 (res);
185 #endif
186 return res;
189 void
190 _gnutls_write_uint16 (uint16_t num, uint8_t * data)
193 #ifndef WORDS_BIGENDIAN
194 num = bswap_16 (num);
195 #endif
196 memcpy (data, &num, sizeof (uint16_t));
199 uint32_t
200 _gnutls_conv_uint32 (uint32_t data)
202 #ifndef WORDS_BIGENDIAN
203 return bswap_32 (data);
204 #else
205 return data;
206 #endif
209 uint16_t
210 _gnutls_conv_uint16 (uint16_t data)
212 #ifndef WORDS_BIGENDIAN
213 return bswap_16 (data);
214 #else
215 return data;
216 #endif
219 uint32_t
220 _gnutls_uint64touint32 (const uint64 * num)
222 uint32_t ret;
224 memcpy (&ret, &num->i[4], 4);
225 #ifndef WORDS_BIGENDIAN
226 ret = bswap_32 (ret);
227 #endif
229 return ret;