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