1 | /** |
2 | * PhysicsFS; a portable, flexible file i/o abstraction. |
3 | * |
4 | * Documentation is in physfs.h. It's verbose, honest. :) |
5 | * |
6 | * Please see the file LICENSE.txt in the source's root directory. |
7 | * |
8 | * This file written by Ryan C. Gordon. |
9 | */ |
10 | |
11 | #define __PHYSICSFS_INTERNAL__ |
12 | #include "physfs_internal.h" |
13 | |
14 | #ifndef PHYSFS_Swap16 |
15 | static inline PHYSFS_uint16 PHYSFS_Swap16(PHYSFS_uint16 D) |
16 | { |
17 | return ((D<<8)|(D>>8)); |
18 | } |
19 | #endif |
20 | #ifndef PHYSFS_Swap32 |
21 | static inline PHYSFS_uint32 PHYSFS_Swap32(PHYSFS_uint32 D) |
22 | { |
23 | return ((D<<24)|((D<<8)&0x00FF0000)|((D>>8)&0x0000FF00)|(D>>24)); |
24 | } |
25 | #endif |
26 | #ifndef PHYSFS_NO_64BIT_SUPPORT |
27 | #ifndef PHYSFS_Swap64 |
28 | static inline PHYSFS_uint64 PHYSFS_Swap64(PHYSFS_uint64 val) { |
29 | PHYSFS_uint32 hi, lo; |
30 | |
31 | /* Separate into high and low 32-bit values and swap them */ |
32 | lo = (PHYSFS_uint32)(val&0xFFFFFFFF); |
33 | val >>= 32; |
34 | hi = (PHYSFS_uint32)(val&0xFFFFFFFF); |
35 | val = PHYSFS_Swap32(lo); |
36 | val <<= 32; |
37 | val |= PHYSFS_Swap32(hi); |
38 | return val; |
39 | } |
40 | #endif |
41 | #else |
42 | #ifndef PHYSFS_Swap64 |
43 | /* This is mainly to keep compilers from complaining in PHYSFS code. |
44 | If there is no real 64-bit datatype, then compilers will complain about |
45 | the fake 64-bit datatype that PHYSFS provides when it compiles user code. |
46 | */ |
47 | #define PHYSFS_Swap64(X) (X) |
48 | #endif |
49 | #endif /* PHYSFS_NO_64BIT_SUPPORT */ |
50 | |
51 | |
52 | /* Byteswap item from the specified endianness to the native endianness */ |
53 | #if PHYSFS_BYTEORDER == PHYSFS_LIL_ENDIAN |
54 | PHYSFS_uint16 PHYSFS_swapULE16(PHYSFS_uint16 x) { return x; } |
55 | PHYSFS_sint16 PHYSFS_swapSLE16(PHYSFS_sint16 x) { return x; } |
56 | PHYSFS_uint32 PHYSFS_swapULE32(PHYSFS_uint32 x) { return x; } |
57 | PHYSFS_sint32 PHYSFS_swapSLE32(PHYSFS_sint32 x) { return x; } |
58 | PHYSFS_uint64 PHYSFS_swapULE64(PHYSFS_uint64 x) { return x; } |
59 | PHYSFS_sint64 PHYSFS_swapSLE64(PHYSFS_sint64 x) { return x; } |
60 | |
61 | PHYSFS_uint16 PHYSFS_swapUBE16(PHYSFS_uint16 x) { return PHYSFS_Swap16(x); } |
62 | PHYSFS_sint16 PHYSFS_swapSBE16(PHYSFS_sint16 x) { return PHYSFS_Swap16(x); } |
63 | PHYSFS_uint32 PHYSFS_swapUBE32(PHYSFS_uint32 x) { return PHYSFS_Swap32(x); } |
64 | PHYSFS_sint32 PHYSFS_swapSBE32(PHYSFS_sint32 x) { return PHYSFS_Swap32(x); } |
65 | PHYSFS_uint64 PHYSFS_swapUBE64(PHYSFS_uint64 x) { return PHYSFS_Swap64(x); } |
66 | PHYSFS_sint64 PHYSFS_swapSBE64(PHYSFS_sint64 x) { return PHYSFS_Swap64(x); } |
67 | #else |
68 | PHYSFS_uint16 PHYSFS_swapULE16(PHYSFS_uint16 x) { return PHYSFS_Swap16(x); } |
69 | PHYSFS_sint16 PHYSFS_swapSLE16(PHYSFS_sint16 x) { return PHYSFS_Swap16(x); } |
70 | PHYSFS_uint32 PHYSFS_swapULE32(PHYSFS_uint32 x) { return PHYSFS_Swap32(x); } |
71 | PHYSFS_sint32 PHYSFS_swapSLE32(PHYSFS_sint32 x) { return PHYSFS_Swap32(x); } |
72 | PHYSFS_uint64 PHYSFS_swapULE64(PHYSFS_uint64 x) { return PHYSFS_Swap64(x); } |
73 | PHYSFS_sint64 PHYSFS_swapSLE64(PHYSFS_sint64 x) { return PHYSFS_Swap64(x); } |
74 | |
75 | PHYSFS_uint16 PHYSFS_swapUBE16(PHYSFS_uint16 x) { return x; } |
76 | PHYSFS_sint16 PHYSFS_swapSBE16(PHYSFS_sint16 x) { return x; } |
77 | PHYSFS_uint32 PHYSFS_swapUBE32(PHYSFS_uint32 x) { return x; } |
78 | PHYSFS_sint32 PHYSFS_swapSBE32(PHYSFS_sint32 x) { return x; } |
79 | PHYSFS_uint64 PHYSFS_swapUBE64(PHYSFS_uint64 x) { return x; } |
80 | PHYSFS_sint64 PHYSFS_swapSBE64(PHYSFS_sint64 x) { return x; } |
81 | #endif |
82 | |
83 | static inline int readAll(PHYSFS_File *file, void *val, const size_t len) |
84 | { |
85 | return (PHYSFS_readBytes(file, val, len) == len); |
86 | } /* readAll */ |
87 | |
88 | #define PHYSFS_BYTEORDER_READ(datatype, swaptype) \ |
89 | int PHYSFS_read##swaptype(PHYSFS_File *file, PHYSFS_##datatype *val) { \ |
90 | PHYSFS_##datatype in; \ |
91 | BAIL_IF(val == NULL, PHYSFS_ERR_INVALID_ARGUMENT, 0); \ |
92 | BAIL_IF_ERRPASS(!readAll(file, &in, sizeof (in)), 0); \ |
93 | *val = PHYSFS_swap##swaptype(in); \ |
94 | return 1; \ |
95 | } |
96 | |
97 | PHYSFS_BYTEORDER_READ(sint16, SLE16) |
98 | PHYSFS_BYTEORDER_READ(uint16, ULE16) |
99 | PHYSFS_BYTEORDER_READ(sint16, SBE16) |
100 | PHYSFS_BYTEORDER_READ(uint16, UBE16) |
101 | PHYSFS_BYTEORDER_READ(sint32, SLE32) |
102 | PHYSFS_BYTEORDER_READ(uint32, ULE32) |
103 | PHYSFS_BYTEORDER_READ(sint32, SBE32) |
104 | PHYSFS_BYTEORDER_READ(uint32, UBE32) |
105 | PHYSFS_BYTEORDER_READ(sint64, SLE64) |
106 | PHYSFS_BYTEORDER_READ(uint64, ULE64) |
107 | PHYSFS_BYTEORDER_READ(sint64, SBE64) |
108 | PHYSFS_BYTEORDER_READ(uint64, UBE64) |
109 | |
110 | |
111 | static inline int writeAll(PHYSFS_File *f, const void *val, const size_t len) |
112 | { |
113 | return (PHYSFS_writeBytes(f, val, len) == len); |
114 | } /* writeAll */ |
115 | |
116 | #define PHYSFS_BYTEORDER_WRITE(datatype, swaptype) \ |
117 | int PHYSFS_write##swaptype(PHYSFS_File *file, PHYSFS_##datatype val) { \ |
118 | const PHYSFS_##datatype out = PHYSFS_swap##swaptype(val); \ |
119 | BAIL_IF_ERRPASS(!writeAll(file, &out, sizeof (out)), 0); \ |
120 | return 1; \ |
121 | } |
122 | |
123 | PHYSFS_BYTEORDER_WRITE(sint16, SLE16) |
124 | PHYSFS_BYTEORDER_WRITE(uint16, ULE16) |
125 | PHYSFS_BYTEORDER_WRITE(sint16, SBE16) |
126 | PHYSFS_BYTEORDER_WRITE(uint16, UBE16) |
127 | PHYSFS_BYTEORDER_WRITE(sint32, SLE32) |
128 | PHYSFS_BYTEORDER_WRITE(uint32, ULE32) |
129 | PHYSFS_BYTEORDER_WRITE(sint32, SBE32) |
130 | PHYSFS_BYTEORDER_WRITE(uint32, UBE32) |
131 | PHYSFS_BYTEORDER_WRITE(sint64, SLE64) |
132 | PHYSFS_BYTEORDER_WRITE(uint64, ULE64) |
133 | PHYSFS_BYTEORDER_WRITE(sint64, SBE64) |
134 | PHYSFS_BYTEORDER_WRITE(uint64, UBE64) |
135 | |
136 | /* end of physfs_byteorder.c ... */ |
137 | |
138 | |