update libretro-common

This commit is contained in:
zeromus 2016-04-22 00:34:34 +00:00
parent 3685c6e1f6
commit b0f4989230
17 changed files with 723 additions and 144 deletions

View File

@ -216,9 +216,6 @@ static int file_archive_get_file_list_cb(
(void)csize;
(void)size;
(void)checksum;
(void)valid_exts;
(void)file_ext;
(void)ext_list;
memset(&attr, 0, sizeof(attr));
@ -538,10 +535,8 @@ static bool file_archive_parse_file(const char *file, const char *valid_exts,
for (;;)
{
int ret = file_archive_parse_file_iterate(&state, &returnerr, file,
valid_exts, file_cb, userdata);
if (ret != 0)
if (file_archive_parse_file_iterate(&state, &returnerr, file,
valid_exts, file_cb, userdata) != 0)
break;
}
@ -656,7 +651,7 @@ bool file_archive_perform_mode(const char *path, const char *valid_exts,
{
case ZLIB_MODE_UNCOMPRESSED:
if (!filestream_write_file(path, cdata, size))
return false;
goto error;
break;
case ZLIB_MODE_DEFLATE:
@ -667,7 +662,7 @@ bool file_archive_perform_mode(const char *path, const char *valid_exts,
if (!handle.backend->stream_decompress_data_to_file_init(&handle,
cdata, csize, size))
return false;
goto error;
do{
ret = handle.backend->stream_decompress_data_to_file_iterate(
@ -677,14 +672,17 @@ bool file_archive_perform_mode(const char *path, const char *valid_exts,
if (!file_archive_decompress_data_to_file(&handle,
ret, path, valid_exts,
cdata, csize, size, crc32))
return false;
goto error;
}
break;
default:
return false;
goto error;
}
return true;
error:
return false;
}
const struct file_archive_file_backend *file_archive_get_default_file_backend(void)

View File

@ -167,7 +167,7 @@ static int zlib_stream_decompress_data_to_file_iterate(void *data)
z_stream *stream = (z_stream*)data;
if (!stream)
return -1;
goto error;
zstatus = inflate(stream, Z_NO_FLUSH);
@ -175,9 +175,12 @@ static int zlib_stream_decompress_data_to_file_iterate(void *data)
return 1;
if (zstatus != Z_OK && zstatus != Z_BUF_ERROR)
return -1;
goto error;
return 0;
error:
return -1;
}
static void zlib_stream_compress_init(void *data, int level)

View File

@ -421,6 +421,15 @@ void rglLinkProgram(GLuint program)
glLinkProgram(program);
}
void rglFramebufferTexture(GLenum target, GLenum attachment,
GLuint texture, GLint level)
{
#if defined(HAVE_OPENGLES) && !defined(HAVE_OPENGLES32)
#else
glFramebufferTexture(target, attachment, texture, level);
#endif
}
void rglFramebufferTexture2D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level)
{
@ -446,7 +455,7 @@ void rglFramebufferRenderbuffer(GLenum target, GLenum attachment,
glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
}
void rglDeleteFramebuffers(GLsizei n, GLuint *framebuffers)
void rglDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
{
glDeleteFramebuffers(n, framebuffers);
}
@ -703,6 +712,12 @@ void rglUniform4fv(GLint location, GLsizei count, const GLfloat *value)
glUniform4fv(location, count, value);
}
void rglTexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat,
GLsizei width, GLsizei height)
{
glTexStorage2D(target, levels, internalFormat, width, height);
}
void rglPolygonOffset(GLfloat factor, GLfloat units)
{
glsm_ctl(GLSM_CTL_IMM_VBO_DRAW, NULL);
@ -712,6 +727,41 @@ void rglPolygonOffset(GLfloat factor, GLfloat units)
gl_state.polygonoffset.units = units;
}
void rglDrawBuffers(GLsizei n, const GLenum *bufs)
{
#if defined(HAVE_OPENGLES) && !defined(HAVE_OPENGLES3) && !defined(HAVE_OPENGLES31)
#else
glDrawBuffers(n, bufs);
#endif
}
void rglBlendEquation(GLenum mode)
{
glBlendEquation(mode);
}
void rglBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
glBlendColor(red, green, blue, alpha);
}
void rglBindVertexArray(GLuint array)
{
#if defined(HAVE_OPENGLES) && !defined(HAVE_OPENGLES3) && !defined(HAVE_OPENGLES31)
#else
glBindVertexArray(array);
#endif
}
void rglGenVertexArrays(GLsizei n, GLuint *arrays)
{
#if defined(HAVE_OPENGLES) && !defined(HAVE_OPENGLES3) && !defined(HAVE_OPENGLES31)
#else
glGenVertexArrays(n, arrays);
#endif
}
/* GLSM-side */
static void glsm_state_setup(void)

