FreeTDS API: include/freetds/bytes.h Source File

FreeTDS API

Loading...
Searching...
No Matches
bytes.h
1/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
2 * Copyright (C) 2005-2008 Frediano Ziglio
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20#ifndef _tdsguard_eO1lgptMUEXAnSnm4l3QiK_
21#define _tdsguard_eO1lgptMUEXAnSnm4l3QiK_
22
23/*
24 * read a word of n bytes aligned, architecture dependent endian
25 * TDS_GET_An
26 * read a word of n bytes aligned, little endian
27 * TDS_GET_AnLE
28 * read a word of n bytes aligned, big endian
29 * TDS_GET_AnBE
30 * read a word of n bytes unaligned, architecture dependent endian
31 * TDS_GET_UAn
32 * read a word of n bytes unaligned, little endian
33 * TDS_GET_UAnLE
34 * read a word of n bytes unaligned, big endian
35 * TDS_GET_UAnBE
36 */
37
38/* one byte, easy... */
39#define TDS_GET_A1LE(ptr) (((uint8_t *)(ptr))[0])
40#define TDS_GET_A1BE(ptr) TDS_GET_A1LE(ptr)
41#define TDS_GET_UA1LE(ptr) TDS_GET_A1LE(ptr)
42#define TDS_GET_UA1BE(ptr) TDS_GET_A1LE(ptr)
43
44#define TDS_PUT_A1LE(ptr,val) do { ((uint8_t *)(ptr))[0] = (val); } while(0)
45#define TDS_PUT_A1BE(ptr,val) TDS_PUT_A1LE(ptr,val)
46#define TDS_PUT_UA1LE(ptr,val) TDS_PUT_A1LE(ptr,val)
47#define TDS_PUT_UA1BE(ptr,val) TDS_PUT_A1LE(ptr,val)
48
49/* two bytes */
50#define TDS_GET_UA2LE(ptr) (((uint8_t *)(ptr))[1] * 0x100u + ((uint8_t *)(ptr))[0])
51#define TDS_GET_UA2BE(ptr) (((uint8_t *)(ptr))[0] * 0x100u + ((uint8_t *)(ptr))[1])
52#define TDS_GET_A2LE(ptr) TDS_GET_UA2LE(ptr)
53#define TDS_GET_A2BE(ptr) TDS_GET_UA2BE(ptr)
54
55#define TDS_PUT_UA2LE(ptr,val) do {\
56 ((uint8_t *)(ptr))[1] = (uint8_t)((val)>>8); ((uint8_t *)(ptr))[0] = (uint8_t)(val); } while(0)
57#define TDS_PUT_UA2BE(ptr,val) do {\
58 ((uint8_t *)(ptr))[0] = (uint8_t)((val)>>8); ((uint8_t *)(ptr))[1] = (uint8_t)(val); } while(0)
59#define TDS_PUT_A2LE(ptr,val) TDS_PUT_UA2LE(ptr,val)
60#define TDS_PUT_A2BE(ptr,val) TDS_PUT_UA2BE(ptr,val)
61
62/* four bytes */
63#define TDS_GET_UA4LE(ptr) \
64 (((uint8_t *)(ptr))[3] * 0x1000000u + ((uint8_t *)(ptr))[2] * 0x10000u +\
65 ((uint8_t *)(ptr))[1] * 0x100u + ((uint8_t *)(ptr))[0])
66#define TDS_GET_UA4BE(ptr) \
67 (((uint8_t *)(ptr))[0] * 0x1000000u + ((uint8_t *)(ptr))[1] * 0x10000u +\
68 ((uint8_t *)(ptr))[2] * 0x100u + ((uint8_t *)(ptr))[3])
69#define TDS_GET_A4LE(ptr) TDS_GET_UA4LE(ptr)
70#define TDS_GET_A4BE(ptr) TDS_GET_UA4BE(ptr)
71
72#define TDS_PUT_UA4LE(ptr,val) do {\
73 ((uint8_t *)(ptr))[3] = (uint8_t)((val)>>24); ((uint8_t *)(ptr))[2] = (uint8_t)((val)>>16);\
74 ((uint8_t *)(ptr))[1] = (uint8_t)((val)>>8); ((uint8_t *)(ptr))[0] = (uint8_t)(val); } while(0)
75#define TDS_PUT_UA4BE(ptr,val) do {\
76 ((uint8_t *)(ptr))[0] = (uint8_t)((val)>>24); ((uint8_t *)(ptr))[1] = (uint8_t)((val)>>16);\
77 ((uint8_t *)(ptr))[2] = (uint8_t)((val)>>8); ((uint8_t *)(ptr))[3] = (uint8_t)(val); } while(0)
78#define TDS_PUT_A4LE(ptr,val) TDS_PUT_UA4LE(ptr,val)
79#define TDS_PUT_A4BE(ptr,val) TDS_PUT_UA4BE(ptr,val)
80
81#if defined(__GNUC__)
82# define TDS_MAY_ALIAS __attribute__((__may_alias__))
83#else
84# define TDS_MAY_ALIAS
85#endif
86
87 typedef union {
88 uint16_t usi;
89 uint8_t uc[2];
90} TDS_MAY_ALIAS TDS_BYTE_CONVERT2;
91
92typedef union {
93 uint32_t ui;
94 uint8_t uc[4];
95} TDS_MAY_ALIAS TDS_BYTE_CONVERT4;
96
97/* architecture dependent */
98/* map to generic macros or redefine for aligned and same endianess */
99#ifdef WORDS_BIGENDIAN
100# define TDS_GET_A1(ptr) TDS_GET_A1BE(ptr)
101# define TDS_GET_UA1(ptr) TDS_GET_UA1BE(ptr)
102# define TDS_GET_A2(ptr) TDS_GET_A2BE(ptr)
103# define TDS_GET_UA2(ptr) TDS_GET_UA2BE(ptr)
104# define TDS_GET_A4(ptr) TDS_GET_A4BE(ptr)
105# define TDS_GET_UA4(ptr) TDS_GET_UA4BE(ptr)
106# undef TDS_GET_A2BE
107# undef TDS_GET_A4BE
108# define TDS_GET_A2BE(ptr) (((TDS_BYTE_CONVERT2*)(ptr))->usi)
109# define TDS_GET_A4BE(ptr) (((TDS_BYTE_CONVERT4*)(ptr))->ui)
110
111# define TDS_PUT_A1(ptr,val) TDS_PUT_A1BE(ptr,val)
112# define TDS_PUT_UA1(ptr,val) TDS_PUT_UA1BE(ptr,val)
113# define TDS_PUT_A2(ptr,val) TDS_PUT_A2BE(ptr,val)
114# define TDS_PUT_UA2(ptr,val) TDS_PUT_UA2BE(ptr,val)
115# define TDS_PUT_A4(ptr,val) TDS_PUT_A4BE(ptr,val)
116# define TDS_PUT_UA4(ptr,val) TDS_PUT_UA4BE(ptr,val)
117# undef TDS_PUT_A2BE
118# undef TDS_PUT_A4BE
119# define TDS_PUT_A2BE(ptr,val) (((TDS_BYTE_CONVERT2*)(ptr))->usi = (val))
120# define TDS_PUT_A4BE(ptr,val) (((TDS_BYTE_CONVERT4*)(ptr))->ui = (val))
121# define TDS_HOST2LE(val) TDS_BYTE_SWAP16(val)
122# define TDS_HOST4LE(val) TDS_BYTE_SWAP32(val)
123# define TDS_HOST2BE(val) (val)
124# define TDS_HOST4BE(val) (val)
125#else
126# define TDS_GET_A1(ptr) TDS_GET_A1LE(ptr)
127# define TDS_GET_UA1(ptr) TDS_GET_UA1LE(ptr)
128# define TDS_GET_A2(ptr) TDS_GET_A2LE(ptr)
129# define TDS_GET_UA2(ptr) TDS_GET_UA2LE(ptr)
130# define TDS_GET_A4(ptr) TDS_GET_A4LE(ptr)
131# define TDS_GET_UA4(ptr) TDS_GET_UA4LE(ptr)
132# undef TDS_GET_A2LE
133# undef TDS_GET_A4LE
134# define TDS_GET_A2LE(ptr) (((TDS_BYTE_CONVERT2*)(ptr))->usi)
135# define TDS_GET_A4LE(ptr) (((TDS_BYTE_CONVERT4*)(ptr))->ui)
136
137# define TDS_PUT_A1(ptr,val) TDS_PUT_A1LE(ptr,val)
138# define TDS_PUT_UA1(ptr,val) TDS_PUT_UA1LE(ptr,val)
139# define TDS_PUT_A2(ptr,val) TDS_PUT_A2LE(ptr,val)
140# define TDS_PUT_UA2(ptr,val) TDS_PUT_UA2LE(ptr,val)
141# define TDS_PUT_A4(ptr,val) TDS_PUT_A4LE(ptr,val)
142# define TDS_PUT_UA4(ptr,val) TDS_PUT_UA4LE(ptr,val)
143# undef TDS_PUT_A2LE
144# undef TDS_PUT_A4LE
145# define TDS_PUT_A2LE(ptr,val) (((TDS_BYTE_CONVERT2*)(ptr))->usi = (val))
146# define TDS_PUT_A4LE(ptr,val) (((TDS_BYTE_CONVERT4*)(ptr))->ui = (val))
147# define TDS_HOST2LE(val) (val)
148# define TDS_HOST4LE(val) (val)
149# define TDS_HOST2BE(val) TDS_BYTE_SWAP16(val)
150# define TDS_HOST4BE(val) TDS_BYTE_SWAP32(val)
151#endif
152
153#if defined(__GNUC__) || defined(_MSC_VER)
154# if defined(__MINGW32__)
155# pragma pack(push,1)
156# elif defined(_MSC_VER)
157# pragma pack(push)
158# pragma pack(1)
159# endif
160
161# if defined(__GNUC__)
162# define TDS_PACKED __attribute__((__packed__))
163# else
164# define TDS_PACKED
165# endif
166
167typedef union TDS_PACKED
168{
169 uint16_t usi;
170 uint8_t uc[2];
171} TDS_MAY_ALIAS TDS_UNALIGNED_BYTE_CONVERT2;
172
173typedef union TDS_PACKED
174{
175 uint32_t ui;
176 uint8_t uc[4];
177} TDS_MAY_ALIAS TDS_UNALIGNED_BYTE_CONVERT4;
178
179# ifdef WORDS_BIGENDIAN
180# undef TDS_GET_UA2BE
181# undef TDS_GET_UA4BE
182# define TDS_GET_UA2BE(ptr) (((TDS_UNALIGNED_BYTE_CONVERT2*)(ptr))->usi)
183# define TDS_GET_UA4BE(ptr) (((TDS_UNALIGNED_BYTE_CONVERT4*)(ptr))->ui)
184
185# undef TDS_PUT_UA2BE
186# undef TDS_PUT_UA4BE
187# define TDS_PUT_UA2BE(ptr,val) (((TDS_UNALIGNED_BYTE_CONVERT2*)(ptr))->usi = (val))
188# define TDS_PUT_UA4BE(ptr,val) (((TDS_UNALIGNED_BYTE_CONVERT4*)(ptr))->ui = (val))
189# else
190# undef TDS_GET_UA2LE
191# undef TDS_GET_UA4LE
192# define TDS_GET_UA2LE(ptr) (((TDS_UNALIGNED_BYTE_CONVERT2*)(ptr))->usi)
193# define TDS_GET_UA4LE(ptr) (((TDS_UNALIGNED_BYTE_CONVERT4*)(ptr))->ui)
194
195# undef TDS_PUT_UA2LE
196# undef TDS_PUT_UA4LE
197# define TDS_PUT_UA2LE(ptr,val) (((TDS_UNALIGNED_BYTE_CONVERT2*)(ptr))->usi = (val))
198# define TDS_PUT_UA4LE(ptr,val) (((TDS_UNALIGNED_BYTE_CONVERT4*)(ptr))->ui = (val))
199# endif
200
201# if defined(__MINGW32__) || defined(_MSC_VER)
202# pragma pack(pop)
203# endif
204
205#else
206
207/* these platform support unaligned fetch/store */
208/* map unaligned macro to aligned ones */
209# if defined(__i386__) || defined(__amd64__) || defined(__CRIS__) ||\
210 defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || defined(__ppc64__) ||\
211 defined(__s390__) || defined(__s390x__) || defined(__m68k__) ||\
212 (defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_IX86) || defined(_M_X64))) ||\
213 defined(__ARM_FEATURE_UNALIGNED) ||\
214 defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_8__) ||\
215 (defined(_M_ARM) && (_M_ARM >= 7))
216# ifdef WORDS_BIGENDIAN
217# undef TDS_GET_UA2BE
218# undef TDS_GET_UA4BE
219# define TDS_GET_UA2BE(ptr) TDS_GET_A2BE(ptr)
220# define TDS_GET_UA4BE(ptr) TDS_GET_A4BE(ptr)
221
222# undef TDS_PUT_UA2BE
223# undef TDS_PUT_UA4BE
224# define TDS_PUT_UA2BE(ptr,val) TDS_PUT_A2BE(ptr,val)
225# define TDS_PUT_UA4BE(ptr,val) TDS_PUT_A4BE(ptr,val)
226# else
227# undef TDS_GET_UA2LE
228# undef TDS_GET_UA4LE
229# define TDS_GET_UA2LE(ptr) TDS_GET_A2LE(ptr)
230# define TDS_GET_UA4LE(ptr) TDS_GET_A4LE(ptr)
231
232# undef TDS_PUT_UA2LE
233# undef TDS_PUT_UA4LE
234# define TDS_PUT_UA2LE(ptr,val) TDS_PUT_A2LE(ptr,val)
235# define TDS_PUT_UA4LE(ptr,val) TDS_PUT_A4LE(ptr,val)
236# endif
237# endif
238
239#endif
240
241#undef TDS_BSWAP16
242#undef TDS_BSWAP32
243/* __builtin_bswap16 was introduced in GCC 4.8 */
244#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) && defined(__OPTIMIZE__)
245# define TDS_BSWAP16(val) __builtin_bswap16(val)
246# define TDS_BSWAP32(val) __builtin_bswap32(val)
247/* __builtin_bswap32 was introduced in GCC 4.3 */
248#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && defined(__OPTIMIZE__)
249# define TDS_BSWAP32(val) __builtin_bswap32(val)
250#elif defined(_MSC_VER)
251# include <stdlib.h>
252# define TDS_BSWAP16(val) _byteswap_ushort(val)
253# define TDS_BSWAP32(val) _byteswap_ulong(val)
254#endif
255
256#if defined(TDS_BSWAP16) && !defined(WORDS_BIGENDIAN)
257# undef TDS_GET_UA2BE
258# define TDS_GET_UA2BE(ptr) TDS_BSWAP16(TDS_GET_UA2LE(ptr))
259
260# undef TDS_PUT_UA2BE
261# define TDS_PUT_UA2BE(ptr,val) do {\
262 uint16_t _tds_si = TDS_BSWAP16(val); TDS_PUT_UA2LE(ptr,_tds_si); } while(0)
263#elif defined(TDS_BSWAP16) && defined(WORDS_BIGENDIAN)
264# undef TDS_GET_UA2LE
265# define TDS_GET_UA2LE(ptr) TDS_BSWAP16(TDS_GET_UA2BE(ptr))
266
267# undef TDS_PUT_UA2LE
268# define TDS_PUT_UA2LE(ptr,val) do {\
269 uint16_t _tds_si = TDS_BSWAP16(val); TDS_PUT_UA2BE(ptr,_tds_si); } while(0)
270#endif
271
272#if defined(TDS_BSWAP32) && !defined(WORDS_BIGENDIAN)
273# undef TDS_GET_UA4BE
274# define TDS_GET_UA4BE(ptr) TDS_BSWAP32(TDS_GET_UA4LE(ptr))
275
276# undef TDS_PUT_UA4BE
277# define TDS_PUT_UA4BE(ptr,val) do {\
278 uint32_t _tds_i = TDS_BSWAP32(val); TDS_PUT_UA4LE(ptr,_tds_i); } while(0)
279#elif defined(TDS_BSWAP32) && defined(WORDS_BIGENDIAN)
280# undef TDS_GET_UA4LE
281# define TDS_GET_UA4LE(ptr) TDS_BSWAP32(TDS_GET_UA4BE(ptr))
282
283# undef TDS_PUT_UA4LE
284# define TDS_PUT_UA4LE(ptr,val) do {\
285 uint32_t _tds_i = TDS_BSWAP32(val); TDS_PUT_UA4BE(ptr,_tds_i); } while(0)
286#endif
287
288#if defined(__GNUC__) && defined(__powerpc__) && defined(WORDS_BIGENDIAN)
289# undef TDS_GET_UA2LE
290# undef TDS_GET_UA4LE
291static inline uint16_t
292TDS_GET_UA2LE(void *ptr)
293{
294 unsigned long res;
295 __asm__ ("lhbrx %0,0,%1\n" : "=r" (res) : "r" (ptr), "m"(*(uint16_t *)ptr));
296 return (uint16_t) res;
297}
298static inline uint32_t
299TDS_GET_UA4LE(void *ptr)
300{
301 unsigned long res;
302 __asm__ ("lwbrx %0,0,%1\n" : "=r" (res) : "r" (ptr), "m"(*(uint32_t *)ptr));
303 return (uint32_t) res;
304}
305
306# undef TDS_PUT_UA2LE
307# undef TDS_PUT_UA4LE
308static inline void
309TDS_PUT_UA2LE(void *ptr, unsigned data)
310{
311 __asm__ ("sthbrx %1,0,%2\n" : "=m" (*(uint16_t *)ptr) : "r" (data), "r" (ptr));
312}
313static inline void
314TDS_PUT_UA4LE(void *ptr, unsigned data)
315{
316 __asm__ ("stwbrx %1,0,%2\n" : "=m" (*(uint32_t *)ptr) : "r" (data), "r" (ptr));
317}
318#endif
319
320#endif