Home | API | File List | Examples | Download

lib3ds_io.c

00001 /*
00002     Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
00003     All rights reserved.
00004     
00005     This program is free  software: you can redistribute it and/or modify 
00006     it under the terms of the GNU Lesser General Public License as published 
00007     by the Free Software Foundation, either version 2.1 of the License, or 
00008     (at your option) any later version.
00009 
00010     Thisprogram  is  distributed in the hope that it will be useful, 
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of 
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
00013     GNU Lesser General Public License for more details.
00014     
00015     You should  have received a copy of the GNU Lesser General Public License
00016     along with  this program; If not, see <http://www.gnu.org/licenses/>. 
00017 */
00018 #include "lib3ds_impl.h"
00019 
00020 
00021 typedef union {
00022     uint32_t dword_value;
00023     float float_value;
00024 } Lib3dsDwordFloat;
00025 
00026 
00027 void
00028 lib3ds_io_setup(Lib3dsIo *io) {
00029     assert(io);
00030     io->impl = calloc(sizeof(Lib3dsIoImpl), 1);
00031 }
00032 
00033 
00034 void
00035 lib3ds_io_cleanup(Lib3dsIo *io) {
00036     Lib3dsIoImpl *impl;
00037     assert(io);
00038     impl = (Lib3dsIoImpl*)io->impl;
00039     if (impl->tmp_mem) {
00040         free(impl->tmp_mem);
00041         impl->tmp_mem = NULL;
00042     }
00043     if (impl->tmp_node) {
00044         lib3ds_node_free(impl->tmp_node);
00045         impl->tmp_node = NULL;
00046     }
00047     free(impl);
00048 }
00049 
00050 
00051 long
00052 lib3ds_io_seek(Lib3dsIo *io, long offset, Lib3dsIoSeek origin) {
00053     assert(io);
00054     if (!io || !io->seek_func) {
00055         return 0;
00056     }
00057     return (*io->seek_func)(io->self, offset, origin);
00058 }
00059 
00060 
00061 long
00062 lib3ds_io_tell(Lib3dsIo *io) {
00063     assert(io);
00064     if (!io || !io->tell_func) {
00065         return 0;
00066     }
00067     return (*io->tell_func)(io->self);
00068 }
00069 
00070 
00071 size_t
00072 lib3ds_io_read(Lib3dsIo *io, void *buffer, size_t size) {
00073     assert(io);
00074     if (!io || !io->read_func) {
00075         return 0;
00076     }
00077     return (*io->read_func)(io->self, buffer, size);
00078 }
00079 
00080 
00081 size_t
00082 lib3ds_io_write(Lib3dsIo *io, const void *buffer, size_t size) {
00083     assert(io);
00084     if (!io || !io->write_func) {
00085         return 0;
00086     }
00087     return (*io->write_func)(io->self, buffer, size);
00088 }
00089 
00090 
00091 static void 
00092 lib3ds_io_log_str(Lib3dsIo *io, Lib3dsLogLevel level, const char *str) {
00093     if (!io || !io->log_func)
00094         return;
00095     (*io->log_func)(io->self, level, ((Lib3dsIoImpl*)io->impl)->log_indent, str);
00096 }
00097 
00098 
00099 void 
00100 lib3ds_io_log(Lib3dsIo *io, Lib3dsLogLevel level, const char *format, ...) {
00101     va_list args;
00102     /* FIXME */ char str[1024];
00103 
00104     assert(io);
00105     if (!io || !io->log_func)
00106         return;
00107 
00108     va_start(args, format);
00109     /* FIXME: */ vsprintf(str, format, args); 
00110     lib3ds_io_log_str(io, level, str);
00111 
00112     if (level == LIB3DS_LOG_ERROR) {
00113         longjmp(((Lib3dsIoImpl*)io->impl)->jmpbuf, 1);
00114     }
00115 }
00116 
00117 
00118 void 
00119 lib3ds_io_log_indent(Lib3dsIo *io, int indent) {
00120     assert(io);
00121     if (!io)
00122         return;
00123     ((Lib3dsIoImpl*)io->impl)->log_indent += indent;
00124 }
00125 
00126 
00127 void 
00128 lib3ds_io_read_error(Lib3dsIo *io) {
00129     lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Reading from input stream failed.");
00130 }
00131 
00132 
00133 void 
00134 lib3ds_io_write_error(Lib3dsIo *io) {
00135     lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Writing to output stream failed.");
00136 }
00137 
00138 
00142 uint8_t
00143 lib3ds_io_read_byte(Lib3dsIo *io) {
00144     uint8_t b;
00145 
00146     assert(io);
00147     lib3ds_io_read(io, &b, 1);
00148     return(b);
00149 }
00150 
00151 
00155 uint16_t
00156 lib3ds_io_read_word(Lib3dsIo *io) {
00157     uint8_t b[2];
00158     uint16_t w;
00159 
00160     assert(io);
00161     lib3ds_io_read(io, b, 2);
00162     w = ((uint16_t)b[1] << 8) |
00163         ((uint16_t)b[0]);
00164     return(w);
00165 }
00166 
00167 
00171 uint32_t
00172 lib3ds_io_read_dword(Lib3dsIo *io) {
00173     uint8_t b[4];
00174     uint32_t d;
00175 
00176     assert(io);
00177     lib3ds_io_read(io, b, 4);
00178     d = ((uint32_t)b[3] << 24) |
00179         ((uint32_t)b[2] << 16) |
00180         ((uint32_t)b[1] << 8) |
00181         ((uint32_t)b[0]);
00182     return(d);
00183 }
00184 
00185 
00189 int8_t
00190 lib3ds_io_read_intb(Lib3dsIo *io) {
00191     int8_t b;
00192 
00193     assert(io);
00194     lib3ds_io_read(io, &b, 1);
00195     return(b);
00196 }
00197 
00198 
00202 int16_t
00203 lib3ds_io_read_intw(Lib3dsIo *io) {
00204     uint8_t b[2];
00205     uint16_t w;
00206 
00207     assert(io);
00208     lib3ds_io_read(io, b, 2);
00209     w = ((uint16_t)b[1] << 8) |
00210         ((uint16_t)b[0]);
00211     return((int16_t)w);
00212 }
00213 
00214 
00218 int32_t
00219 lib3ds_io_read_intd(Lib3dsIo *io) {
00220     uint8_t b[4];
00221     uint32_t d;
00222 
00223     assert(io);
00224     lib3ds_io_read(io, b, 4);
00225     d = ((uint32_t)b[3] << 24) |
00226         ((uint32_t)b[2] << 16) |
00227         ((uint32_t)b[1] << 8) |
00228         ((uint32_t)b[0]);
00229     return((int32_t)d);
00230 }
00231 
00232 
00236 float
00237 lib3ds_io_read_float(Lib3dsIo *io) {
00238     uint8_t b[4];
00239     Lib3dsDwordFloat d;
00240 
00241     assert(io);
00242     lib3ds_io_read(io, b, 4);
00243     d.dword_value = ((uint32_t)b[3] << 24) |
00244                     ((uint32_t)b[2] << 16) |
00245                     ((uint32_t)b[1] << 8) |
00246                     ((uint32_t)b[0]);
00247     return d.float_value;
00248 }
00249 
00250 
00257 void
00258 lib3ds_io_read_vector(Lib3dsIo *io, float v[3]) {
00259     assert(io);
00260     v[0] = lib3ds_io_read_float(io);
00261     v[1] = lib3ds_io_read_float(io);
00262     v[2] = lib3ds_io_read_float(io);
00263 }
00264 
00265 
00266 void
00267 lib3ds_io_read_rgb(Lib3dsIo *io, float rgb[3]) {
00268     assert(io);
00269     rgb[0] = lib3ds_io_read_float(io);
00270     rgb[1] = lib3ds_io_read_float(io);
00271     rgb[2] = lib3ds_io_read_float(io);
00272 }
00273 
00274 
00284 void
00285 lib3ds_io_read_string(Lib3dsIo *io, char *s, int buflen) {
00286     char c;
00287     int k = 0;
00288 
00289     assert(io);
00290     for (;;) {
00291         if (lib3ds_io_read(io, &c, 1) != 1) {
00292             lib3ds_io_read_error(io);
00293         }
00294         *s++ = c;
00295         if (!c) {
00296             break;
00297         }
00298         ++k;
00299         if (k >= buflen) {
00300             lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Invalid string in input stream.");
00301         }
00302     }
00303 }
00304 
00305 
00309 void
00310 lib3ds_io_write_byte(Lib3dsIo *io, uint8_t b) {
00311     assert(io);
00312     if (lib3ds_io_write(io, &b, 1) != 1) {
00313         lib3ds_io_write_error(io);
00314     }
00315 }
00316 
00317 
00321 void
00322 lib3ds_io_write_word(Lib3dsIo *io, uint16_t w) {
00323     uint8_t b[2];
00324 
00325     assert(io);
00326     b[1] = ((uint16_t)w & 0xFF00) >> 8;
00327     b[0] = ((uint16_t)w & 0x00FF);
00328     if (lib3ds_io_write(io, b, 2) != 2) {
00329         lib3ds_io_write_error(io);
00330     }
00331 }
00332 
00333 
00337 void
00338 lib3ds_io_write_dword(Lib3dsIo *io, uint32_t d) {
00339     uint8_t b[4];
00340 
00341     assert(io);
00342     b[3] = (uint8_t)(((uint32_t)d & 0xFF000000) >> 24);
00343     b[2] = (uint8_t)(((uint32_t)d & 0x00FF0000) >> 16);
00344     b[1] = (uint8_t)(((uint32_t)d & 0x0000FF00) >> 8);
00345     b[0] = (uint8_t)(((uint32_t)d & 0x000000FF));
00346     if (lib3ds_io_write(io, b, 4) != 4) {
00347         lib3ds_io_write_error(io);
00348     }
00349 }
00350 
00351 
00355 void
00356 lib3ds_io_write_intb(Lib3dsIo *io, int8_t b) {
00357     assert(io);
00358     if (lib3ds_io_write(io, &b, 1) != 1) {
00359         lib3ds_io_write_error(io);
00360     }
00361 }
00362 
00363 
00367 void
00368 lib3ds_io_write_intw(Lib3dsIo *io, int16_t w) {
00369     uint8_t b[2];
00370 
00371     assert(io);
00372     b[1] = ((uint16_t)w & 0xFF00) >> 8;
00373     b[0] = ((uint16_t)w & 0x00FF);
00374     if (lib3ds_io_write(io, b, 2) != 2) {
00375         lib3ds_io_write_error(io);
00376     }
00377 }
00378 
00379 
00383 void
00384 lib3ds_io_write_intd(Lib3dsIo *io, int32_t d) {
00385     uint8_t b[4];
00386 
00387     assert(io);
00388     b[3] = (uint8_t)(((uint32_t)d & 0xFF000000) >> 24);
00389     b[2] = (uint8_t)(((uint32_t)d & 0x00FF0000) >> 16);
00390     b[1] = (uint8_t)(((uint32_t)d & 0x0000FF00) >> 8);
00391     b[0] = (uint8_t)(((uint32_t)d & 0x000000FF));
00392     if (lib3ds_io_write(io, b, 4) != 4) {
00393         lib3ds_io_write_error(io);
00394     }
00395 }
00396 
00397 
00401 void
00402 lib3ds_io_write_float(Lib3dsIo *io, float l) {
00403     uint8_t b[4];
00404     Lib3dsDwordFloat d;
00405 
00406     assert(io);
00407     d.float_value = l;
00408     b[3] = (uint8_t)(((uint32_t)d.dword_value & 0xFF000000) >> 24);
00409     b[2] = (uint8_t)(((uint32_t)d.dword_value & 0x00FF0000) >> 16);
00410     b[1] = (uint8_t)(((uint32_t)d.dword_value & 0x0000FF00) >> 8);
00411     b[0] = (uint8_t)(((uint32_t)d.dword_value & 0x000000FF));
00412     if (lib3ds_io_write(io, b, 4) != 4) {
00413         lib3ds_io_write_error(io);
00414     }
00415 }
00416 
00417 
00421 void
00422 lib3ds_io_write_vector(Lib3dsIo *io, float v[3]) {
00423     int i;
00424     for (i = 0; i < 3; ++i) {
00425         lib3ds_io_write_float(io, v[i]);
00426     }
00427 }
00428 
00429 
00430 void
00431 lib3ds_io_write_rgb(Lib3dsIo *io, float rgb[3]) {
00432     int i;
00433     for (i = 0; i < 3; ++i) {
00434         lib3ds_io_write_float(io, rgb[i]);
00435     }
00436 }
00437 
00438 
00442 void
00443 lib3ds_io_write_string(Lib3dsIo *io, const char *s) {
00444     size_t len;
00445     assert(io && s);
00446     len = strlen(s);
00447     if (lib3ds_io_write(io, s, len + 1) != len +1) {
00448         lib3ds_io_write_error(io);
00449     }
00450 }