View File

@ -41,6 +41,7 @@ extern "C" {
#define glCompressedTexImage2D rglCompressedTexImage2D
#define glBindTexture rglBindTexture
#define glActiveTexture rglActiveTexture
#define glFramebufferTexture rglFramebufferTexture
#define glFramebufferTexture2D rglFramebufferTexture2D
#define glFramebufferRenderbuffer rglFramebufferRenderbuffer
#define glDeleteFramebuffers rglDeleteFramebuffers
@ -112,22 +113,35 @@ extern "C" {
#define glReadBuffer rglReadBuffer
#define glUniformMatrix4fv rglUniformMatrix4fv
#define glGetAttribLocation rglGetAttribLocation
#define glTexStorage2D rglTexStorage2D
#define glDrawBuffers rglDrawBuffers
#define glGenVertexArrays rglGenVertexArrays
#define glBindVertexArray rglBindVertexArray
#define glBlendEquation rglBlendEquation
#define glBlendColor rglBlendColor
void rglBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
void rglBlendEquation(GLenum mode);
void rglGenVertexArrays(GLsizei n, GLuint *arrays);
void rglReadBuffer(GLenum mode);
void rglPixelStorei(GLenum pname, GLint param);
void rglTexCoord2f(GLfloat s, GLfloat t);
void rglDrawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid * indices);
void rglTexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat,
GLsizei width, GLsizei height);
void rglCompressedTexImage2D(GLenum target, GLint level,
GLenum internalformat, GLsizei width, GLsizei height,
GLint border, GLsizei imageSize, const GLvoid *data);
void glBindTexture(GLenum target, GLuint texture);
void glActiveTexture(GLenum texture);
void rglFramebufferTexture(GLenum target, GLenum attachment,
GLuint texture, GLint level);
void rglFramebufferTexture2D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level);
void rglFramebufferRenderbuffer(GLenum target, GLenum attachment,
GLenum renderbuffertarget, GLuint renderbuffer);
void rglDeleteFramebuffers(GLsizei n, GLuint *framebuffers);
void rglDeleteFramebuffers(GLsizei n, const GLuint *framebuffers);
void rglRenderbufferStorage(GLenum target, GLenum internalFormat,
GLsizei width, GLsizei height);
void rglDeleteTextures(GLsizei n, const GLuint *textures);
@ -214,6 +228,8 @@ void rglDetachShader(GLuint program, GLuint shader);
void rglUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value);
GLint rglGetAttribLocation(GLuint program, const GLchar *name);
void rglDrawBuffers(GLsizei n, const GLenum *bufs);
void rglBindVertexArray(GLuint array);
#ifdef __cplusplus
}

View File

@ -65,6 +65,11 @@ bool file_list_append(file_list_t *userdata, const char *path,
const char *label, unsigned type, size_t current_directory_ptr,
size_t entry_index);
bool file_list_prepend(file_list_t *list,
const char *path, const char *label,
unsigned type, size_t directory_ptr,
size_t entry_idx);
void file_list_pop(file_list_t *list, size_t *directory_ptr);
void file_list_clear(file_list_t *list);

View File

@ -23,6 +23,10 @@
#ifndef __LIBRETRO_SDK_SEMAPHORE_H
#define __LIBRETRO_SDK_SEMAPHORE_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ssem ssem_t;
/**
@ -37,8 +41,14 @@ ssem_t *ssem_new(int value);
void ssem_free(ssem_t *semaphore);
int ssem_get(ssem_t *semaphore);
void ssem_wait(ssem_t *semaphore);
void ssem_signal(ssem_t *semaphore);
#ifdef __cplusplus
}
#endif
#endif /* __LIBRETRO_SDK_SEMAPHORE_H */

View File

