]> git.jsancho.org Git - lugaru.git/blob - Source/pack.c
License: Update GPLv2+ header to match current FSF recommendation
[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 modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 Lugaru 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.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <stdlib.h>
21
22 #include "binio.h"
23 #include "private.h"
24
25 struct BinIOPackContext {
26     uint8_t *buffer;
27     va_list  args;
28 };
29
30 static void BinIOPack(void *context, int type, int byte_order, int count)
31 {
32     struct BinIOPackContext *ctx = (struct BinIOPackContext*)context;
33     if (count == -1) {
34         switch (type) {
35         case BinIO_TYPE_IGNORE_BYTE: {
36             ctx->buffer += 1;
37         }
38         break;
39         case BinIO_TYPE_BYTE: {
40             uint8_t value = va_arg(ctx->args, int);
41             BinIOConvert1(BinIO_HOST_BYTE_ORDER, byte_order, (const uint8_t *)&value, ctx->buffer, 1);
42             ctx->buffer += 1;
43         }
44         break;
45         case BinIO_TYPE_INT16: {
46             uint16_t value = va_arg(ctx->args, int);
47             BinIOConvert2(BinIO_HOST_BYTE_ORDER, byte_order, (const uint8_t *)&value, ctx->buffer, 1);
48             ctx->buffer += 2;
49         }
50         break;
51         case BinIO_TYPE_INT32: {
52             int value = va_arg(ctx->args, int);
53             BinIOConvert4(BinIO_HOST_BYTE_ORDER, byte_order, (const uint8_t *)&value, ctx->buffer, 1);
54             ctx->buffer += 4;
55         }
56         break;
57         case BinIO_TYPE_INT64: {
58             uint64_t value = va_arg(ctx->args, uint64_t);
59             BinIOConvert8(BinIO_HOST_BYTE_ORDER, byte_order, (const uint8_t *)&value, ctx->buffer, 1);
60             ctx->buffer += 8;
61         }
62         break;
63         case BinIO_TYPE_FLOAT32: {
64             float32_t value = (float32_t)va_arg(ctx->args, double);
65             BinIOConvert4(BinIO_HOST_BYTE_ORDER, byte_order, (const uint8_t *)&value, ctx->buffer, 1);
66             ctx->buffer += 4;
67         }
68         break;
69         case BinIO_TYPE_FLOAT64: {
70             float64_t value = va_arg(ctx->args, float64_t);
71             BinIOConvert8(BinIO_HOST_BYTE_ORDER, byte_order, (const uint8_t *)&value, ctx->buffer, 1);
72             ctx->buffer += 8;
73         }
74         break;
75         }
76     } else {
77         switch (type) {
78         case BinIO_TYPE_IGNORE_BYTE:
79             ctx->buffer += 1 * count;
80             break;
81         case BinIO_TYPE_BYTE:
82             BinIOConvert1(BinIO_HOST_BYTE_ORDER, byte_order, va_arg(ctx->args, uint8_t *), ctx->buffer, count);
83             ctx->buffer += 1 * count;
84             break;
85         case BinIO_TYPE_INT16:
86             BinIOConvert2(BinIO_HOST_BYTE_ORDER, byte_order, va_arg(ctx->args, uint8_t *), ctx->buffer, count);
87             ctx->buffer += 2 * count;
88             break;
89         case BinIO_TYPE_INT32:
90             BinIOConvert4(BinIO_HOST_BYTE_ORDER, byte_order, va_arg(ctx->args, uint8_t *), ctx->buffer, count);
91             ctx->buffer += 4 * count;
92             break;
93         case BinIO_TYPE_INT64:
94             BinIOConvert8(BinIO_HOST_BYTE_ORDER, byte_order, va_arg(ctx->args, uint8_t *), ctx->buffer, count);
95             ctx->buffer += 8 * count;
96             break;
97         case BinIO_TYPE_FLOAT32:
98             BinIOConvert4(BinIO_HOST_BYTE_ORDER, byte_order, va_arg(ctx->args, uint8_t *), ctx->buffer, count);
99             ctx->buffer += 4 * count;
100             break;
101         case BinIO_TYPE_FLOAT64:
102             BinIOConvert8(BinIO_HOST_BYTE_ORDER, byte_order, va_arg(ctx->args, uint8_t *), ctx->buffer, count);
103             ctx->buffer += 8 * count;
104             break;
105         }
106     }
107 }
108
109 extern void packf(const char *format, ...)
110 {
111     va_list args;
112     va_start(args, format);
113     vfpackf(stdout, format, args);
114     va_end(args);
115 }
116
117 extern void spackf(void *buffer, const char *format, ...)
118 {
119     va_list args;
120     va_start(args, format);
121     vspackf(buffer, format, args);
122     va_end(args);
123 }
124
125 extern void fpackf(FILE *file, const char *format, ...)
126 {
127     va_list args;
128     va_start(args, format);
129     vfpackf(file, format, args);
130     va_end(args);
131 }
132
133 extern void vspackf(void *buffer, const char *format, va_list args)
134 {
135     struct BinIOFormatCursor cursor;
136     struct BinIOPackContext context;
137
138     BinIOInitFormatCursor(&cursor, format);
139
140     context.buffer = (unsigned char *)buffer;
141     va_copy(context.args, args);
142
143     while (BinIONextChar(&context, &cursor, BinIOPack)) {}
144
145     va_end(context.args);
146 }
147
148 extern void vfpackf(FILE *file, const char *format, va_list args)
149 {
150     size_t n_bytes = BinIOFormatByteCount(format);
151     void* buffer = malloc(n_bytes);
152
153     vspackf(buffer, format, args);
154
155     fwrite(buffer, n_bytes, 1, file);
156     free(buffer);
157 }