123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- /*
- * Copyright (c) 2013 Hugh Bailey <[email protected]>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
- #include <errno.h>
- #include <stdlib.h>
- #include "c99defs.h"
- #include "platform.h"
- #include "bmem.h"
- #include "utf8.h"
- #include "dstr.h"
- FILE *os_wfopen(const wchar_t *path, const char *mode)
- {
- FILE *file;
- #ifdef _MSC_VER
- wchar_t *wcs_mode;
- os_utf8_to_wcs(mode, 0, &wcs_mode);
- file = _wfopen(path, wcs_mode);
- bfree(wcs_mode);
- #else
- char *mbs_path;
- os_wcs_to_utf8(path, 0, &mbs_path);
- file = fopen(mbs_path, mode);
- bfree(mbs_path);
- #endif
- return file;
- }
- FILE *os_fopen(const char *path, const char *mode)
- {
- #ifdef _WIN32
- wchar_t *wpath = NULL;
- FILE *file = NULL;
- os_utf8_to_wcs(path, 0, &wpath);
- file = os_wfopen(wpath, mode);
- bfree(wpath);
- return file;
- #else
- return fopen(path, mode);
- #endif
- }
- off_t os_fgetsize(FILE *file)
- {
- off_t cur_offset = ftello(file);
- off_t size;
- int errval = 0;
- if (fseeko(file, 0, SEEK_END) == -1)
- return -1;
- size = ftello(file);
- if (size == -1)
- errval = errno;
- if (fseeko(file, cur_offset, SEEK_SET) != 0 && errval != 0)
- errno = errval;
- return size;
- }
- size_t os_fread_mbs(FILE *file, char **pstr)
- {
- size_t size = 0;
- size_t len = 0;
- fseeko(file, 0, SEEK_END);
- size = (size_t)ftello(file);
- if (size > 0) {
- char *mbstr = bmalloc(size+1);
- fseeko(file, 0, SEEK_SET);
- fread(mbstr, 1, size, file);
- mbstr[size] = 0;
- len = os_mbs_to_utf8(mbstr, size, pstr);
- bfree(mbstr);
- } else {
- *pstr = NULL;
- }
- return len;
- }
- size_t os_fread_utf8(FILE *file, char **pstr)
- {
- size_t size = 0;
- size_t len = 0;
- fseeko(file, 0, SEEK_END);
- size = (size_t)ftello(file);
- if (size > 0) {
- char bom[3];
- char *utf8str = bmalloc(size+1);
- off_t offset;
- /* remove the ghastly BOM if present */
- fseeko(file, 0, SEEK_SET);
- fread(bom, 1, 3, file);
- offset = (astrcmp_n(bom, "\xEF\xBB\xBF", 3) == 0) ? 3 : 0;
- fseeko(file, offset, SEEK_SET);
- fread(utf8str, 1, size, file);
- utf8str[size] = 0;
- *pstr = utf8str;
- } else {
- *pstr = NULL;
- }
- return len;
- }
- char *os_quick_read_mbs_file(const char *path)
- {
- FILE *f = os_fopen(path, "rb");
- char *file_string = NULL;
- if (!f)
- return NULL;
- os_fread_mbs(f, &file_string);
- fclose(f);
- return file_string;
- }
- char *os_quick_read_utf8_file(const char *path)
- {
- FILE *f = os_fopen(path, "rb");
- char *file_string = NULL;
- if (!f)
- return NULL;
- os_fread_utf8(f, &file_string);
- fclose(f);
- return file_string;
- }
- bool os_quick_write_mbs_file(const char *path, const char *str, size_t len)
- {
- FILE *f = os_fopen(path, "wb");
- char *mbs = NULL;
- size_t mbs_len = 0;
- if (!f)
- return false;
- mbs_len = os_utf8_to_mbs(str, len, &mbs);
- if (mbs_len)
- fwrite(mbs, 1, mbs_len, f);
- bfree(mbs);
- fclose(f);
- return true;
- }
- bool os_quick_write_utf8_file(const char *path, const char *str, size_t len,
- bool marker)
- {
- FILE *f = os_fopen(path, "wb");
- if (!f)
- return false;
- if (marker)
- fwrite("\xEF\xBB\xBF", 1, 3, f);
- if (len)
- fwrite(str, 1, len, f);
- fclose(f);
- return true;
- }
- size_t os_mbs_to_wcs(const char *str, size_t len, wchar_t **pstr)
- {
- size_t out_len = mbstowcs(NULL, str, len);
- wchar_t *dst = NULL;
- if (len) {
- dst = bmalloc((out_len+1) * sizeof(wchar_t));
- mbstowcs(dst, str, out_len+1);
- dst[out_len] = 0;
- }
- *pstr = dst;
- return out_len;
- }
- size_t os_utf8_to_wcs(const char *str, size_t len, wchar_t **pstr)
- {
- size_t in_len = len ? len : strlen(str);
- size_t out_len = utf8_to_wchar(str, in_len, NULL, 0, 0);
- wchar_t *dst = NULL;
- if (out_len) {
- dst = bmalloc((out_len+1) * sizeof(wchar_t));
- utf8_to_wchar(str, in_len, dst, out_len+1, 0);
- dst[out_len] = 0;
- }
- *pstr = dst;
- return out_len;
- }
- size_t os_wcs_to_mbs(const wchar_t *str, size_t len, char **pstr)
- {
- size_t out_len = wcstombs(NULL, str, len);
- char *dst = NULL;
- if (len) {
- dst = bmalloc(out_len+1);
- wcstombs(dst, str, out_len+1);
- dst[out_len] = 0;
- }
- *pstr = dst;
- return out_len;
- }
- size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char **pstr)
- {
- size_t in_len = (len != 0) ? len : wcslen(str);
- size_t out_len = wchar_to_utf8(str, in_len, NULL, 0, 0);
- char *dst = NULL;
- if (out_len) {
- dst = bmalloc(out_len+1);
- wchar_to_utf8(str, in_len, dst, out_len+1, 0);
- dst[out_len] = 0;
- }
- *pstr = dst;
- return out_len;
- }
- size_t os_utf8_to_mbs(const char *str, size_t len, char **pstr)
- {
- wchar_t *wstr = NULL;
- char *dst = NULL;
- size_t wlen = os_utf8_to_wcs(str, len, &wstr);
- size_t out_len = os_wcs_to_mbs(wstr, wlen, &dst);
- bfree(wstr);
- *pstr = dst;
- return out_len;
- }
- size_t os_mbs_to_utf8(const char *str, size_t len, char **pstr)
- {
- wchar_t *wstr = NULL;
- char *dst = NULL;
- size_t wlen = os_mbs_to_wcs(str, len, &wstr);
- size_t out_len = os_wcs_to_utf8(wstr, wlen, &dst);
- bfree(wstr);
- *pstr = dst;
- return out_len;
- }
- #ifdef _MSC_VER
- int fseeko(FILE *stream, off_t offset, int whence)
- {
- #if _FILE_OFFSET_BITS == 64
- return _fseeki64(stream, offset, whence);
- #else
- return fseek(stream, offset, whence);
- #endif /* _FILE_OFFSET_BITS == 64 */
- }
- off_t ftello(FILE *stream)
- {
- #if _FILE_OFFSET_BITS == 64
- return _ftelli64(stream);
- #else
- return ftell(stream);
- #endif /* _FILE_OFFSET_BITS == 64 */
- }
- #endif /* _MSC_VER */
|