00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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 char str[1024];
00103
00104 assert(io);
00105 if (!io || !io->log_func)
00106 return;
00107
00108 va_start(args, format);
00109 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 }