]> git.jsancho.org Git - lugaru.git/blob - Source/pack.c
f26b2e2b0abc0bff0f95ee70db6aa4a1e0b7bc6d
[lugaru.git] / Source / pack.c
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3
4 This file is part of Lugaru.
5
6 Lugaru is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
15 See the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */
21
22 #include <stdlib.h>
23
24 #include "binio.h"
25 #include "private.h"
26
27 struct BinIOPackContext {
28     uint8_t *buffer;
29     va_list  args;
30 };
31
32 static void BinIOPack(void *context, int type, int byte_order, int count)
33 {
34     struct BinIOPackContext *ctx = (struct BinIOPackContext*)context;
35     if (count == -1) {
36         switch (type) {
37         case BinIO_TYPE_IGNORE_BYTE: {
38             ctx->buffer += 1;
39         }
40         break;
41         case BinIO_TYPE_BYTE: {
42             uint8_t value = va_arg(ctx->args, int);
43             BinIOConvert1(BinIO_HOST_BYTE_ORDER, byte_order, (const uint8_t *)&value, ctx->buffer, 1);
44             ctx->buffer += 1;
45         }
46         break;
47         case BinIO_TYPE_INT16: {
48             uint16_t value = va_arg(ctx->args, int);
49             BinIOConvert2(BinIO_HOST_BYTE_ORDER, byte_order, (const uint8_t *)&value, ctx->buffer, 1);
50             ctx->buffer += 2;
51         }
52         break;
53         case BinIO_TYPE_INT32: {
54             int value = va_arg(ctx->args, int);
55             BinIOConvert4(BinIO_HOST_BYTE_ORDER, byte_order, (const uint8_t *)&value, ctx->buffer, 1);
56             ctx->buffer += 4;
57         }
58         break;
59         case BinIO_TYPE_INT64: {
60             uint64_t value = va_arg(ctx->args, uint64_t);
61             BinIOConvert8(BinIO_HOST_BYTE_ORDER, byte_order, (const uint8_t *)&value, ctx->buffer, 1);
62             ctx->buffer += 8;
63         }
64         break;
65         case BinIO_TYPE_FLOAT32: {
66             float32_t value = (float32_t)va_arg(ctx->args, double);
67             BinIOConvert4(BinIO_HOST_BYTE_ORDER, byte_order, (const uint8_t *)&value, ctx->buffer, 1);
68             ctx->buffer += 4;
69         }
70         break;
71         case BinIO_TYPE_FLOAT64: {
72             float64_t value = va_arg(ctx->args, float64_t);
73             BinIOConvert8(BinIO_HOST_BYTE_ORDER, byte_order, (const uint8_t *)&value, ctx->buffer, 1);
74             ctx->buffer += 8;
75         }
76         break;
77         }
78     } else {
79         switch (type) {
80         case BinIO_TYPE_IGNORE_BYTE:
81             ctx->buffer += 1 * count;
82             break;
83         case BinIO_TYPE_BYTE:
84             BinIOConvert1(BinIO_HOST_BYTE_ORDER, byte_order, va_arg(ctx->args, uint8_t *), ctx->buffer, count);
85             ctx->buffer += 1 * count;
86             break;
87         case BinIO_TYPE_INT16:
88             BinIOConvert2(BinIO_HOST_BYTE_ORDER, byte_order, va_arg(ctx->args, uint8_t *), ctx->buffer, count);
89             ctx->buffer += 2 * count;
90             break;
91         case BinIO_TYPE_INT32:
92             BinIOConvert4(BinIO_HOST_BYTE_ORDER, byte_order, va_arg(ctx->args, uint8_t *), ctx->buffer, count);
93             ctx->buffer += 4 * count;
94             break;
95         case BinIO_TYPE_INT64:
96             BinIOConvert8(BinIO_HOST_BYTE_ORDER, byte_order, va_arg(ctx->args, uint8_t *), ctx->buffer, count);
97             ctx->buffer += 8 * count;
98             break;
99         case BinIO_TYPE_FLOAT32:
100             BinIOConvert4(BinIO_HOST_BYTE_ORDER, byte_order, va_arg(ctx->args, uint8_t *), ctx->buffer, count);
101             ctx->buffer += 4 * count;
102             break;
103         case BinIO_TYPE_FLOAT64:
104             BinIOConvert8(BinIO_HOST_BYTE_ORDER, byte_order, va_arg(ctx->args, uint8_t *), ctx->buffer, count);
105             ctx->buffer += 8 * count;
106             break;
107         }
108     }
109 }
110
111 extern void packf(const char *format, ...)
112 {
113     va_list args;
114     va_start(args, format);
115     vfpackf(stdout, format, args);
116     va_end(args);
117 }
118
119 extern void spackf(void *buffer, const char *format, ...)
120 {
121     va_list args;
122     va_start(args, format);
123     vspackf(buffer, format, args);
124     va_end(args);
125 }
126
127 extern void fpackf(FILE *file, const char *format, ...)
128 {
129     va_list args;
130     va_start(args, format);
131     vfpackf(file, format, args);
132     va_end(args);
133 }
134
135 extern void vspackf(void *buffer, const char *format, va_list args)
136 {
137     struct BinIOFormatCursor cursor;
138     struct BinIOPackContext context;
139
140     BinIOInitFormatCursor(&cursor, format);
141
142     context.buffer = (unsigned char *)buffer;
143     va_copy(context.args, args);
144
145     while (BinIONextChar(&context, &cursor, BinIOPack)) {}
146
147     va_end(context.args);
148 }
149
150 extern void vfpackf(FILE *file, const char *format, va_list args)
151 {
152     size_t n_bytes = BinIOFormatByteCount(format);
153     void* buffer = malloc(n_bytes);
154
155     vspackf(buffer, format, args);
156
157     fwrite(buffer, n_bytes, 1, file);
158     free(buffer);
159 }