FreeTDS API
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 /* TODO optimize (use swap, unaligned platforms) */
39 
40 /* one byte, easy... */
41 #define TDS_GET_A1LE(ptr) (((uint8_t *)(ptr))[0])
42 #define TDS_GET_A1BE(ptr) TDS_GET_A1LE(ptr)
43 #define TDS_GET_UA1LE(ptr) TDS_GET_A1LE(ptr)
44 #define TDS_GET_UA1BE(ptr) TDS_GET_A1LE(ptr)
45 
46 #define TDS_PUT_A1LE(ptr,val) do { ((uint8_t *)(ptr))[0] = (val); } while(0)
47 #define TDS_PUT_A1BE(ptr,val) TDS_PUT_A1LE(ptr,val)
48 #define TDS_PUT_UA1LE(ptr,val) TDS_PUT_A1LE(ptr,val)
49 #define TDS_PUT_UA1BE(ptr,val) TDS_PUT_A1LE(ptr,val)
50 
51 /* two bytes */
52 #define TDS_GET_UA2LE(ptr) (((uint8_t *)(ptr))[1] * 0x100u + ((uint8_t *)(ptr))[0])
53 #define TDS_GET_UA2BE(ptr) (((uint8_t *)(ptr))[0] * 0x100u + ((uint8_t *)(ptr))[1])
54 #define TDS_GET_A2LE(ptr) TDS_GET_UA2LE(ptr)
55 #define TDS_GET_A2BE(ptr) TDS_GET_UA2BE(ptr)
56 
57 #define TDS_PUT_UA2LE(ptr,val) do {\
58  ((uint8_t *)(ptr))[1] = (uint8_t)((val)>>8); ((uint8_t *)(ptr))[0] = (uint8_t)(val); } while(0)
59 #define TDS_PUT_UA2BE(ptr,val) do {\
60  ((uint8_t *)(ptr))[0] = (uint8_t)((val)>>8); ((uint8_t *)(ptr))[1] = (uint8_t)(val); } while(0)
61 #define TDS_PUT_A2LE(ptr,val) TDS_PUT_UA2LE(ptr,val)
62 #define TDS_PUT_A2BE(ptr,val) TDS_PUT_UA2BE(ptr,val)
63 
64 /* four bytes */
65 #define TDS_GET_UA4LE(ptr) \
66  (((uint8_t *)(ptr))[3] * 0x1000000u + ((uint8_t *)(ptr))[2] * 0x10000u +\
67  ((uint8_t *)(ptr))[1] * 0x100u + ((uint8_t *)(ptr))[0])
68 #define TDS_GET_UA4BE(ptr) \
69  (((uint8_t *)(ptr))[0] * 0x1000000u + ((uint8_t *)(ptr))[1] * 0x10000u +\
70  ((uint8_t *)(ptr))[2] * 0x100u + ((uint8_t *)(ptr))[3])
71 #define TDS_GET_A4LE(ptr) TDS_GET_UA4LE(ptr)
72 #define TDS_GET_A4BE(ptr) TDS_GET_UA4BE(ptr)
73 
74 #define TDS_PUT_UA4LE(ptr,val) do {\
75  ((uint8_t *)(ptr))[3] = (uint8_t)((val)>>24); ((uint8_t *)(ptr))[2] = (uint8_t)((val)>>16);\
76  ((uint8_t *)(ptr))[1] = (uint8_t)((val)>>8); ((uint8_t *)(ptr))[0] = (uint8_t)(val); } while(0)
77 #define TDS_PUT_UA4BE(ptr,val) do {\
78  ((uint8_t *)(ptr))[0] = (uint8_t)((val)>>24); ((uint8_t *)(ptr))[1] = (uint8_t)((val)>>16);\
79  ((uint8_t *)(ptr))[2] = (uint8_t)((val)>>8); ((uint8_t *)(ptr))[3] = (uint8_t)(val); } while(0)
80 #define TDS_PUT_A4LE(ptr,val) TDS_PUT_UA4LE(ptr,val)
81 #define TDS_PUT_A4BE(ptr,val) TDS_PUT_UA4BE(ptr,val)
82 
83 #if defined(__GNUC__)
84 # define TDS_MAY_ALIAS __attribute__((__may_alias__))
85 #else
86 # define TDS_MAY_ALIAS
87 #endif
88 
89 typedef union {
90  uint16_t usi;
91  uint8_t uc[2];
92 } TDS_MAY_ALIAS TDS_BYTE_CONVERT2;
93 
94 typedef union {
95  uint32_t ui;
96  uint8_t uc[4];
97 } TDS_MAY_ALIAS TDS_BYTE_CONVERT4;
98 
99 /* architecture dependent */
100 /* map to generic macros or redefine for aligned and same endianess */
101 #ifdef WORDS_BIGENDIAN
102 # define TDS_GET_A1(ptr) TDS_GET_A1BE(ptr)
103 # define TDS_GET_UA1(ptr) TDS_GET_UA1BE(ptr)
104 # define TDS_GET_A2(ptr) TDS_GET_A2BE(ptr)
105 # define TDS_GET_UA2(ptr) TDS_GET_UA2BE(ptr)
106 # define TDS_GET_A4(ptr) TDS_GET_A4BE(ptr)
107 # define TDS_GET_UA4(ptr) TDS_GET_UA4BE(ptr)
108 # undef TDS_GET_A2BE
109 # undef TDS_GET_A4BE
110 # define TDS_GET_A2BE(ptr) (((TDS_BYTE_CONVERT2*)(ptr))->usi)
111 # define TDS_GET_A4BE(ptr) (((TDS_BYTE_CONVERT4*)(ptr))->ui)
112 
113 # define TDS_PUT_A1(ptr,val) TDS_PUT_A1BE(ptr,val)
114 # define TDS_PUT_UA1(ptr,val) TDS_PUT_UA1BE(ptr,val)
115 # define TDS_PUT_A2(ptr,val) TDS_PUT_A2BE(ptr,val)
116 # define TDS_PUT_UA2(ptr,val) TDS_PUT_UA2BE(ptr,val)
117 # define TDS_PUT_A4(ptr,val) TDS_PUT_A4BE(ptr,val)
118 # define TDS_PUT_UA4(ptr,val) TDS_PUT_UA4BE(ptr,val)
119 # undef TDS_PUT_A2BE
120 # undef TDS_PUT_A4BE
121 # define TDS_PUT_A2BE(ptr,val) (((TDS_BYTE_CONVERT2*)(ptr))->usi = (val))
122 # define TDS_PUT_A4BE(ptr,val) (((TDS_BYTE_CONVERT4*)(ptr))->ui = (val))
123 # define TDS_HOST2LE(val) TDS_BYTE_SWAP16(val)
124 # define TDS_HOST4LE(val) TDS_BYTE_SWAP32(val)
125 # define TDS_HOST2BE(val) (val)
126 # define TDS_HOST4BE(val) (val)
127 #else
128 # define TDS_GET_A1(ptr) TDS_GET_A1LE(ptr)
129 # define TDS_GET_UA1(ptr) TDS_GET_UA1LE(ptr)
130 # define TDS_GET_A2(ptr) TDS_GET_A2LE(ptr)
131 # define TDS_GET_UA2(ptr) TDS_GET_UA2LE(ptr)
132 # define TDS_GET_A4(ptr) TDS_GET_A4LE(ptr)
133 # define TDS_GET_UA4(ptr) TDS_GET_UA4LE(ptr)
134 # undef TDS_GET_A2LE
135 # undef TDS_GET_A4LE
136 # define TDS_GET_A2LE(ptr) (((TDS_BYTE_CONVERT2*)(ptr))->usi)
137 # define TDS_GET_A4LE(ptr) (((TDS_BYTE_CONVERT4*)(ptr))->ui)
138 
139 # define TDS_PUT_A1(ptr,val) TDS_PUT_A1LE(ptr,val)
140 # define TDS_PUT_UA1(ptr,val) TDS_PUT_UA1LE(ptr,val)
141 # define TDS_PUT_A2(ptr,val) TDS_PUT_A2LE(ptr,val)
142 # define TDS_PUT_UA2(ptr,val) TDS_PUT_UA2LE(ptr,val)
143 # define TDS_PUT_A4(ptr,val) TDS_PUT_A4LE(ptr,val)
144 # define TDS_PUT_UA4(ptr,val) TDS_PUT_UA4LE(ptr,val)
145 # undef TDS_PUT_A2LE
146 # undef TDS_PUT_A4LE
147 # define TDS_PUT_A2LE(ptr,val) (((TDS_BYTE_CONVERT2*)(ptr))->usi = (val))
148 # define TDS_PUT_A4LE(ptr,val) (((TDS_BYTE_CONVERT4*)(ptr))->ui = (val))
149 # define TDS_HOST2LE(val) (val)
150 # define TDS_HOST4LE(val) (val)
151 # define TDS_HOST2BE(val) TDS_BYTE_SWAP16(val)
152 # define TDS_HOST4BE(val) TDS_BYTE_SWAP32(val)
153 #endif
154 
155 /* these platform support unaligned fetch/store */
156 /* map unaligned macro to aligned ones */
157 #if defined(__i386__) || defined(__amd64__) || defined(__CRIS__) ||\
158  defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || defined(__ppc64__) ||\
159  defined(__s390__) || defined(__s390x__) || defined(__m68k__) ||\
160  (defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_IX86) || defined(_M_X64))) ||\
161  defined(__ARM_FEATURE_UNALIGNED) ||\
162  defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_8__) ||\
163  (defined(_M_ARM) && (_M_ARM >= 7))
164 # ifdef WORDS_BIGENDIAN
165 # undef TDS_GET_UA2BE
166 # undef TDS_GET_UA4BE
167 # define TDS_GET_UA2BE(ptr) TDS_GET_A2BE(ptr)
168 # define TDS_GET_UA4BE(ptr) TDS_GET_A4BE(ptr)
169 
170 # undef TDS_PUT_UA2BE
171 # undef TDS_PUT_UA4BE
172 # define TDS_PUT_UA2BE(ptr,val) TDS_PUT_A2BE(ptr,val)
173 # define TDS_PUT_UA4BE(ptr,val) TDS_PUT_A4BE(ptr,val)
174 # else
175 # undef TDS_GET_UA2LE
176 # undef TDS_GET_UA4LE
177 # define TDS_GET_UA2LE(ptr) TDS_GET_A2LE(ptr)
178 # define TDS_GET_UA4LE(ptr) TDS_GET_A4LE(ptr)
179 
180 # undef TDS_PUT_UA2LE
181 # undef TDS_PUT_UA4LE
182 # define TDS_PUT_UA2LE(ptr,val) TDS_PUT_A2LE(ptr,val)
183 # define TDS_PUT_UA4LE(ptr,val) TDS_PUT_A4LE(ptr,val)
184 # endif
185 #endif
186 
187 #if defined(__linux__) && defined(__GNUC__) && (defined(__i386__) || defined(__amd64__))
188 # include <byteswap.h>
189 # undef TDS_GET_UA2BE
190 # undef TDS_GET_UA4BE
191 # define TDS_GET_UA2BE(ptr) ({ uint16_t _tds_si = TDS_GET_UA2LE(ptr); bswap_16(_tds_si); })
192 # define TDS_GET_UA4BE(ptr) ({ uint32_t _tds_i = TDS_GET_UA4LE(ptr); bswap_32(_tds_i); })
193 
194 # undef TDS_PUT_UA2BE
195 # undef TDS_PUT_UA4BE
196 # define TDS_PUT_UA2BE(ptr,val) do {\
197  uint16_t _tds_si = bswap_16(val); TDS_PUT_UA2LE(ptr,_tds_si); } while(0)
198 # define TDS_PUT_UA4BE(ptr,val) do {\
199  uint32_t _tds_i = bswap_32(val); TDS_PUT_UA4LE(ptr,_tds_i); } while(0)
200 #endif
201 
202 #if defined(__GNUC__) && defined(__powerpc__)
203 # undef TDS_GET_UA2LE
204 # undef TDS_GET_UA4LE
205 static inline uint16_t
206 TDS_GET_UA2LE(void *ptr)
207 {
208  unsigned long res;
209  __asm__ ("lhbrx %0,0,%1\n" : "=r" (res) : "r" (ptr), "m"(*(uint16_t *)ptr));
210  return (uint16_t) res;
211 }
212 static inline uint32_t
213 TDS_GET_UA4LE(void *ptr)
214 {
215  unsigned long res;
216  __asm__ ("lwbrx %0,0,%1\n" : "=r" (res) : "r" (ptr), "m"(*(uint32_t *)ptr));
217  return (uint32_t) res;
218 }
219 
220 # undef TDS_PUT_UA2LE
221 # undef TDS_PUT_UA4LE
222 static inline void
223 TDS_PUT_UA2LE(void *ptr, unsigned data)
224 {
225  __asm__ ("sthbrx %1,0,%2\n" : "=m" (*(uint16_t *)ptr) : "r" (data), "r" (ptr));
226 }
227 static inline void
228 TDS_PUT_UA4LE(void *ptr, unsigned data)
229 {
230  __asm__ ("stwbrx %1,0,%2\n" : "=m" (*(uint32_t *)ptr) : "r" (data), "r" (ptr));
231 }
232 #endif
233 
234 #endif
Definition: bytes.h:89