1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdarg.h>
5 #include <stdint.h>
6 #include <errno.h>
7
8 #include "shadowdive/internal/writer.h"
9
10 struct sd_writer_t {
11 FILE *handle;
12 int sd_errno;
13 };
14
sd_writer_open(const char * file)15 sd_writer* sd_writer_open(const char *file) {
16 sd_writer *writer = malloc(sizeof(sd_writer));
17
18 writer->handle = fopen(file, "wb");
19 writer->sd_errno = 0;
20 if(!writer->handle) {
21 free(writer);
22 return 0;
23 }
24
25 return writer;
26 }
27
sd_writer_errno(const sd_writer * writer)28 int sd_writer_errno(const sd_writer *writer) {
29 return writer->sd_errno;
30 }
31
sd_writer_close(sd_writer * writer)32 void sd_writer_close(sd_writer *writer) {
33 fclose(writer->handle);
34 free(writer);
35 }
36
sd_writer_pos(sd_writer * writer)37 long sd_writer_pos(sd_writer *writer) {
38 long res = ftell(writer->handle);
39 if (res == -1) {
40 writer->sd_errno = errno;
41 }
42 return res;
43 }
44
sd_writer_seek_start(const sd_writer * writer,long offset)45 int sd_writer_seek_start(const sd_writer *writer, long offset) {
46 return fseek(writer->handle, offset, SEEK_SET);
47 }
48
sd_writer_seek_cur(const sd_writer * writer,long offset)49 int sd_writer_seek_cur(const sd_writer *writer, long offset) {
50 return fseek(writer->handle, offset, SEEK_CUR);
51 }
52
sd_writer_seek_end(const sd_writer * writer,long offset)53 int sd_writer_seek_end(const sd_writer *writer, long offset) {
54 return fseek(writer->handle, offset, SEEK_END);
55 }
56
sd_write_buf(sd_writer * writer,const char * buf,int len)57 int sd_write_buf(sd_writer *writer, const char *buf, int len) {
58 if(fwrite(buf, 1, len, writer->handle) != len) {
59 writer->sd_errno = ferror(writer->handle);
60 return 0;
61 }
62 return 1;
63 }
64
sd_write_fprintf(const sd_writer * writer,const char * format,...)65 int sd_write_fprintf(const sd_writer *writer, const char *format, ...) {
66 va_list argp;
67 va_start(argp, format);
68 int ret = vfprintf(writer->handle, format, argp);
69 va_end(argp);
70 return ret;
71 }
72
sd_write_ubyte(sd_writer * writer,uint8_t data)73 void sd_write_ubyte(sd_writer *writer, uint8_t data) {
74 sd_write_buf(writer, (char*)&data, 1);
75 }
76
sd_write_uword(sd_writer * writer,uint16_t data)77 void sd_write_uword(sd_writer *writer, uint16_t data) {
78 sd_write_buf(writer, (char*)&data, 2);
79 }
80
sd_write_udword(sd_writer * writer,uint32_t data)81 void sd_write_udword(sd_writer *writer, uint32_t data) {
82 sd_write_buf(writer, (char*)&data, 4);
83 }
84
sd_write_byte(sd_writer * writer,int8_t data)85 void sd_write_byte(sd_writer *writer, int8_t data) {
86 sd_write_buf(writer, (char*)&data, 1);
87 }
88
sd_write_word(sd_writer * writer,int16_t data)89 void sd_write_word(sd_writer *writer, int16_t data) {
90 sd_write_buf(writer, (char*)&data, 2);
91 }
92
sd_write_dword(sd_writer * writer,int32_t data)93 void sd_write_dword(sd_writer *writer, int32_t data) {
94 sd_write_buf(writer, (char*)&data, 4);
95 }
96
sd_write_float(sd_writer * writer,float data)97 void sd_write_float(sd_writer *writer, float data) {
98 sd_write_buf(writer, (char*)&data, sizeof(float));
99 }
100
sd_write_fill(sd_writer * writer,char content,int len)101 void sd_write_fill(sd_writer *writer, char content, int len) {
102 int left = len;
103 int now = 0;
104 char buffer[1024];
105
106 memset(buffer, content, 1024);
107 while(left > 0) {
108 now = (left > 1024) ? 1024 : left;
109 if (fwrite(buffer, 1, now, writer->handle) != now) {
110 writer->sd_errno = ferror(writer->handle);
111 return;
112 }
113 left -= now;
114 }
115 }
116
sd_write_variable_str(sd_writer * w,const char * str)117 void sd_write_variable_str(sd_writer *w, const char *str) {
118 if(str == NULL) {
119 sd_write_uword(w, 0);
120 return;
121 }
122 uint16_t len = strlen(str) + 1;
123 sd_write_uword(w, len);
124 sd_write_buf(w, str, len);
125 }
126