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 _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
89typedef union {
90 uint16_t usi;
91 uint8_t uc[2];
92} TDS_MAY_ALIAS TDS_BYTE_CONVERT2;
93
94typedef 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__) && defined(WORDS_BIGENDIAN)
203# undef TDS_GET_UA2LE
204# undef TDS_GET_UA4LE
205static inline uint16_t
206TDS_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}
212static inline uint32_t
213TDS_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
222static inline void
223TDS_PUT_UA2LE(void *ptr, unsigned data)
224{
225 __asm__ ("sthbrx %1,0,%2\n" : "=m" (*(uint16_t *)ptr) : "r" (data), "r" (ptr));
226}
227static inline void
228TDS_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