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

FreeTDS API

- Main Page
- Related Pages
- Modules
- Classes
- Files

- File List
- File Members

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