FreeTDS API
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 _tdsbytes_h_
21 #define _tdsbytes_h_
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 
92 typedef 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 /* these platform support unaligned fetch/store */
154 /* map unaligned macro to aligned ones */
155 #if defined(__i386__) || defined(__amd64__) || defined(__CRIS__) ||\
156  defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || defined(__ppc64__) ||\
157  defined(__s390__) || defined(__s390x__) || defined(__m68k__) ||\
158  (defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_IX86) || defined(_M_X64))) ||\
159  defined(__ARM_FEATURE_UNALIGNED) ||\
160  defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_8__) ||\
161  (defined(_M_ARM) && (_M_ARM >= 7))
162 # ifdef WORDS_BIGENDIAN
163 # undef TDS_GET_UA2BE
164 # undef TDS_GET_UA4BE
165 # define TDS_GET_UA2BE(ptr) TDS_GET_A2BE(ptr)
166 # define TDS_GET_UA4BE(ptr) TDS_GET_A4BE(ptr)
167 
168 # undef TDS_PUT_UA2BE
169 # undef TDS_PUT_UA4BE
170 # define TDS_PUT_UA2BE(ptr,val) TDS_PUT_A2BE(ptr,val)
171 # define TDS_PUT_UA4BE(ptr,val) TDS_PUT_A4BE(ptr,val)
172 # else
173 # undef TDS_GET_UA2LE
174 # undef TDS_GET_UA4LE
175 # define TDS_GET_UA2LE(ptr) TDS_GET_A2LE(ptr)
176 # define TDS_GET_UA4LE(ptr) TDS_GET_A4LE(ptr)
177 
178 # undef TDS_PUT_UA2LE
179 # undef TDS_PUT_UA4LE
180 # define TDS_PUT_UA2LE(ptr,val) TDS_PUT_A2LE(ptr,val)
181 # define TDS_PUT_UA4LE(ptr,val) TDS_PUT_A4LE(ptr,val)
182 # endif
183 #endif
184 
185 #undef TDS_BSWAP16
186 #undef TDS_BSWAP32
187 /* __builtin_bswap16 was introduced in GCC 4.8 */
188 #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) && defined(__OPTIMIZE__)
189 # define TDS_BSWAP16(val) __builtin_bswap16(val)
190 # define TDS_BSWAP32(val) __builtin_bswap32(val)
191 /* __builtin_bswap32 was introduced in GCC 4.3 */
192 #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && defined(__OPTIMIZE__)
193 # define TDS_BSWAP32(val) __builtin_bswap32(val)
194 #elif defined(_MSC_VER)
195 # define TDS_BSWAP16(val) _byteswap_ushort(val)
196 # define TDS_BSWAP32(val) _byteswap_ulong(val)
197 #endif
198 
199 #if defined(TDS_BSWAP16) && !defined(WORDS_BIGENDIAN)
200 # undef TDS_GET_UA2BE
201 # define TDS_GET_UA2BE(ptr) TDS_BSWAP16(TDS_GET_UA2LE(ptr))
202 
203 # undef TDS_PUT_UA2BE
204 # define TDS_PUT_UA2BE(ptr,val) do {\
205  uint16_t _tds_si = TDS_BSWAP16(val); TDS_PUT_UA2LE(ptr,_tds_si); } while(0)
206 #elif defined(TDS_BSWAP16) && defined(WORDS_BIGENDIAN)
207 # undef TDS_GET_UA2LE
208 # define TDS_GET_UA2LE(ptr) TDS_BSWAP16(TDS_GET_UA2BE(ptr))
209 
210 # undef TDS_PUT_UA2LE
211 # define TDS_PUT_UA2LE(ptr,val) do {\
212  uint16_t _tds_si = TDS_BSWAP16(val); TDS_PUT_UA2BE(ptr,_tds_si); } while(0)
213 #endif
214 
215 #if defined(TDS_BSWAP32) && !defined(WORDS_BIGENDIAN)
216 # undef TDS_GET_UA4BE
217 # define TDS_GET_UA4BE(ptr) TDS_BSWAP32(TDS_GET_UA4LE(ptr))
218 
219 # undef TDS_PUT_UA4BE
220 # define TDS_PUT_UA4BE(ptr,val) do {\
221  uint32_t _tds_i = TDS_BSWAP32(val); TDS_PUT_UA4LE(ptr,_tds_i); } while(0)
222 #elif defined(TDS_BSWAP32) && defined(WORDS_BIGENDIAN)
223 # undef TDS_GET_UA4LE
224 # define TDS_GET_UA4LE(ptr) TDS_BSWAP32(TDS_GET_UA4BE(ptr))
225 
226 # undef TDS_PUT_UA4LE
227 # define TDS_PUT_UA4LE(ptr,val) do {\
228  uint32_t _tds_i = TDS_BSWAP32(val); TDS_PUT_UA4BE(ptr,_tds_i); } while(0)
229 #endif
230 
231 #if defined(__GNUC__) && defined(__powerpc__) && defined(WORDS_BIGENDIAN)
232 # undef TDS_GET_UA2LE
233 # undef TDS_GET_UA4LE
234 static inline uint16_t
235 TDS_GET_UA2LE(void *ptr)
236 {
237  unsigned long res;
238  __asm__ ("lhbrx %0,0,%1\n" : "=r" (res) : "r" (ptr), "m"(*(uint16_t *)ptr));
239  return (uint16_t) res;
240 }
241 static inline uint32_t
242 TDS_GET_UA4LE(void *ptr)
243 {
244  unsigned long res;
245  __asm__ ("lwbrx %0,0,%1\n" : "=r" (res) : "r" (ptr), "m"(*(uint32_t *)ptr));
246  return (uint32_t) res;
247 }
248 
249 # undef TDS_PUT_UA2LE
250 # undef TDS_PUT_UA4LE
251 static inline void
252 TDS_PUT_UA2LE(void *ptr, unsigned data)
253 {
254  __asm__ ("sthbrx %1,0,%2\n" : "=m" (*(uint16_t *)ptr) : "r" (data), "r" (ptr));
255 }
256 static inline void
257 TDS_PUT_UA4LE(void *ptr, unsigned data)
258 {
259  __asm__ ("stwbrx %1,0,%2\n" : "=m" (*(uint32_t *)ptr) : "r" (data), "r" (ptr));
260 }
261 #endif
262 
263 #endif
Definition: bytes.h:87