@ -66,6 +66,8 @@ int filestream_read_file(const char *path, void **buf, ssize_t *len);
bool filestream_write_file(const char *path, const void *data, ssize_t size);
int filestream_putc(RFILE *stream, int c);
int filestream_get_fd(RFILE *stream);
#ifdef __cplusplus

View File

@ -0,0 +1,85 @@
/* Copyright (C) 2010-2015 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (interface_stream.h).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _LIBRETRO_SDK_INTERFACE_STREAM_H
#define _LIBRETRO_SDK_INTERFACE_STREAM_H
#include <stdint.h>
#include <stddef.h>
#include <boolean.h>
enum intfstream_type
{
INTFSTREAM_FILE = 0,
INTFSTREAM_MEMORY
};
typedef struct intfstream_internal intfstream_internal_t;
typedef struct intfstream intfstream_t;
typedef struct intfstream_info
{
struct
{
struct
{
uint8_t *data;
unsigned size;
} buf;
bool writable;
} memory;
enum intfstream_type type;
} intfstream_info_t;
void *intfstream_init(intfstream_info_t *info);
bool intfstream_resize(intfstream_internal_t *intf,
intfstream_info_t *info);
bool intfstream_open(intfstream_internal_t *intf,
const char *path, unsigned mode, ssize_t len);
ssize_t intfstream_read(intfstream_internal_t *intf,
void *s, size_t len);
ssize_t intfstream_write(intfstream_internal_t *intf,
const void *s, size_t len);
char *intfstream_gets(intfstream_internal_t *intf,
char *buffer, size_t len);
int intfstream_getc(intfstream_internal_t *intf);
int intfstream_seek(intfstream_internal_t *intf,
int offset, int whence);
void intfstream_rewind(intfstream_internal_t *intf);
int intfstream_tell(intfstream_internal_t *intf);
void intfstream_putc(intfstream_internal_t *intf, int c);
int intfstream_close(intfstream_internal_t *intf);
#endif

View File

@ -28,7 +28,7 @@
typedef struct memstream memstream_t;
memstream_t *memstream_open(void);
memstream_t *memstream_open(unsigned writing);
void memstream_close(memstream_t *stream);
@ -38,10 +38,14 @@ size_t memstream_write(memstream_t *stream, const void *data, size_t bytes);
int memstream_getc(memstream_t *stream);
void memstream_putc(memstream_t *stream, int c);
char *memstream_gets(memstream_t *stream, char *buffer, size_t len);
size_t memstream_pos(memstream_t *stream);
void memstream_rewind(memstream_t *stream);
int memstream_seek(memstream_t *stream, int offset, int whence);
void memstream_set_buffer(uint8_t *buffer, size_t size);

View File

@ -24,7 +24,7 @@ static void (*co_swap)(cothread_t, cothread_t) = 0;
#endif
#ifdef _WIN32
//ABI: Win64
/* ABI: Win64 */
static unsigned char co_swap_function[] = {
0x48, 0x89, 0x22, /* mov [rdx],rsp */
0x48, 0x8b, 0x21, /* mov rsp,[rcx] */
@ -81,7 +81,7 @@ void co_init(void)
sizeof(co_swap_function), PAGE_EXECUTE_READWRITE, &old_privileges);
}
#else
//ABI: SystemV
/* ABI: SystemV */
#ifndef CO_USE_INLINE_ASM
static unsigned char co_swap_function[] = {
0x48, 0x89, 0x26, /* mov [rsi],rsp */

View File

@ -59,6 +59,49 @@ static bool file_list_capacity(file_list_t *list, size_t cap)
return true;
}
bool file_list_prepend(file_list_t *list,
const char *path, const char *label,
unsigned type, size_t directory_ptr,
size_t entry_idx)
{
unsigned i;
if (list->size >= list->capacity &&
!file_list_capacity(list, list->capacity * 2 + 1))
return false;
list->size++;
for (i = list->size -1; i > 0; i--)
{
struct item_file *copy = calloc(1, sizeof(struct item_file));
memcpy(copy, &list->list[i-1], sizeof(struct item_file));
memcpy(&list->list[i-1], &list->list[i], sizeof(struct item_file));
memcpy(&list->list[i], copy, sizeof(struct item_file));
free(copy);
}
memset(&list->list[0], 0, sizeof(file_list_t));
list->list[0].label = NULL;
list->list[0].path = NULL;
list->list[0].alt = NULL;
list->list[0].userdata = NULL;
list->list[0].actiondata = NULL;
list->list[0].type = type;
list->list[0].directory_ptr = directory_ptr;
list->list[0].entry_idx = entry_idx;
if (label)
list->list[0].label = strdup(label);
if (path)
list->list[0].path = strdup(path);
return true;
}
bool file_list_append(file_list_t *list,
const char *path, const char *label,
unsigned type, size_t directory_ptr,

View File

@ -175,12 +175,9 @@ void msg_queue_clear(msg_queue_t *queue)
**/
const char *msg_queue_pull(msg_queue_t *queue)
{
struct queue_elem *front = NULL, *last = NULL,
*parent = NULL, *child = NULL;
struct queue_elem *front = NULL, *last = NULL;
size_t tmp_ptr = 1;
(void)parent;
(void)child;
(void)tmp_ptr;
/* Nothing in queue. */
@ -203,10 +200,12 @@ const char *msg_queue_pull(msg_queue_t *queue)
for (;;)
{
size_t switch_index = tmp_ptr;
bool left = (tmp_ptr * 2 <= queue->ptr)
struct queue_elem *parent = NULL;
struct queue_elem *child = NULL;
size_t switch_index = tmp_ptr;
bool left = (tmp_ptr * 2 <= queue->ptr)
&& (queue->elems[tmp_ptr] < queue->elems[tmp_ptr * 2]);
bool right = (tmp_ptr * 2 + 1 <= queue->ptr)
bool right = (tmp_ptr * 2 + 1 <= queue->ptr)
&& (queue->elems[tmp_ptr] < queue->elems[tmp_ptr * 2 + 1]);
if (!left && !right)
@ -227,9 +226,9 @@ const char *msg_queue_pull(msg_queue_t *queue)
parent = (struct queue_elem*)queue->elems[tmp_ptr];
child = (struct queue_elem*)queue->elems[switch_index];
queue->elems[tmp_ptr] = child;
queue->elems[tmp_ptr] = child;
queue->elems[switch_index] = parent;
tmp_ptr = switch_index;
tmp_ptr = switch_index;
}
return queue->tmp_msg;

View File

@ -20,6 +20,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifdef __unix__
#define _POSIX_C_SOURCE 199309
#endif
#include <stdlib.h>
#include <rthreads/rthreads.h>
@ -73,6 +77,21 @@ void ssem_free(ssem_t *semaphore)
free((void*)semaphore);
}
int ssem_get(ssem_t *semaphore)
{
int val = 0;
if (!semaphore)
return 0;
slock_lock(semaphore->mutex);
val = semaphore->value;
slock_unlock(semaphore->mutex);
return val;
}
void ssem_wait(ssem_t *semaphore)
{
if (!semaphore)

View File

@ -20,6 +20,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifdef __unix__
#define _POSIX_C_SOURCE 199309
#endif
#include <stdlib.h>
#include <boolean.h>

View File

@ -66,10 +66,6 @@
#include <streams/file_stream.h>
#include <memmap.h>
#if 1
#define HAVE_BUFFERED_IO 1
#endif
struct RFILE
{
unsigned hints;
@ -78,6 +74,9 @@ struct RFILE
#elif defined(__CELLOS_LV2__)
int fd;
#else
#define HAVE_BUFFERED_IO 1
#if defined(HAVE_BUFFERED_IO)
FILE *fp;
#endif
@ -94,28 +93,25 @@ int filestream_get_fd(RFILE *stream)
{
if (!stream)
return -1;
#if defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__)
return stream->fd;
#else
#if defined(HAVE_BUFFERED_IO)
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
return fileno(stream->fp);
#endif
return stream->fd;
#endif
}
RFILE *filestream_open(const char *path, unsigned mode, ssize_t len)
{
int flags = 0;
int mode_int = 0;
#if defined(HAVE_BUFFERED_IO)
const char *mode_str = NULL;
#endif
RFILE *stream = (RFILE*)calloc(1, sizeof(*stream));
if (!stream)
return NULL;
(void)mode_str;
(void)mode_int;
(void)flags;
@ -220,7 +216,8 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t len)
filestream_rewind(stream);
stream->mapped = (uint8_t*)mmap((void*)0, stream->mapsize, PROT_READ, MAP_SHARED, stream->fd, 0);
stream->mapped = (uint8_t*)mmap((void*)0,
stream->mapsize, PROT_READ, MAP_SHARED, stream->fd, 0);
if (stream->mapped == MAP_FAILED)
stream->hints &= ~RFILE_HINT_MMAP;
@ -243,98 +240,103 @@ error:
ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence)
{
int ret = 0;
#if defined(__CELLOS_LV2__)
uint64_t pos = 0;
#endif
if (!stream)
return -1;
(void)ret;
goto error;
#if defined(VITA) || defined(PSP)
ret = sceIoLseek(stream->fd, (SceOff)offset, whence);
if (ret == -1)
return -1;
return 0;
if (sceIoLseek(stream->fd, (SceOff)offset, whence) == -1)
goto error;
#elif defined(__CELLOS_LV2__)
uint64_t pos = 0;
if (cellFsLseek(stream->fd, offset, whence, &pos) != CELL_FS_SUCCEEDED)
return -1;
return 0;
goto error;
#else
#if defined(HAVE_BUFFERED_IO)
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
return fseek(stream->fp, (long)offset, whence);
else
#endif
#ifdef HAVE_MMAP
/* Need to check stream->mapped because this function is
* called in filestream_open() */
if (stream->mapped && stream->hints & RFILE_HINT_MMAP)
/* Need to check stream->mapped because this function is
* called in filestream_open() */
if (stream->mapped && stream->hints & RFILE_HINT_MMAP)
{
/* fseek() returns error on under/overflow but allows cursor > EOF for
read-only file descriptors. */
switch (whence)
{
/* fseek() returns error on under/overflow but allows cursor > EOF for
read-only file descriptors. */
switch (whence)
{
case SEEK_SET:
if (offset < 0)
return -1;
case SEEK_SET:
if (offset < 0)
goto error;
stream->mappos = offset;
break;
stream->mappos = offset;
break;
case SEEK_CUR:
if ((offset < 0 && stream->mappos + offset > stream->mappos) ||
(offset > 0 && stream->mappos + offset < stream->mappos))
return -1;
case SEEK_CUR:
if ((offset < 0 && stream->mappos + offset > stream->mappos) ||
(offset > 0 && stream->mappos + offset < stream->mappos))
goto error;
stream->mappos += offset;
break;
stream->mappos += offset;
break;
case SEEK_END:
if (stream->mapsize + offset < stream->mapsize)
return -1;
case SEEK_END:
if (stream->mapsize + offset < stream->mapsize)
goto error;
stream->mappos = stream->mapsize + offset;
break;
}
return stream->mappos;
stream->mappos = stream->mapsize + offset;
break;
}
else
return stream->mappos;
}
#endif
{
ret = lseek(stream->fd, offset, whence);
return ret < 0 ? -1 : ret;
}
if (lseek(stream->fd, offset, whence) < 0)
goto error;
#endif
return 0;
error:
return -1;
}
ssize_t filestream_tell(RFILE *stream)
{
if (!stream)
return -1;
#if defined(VITA) || defined(PSP)
return sceIoLseek(stream->fd, 0, SEEK_CUR);
#elif defined(__CELLOS_LV2__)
#if defined(__CELLOS_LV2__)
uint64_t pos = 0;
#endif
if (!stream)
goto error;
#if defined(VITA) || defined(PSP)
if (sceIoLseek(stream->fd, 0, SEEK_CUR) < 0)
goto error;
#elif defined(__CELLOS_LV2__)
if (cellFsLseek(stream->fd, 0, CELL_FS_SEEK_CUR, &pos) != CELL_FS_SUCCEEDED)
return -1;
return 0;
goto error;
#else
#if defined(HAVE_BUFFERED_IO)
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
return ftell(stream->fp);
else
#endif
#ifdef HAVE_MMAP
/* Need to check stream->mapped because this function
* is called in filestream_open() */
if (stream->mapped && stream->hints & RFILE_HINT_MMAP)
return stream->mappos;
else
/* Need to check stream->mapped because this function
* is called in filestream_open() */
if (stream->mapped && stream->hints & RFILE_HINT_MMAP)
return stream->mappos;
#endif
return lseek(stream->fd, 0, SEEK_CUR);
if (lseek(stream->fd, 0, SEEK_CUR) < 0)
goto error;
#endif
return 0;
error:
return -1;
}
void filestream_rewind(RFILE *stream)
@ -345,70 +347,85 @@ void filestream_rewind(RFILE *stream)
ssize_t filestream_read(RFILE *stream, void *s, size_t len)
{
if (!stream || !s)
return -1;
goto error;
#if defined(VITA) || defined(PSP)
return sceIoRead(stream->fd, s, len);
#elif defined(__CELLOS_LV2__)
uint64_t bytes_written;
if (cellFsRead(stream->fd, s, len, &bytes_written) != CELL_FS_SUCCEEDED)
return -1;
goto error;
return bytes_written;
#else
#if defined(HAVE_BUFFERED_IO)
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
return fread(s, 1, len, stream->fp);
else
#endif
#ifdef HAVE_MMAP
if (stream->hints & RFILE_HINT_MMAP)
{
if (stream->mappos > stream->mapsize)
return -1;
if (stream->hints & RFILE_HINT_MMAP)
{
if (stream->mappos > stream->mapsize)
goto error;
if (stream->mappos + len > stream->mapsize)
len = stream->mapsize - stream->mappos;
if (stream->mappos + len > stream->mapsize)
len = stream->mapsize - stream->mappos;
memcpy(s, &stream->mapped[stream->mappos], len);
stream->mappos += len;
memcpy(s, &stream->mapped[stream->mappos], len);
stream->mappos += len;
return len;
}
else
return len;
}
#endif
return read(stream->fd, s, len);
return read(stream->fd, s, len);
#endif
error:
return -1;
}
ssize_t filestream_write(RFILE *stream, const void *s, size_t len)
{
if (!stream)
return -1;
goto error;
#if defined(VITA) || defined(PSP)
return sceIoWrite(stream->fd, s, len);
#elif defined(__CELLOS_LV2__)
uint64_t bytes_written;
if (cellFsWrite(stream->fd, s, len, &bytes_written) != CELL_FS_SUCCEEDED)
return -1;
goto error;
return bytes_written;
#else
#if defined(HAVE_BUFFERED_IO)
if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
return fwrite(s, 1, len, stream->fp);
else
#endif
#ifdef HAVE_MMAP
if (stream->hints & RFILE_HINT_MMAP)
return -1;
else
if (stream->hints & RFILE_HINT_MMAP)
goto error;
#endif
return write(stream->fd, s, len);
return write(stream->fd, s, len);
#endif
error:
return -1;
}
int filestream_putc(RFILE *stream, int c)
{
if (!stream)
return EOF;
#if defined(HAVE_BUFFERED_IO)
return fputc(c, stream->fp);
#else
/* unimplemented */
return EOF;
#endif
}
int filestream_close(RFILE *stream)
{
if (!stream)
return -1;
goto error;
#if defined(VITA) || defined(PSP)
if (stream->fd > 0)
@ -430,12 +447,15 @@ int filestream_close(RFILE *stream)
munmap(stream->mapped, stream->mapsize);
#endif
if (stream->fd > 0)
close(stream->fd);
if (stream->fd > 0)
close(stream->fd);
#endif
free(stream);
return 0;
error:
return -1;
}
/**
@ -534,5 +554,8 @@ bool filestream_write_file(const char *path, const void *data, ssize_t size)
ret = filestream_write(file, data, size);
filestream_close(file);
return (ret == size);
if (ret != size)
return false;
return true;
}

View File

@ -0,0 +1,270 @@
/* Copyright (C) 2010-2016 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (interface_stream.c).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <streams/interface_stream.h>
#include <streams/file_stream.h>
#include <streams/memory_stream.h>
struct intfstream_internal
{
enum intfstream_type type;
struct
{
RFILE *fp;
} file;
struct
{
struct
{
uint8_t *data;
unsigned size;
} buf;
memstream_t *fp;
bool writable;
} memory;
};
bool intfstream_resize(intfstream_internal_t *intf, intfstream_info_t *info)
{
if (!intf || !info)
return false;
switch (intf->type)
{
case INTFSTREAM_FILE:
break;
case INTFSTREAM_MEMORY:
intf->memory.buf.data = info->memory.buf.data;
intf->memory.buf.size = info->memory.buf.size;
memstream_set_buffer(intf->memory.buf.data,
intf->memory.buf.size);
break;
}
return true;
}
bool intfstream_open(intfstream_internal_t *intf, const char *path,
unsigned mode, ssize_t len)
{
if (!intf)
return false;
switch (intf->type)
{
case INTFSTREAM_FILE:
intf->file.fp = filestream_open(path, mode, len);
if (!intf->file.fp)
return false;
break;
case INTFSTREAM_MEMORY:
intf->memory.fp = memstream_open(intf->memory.writable);
if (!intf->memory.fp)
return false;
break;
}
return true;
}
int intfstream_close(intfstream_internal_t *intf)
{
if (!intf)
return -1;
switch (intf->type)
{
case INTFSTREAM_FILE:
return filestream_close(intf->file.fp);
case INTFSTREAM_MEMORY:
memstream_close(intf->memory.fp);
return 0;
}
return -1;
}
void *intfstream_init(intfstream_info_t *info)
{
intfstream_internal_t *intf = NULL;
if (!info)
goto error;
intf = (intfstream_internal_t*)calloc(1, sizeof(*intf));
if (!intf)
goto error;
intf->type = info->type;
switch (intf->type)
{
case INTFSTREAM_FILE:
break;
case INTFSTREAM_MEMORY:
intf->memory.writable = info->memory.writable;
if (!intfstream_resize(intf, info))
goto error;
break;
}
return intf;
error:
if (intf)
free(intf);
return NULL;
}
int intfstream_seek(intfstream_internal_t *intf, int offset, int whence)
{
if (!intf)
return -1;
switch (intf->type)
{
case INTFSTREAM_FILE:
return filestream_seek(intf->file.fp, offset, whence);
case INTFSTREAM_MEMORY:
return memstream_seek(intf->memory.fp, offset, whence);
}
return -1;
}
ssize_t intfstream_read(intfstream_internal_t *intf, void *s, size_t len)
{
if (!intf)
return 0;
switch (intf->type)
{
case INTFSTREAM_FILE:
return filestream_read(intf->file.fp, s, len);
case INTFSTREAM_MEMORY:
return memstream_read(intf->memory.fp, s, len);
}
return 0;
}
ssize_t intfstream_write(intfstream_internal_t *intf,
const void *s, size_t len)
{
if (!intf)
return 0;
switch (intf->type)
{
case INTFSTREAM_FILE:
return filestream_write(intf->file.fp, s, len);
case INTFSTREAM_MEMORY:
return memstream_write(intf->memory.fp, s, len);
}
return 0;
}
char *intfstream_gets(intfstream_internal_t *intf,
char *buffer, size_t len)
{
if (!intf)
return NULL;
switch (intf->type)
{
case INTFSTREAM_FILE:
/* unimplemented */
break;
case INTFSTREAM_MEMORY:
return memstream_gets(intf->memory.fp, buffer, len);
}
return NULL;
}
int intfstream_getc(intfstream_internal_t *intf)
{
if (!intf)
return 0;
switch (intf->type)
{
case INTFSTREAM_FILE:
/* unimplemented */
break;
case INTFSTREAM_MEMORY:
return memstream_getc(intf->memory.fp);
}
return 0;
}
int intfstream_tell(intfstream_internal_t *intf)
{
if (!intf)
return -1;
switch (intf->type)
{
case INTFSTREAM_FILE:
return filestream_tell(intf->file.fp);
case INTFSTREAM_MEMORY:
return memstream_pos(intf->memory.fp);
}
return -1;
}
void intfstream_rewind(intfstream_internal_t *intf)
{
switch (intf->type)
{
case INTFSTREAM_FILE:
filestream_rewind(intf->file.fp);
break;
case INTFSTREAM_MEMORY:
memstream_rewind(intf->memory.fp);
break;
}
}
void intfstream_putc(intfstream_internal_t *intf, int c)
{
if (!intf)
return;
switch (intf->type)
{
case INTFSTREAM_FILE:
filestream_putc(intf->file.fp, c);
break;
case INTFSTREAM_MEMORY:
memstream_putc(intf->memory.fp, c);
break;
}
}

