include/SDL_endian.h
author Ryan C. Gordon <icculus@icculus.org>
Thu, 28 May 2015 01:54:52 -0400
changeset 9671 0e1f57b051f4
parent 9619 b94b6d0bff0f
child 9710 38ca9a2dd2ef
permissions -rw-r--r--
Windows GetBasePath should use GetModuleFileNameExW() and check for overflows.

Apparently you might get strange paths from GetModuleFileName(), such as
short path names or UNC filenames, so this avoids that problem. Since you have
to tapdance with linking different libraries and defining macros depending on
what Windows you plan to target, we dynamically load the API we need, which
works on all versions of Windows (on Win7, it'll load a compatibility wrapper
for the newer API location).

What a mess.

This also now does the right thing if there isn't enough space to store the
path, looping with a larger allocated buffer each try.

Fixes Bugzilla #2435.
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@9619
     3
  Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
slouken@0
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@0
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@0
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@0
    20
*/
slouken@0
    21
slouken@1895
    22
/**
slouken@3407
    23
 *  \file SDL_endian.h
slouken@7191
    24
 *
slouken@3407
    25
 *  Functions for reading and writing endian-specific values
slouken@1895
    26
 */
slouken@0
    27
slouken@0
    28
#ifndef _SDL_endian_h
slouken@0
    29
#define _SDL_endian_h
slouken@0
    30
slouken@1354
    31
#include "SDL_stdinc.h"
slouken@0
    32
slouken@3407
    33
/**
slouken@3407
    34
 *  \name The two types of endianness
slouken@3407
    35
 */
gabomdq@7678
    36
/* @{ */
slouken@7191
    37
#define SDL_LIL_ENDIAN  1234
slouken@7191
    38
#define SDL_BIG_ENDIAN  4321
gabomdq@7678
    39
/* @} */
slouken@0
    40
slouken@1895
    41
#ifndef SDL_BYTEORDER           /* Not defined in SDL_config.h? */
slouken@4552
    42
#ifdef __linux__
slouken@4552
    43
#include <endian.h>
slouken@4552
    44
#define SDL_BYTEORDER  __BYTE_ORDER
slouken@4552
    45
#else /* __linux __ */
slouken@1474
    46
#if defined(__hppa__) || \
slouken@1475
    47
    defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
slouken@1474
    48
    (defined(__MIPS__) && defined(__MISPEB__)) || \
slouken@1475
    49
    defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \
slouken@1474
    50
    defined(__sparc__)
slouken@7191
    51
#define SDL_BYTEORDER   SDL_BIG_ENDIAN
slouken@1474
    52
#else
slouken@7191
    53
#define SDL_BYTEORDER   SDL_LIL_ENDIAN
slouken@1354
    54
#endif
slouken@4552
    55
#endif /* __linux __ */
slouken@1354
    56
#endif /* !SDL_BYTEORDER */
slouken@1354
    57
slouken@0
    58
slouken@0
    59
#include "begin_code.h"
slouken@0
    60
/* Set up for C function definitions, even when using C++ */
slouken@0
    61
#ifdef __cplusplus
slouken@0
    62
extern "C" {
slouken@0
    63
#endif
slouken@0
    64
slouken@3407
    65
/**
slouken@3407
    66
 *  \file SDL_endian.h
slouken@3407
    67
 */
slouken@1372
    68
#if defined(__GNUC__) && defined(__i386__) && \
slouken@1368
    69
   !(__GNUC__ == 2 && __GNUC_MINOR__ == 95 /* broken gcc version */)
icculus@7004
    70
SDL_FORCE_INLINE Uint16
slouken@1895
    71
SDL_Swap16(Uint16 x)
slouken@848
    72
{
slouken@1895
    73
  __asm__("xchgb %b0,%h0": "=q"(x):"0"(x));
slouken@1895
    74
    return x;
slouken@849
    75
}
slouken@849
    76
#elif defined(__GNUC__) && defined(__x86_64__)
icculus@7004
    77
SDL_FORCE_INLINE Uint16
slouken@1895
    78
SDL_Swap16(Uint16 x)
slouken@849
    79
{
slouken@1895
    80
  __asm__("xchgb %b0,%h0": "=Q"(x):"0"(x));
slouken@1895
    81
    return x;
slouken@849
    82
}
slouken@859
    83
#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
icculus@7004
    84
SDL_FORCE_INLINE Uint16
slouken@1895
    85
SDL_Swap16(Uint16 x)
slouken@849
    86
{
slouken@6213
    87
    int result;
slouken@849
    88
slouken@1895
    89
  __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x));
