Add `gnutls/dtls.h' to the distribution.
[gnutls.git] / lib / gnutls_num.c
blob46467d5d8e1e428f8010a8e60ce9b8700dccf50d
1 /*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2010 Free
3 * Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22 * USA
26 /* This file contains the functions needed for 64 bit integer support in
27 * TLS, and functions which ease the access to TLS vectors (data of given size).
30 #include <gnutls_int.h>
31 #include <gnutls_num.h>
32 #include <gnutls_errors.h>
34 #include <byteswap.h>
36 /* This function will add one to uint64 x.
37 * Returns 0 on success, or -1 if the uint64 max limit
38 * has been reached.
40 int
41 _gnutls_uint64pp (uint64 * x)
43 register int i, y = 0;
45 for (i = 7; i >= 0; i--)
47 y = 0;
48 if (x->i[i] == 0xff)
50 x->i[i] = 0;
51 y = 1;
53 else
54 x->i[i]++;
56 if (y == 0)
57 break;
59 if (y != 0)
60 return -1; /* over 64 bits! WOW */
62 return 0;
65 /* This function will add one to uint48 x.
66 * Returns 0 on success, or -1 if the uint48 max limit
67 * has been reached.
69 int
70 _gnutls_uint48pp (uint64 * x)
72 register int i, y = 0;
74 for (i = 7; i >= 3; i--)
76 y = 0;
77 if (x->i[i] == 0xff)
79 x->i[i] = 0;
80 y = 1;
82 else
83 x->i[i]++;
85 if (y == 0)
86 break;
88 if (y != 0)
89 return -1; /* over 48 bits */
91 return 0;
94 uint32_t
95 _gnutls_uint24touint32 (uint24 num)
97 uint32_t ret = 0;
99 ((uint8_t *) & ret)[1] = num.pint[0];
100 ((uint8_t *) & ret)[2] = num.pint[1];
101 ((uint8_t *) & ret)[3] = num.pint[2];
102 return ret;
105 uint24
106 _gnutls_uint32touint24 (uint32_t num)
108 uint24 ret;
110 ret.pint[0] = ((uint8_t *) & num)[1];
111 ret.pint[1] = ((uint8_t *) & num)[2];
112 ret.pint[2] = ((uint8_t *) & num)[3];
113 return ret;
117 /* data should be at least 3 bytes */
118 uint32_t
119 _gnutls_read_uint24 (const opaque * data)
121 uint32_t res;
122 uint24 num;
124 num.pint[0] = data[0];
125 num.pint[1] = data[1];
126 num.pint[2] = data[2];
128 res = _gnutls_uint24touint32 (num);
129 #ifndef WORDS_BIGENDIAN
130 res = bswap_32 (res);
131 #endif
132 return res;
135 void
136 _gnutls_write_uint24 (uint32_t num, opaque * data)
138 uint24 tmp;
140 #ifndef WORDS_BIGENDIAN
141 num = bswap_32 (num);
142 #endif
143 tmp = _gnutls_uint32touint24 (num);
145 data[0] = tmp.pint[0];
146 data[1] = tmp.pint[1];
147 data[2] = tmp.pint[2];
150 uint32_t
151 _gnutls_read_uint32 (const opaque * data)
153 uint32_t res;
155 memcpy (&res, data, sizeof (uint32_t));
156 #ifndef WORDS_BIGENDIAN
157 res = bswap_32 (res);
158 #endif
159 return res;
162 void
163 _gnutls_write_uint32 (uint32_t num, opaque * data)
166 #ifndef WORDS_BIGENDIAN
167 num = bswap_32 (num);
168 #endif
169 memcpy (data, &num, sizeof (uint32_t));
172 uint16_t
173 _gnutls_read_uint16 (const opaque * data)
175 uint16_t res;
176 memcpy (&res, data, sizeof (uint16_t));
177 #ifndef WORDS_BIGENDIAN
178 res = bswap_16 (res);
179 #endif
180 return res;
183 void
184 _gnutls_write_uint16 (uint16_t num, opaque * data)
187 #ifndef WORDS_BIGENDIAN
188 num = bswap_16 (num);
189 #endif
190 memcpy (data, &num, sizeof (uint16_t));
193 uint32_t
194 _gnutls_conv_uint32 (uint32_t data)
196 #ifndef WORDS_BIGENDIAN
197 return bswap_32 (data);
198 #else
199 return data;
200 #endif
203 uint16_t
204 _gnutls_conv_uint16 (uint16_t data)
206 #ifndef WORDS_BIGENDIAN
207 return bswap_16 (data);
208 #else
209 return data;
210 #endif
213 uint32_t
214 _gnutls_uint64touint32 (const uint64 * num)
216 uint32_t ret;
218 memcpy (&ret, &num->i[4], 4);
219 #ifndef WORDS_BIGENDIAN
220 ret = bswap_32 (ret);
221 #endif
223 return ret;