Blender V4.3
filereader_memory.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2004-2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <string.h>
10
11#include "BLI_blenlib.h"
12#include "BLI_filereader.h"
13#include "BLI_mmap.h"
14
15#include "MEM_guardedalloc.h"
16
17/* This file implements both memory-backed and memory-mapped-file-backed reading. */
18typedef struct {
20
21 const char *data;
23 size_t length;
25
26static int64_t memory_read_raw(FileReader *reader, void *buffer, size_t size)
27{
28 MemoryReader *mem = (MemoryReader *)reader;
29
30 /* Don't read more bytes than there are available in the buffer. */
31 size_t readsize = MIN2(size, (size_t)(mem->length - mem->reader.offset));
32
33 memcpy(buffer, mem->data + mem->reader.offset, readsize);
34 mem->reader.offset += readsize;
35
36 return readsize;
37}
38
39static off64_t memory_seek(FileReader *reader, off64_t offset, int whence)
40{
41 MemoryReader *mem = (MemoryReader *)reader;
42
43 off64_t new_pos;
44 if (whence == SEEK_CUR) {
45 new_pos = mem->reader.offset + offset;
46 }
47 else if (whence == SEEK_SET) {
48 new_pos = offset;
49 }
50 else if (whence == SEEK_END) {
51 new_pos = mem->length + offset;
52 }
53 else {
54 return -1;
55 }
56
57 if (new_pos < 0 || new_pos > mem->length) {
58 return -1;
59 }
60
61 mem->reader.offset = new_pos;
62 return mem->reader.offset;
63}
64
65static void memory_close_raw(FileReader *reader)
66{
67 MEM_freeN(reader);
68}
69
70FileReader *BLI_filereader_new_memory(const void *data, size_t len)
71{
72 MemoryReader *mem = MEM_callocN(sizeof(MemoryReader), __func__);
73
74 mem->data = (const char *)data;
75 mem->length = len;
76
78 mem->reader.seek = memory_seek;
80
81 return (FileReader *)mem;
82}
83
84/* Memory-mapped file reading.
85 * By using `mmap()`, we can map a file so that it can be treated like normal memory,
86 * meaning that we can just read from it with `memcpy()` etc.
87 * This avoids system call overhead and can significantly speed up file loading.
88 */
89
90static int64_t memory_read_mmap(FileReader *reader, void *buffer, size_t size)
91{
92 MemoryReader *mem = (MemoryReader *)reader;
93
94 /* Don't read more bytes than there are available in the buffer. */
95 size_t readsize = MIN2(size, (size_t)(mem->length - mem->reader.offset));
96
97 if (!BLI_mmap_read(mem->mmap, buffer, mem->reader.offset, readsize)) {
98 return 0;
99 }
100
101 mem->reader.offset += readsize;
102
103 return readsize;
104}
105
106static void memory_close_mmap(FileReader *reader)
107{
108 MemoryReader *mem = (MemoryReader *)reader;
109 BLI_mmap_free(mem->mmap);
110 MEM_freeN(mem);
111}
112
114{
115 BLI_mmap_file *mmap = BLI_mmap_open(filedes);
116 if (mmap == NULL) {
117 return NULL;
118 }
119
120 MemoryReader *mem = MEM_callocN(sizeof(MemoryReader), __func__);
121
122 mem->mmap = mmap;
123 mem->length = BLI_mmap_get_length(mmap);
124
126 mem->reader.seek = memory_seek;
128
129 return (FileReader *)mem;
130}
Wrapper for reading from various sources (e.g. raw files, compressed files, memory....
bool BLI_mmap_read(BLI_mmap_file *file, void *dest, size_t offset, size_t length) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition BLI_mmap.c:182
void BLI_mmap_free(BLI_mmap_file *file) ATTR_NONNULL(1)
Definition BLI_mmap.c:221
BLI_mmap_file * BLI_mmap_open(int fd) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_mmap.c:132
size_t BLI_mmap_get_length(const BLI_mmap_file *file) ATTR_WARN_UNUSED_RESULT
Definition BLI_mmap.c:216
#define MIN2(a, b)
Read Guarded memory(de)allocation.
#define NULL
int len
static void memory_close_mmap(FileReader *reader)
static int64_t memory_read_mmap(FileReader *reader, void *buffer, size_t size)
static void memory_close_raw(FileReader *reader)
static off64_t memory_seek(FileReader *reader, off64_t offset, int whence)
FileReader * BLI_filereader_new_mmap(int filedes)
static int64_t memory_read_raw(FileReader *reader, void *buffer, size_t size)
FileReader * BLI_filereader_new_memory(const void *data, size_t len)
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
__int64 int64_t
Definition stdint.h:89
FileReaderSeekFn seek
off64_t offset
FileReaderCloseFn close
FileReaderReadFn read
const char * data
FileReader reader
BLI_mmap_file * mmap