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