]> git.jsancho.org Git - lugaru.git/blob - Source/unpack.c
429a2cdf5039f5ea202bdd0a45b06efbc3fe4fe2
[lugaru.git] / Source / unpack.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 BinIOUnpackContext {
28     const uint8_t *data;
29     va_list        args;
30 };
31
32 static void BinIOUnpack(void *context, int type, int byte_order, int count)
33 {
34     struct BinIOUnpackContext *ctx = (struct BinIOUnpackContext*)context;
35     if (count == -1) {
36         count = 1;
37     }
38
39     switch (type) {
40     case BinIO_TYPE_IGNORE_BYTE:
41         ctx->data += 1 * count;
42         break;
43     case BinIO_TYPE_BYTE:
44         BinIOConvert1(byte_order, BinIO_HOST_BYTE_ORDER, ctx->data, va_arg(ctx->args, uint8_t *), count);
45         ctx->data += 1 * count;
46         break;
47     case BinIO_TYPE_INT16:
48         BinIOConvert2(byte_order, BinIO_HOST_BYTE_ORDER, ctx->data, va_arg(ctx->args, uint8_t *), count);
49         ctx->data += 2 * count;
50         break;
51     case BinIO_TYPE_INT32:
52         BinIOConvert4(byte_order, BinIO_HOST_BYTE_ORDER, ctx->data, va_arg(ctx->args, uint8_t *), count);
53         ctx->data += 4 * count;
54         break;
55     case BinIO_TYPE_INT64:
56         BinIOConvert8(byte_order, BinIO_HOST_BYTE_ORDER, ctx->data, va_arg(ctx->args, uint8_t *), count);
57         ctx->data += 8 * count;
58         break;
59     case BinIO_TYPE_FLOAT32:
60         BinIOConvert4(byte_order, BinIO_HOST_BYTE_ORDER, ctx->data, va_arg(ctx->args, uint8_t *), count);
61         ctx->data += 4 * count;
62         break;
63     case BinIO_TYPE_FLOAT64:
64         BinIOConvert8(byte_order, BinIO_HOST_BYTE_ORDER, ctx->data, va_arg(ctx->args, uint8_t *), count);
65         ctx->data += 8 * count;
66         break;
67     }
68 }
69
70 void unpackf(const char *format, ...)
71 {
72     va_list args;
73     va_start(args, format);
74     vfunpackf(stdin, format, args);
75     va_end(args);
76 }
77
78 void sunpackf(const void *buffer, const char *format, ...)
79 {
80     va_list args;
81     va_start(args, format);
82     vsunpackf(buffer, format, args);
83     va_end(args);
84 }
85
86 void funpackf(FILE *file, const char *format, ...)
87 {
88     va_list args;
89     va_start(args, format);
90     vfunpackf(file, format, args);
91     va_end(args);
92 }
93
94 void vsunpackf(const void *buffer, const char *format, va_list args)
95 {
96     struct BinIOFormatCursor cursor;
97     struct BinIOUnpackContext context;
98
99     BinIOInitFormatCursor(&cursor, format);
100
101     context.data = (const unsigned char*)buffer;
102     va_copy(context.args, args);
103
104     while (BinIONextChar(&context, &cursor, BinIOUnpack)) {}
105
106     va_end(context.args);
107 }
108
109 void vfunpackf(FILE *file, const char *format, va_list args)
110 {
111     size_t n_bytes = BinIOFormatByteCount(format);
112     void* buffer = malloc(n_bytes);
113     fread(buffer, n_bytes, 1, file);
114
115     vsunpackf(buffer, format, args);
116
117     free(buffer);
118 }