Tizen 2.0 Release
[external/libgnutls26.git] / lib / gnutls_num.c
1 /*
2  * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2010 Free
3  * Software Foundation, Inc.
4  *
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This file is part of GnuTLS.
8  *
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.
13  *
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.
18  *
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
23  *
24  */
25
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).
28  */
29
30 #include <gnutls_int.h>
31 #include <gnutls_num.h>
32 #include <gnutls_errors.h>
33
34 #include <byteswap.h>
35
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.
39  */
40 int
41 _gnutls_uint64pp (uint64 * x)
42 {
43   register int i, y = 0;
44
45   for (i = 7; i >= 0; i--)
46     {
47       y = 0;
48       if (x->i[i] == 0xff)
49         {
50           x->i[i] = 0;
51           y = 1;
52         }
53       else
54         x->i[i]++;
55
56       if (y == 0)
57         break;
58     }
59   if (y != 0)
60     return -1;                  /* over 64 bits! WOW */
61
62   return 0;
63 }
64
65 uint32_t
66 _gnutls_uint24touint32 (uint24 num)
67 {
68   uint32_t ret = 0;
69
70   ((uint8_t *) & ret)[1] = num.pint[0];
71   ((uint8_t *) & ret)[2] = num.pint[1];
72   ((uint8_t *) & ret)[3] = num.pint[2];
73   return ret;
74 }
75
76 uint24
77 _gnutls_uint32touint24 (uint32_t num)
78 {
79   uint24 ret;
80
81   ret.pint[0] = ((uint8_t *) & num)[1];
82   ret.pint[1] = ((uint8_t *) & num)[2];
83   ret.pint[2] = ((uint8_t *) & num)[3];
84   return ret;
85
86 }
87
88 /* data should be at least 3 bytes */
89 uint32_t
90 _gnutls_read_uint24 (const opaque * data)
91 {
92   uint32_t res;
93   uint24 num;
94
95   num.pint[0] = data[0];
96   num.pint[1] = data[1];
97   num.pint[2] = data[2];
98
99   res = _gnutls_uint24touint32 (num);
100 #ifndef WORDS_BIGENDIAN
101   res = bswap_32 (res);
102 #endif
103   return res;
104 }
105
106 void
107 _gnutls_write_uint24 (uint32_t num, opaque * data)
108 {
109   uint24 tmp;
110
111 #ifndef WORDS_BIGENDIAN
112   num = bswap_32 (num);
113 #endif
114   tmp = _gnutls_uint32touint24 (num);
115
116   data[0] = tmp.pint[0];
117   data[1] = tmp.pint[1];
118   data[2] = tmp.pint[2];
119 }
120
121 uint32_t
122 _gnutls_read_uint32 (const opaque * data)
123 {
124   uint32_t res;
125
126   memcpy (&res, data, sizeof (uint32_t));
127 #ifndef WORDS_BIGENDIAN
128   res = bswap_32 (res);
129 #endif
130   return res;
131 }
132
133 void
134 _gnutls_write_uint32 (uint32_t num, opaque * data)
135 {
136
137 #ifndef WORDS_BIGENDIAN
138   num = bswap_32 (num);
139 #endif
140   memcpy (data, &num, sizeof (uint32_t));
141 }
142
143 uint16_t
144 _gnutls_read_uint16 (const opaque * data)
145 {
146   uint16_t res;
147   memcpy (&res, data, sizeof (uint16_t));
148 #ifndef WORDS_BIGENDIAN
149   res = bswap_16 (res);
150 #endif
151   return res;
152 }
153
154 void
155 _gnutls_write_uint16 (uint16_t num, opaque * data)
156 {
157
158 #ifndef WORDS_BIGENDIAN
159   num = bswap_16 (num);
160 #endif
161   memcpy (data, &num, sizeof (uint16_t));
162 }
163
164 uint32_t
165 _gnutls_conv_uint32 (uint32_t data)
166 {
167 #ifndef WORDS_BIGENDIAN
168   return bswap_32 (data);
169 #else
170   return data;
171 #endif
172 }
173
174 uint16_t
175 _gnutls_conv_uint16 (uint16_t data)
176 {
177 #ifndef WORDS_BIGENDIAN
178   return bswap_16 (data);
179 #else
180   return data;
181 #endif
182 }
183
184 uint32_t
185 _gnutls_uint64touint32 (const uint64 * num)
186 {
187   uint32_t ret;
188
189   memcpy (&ret, &num->i[4], 4);
190 #ifndef WORDS_BIGENDIAN
191   ret = bswap_32 (ret);
192 #endif
193
194   return ret;
195 }