38
|
1 #ifndef ALMIXER_COMPILED_WITH_SDL
|
|
2
|
|
3 #include "ALmixer_RWops.h"
|
|
4 #include <stdlib.h> /* malloc, free */
|
|
5 #include <stdio.h> /* fopen, fseek, fread, fclose */
|
|
6 #include <string.h> /* strerror */
|
|
7 #include <errno.h> /* errno */
|
|
8
|
|
9 /* (Note this is different than stdio's seek. This returns ftell.)
|
|
10 */
|
|
11 static int stdio_seek(ALmixer_RWops* the_context, long offset, int whence)
|
|
12 {
|
|
13 if(0 == fseek(the_context->hidden.stdio.fp, offset, whence))
|
|
14 {
|
|
15 return(ftell(the_context->hidden.stdio.fp));
|
|
16 }
|
|
17 else
|
|
18 {
|
|
19 /* ALmixer_SetError("ALmixer_RWops seek failed: %s", strerror(errno)); */
|
|
20 return (-1);
|
|
21 }
|
|
22 }
|
|
23
|
|
24 static size_t stdio_read(ALmixer_RWops* the_context, void* ptr, size_t size, size_t nitems)
|
|
25 {
|
|
26 size_t bytes_read;
|
|
27
|
|
28 bytes_read = fread(ptr, size, nitems, the_context->hidden.stdio.fp);
|
|
29 if(0 == bytes_read && ferror(the_context->hidden.stdio.fp))
|
|
30 {
|
|
31 /* not sure if strerror can convert ferror */
|
|
32 /* ALmixer_SetError("ALmixer_RWops read failed: %s", strerror(ferror(the_context->hidden.stdio.fp))); */
|
|
33 }
|
|
34 return bytes_read;
|
|
35 }
|
|
36
|
|
37 static size_t stdio_write(ALmixer_RWops* the_context, const void* ptr, size_t size, size_t nitems)
|
|
38 {
|
|
39 size_t bytes_written;
|
|
40
|
|
41 bytes_written = fwrite(ptr, size, nitems, the_context->hidden.stdio.fp);
|
|
42 if(0 == bytes_written && ferror(the_context->hidden.stdio.fp))
|
|
43 {
|
|
44 /* ALmixer_SetError("ALmixer_RWops write failed: %s", strerror(ferror(the_context->hidden.stdio.fp))); */
|
|
45 }
|
|
46 return bytes_written;
|
|
47 }
|
|
48
|
|
49 static int stdio_close(ALmixer_RWops* the_context)
|
|
50 {
|
|
51 int return_status = 0;
|
|
52 if(NULL != the_context)
|
|
53 {
|
|
54 if(0 != the_context->hidden.stdio.autoclose)
|
|
55 {
|
|
56 if(0 != fclose(the_context->hidden.stdio.fp))
|
|
57 {
|
|
58 /* ALmixer_SetError("ALmixer_RWops close failed: %s", strerror(errno)); */
|
|
59 return_status = -1;
|
|
60 }
|
|
61 }
|
|
62 free(the_context);
|
|
63 }
|
|
64 return return_status;
|
|
65 }
|
|
66
|
|
67 ALmixer_RWops* ALmixer_RWFromFP(FILE* file_pointer, char autoclose_flag)
|
|
68 {
|
|
69 ALmixer_RWops* rw_ops = NULL;
|
|
70
|
|
71 rw_ops = (ALmixer_RWops*)malloc(sizeof(ALmixer_RWops));
|
|
72 if(NULL == rw_ops)
|
|
73 {
|
|
74 /* ALmixer_SetError("ALmixer_RWFromFP: Out of memory"); */
|
|
75 return NULL;
|
|
76 }
|
|
77
|
|
78 rw_ops->seek = stdio_seek;
|
|
79 rw_ops->read = stdio_read;
|
|
80 rw_ops->write = stdio_write;
|
|
81 rw_ops->close = stdio_close;
|
|
82 rw_ops->hidden.stdio.fp = file_pointer;
|
|
83 rw_ops->hidden.stdio.autoclose = autoclose_flag;
|
|
84 return rw_ops;
|
|
85 }
|
|
86
|
|
87 ALmixer_RWops* ALmixer_RWFromFile(const char* file_name, const char* file_mode)
|
|
88 {
|
|
89 ALmixer_RWops* rw_ops = NULL;
|
|
90 FILE* file_pointer = NULL;
|
|
91 if(NULL == file_name || NULL == file_mode)
|
|
92 {
|
|
93 /* ALmixer_SetError("ALmixer_RWFromFile: No file or mode specified"); */
|
|
94 return NULL;
|
|
95 }
|
|
96 file_pointer = fopen(file_name, file_mode);
|
|
97 if(NULL == file_pointer)
|
|
98 {
|
|
99 /* ALmixer_SetError("ALmixer_RWFromFile: Could not open file: %s", strerror(errno)); */
|
|
100 return NULL;
|
|
101 }
|
|
102
|
|
103 rw_ops = ALmixer_RWFromFP(file_pointer, 1);
|
|
104 return rw_ops;
|
|
105 }
|
|
106
|
|
107
|
|
108 #endif /* ALMIXER_COMPILED_WITH_SDL */
|