diff --git a/src/base/plugins.c b/src/base/plugins.c
index 27d9193d..22b62a4f 100644
--- a/src/base/plugins.c
+++ b/src/base/plugins.c
@@ -1,6 +1,7 @@
#include "../vgmstream.h"
#include "../util/log.h"
#include "../util/reader_sf.h"
+#include "../util/reader_text.h"
#include "plugins.h"
#include "mixing.h"
diff --git a/src/libvgmstream.vcxproj b/src/libvgmstream.vcxproj
index 2a977e14..ff8be911 100644
--- a/src/libvgmstream.vcxproj
+++ b/src/libvgmstream.vcxproj
@@ -183,6 +183,7 @@
+
@@ -746,7 +747,7 @@
-
+
diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters
index e9aa66ba..493d257a 100644
--- a/src/libvgmstream.vcxproj.filters
+++ b/src/libvgmstream.vcxproj.filters
@@ -374,6 +374,9 @@
util\Header Files
+
+ util\Header Files
+
util\Header Files
@@ -2059,7 +2062,7 @@
util\Source Files
-
+
util\Source Files
diff --git a/src/meta/meta.h b/src/meta/meta.h
index 2df93035..c0d9c08c 100644
--- a/src/meta/meta.h
+++ b/src/meta/meta.h
@@ -3,6 +3,7 @@
#include "../vgmstream.h"
#include "../util/reader_sf.h"
+#include "../util/reader_text.h"
typedef VGMSTREAM* (*init_vgmstream_t)(STREAMFILE* sf);
diff --git a/src/streamfile.c b/src/streamfile.c
index 7fb25eff..77ec2bf8 100644
--- a/src/streamfile.c
+++ b/src/streamfile.c
@@ -1078,123 +1078,6 @@ STREAMFILE* reopen_streamfile(STREAMFILE* sf, size_t buffer_size) {
return sf->open(sf, pathname, buffer_size);
}
-/* **************************************************** */
-
-size_t read_line(char* buf, int buf_size, off_t offset, STREAMFILE* sf, int* p_line_ok) {
- int i;
- off_t file_size = get_streamfile_size(sf);
- int extra_bytes = 0; /* how many bytes over those put in the buffer were read */
-
- if (p_line_ok) *p_line_ok = 0;
-
- for (i = 0; i < buf_size-1 && offset+i < file_size; i++) {
- char in_char = read_8bit(offset+i, sf);
- /* check for end of line */
- if (in_char == 0x0d && read_8bit(offset+i+1, sf) == 0x0a) { /* CRLF */
- extra_bytes = 2;
- if (p_line_ok) *p_line_ok = 1;
- break;
- }
- else if (in_char == 0x0d || in_char == 0x0a) { /* CR or LF */
- extra_bytes = 1;
- if (p_line_ok) *p_line_ok = 1;
- break;
- }
-
- buf[i] = in_char;
- }
-
- buf[i] = '\0';
-
- /* did we fill the buffer? */
- if (i == buf_size) {
- char in_char = read_8bit(offset+i, sf);
- /* did the bytes we missed just happen to be the end of the line? */
- if (in_char == 0x0d && read_8bit(offset+i+1, sf) == 0x0a) { /* CRLF */
- extra_bytes = 2;
- if (p_line_ok) *p_line_ok = 1;
- }
- else if (in_char == 0x0d || in_char == 0x0a) { /* CR or LF */
- extra_bytes = 1;
- if (p_line_ok) *p_line_ok = 1;
- }
- }
-
- /* did we hit the file end? */
- if (offset+i == file_size) {
- /* then we did in fact finish reading the last line */
- if (p_line_ok) *p_line_ok = 1;
- }
-
- return i + extra_bytes;
-}
-
-size_t read_bom(STREAMFILE* sf) {
- if (read_u16le(0x00, sf) == 0xFFFE ||
- read_u16le(0x00, sf) == 0xFEFF) {
- return 0x02;
- }
-
- if ((read_u32be(0x00, sf) & 0xFFFFFF00) == 0xEFBBBF00) {
- return 0x03;
- }
-
- return 0x00;
-}
-
-size_t read_string(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf) {
- size_t pos;
-
- for (pos = 0; pos < buf_size; pos++) {
- uint8_t byte = read_u8(offset + pos, sf);
- char c = (char)byte;
- if (buf) buf[pos] = c;
- if (c == '\0')
- return pos;
- if (pos+1 == buf_size) { /* null at maxsize and don't validate (expected to be garbage) */
- if (buf) buf[pos] = '\0';
- return buf_size;
- }
- /* UTF-8 only goes to 0x7F, but allow a bunch of Windows-1252 codes that some games use */
- if (byte < 0x20 || byte > 0xF0)
- goto fail;
- }
-
-fail:
- if (buf) buf[0] = '\0';
- return 0;
-}
-
-size_t read_string_utf16(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf, int big_endian) {
- size_t pos, offpos;
- uint16_t (*read_u16)(off_t,STREAMFILE*) = big_endian ? read_u16be : read_u16le;
-
-
- for (pos = 0, offpos = 0; pos < buf_size; pos++, offpos += 2) {
- char c = read_u16(offset + offpos, sf) & 0xFF; /* lower byte for now */
- if (buf) buf[pos] = c;
- if (c == '\0')
- return pos;
- if (pos+1 == buf_size) { /* null at maxsize and don't validate (expected to be garbage) */
- if (buf) buf[pos] = '\0';
- return buf_size;
- }
- if (c < 0x20 || (uint8_t)c > 0xA5)
- goto fail;
- }
-
-fail:
- if (buf) buf[0] = '\0';
- return 0;
-}
-
-size_t read_string_utf16le(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf) {
- return read_string_utf16(buf, buf_size, offset, sf, 0);
-}
-size_t read_string_utf16be(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf) {
- return read_string_utf16(buf, buf_size, offset, sf, 1);
-}
-
/* ************************************************************************* */
int check_extensions(STREAMFILE* sf, const char* cmp_exts) {
diff --git a/src/streamfile.h b/src/streamfile.h
index 119bea94..476372c3 100644
--- a/src/streamfile.h
+++ b/src/streamfile.h
@@ -163,22 +163,6 @@ static inline size_t get_streamfile_size(STREAMFILE* sf) {
/* various STREAMFILE helpers functions */
-/* Read into dst a line delimited by CRLF (Windows) / LF (Unux) / CR (Mac) / EOF, null-terminated
- * and without line feeds. Returns bytes read (including CR/LF), *not* the same as string length.
- * p_line_ok is set to 1 if the complete line was read; pass NULL to ignore. */
-size_t read_line(char* buf, int buf_size, off_t offset, STREAMFILE* sf, int* p_line_ok);
-
-/* skip BOM if needed */
-size_t read_bom(STREAMFILE* sf);
-
-/* reads a c-string (ANSI only), up to bufsize or NULL, returning size. buf is optional (works as get_string_size). */
-size_t read_string(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf);
-/* reads a UTF16 string... but actually only as ANSI (discards the upper byte) */
-size_t read_string_utf16(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf, int big_endian);
-size_t read_string_utf16le(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf);
-size_t read_string_utf16be(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf);
-
-
/* Checks if the stream filename is one of the extensions (comma-separated, ex. "adx" or "adx,aix").
* Empty is ok to accept files without extension ("", "adx,,aix"). Returns 0 on failure */
int check_extensions(STREAMFILE* sf, const char* cmp_exts);
diff --git a/src/util/companion_files.c b/src/util/companion_files.c
index 9a3d02a4..253b18e3 100644
--- a/src/util/companion_files.c
+++ b/src/util/companion_files.c
@@ -1,6 +1,7 @@
#include "companion_files.h"
#include "paths.h"
#include "../vgmstream.h"
+#include "../util/reader_text.h"
size_t read_key_file(uint8_t* buf, size_t buf_size, STREAMFILE* sf) {
diff --git a/src/util/reader.c b/src/util/reader.c
new file mode 100644
index 00000000..8b4a2fe8
--- /dev/null
+++ b/src/util/reader.c
@@ -0,0 +1,149 @@
+#include "reader_put.h"
+#include "reader_text.h"
+#include "reader_sf.h"
+#include "endianness.h"
+
+void put_8bit(uint8_t* buf, int8_t i) {
+ buf[0] = i;
+}
+
+void put_16bitLE(uint8_t* buf, int16_t i) {
+ buf[0] = (i & 0xFF);
+ buf[1] = i >> 8;
+}
+
+void put_32bitLE(uint8_t* buf, int32_t i) {
+ buf[0] = (uint8_t)(i & 0xFF);
+ buf[1] = (uint8_t)((i >> 8) & 0xFF);
+ buf[2] = (uint8_t)((i >> 16) & 0xFF);
+ buf[3] = (uint8_t)((i >> 24) & 0xFF);
+}
+
+void put_16bitBE(uint8_t* buf, int16_t i) {
+ buf[0] = i >> 8;
+ buf[1] = (i & 0xFF);
+}
+
+void put_32bitBE(uint8_t* buf, int32_t i) {
+ buf[0] = (uint8_t)((i >> 24) & 0xFF);
+ buf[1] = (uint8_t)((i >> 16) & 0xFF);
+ buf[2] = (uint8_t)((i >> 8) & 0xFF);
+ buf[3] = (uint8_t)(i & 0xFF);
+}
+
+/* **************************************************** */
+
+size_t read_line(char* buf, int buf_size, off_t offset, STREAMFILE* sf, int* p_line_ok) {
+ int i;
+ off_t file_size = get_streamfile_size(sf);
+ int extra_bytes = 0; /* how many bytes over those put in the buffer were read */
+
+ if (p_line_ok) *p_line_ok = 0;
+
+ for (i = 0; i < buf_size-1 && offset+i < file_size; i++) {
+ char in_char = read_8bit(offset+i, sf);
+ /* check for end of line */
+ if (in_char == 0x0d && read_8bit(offset+i+1, sf) == 0x0a) { /* CRLF */
+ extra_bytes = 2;
+ if (p_line_ok) *p_line_ok = 1;
+ break;
+ }
+ else if (in_char == 0x0d || in_char == 0x0a) { /* CR or LF */
+ extra_bytes = 1;
+ if (p_line_ok) *p_line_ok = 1;
+ break;
+ }
+
+ buf[i] = in_char;
+ }
+
+ buf[i] = '\0';
+
+ /* did we fill the buffer? */
+ if (i == buf_size) {
+ char in_char = read_8bit(offset+i, sf);
+ /* did the bytes we missed just happen to be the end of the line? */
+ if (in_char == 0x0d && read_8bit(offset+i+1, sf) == 0x0a) { /* CRLF */
+ extra_bytes = 2;
+ if (p_line_ok) *p_line_ok = 1;
+ }
+ else if (in_char == 0x0d || in_char == 0x0a) { /* CR or LF */
+ extra_bytes = 1;
+ if (p_line_ok) *p_line_ok = 1;
+ }
+ }
+
+ /* did we hit the file end? */
+ if (offset+i == file_size) {
+ /* then we did in fact finish reading the last line */
+ if (p_line_ok) *p_line_ok = 1;
+ }
+
+ return i + extra_bytes;
+}
+
+size_t read_bom(STREAMFILE* sf) {
+ if (read_u16le(0x00, sf) == 0xFFFE ||
+ read_u16le(0x00, sf) == 0xFEFF) {
+ return 0x02;
+ }
+
+ if ((read_u32be(0x00, sf) & 0xFFFFFF00) == 0xEFBBBF00) {
+ return 0x03;
+ }
+
+ return 0x00;
+}
+
+size_t read_string(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf) {
+ size_t pos;
+
+ for (pos = 0; pos < buf_size; pos++) {
+ uint8_t byte = read_u8(offset + pos, sf);
+ char c = (char)byte;
+ if (buf) buf[pos] = c;
+ if (c == '\0')
+ return pos;
+ if (pos+1 == buf_size) { /* null at maxsize and don't validate (expected to be garbage) */
+ if (buf) buf[pos] = '\0';
+ return buf_size;
+ }
+ /* UTF-8 only goes to 0x7F, but allow a bunch of Windows-1252 codes that some games use */
+ if (byte < 0x20 || byte > 0xF0)
+ goto fail;
+ }
+
+fail:
+ if (buf) buf[0] = '\0';
+ return 0;
+}
+
+size_t read_string_utf16(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf, int big_endian) {
+ size_t pos, offpos;
+ read_u16_t read_u16 = big_endian ? read_u16be : read_u16le;
+
+
+ for (pos = 0, offpos = 0; pos < buf_size; pos++, offpos += 2) {
+ char c = read_u16(offset + offpos, sf) & 0xFF; /* lower byte for now */
+ if (buf) buf[pos] = c;
+ if (c == '\0')
+ return pos;
+ if (pos+1 == buf_size) { /* null at maxsize and don't validate (expected to be garbage) */
+ if (buf) buf[pos] = '\0';
+ return buf_size;
+ }
+ if (c < 0x20 || (uint8_t)c > 0xA5)
+ goto fail;
+ }
+
+fail:
+ if (buf) buf[0] = '\0';
+ return 0;
+}
+
+size_t read_string_utf16le(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf) {
+ return read_string_utf16(buf, buf_size, offset, sf, 0);
+}
+size_t read_string_utf16be(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf) {
+ return read_string_utf16(buf, buf_size, offset, sf, 1);
+}
diff --git a/src/util/reader_put.c b/src/util/reader_put.c
deleted file mode 100644
index ed04f154..00000000
--- a/src/util/reader_put.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "reader_put.h"
-
-void put_8bit(uint8_t * buf, int8_t i) {
- buf[0] = i;
-}
-
-void put_16bitLE(uint8_t * buf, int16_t i) {
- buf[0] = (i & 0xFF);
- buf[1] = i >> 8;
-}
-
-void put_32bitLE(uint8_t * buf, int32_t i) {
- buf[0] = (uint8_t)(i & 0xFF);
- buf[1] = (uint8_t)((i >> 8) & 0xFF);
- buf[2] = (uint8_t)((i >> 16) & 0xFF);
- buf[3] = (uint8_t)((i >> 24) & 0xFF);
-}
-
-void put_16bitBE(uint8_t * buf, int16_t i) {
- buf[0] = i >> 8;
- buf[1] = (i & 0xFF);
-}
-
-void put_32bitBE(uint8_t * buf, int32_t i) {
- buf[0] = (uint8_t)((i >> 24) & 0xFF);
- buf[1] = (uint8_t)((i >> 16) & 0xFF);
- buf[2] = (uint8_t)((i >> 8) & 0xFF);
- buf[3] = (uint8_t)(i & 0xFF);
-}
diff --git a/src/util/reader_text.h b/src/util/reader_text.h
new file mode 100644
index 00000000..f18b2092
--- /dev/null
+++ b/src/util/reader_text.h
@@ -0,0 +1,21 @@
+#ifndef _READER_TEXT_H
+#define _READER_TEXT_H
+#include "../streamfile.h"
+
+
+/* Read into dst a line delimited by CRLF (Windows) / LF (Unux) / CR (Mac) / EOF, null-terminated
+ * and without line feeds. Returns bytes read (including CR/LF), *not* the same as string length.
+ * p_line_ok is set to 1 if the complete line was read; pass NULL to ignore. */
+size_t read_line(char* buf, int buf_size, off_t offset, STREAMFILE* sf, int* p_line_ok);
+
+/* skip BOM if needed */
+size_t read_bom(STREAMFILE* sf);
+
+/* reads a c-string (ANSI only), up to bufsize or NULL, returning size. buf is optional (works as get_string_size). */
+size_t read_string(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf);
+/* reads a UTF16 string... but actually only as ANSI (discards the upper byte) */
+size_t read_string_utf16(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf, int big_endian);
+size_t read_string_utf16le(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf);
+size_t read_string_utf16be(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf);
+
+#endif