View File

@ -32,11 +32,19 @@ static size_t last_file_size = 0;
struct memstream
{
uint8_t *m_buf;
size_t m_size;
size_t m_ptr;
uint8_t *buf;
size_t size;
size_t ptr;
size_t max_ptr;
unsigned writing;
};
static void memstream_update_pos(memstream_t *stream)
{
if (stream->ptr > stream->max_ptr)
stream->max_ptr = stream->ptr;
}
void memstream_set_buffer(uint8_t *buffer, size_t size)
{
g_buffer = buffer;
@ -48,21 +56,27 @@ size_t memstream_get_last_size(void)
return last_file_size;
}
static void memstream_init(memstream_t *stream, uint8_t *buffer, size_t max_size)
static void memstream_init(memstream_t *stream,
uint8_t *buffer, size_t max_size, unsigned writing)
{
stream->m_buf = buffer;
stream->m_size = max_size;
stream->m_ptr = 0;
if (!stream)
return;
stream->buf = buffer;
stream->size = max_size;
stream->ptr = 0;
stream->max_ptr = 0;
stream->writing = writing;
}
memstream_t *memstream_open(void)
memstream_t *memstream_open(unsigned writing)
{
memstream_t *stream;
if (!g_buffer || !g_size)
return NULL;
stream = (memstream_t*)calloc(1, sizeof(*stream));
memstream_init(stream, g_buffer, g_size);
memstream_init(stream, g_buffer, g_size, writing);
g_buffer = NULL;
g_size = 0;
@ -71,29 +85,44 @@ memstream_t *memstream_open(void)
void memstream_close(memstream_t *stream)
{
last_file_size = stream->m_ptr;
if (!stream)
return;
last_file_size = stream->writing ? stream->max_ptr : stream->size;
free(stream);
}
size_t memstream_read(memstream_t *stream, void *data, size_t bytes)
{
size_t avail = stream->m_size - stream->m_ptr;
size_t avail = 0;
if (!stream)
return 0;
avail = stream->size - stream->ptr;
if (bytes > avail)
bytes = avail;
memcpy(data, stream->m_buf + stream->m_ptr, bytes);
stream->m_ptr += bytes;
memcpy(data, stream->buf + stream->ptr, bytes);
stream->ptr += bytes;
memstream_update_pos(stream);
return bytes;
}
size_t memstream_write(memstream_t *stream, const void *data, size_t bytes)
{
size_t avail = stream->m_size - stream->m_ptr;
size_t avail = 0;
if (!stream)
return 0;
avail = stream->size - stream->ptr;
if (bytes > avail)
bytes = avail;
memcpy(stream->m_buf + stream->m_ptr, data, bytes);
stream->m_ptr += bytes;
memcpy(stream->buf + stream->ptr, data, bytes);
stream->ptr += bytes;
memstream_update_pos(stream);
return bytes;
}
@ -107,26 +136,32 @@ int memstream_seek(memstream_t *stream, int offset, int whence)
ptr = offset;
break;
case SEEK_CUR:
ptr = stream->m_ptr + offset;
ptr = stream->ptr + offset;
break;
case SEEK_END:
ptr = stream->m_size + offset;
ptr = (stream->writing ? stream->max_ptr : stream->size) + offset;
break;
default:
return -1;
}
if (ptr <= stream->m_size)
if (ptr <= stream->size)
{
stream->m_ptr = ptr;
stream->ptr = ptr;
return 0;
}
return -1;
}
void memstream_rewind(memstream_t *stream)
{
memstream_seek(stream, 0L, SEEK_SET);
}
size_t memstream_pos(memstream_t *stream)
{
return stream->m_ptr;
return stream->ptr;
}
char *memstream_gets(memstream_t *stream, char *buffer, size_t len)
@ -136,7 +171,20 @@ char *memstream_gets(memstream_t *stream, char *buffer, size_t len)
int memstream_getc(memstream_t *stream)
{
if (stream->m_ptr >= stream->m_size)
int ret = 0;
if (stream->ptr >= stream->size)
return EOF;
return stream->m_buf[stream->m_ptr++];
ret = stream->buf[stream->ptr++];
memstream_update_pos(stream);
return ret;
}
void memstream_putc(memstream_t *stream, int c)
{
if (stream->ptr < stream->size)
stream->buf[stream->ptr++] = c;
memstream_update_pos(stream);
}