]> git.draconx.ca Git - upkg.git/blob - src/pack.c
upkg: Add license information to --version output.
[upkg.git] / src / pack.c
1 /*
2  *  upkg: tool for manipulating Unreal Tournament packages.
3  *  Copyright (C) 2009 Nick Bowler
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include <stdio.h>
20 #include <limits.h>
21
22 #include "pack.h"
23
24 /* Unsigned integer packing. */
25 #define DEFPACK_BE(bits, type) void pack_ ## bits ## _be ( \
26         unsigned char *out, type v \
27 ) { \
28         unsigned i; \
29         for (i = 1; i <= bits/8; i++) { \
30                 out[bits/8 - i] = v % 256; \
31                 v /= 256; \
32         } \
33 }
34
35 #define DEFPACK_LE(bits, type) void pack_ ## bits ## _le ( \
36         unsigned char *out, type v \
37 ) { \
38         unsigned i; \
39         for (i = 0; i < bits/8; i++) { \
40                 out[i] = v % 256; \
41                 v /= 256; \
42         } \
43 }
44
45 DEFPACK_BE(16, unsigned short)
46 DEFPACK_BE(32, unsigned long)
47 #ifdef ULLONG_MAX
48 DEFPACK_BE(64, unsigned long long)
49 #endif
50
51 DEFPACK_LE(16, unsigned short)
52 DEFPACK_LE(32, unsigned long)
53 #ifdef ULLONG_MAX
54 DEFPACK_LE(64, unsigned long long)
55 #endif
56
57 #define DEFUNPACK_BE(bits, type) type unpack_ ## bits ## _be ( \
58         const unsigned char *in \
59 ) { \
60         type v = 0; \
61         unsigned i; \
62         for (i = 0; i < bits/8; i++) { \
63                 v *= 256; \
64                 v += in[i]; \
65         } \
66         return v; \
67 }
68
69 #define DEFUNPACK_LE(bits, type) type unpack_ ## bits ## _le ( \
70         const unsigned char *in \
71 ) { \
72         type v = 0; \
73         unsigned i; \
74         for (i = 1; i <= bits/8; i++) { \
75                 v *= 256; \
76                 v += in[bits/8 - i]; \
77         } \
78         return v; \
79 }
80
81 DEFUNPACK_BE(16, unsigned short)
82 DEFUNPACK_BE(32, unsigned long)
83 #ifdef ULLONG_MAX
84 DEFUNPACK_BE(64, unsigned long long)
85 #endif
86
87 DEFUNPACK_LE(16, unsigned short)
88 DEFUNPACK_LE(32, unsigned long)
89 #ifdef ULLONG_MAX
90 DEFUNPACK_LE(64, unsigned long long)
91 #endif
92
93 /*
94  * Two's complement signed integer packing.  This is unlikely to work on
95  * systems that don't themselves use two's complement.
96  */
97
98 #define DEFUNPACK_SBE(bits, max, type) type unpack_s ## bits ## _be ( \
99         const unsigned char *in \
100 ) { \
101         type v = 0; \
102         unsigned i; \
103         int sign = (in[0] & 0x80) ? 1 : 0; \
104         for (i = 0; i < bits/8; i++) { \
105                 v *= 256; \
106                 v += in[i] & (i == 0 ? 0x7f : 0xff); \
107         } \
108         return sign*(-max-1) + v; \
109 }
110
111 #define DEFUNPACK_SLE(bits, max, type) type unpack_s ## bits ## _le ( \
112         const unsigned char *in \
113 ) { \
114         type v = 0; \
115         unsigned i; \
116         int sign = (in[bits/8 - 1] & 0x80) ? 1 : 0; \
117         for (i = 1; i <= bits/8; i++) { \
118                 v *= 256; \
119                 v += in[bits/8 - i] & (i == 1 ? 0x7f : 0xff); \
120         } \
121         return sign*(-max-1) + v; \
122 }
123
124 DEFUNPACK_SBE(16, 32767, short)
125 DEFUNPACK_SBE(32, 2147483647l, long)
126 #ifdef LLONG_MAX
127 DEFUNPACK_SBE(64, 9223372036854775807ll, long long)
128 #endif
129
130 DEFUNPACK_SLE(16, 32767, short)
131 DEFUNPACK_SLE(32, 2147483647l, long)
132 #ifdef LLONG_MAX
133 DEFUNPACK_SLE(64, 9223372036854775807ll, long long)
134 #endif