slouken@6213
    90
    return (Uint16)result;
slouken@848
    91
}
icculus@3630
    92
#elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__)
icculus@7004
    93
SDL_FORCE_INLINE Uint16
slouken@1895
    94
SDL_Swap16(Uint16 x)
patmandin@985
    95
{
slouken@1895
    96
  __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc");
slouken@1895
    97
    return x;
patmandin@985
    98
}
slouken@848
    99
#else
icculus@7004
   100
SDL_FORCE_INLINE Uint16
slouken@1895
   101
SDL_Swap16(Uint16 x)
slouken@1895
   102
{
slouken@4439
   103
    return SDL_static_cast(Uint16, ((x << 8) | (x >> 8)));
slouken@0
   104
}
slouken@0
   105
#endif
slouken@848
   106
slouken@849
   107
#if defined(__GNUC__) && defined(__i386__)
icculus@7004
   108
SDL_FORCE_INLINE Uint32
slouken@1895
   109
SDL_Swap32(Uint32 x)
slouken@848
   110
{
slouken@1895
   111
  __asm__("bswap %0": "=r"(x):"0"(x));
slouken@1895
   112
    return x;
slouken@849
   113
}
slouken@849
   114
#elif defined(__GNUC__) && defined(__x86_64__)
icculus@7004
   115
SDL_FORCE_INLINE Uint32
slouken@1895
   116
SDL_Swap32(Uint32 x)
slouken@849
   117
{
slouken@1895
   118
  __asm__("bswapl %0": "=r"(x):"0"(x));
slouken@1895
   119
    return x;
slouken@849
   120
}
slouken@859
   121
#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
icculus@7004
   122
SDL_FORCE_INLINE Uint32
slouken@1895
   123
SDL_Swap32(Uint32 x)
slouken@849
   124
{
slouken@1895
   125
    Uint32 result;
slouken@849
   126
slouken@1895
   127
  __asm__("rlwimi %0,%2,24,16,23": "=&r"(result):"0"(x >> 24), "r"(x));
slouken@1895
   128
  __asm__("rlwimi %0,%2,8,8,15": "=&r"(result):"0"(result), "r"(x));
slouken@1895
   129
  __asm__("rlwimi %0,%2,24,0,7": "=&r"(result):"0"(result), "r"(x));
slouken@1895
   130
    return result;
slouken@848
   131
}
icculus@3630
   132
#elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__)
icculus@7004
   133
SDL_FORCE_INLINE Uint32
slouken@1895
   134
SDL_Swap32(Uint32 x)
patmandin@985
   135
{
slouken@1895
   136
  __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc");
slouken@1895
   137
    return x;
patmandin@985
   138
}
slouken@848
   139
#else
icculus@7004
   140
SDL_FORCE_INLINE Uint32
slouken@1895
   141
SDL_Swap32(Uint32 x)
slouken@1895
   142
{
slouken@4439
   143
    return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) |
slouken@4439
   144
                                    ((x >> 8) & 0x0000FF00) | (x >> 24)));
slouken@0
   145
}
slouken@0
   146
#endif
slouken@848
   147
slouken@849
   148
#if defined(__GNUC__) && defined(__i386__)
icculus@7004
   149
SDL_FORCE_INLINE Uint64
slouken@1895
   150
SDL_Swap64(Uint64 x)
slouken@849
   151
{
slouken@1895
   152
    union
slouken@1895
   153
    {
slouken@1895
   154
        struct
slouken@1895
   155
        {
slouken@1895
   156
            Uint32 a, b;
slouken@1895
   157
        } s;
slouken@1895
   158
        Uint64 u;
slouken@1895
   159
    } v;
slouken@1895
   160
    v.u = x;
slouken@1895
   161
  __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1": "=r"(v.s.a), "=r"(v.s.b):"0"(v.s.a),
slouken@3013
   162
            "1"(v.s.
slouken@3013
   163
                b));
