rxml_document_t *rxml_load_document(const char *path) { #ifndef RXML_TEST RARCH_WARN("Using RXML as drop in for libxml2. Behavior might be very buggy.\n"); #endif char *memory_buffer = NULL; char *new_memory_buffer = NULL; const char *mem_ptr = NULL; long len = 0; RFILE *file = filestream_open(path, RFILE_MODE_READ, -1); if (!file) return NULL; rxml_document_t *doc = (rxml_document_t*)calloc(1, sizeof(*doc)); if (!doc) goto error; filestream_seek(file, 0, SEEK_END); len = filestream_tell(file); filestream_rewind(file); memory_buffer = (char*)malloc(len + 1); if (!memory_buffer) goto error; memory_buffer[len] = '\0'; if (filestream_read(file, memory_buffer, len) != (size_t)len) goto error; filestream_close(file); file = NULL; mem_ptr = memory_buffer; if (!validate_header(&mem_ptr)) goto error; new_memory_buffer = purge_xml_comments(mem_ptr); if (!new_memory_buffer) goto error; free(memory_buffer); mem_ptr = memory_buffer = new_memory_buffer; doc->root_node = rxml_parse_node(&mem_ptr); if (!doc->root_node) goto error; free(memory_buffer); return doc; error: free(memory_buffer); filestream_close(file); rxml_free_document(doc); return NULL; }
/** * filestream_read_file: * @path : path to file. * @buf : buffer to allocate and read the contents of the * file into. Needs to be freed manually. * * Read the contents of a file into @buf. * * Returns: number of items read, -1 on error. */ int filestream_read_file(const char *path, void **buf, ssize_t *len) { ssize_t ret = 0; ssize_t content_buf_size = 0; void *content_buf = NULL; RFILE *file = filestream_open(path, RFILE_MODE_READ, -1); if (!file) { fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno)); goto error; } if (filestream_seek(file, 0, SEEK_END) != 0) goto error; content_buf_size = filestream_tell(file); if (content_buf_size < 0) goto error; filestream_rewind(file); content_buf = malloc(content_buf_size + 1); if (!content_buf) goto error; ret = filestream_read(file, content_buf, content_buf_size); if (ret < 0) { fprintf(stderr, "Failed to read %s: %s\n", path, strerror(errno)); goto error; } filestream_close(file); *buf = content_buf; /* Allow for easy reading of strings to be safe. * Will only work with sane character formatting (Unix). */ ((char*)content_buf)[content_buf_size] = '\0'; if (len) *len = ret; return 1; error: if (file) filestream_close(file); if (content_buf) free(content_buf); if (len) *len = -1; *buf = NULL; return 0; }
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_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; case INTFSTREAM_CHD: #ifdef HAVE_CHD chdstream_rewind(intf->chd.fp); #endif break; } }
RFILE *filestream_open(const char *path, unsigned mode, ssize_t len) { int flags = 0; int mode_int = 0; const char *mode_str = NULL; RFILE *stream = (RFILE*)calloc(1, sizeof(*stream)); if (!stream) return NULL; (void)mode_str; (void)mode_int; (void)flags; stream->hints = mode; #ifdef HAVE_MMAP if (stream->hints & RFILE_HINT_MMAP && (stream->hints & 0xff) == RFILE_MODE_READ) stream->hints |= RFILE_HINT_UNBUFFERED; else #endif stream->hints &= ~RFILE_HINT_MMAP; switch (mode & 0xff) { case RFILE_MODE_READ: #if defined(VITA) || defined(PSP) mode_int = 0777; flags = PSP_O_RDONLY; #elif defined(__CELLOS_LV2__) mode_int = 0777; flags = CELL_FS_O_RDONLY; #else #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = "rb"; #endif /* No "else" here */ flags = O_RDONLY; #endif break; case RFILE_MODE_WRITE: #if defined(VITA) || defined(PSP) mode_int = 0777; flags = PSP_O_CREAT | PSP_O_WRONLY | PSP_O_TRUNC; #elif defined(__CELLOS_LV2__) mode_int = 0777; flags = CELL_FS_O_CREAT | CELL_FS_O_WRONLY | CELL_FS_O_TRUNC; #else #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = "wb"; #endif else { flags = O_WRONLY | O_CREAT | O_TRUNC; #ifndef _WIN32 flags |= S_IRUSR | S_IWUSR; #endif } #endif break; case RFILE_MODE_READ_WRITE: #if defined(VITA) || defined(PSP) mode_int = 0777; flags = PSP_O_RDWR; #elif defined(__CELLOS_LV2__) mode_int = 0777; flags = CELL_FS_O_RDWR; #else #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = "w+"; #endif else { flags = O_RDWR; #ifdef _WIN32 flags |= O_BINARY; #endif } #endif break; } #if defined(VITA) || defined(PSP) stream->fd = sceIoOpen(path, flags, mode_int); #elif defined(__CELLOS_LV2__) cellFsOpen(path, flags, &stream->fd, NULL, 0); #else #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) { stream->fp = fopen(path, mode_str); if (!stream->fp) goto error; } else #endif { stream->fd = open(path, flags); if (stream->fd == -1) goto error; #ifdef HAVE_MMAP if (stream->hints & RFILE_HINT_MMAP) { stream->mappos = 0; stream->mapped = NULL; stream->mapsize = filestream_seek(stream, 0, SEEK_END); if (stream->mapsize == (uint64_t)-1) goto error; filestream_rewind(stream); 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; } #endif } #endif #if defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__) if (stream->fd == -1) goto error; #endif return stream; error: filestream_close(stream); return NULL; }
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_int; (void)flags; stream->hints = mode; #ifdef HAVE_MMAP if (stream->hints & RFILE_HINT_MMAP && (stream->hints & 0xff) == RFILE_MODE_READ) stream->hints |= RFILE_HINT_UNBUFFERED; else #endif stream->hints &= ~RFILE_HINT_MMAP; switch (mode & 0xff) { case RFILE_MODE_READ_TEXT: #if defined(PSP) mode_int = 0666; flags = PSP_O_RDONLY; #else #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_READ; #endif /* No "else" here */ flags = O_RDONLY; #endif break; case RFILE_MODE_READ: #if defined(PSP) mode_int = 0666; flags = PSP_O_RDONLY; #else #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_READ_UNBUF; #endif /* No "else" here */ flags = O_RDONLY; #endif break; case RFILE_MODE_WRITE: #if defined(PSP) mode_int = 0666; flags = PSP_O_CREAT | PSP_O_WRONLY | PSP_O_TRUNC; #else #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_WRITE_UNBUF; #endif else { flags = O_WRONLY | O_CREAT | O_TRUNC; #ifndef _WIN32 flags |= S_IRUSR | S_IWUSR; #endif } #endif break; case RFILE_MODE_READ_WRITE: #if defined(PSP) mode_int = 0666; flags = PSP_O_RDWR; #else #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_WRITE_PLUS; #endif else { flags = O_RDWR; #ifdef _WIN32 flags |= O_BINARY; #endif } #endif break; } #if defined(PSP) stream->fd = sceIoOpen(path, flags, mode_int); #else #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) { stream->fp = fopen(path, mode_str); if (!stream->fp) goto error; } else #endif { /* FIXME: HAVE_BUFFERED_IO is always 1, but if it is ever changed, open() needs to be changed to _wopen() for WIndows. */ stream->fd = open(path, flags); if (stream->fd == -1) goto error; #ifdef HAVE_MMAP if (stream->hints & RFILE_HINT_MMAP) { stream->mappos = 0; stream->mapped = NULL; stream->mapsize = filestream_seek(stream, 0, SEEK_END); if (stream->mapsize == (uint64_t)-1) goto error; filestream_rewind(stream); 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; } #endif } #endif #if defined(PSP) if (stream->fd == -1) goto error; #endif return stream; error: filestream_close(stream); return NULL; }