2 * The 3D Studio File Format Library
3 * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or (at
9 * your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * $Id: io.c,v 1.3 2001/07/11 13:47:35 jeh Exp $
23 #include <lib3ds/io.h>
29 * \defgroup io Binary Input/Ouput Abstraction Layer
31 * \author J.E. Hoffmann <je-h@gmx.net>
37 Lib3dsIoErrorFunc error_func;
38 Lib3dsIoSeekFunc seek_func;
39 Lib3dsIoTellFunc tell_func;
40 Lib3dsIoReadFunc read_func;
41 Lib3dsIoWriteFunc write_func;
46 lib3ds_io_new(void *self, Lib3dsIoErrorFunc error_func, Lib3dsIoSeekFunc seek_func,
47 Lib3dsIoTellFunc tell_func, Lib3dsIoReadFunc read_func, Lib3dsIoWriteFunc write_func)
49 Lib3dsIo *io = calloc(sizeof(Lib3dsIo),1);
56 io->error_func = error_func;
57 io->seek_func = seek_func;
58 io->tell_func = tell_func;
59 io->read_func = read_func;
60 io->write_func = write_func;
67 lib3ds_io_free(Lib3dsIo *io)
78 lib3ds_io_error(Lib3dsIo *io)
81 if (!io || !io->error_func) {
84 return (*io->error_func)(io->self);
89 lib3ds_io_seek(Lib3dsIo *io, long offset, Lib3dsIoSeek origin)
92 if (!io || !io->seek_func) {
95 return (*io->seek_func)(io->self, offset, origin);
100 lib3ds_io_tell(Lib3dsIo *io)
103 if (!io || !io->tell_func) {
106 return (*io->tell_func)(io->self);
111 lib3ds_io_read(Lib3dsIo *io, Lib3dsByte *buffer, int size)
114 if (!io || !io->read_func) {
117 return (*io->read_func)(io->self, buffer, size);
122 lib3ds_io_write(Lib3dsIo *io, const Lib3dsByte *buffer, int size)
125 if (!io || !io->write_func) {
128 return (*io->write_func)(io->self, buffer, size);
135 * Read a byte from a file stream.
138 lib3ds_io_read_byte(Lib3dsIo *io)
143 lib3ds_io_read(io, &b, 1);
149 * Read a word from a file stream in little endian format.
152 lib3ds_io_read_word(Lib3dsIo *io)
158 lib3ds_io_read(io, b, 2);
159 w=((Lib3dsWord)b[1] << 8) |
168 * Read a dword from file a stream in little endian format.
171 lib3ds_io_read_dword(Lib3dsIo *io)
177 lib3ds_io_read(io, b, 4);
178 d=((Lib3dsDword)b[3] << 24) |
179 ((Lib3dsDword)b[2] << 16) |
180 ((Lib3dsDword)b[1] << 8) |
189 * Read a signed byte from a file stream.
192 lib3ds_io_read_intb(Lib3dsIo *io)
197 lib3ds_io_read(io, (Lib3dsByte*)&b, 1);
205 * Read a signed word from a file stream in little endian format.
208 lib3ds_io_read_intw(Lib3dsIo *io)
214 lib3ds_io_read(io, b, 2);
215 w=((Lib3dsWord)b[1] << 8) |
217 return((Lib3dsIntw)w);
224 * Read a signed dword a from file stream in little endian format.
227 lib3ds_io_read_intd(Lib3dsIo *io)
233 lib3ds_io_read(io, b, 4);
234 d=((Lib3dsDword)b[3] << 24) |
235 ((Lib3dsDword)b[2] << 16) |
236 ((Lib3dsDword)b[1] << 8) |
238 return((Lib3dsIntd)d);
245 * Read a float from a file stream in little endian format.
248 lib3ds_io_read_float(Lib3dsIo *io)
254 lib3ds_io_read(io, b, 4);
255 d=((Lib3dsDword)b[3] << 24) |
256 ((Lib3dsDword)b[2] << 16) |
257 ((Lib3dsDword)b[1] << 8) |
259 return(*((Lib3dsFloat*)&d));
267 * Read a vector from a file stream in little endian format.
269 * \param io IO input handle.
270 * \param v The vector to store the data.
273 lib3ds_io_read_vector(Lib3dsIo *io, Lib3dsVector v)
277 v[0]=lib3ds_io_read_float(io);
278 v[1]=lib3ds_io_read_float(io);
279 v[2]=lib3ds_io_read_float(io);
281 return(!lib3ds_io_error(io));
289 lib3ds_io_read_rgb(Lib3dsIo *io, Lib3dsRgb rgb)
293 rgb[0]=lib3ds_io_read_float(io);
294 rgb[1]=lib3ds_io_read_float(io);
295 rgb[2]=lib3ds_io_read_float(io);
297 return(!lib3ds_io_error(io));
304 * Read a zero-terminated string from a file stream.
306 * \param io IO input handle.
307 * \param s The buffer to store the read string.
308 * \param buflen Buffer length.
310 * \return True on success, False otherwise.
313 lib3ds_io_read_string(Lib3dsIo *io, char *s, int buflen)
320 if (lib3ds_io_read(io, (Lib3dsByte*)&c, 1)!=1) {
329 return(LIB3DS_FALSE);
333 return(!lib3ds_io_error(io));
340 * Writes a byte into a file stream.
343 lib3ds_io_write_byte(Lib3dsIo *io, Lib3dsByte b)
346 if (lib3ds_io_write(io, &b, 1)!=1) {
347 return(LIB3DS_FALSE);
356 * Writes a word into a little endian file stream.
359 lib3ds_io_write_word(Lib3dsIo *io, Lib3dsWord w)
364 b[1]=((Lib3dsWord)w & 0xFF00) >> 8;
365 b[0]=((Lib3dsWord)w & 0x00FF);
366 if (lib3ds_io_write(io, b, 2)!=2) {
367 return(LIB3DS_FALSE);
376 * Writes a dword into a little endian file stream.
379 lib3ds_io_write_dword(Lib3dsIo *io, Lib3dsDword d)
384 b[3]=(Lib3dsByte)(((Lib3dsDword)d & 0xFF000000) >> 24);
385 b[2]=(Lib3dsByte)(((Lib3dsDword)d & 0x00FF0000) >> 16);
386 b[1]=(Lib3dsByte)(((Lib3dsDword)d & 0x0000FF00) >> 8);
387 b[0]=(Lib3dsByte)(((Lib3dsDword)d & 0x000000FF));
388 if (lib3ds_io_write(io, b, 4)!=4) {
389 return(LIB3DS_FALSE);
398 * Writes a signed byte in a file stream.
401 lib3ds_io_write_intb(Lib3dsIo *io, Lib3dsIntb b)
404 if (lib3ds_io_write(io, (Lib3dsByte*)&b, 1)!=1) {
405 return(LIB3DS_FALSE);
414 * Writes a signed word into a little endian file stream.
417 lib3ds_io_write_intw(Lib3dsIo *io, Lib3dsIntw w)
422 b[1]=((Lib3dsWord)w & 0xFF00) >> 8;
423 b[0]=((Lib3dsWord)w & 0x00FF);
424 if (lib3ds_io_write(io, b, 2)!=2) {
425 return(LIB3DS_FALSE);
434 * Writes a signed dword into a little endian file stream.
437 lib3ds_io_write_intd(Lib3dsIo *io, Lib3dsIntd d)
442 b[3]=(Lib3dsByte)(((Lib3dsDword)d & 0xFF000000) >> 24);
443 b[2]=(Lib3dsByte)(((Lib3dsDword)d & 0x00FF0000) >> 16);
444 b[1]=(Lib3dsByte)(((Lib3dsDword)d & 0x0000FF00) >> 8);
445 b[0]=(Lib3dsByte)(((Lib3dsDword)d & 0x000000FF));
446 if (lib3ds_io_write(io, b, 4)!=4) {
447 return(LIB3DS_FALSE);
456 * Writes a float into a little endian file stream.
459 lib3ds_io_write_float(Lib3dsIo *io, Lib3dsFloat l)
465 d=*((Lib3dsDword*)&l);
466 b[3]=(Lib3dsByte)(((Lib3dsDword)d & 0xFF000000) >> 24);
467 b[2]=(Lib3dsByte)(((Lib3dsDword)d & 0x00FF0000) >> 16);
468 b[1]=(Lib3dsByte)(((Lib3dsDword)d & 0x0000FF00) >> 8);
469 b[0]=(Lib3dsByte)(((Lib3dsDword)d & 0x000000FF));
470 if (lib3ds_io_write(io, b, 4)!=4) {
471 return(LIB3DS_FALSE);
481 * Writes a vector into a file stream in little endian format.
484 lib3ds_io_write_vector(Lib3dsIo *io, Lib3dsVector v)
487 for (i=0; i<3; ++i) {
488 if (!lib3ds_io_write_float(io, v[i])) {
489 return(LIB3DS_FALSE);
500 lib3ds_io_write_rgb(Lib3dsIo *io, Lib3dsRgb rgb)
503 for (i=0; i<3; ++i) {
504 if (!lib3ds_io_write_float(io, rgb[i])) {
505 return(LIB3DS_FALSE);
515 * Writes a zero-terminated string into a file stream.
518 lib3ds_io_write_string(Lib3dsIo *io, const char *s)
522 lib3ds_io_write(io, (const Lib3dsByte*)s, strlen(s)+1);
523 return(!lib3ds_io_error(io));