slouken@1895
   164
    return v.u;
slouken@849
   165
}
slouken@849
   166
#elif defined(__GNUC__) && defined(__x86_64__)
icculus@7004
   167
SDL_FORCE_INLINE Uint64
slouken@1895
   168
SDL_Swap64(Uint64 x)
slouken@849
   169
{
slouken@1895
   170
  __asm__("bswapq %0": "=r"(x):"0"(x));
slouken@1895
   171
    return x;
slouken@849
   172
}
slouken@849
   173
#else
icculus@7004
   174
SDL_FORCE_INLINE Uint64
slouken@1895
   175
SDL_Swap64(Uint64 x)
slouken@849
   176
{
slouken@1895
   177
    Uint32 hi, lo;
slouken@0
   178
slouken@1895
   179
    /* Separate into high and low 32-bit values and swap them */
slouken@3067
   180
    lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF);
slouken@1895
   181
    x >>= 32;
slouken@3067
   182
    hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF);
slouken@1895
   183
    x = SDL_Swap32(lo);
slouken@1895
   184
    x <<= 32;
slouken@1895
   185
    x |= SDL_Swap32(hi);
slouken@1895
   186
    return (x);
slouken@0
   187
}
slouken@0
   188
#endif
slouken@0
   189
slouken@0
   190
icculus@7004
   191
SDL_FORCE_INLINE float
icculus@1984
   192
SDL_SwapFloat(float x)
icculus@1984
   193
{
slouken@1985
   194
    union
slouken@1985
   195
    {
slouken@1985
   196
        float f;
slouken@1985
   197
        Uint32 ui32;
slouken@1985
   198
    } swapper;
icculus@1984
   199
    swapper.f = x;
icculus@1984
   200
    swapper.ui32 = SDL_Swap32(swapper.ui32);
icculus@1984
   201
    return swapper.f;
icculus@1984
   202
}
icculus@1984
   203
icculus@1984
   204
slouken@3407
   205
/**
slouken@3407
   206
 *  \name Swap to native
slouken@3407
   207
 *  Byteswap item from the specified endianness to the native endianness.
slouken@3407
   208
 */
gabomdq@7678
   209
/* @{ */
slouken@0
   210
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
slouken@7191
   211
#define SDL_SwapLE16(X) (X)
slouken@7191
   212
#define SDL_SwapLE32(X) (X)
slouken@7191
   213
#define SDL_SwapLE64(X) (X)
slouken@7191
   214
#define SDL_SwapFloatLE(X)  (X)
slouken@7191
   215
#define SDL_SwapBE16(X) SDL_Swap16(X)
slouken@7191
   216
#define SDL_SwapBE32(X) SDL_Swap32(X)
slouken@7191
   217
#define SDL_SwapBE64(X) SDL_Swap64(X)
slouken@7191
   218
#define SDL_SwapFloatBE(X)  SDL_SwapFloat(X)
slouken@0
   219
#else
slouken@7191
   220
#define SDL_SwapLE16(X) SDL_Swap16(X)
slouken@7191
   221
#define SDL_SwapLE32(X) SDL_Swap32(X)
slouken@7191
   222
#define SDL_SwapLE64(X) SDL_Swap64(X)
slouken@7191
   223
#define SDL_SwapFloatLE(X)  SDL_SwapFloat(X)
slouken@7191
   224
#define SDL_SwapBE16(X) (X)
slouken@7191
   225
#define SDL_SwapBE32(X) (X)
slouken@7191
   226
#define SDL_SwapBE64(X) (X)
slouken@7191
   227
#define SDL_SwapFloatBE(X)  (X)
slouken@0
   228
#endif
gabomdq@7678
   229
/* @} *//* Swap to native */
slouken@0
   230
slouken@0
   231
/* Ends C function definitions when using C++ */
slouken@0
   232
#ifdef __cplusplus
slouken@0
   233
}
slouken@0
   234
#endif
slouken@0
   235
#include "close_code.h"
slouken@0
   236
slouken@0
   237
#endif /* _SDL_endian_h */
slouken@1895
   238
slouken@1895
   239
/* vi: set ts=4 sw=4 expandtab: */