Blender  V3.3
filereader_memory.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2004-2021 Blender Foundation. All rights reserved. */
3 
8 #include <string.h>
9 
10 #include "BLI_blenlib.h"
11 #include "BLI_filereader.h"
12 #include "BLI_mmap.h"
13 
14 #include "MEM_guardedalloc.h"
15 
16 /* This file implements both memory-backed and memory-mapped-file-backed reading. */
17 typedef struct {
19 
20  const char *data;
22  size_t length;
23 } MemoryReader;
24 
25 static ssize_t memory_read_raw(FileReader *reader, void *buffer, size_t size)
26 {
27  MemoryReader *mem = (MemoryReader *)reader;
28 
29  /* Don't read more bytes than there are available in the buffer. */
30  size_t readsize = MIN2(size, (size_t)(mem->length - mem->reader.offset));
31 
32  memcpy(buffer, mem->data + mem->reader.offset, readsize);
33  mem->reader.offset += readsize;
34 
35  return readsize;
36 }
37 
38 static off64_t memory_seek(FileReader *reader, off64_t offset, int whence)
39 {
40  MemoryReader *mem = (MemoryReader *)reader;
41 
42  off64_t new_pos;
43  if (whence == SEEK_CUR) {
44  new_pos = mem->reader.offset + offset;
45  }
46  else if (whence == SEEK_SET) {
47  new_pos = offset;
48  }
49  else if (whence == SEEK_END) {
50  new_pos = mem->length + offset;
51  }
52  else {
53  return -1;
54  }
55 
56  if (new_pos < 0 || new_pos > mem->length) {
57  return -1;
58  }
59 
60  mem->reader.offset = new_pos;
61  return mem->reader.offset;
62 }
63 
64 static void memory_close_raw(FileReader *reader)
65 {
66  MEM_freeN(reader);
67 }
68 
70 {
71  MemoryReader *mem = MEM_callocN(sizeof(MemoryReader), __func__);
72 
73  mem->data = (const char *)data;
74  mem->length = len;
75 
77  mem->reader.seek = memory_seek;
79 
80  return (FileReader *)mem;
81 }
82 
83 /* Memory-mapped file reading.
84  * By using `mmap()`, we can map a file so that it can be treated like normal memory,
85  * meaning that we can just read from it with `memcpy()` etc.
86  * This avoids system call overhead and can significantly speed up file loading.
87  */
88 
89 static ssize_t memory_read_mmap(FileReader *reader, void *buffer, size_t size)
90 {
91  MemoryReader *mem = (MemoryReader *)reader;
92 
93  /* Don't read more bytes than there are available in the buffer. */
94  size_t readsize = MIN2(size, (size_t)(mem->length - mem->reader.offset));
95 
96  if (!BLI_mmap_read(mem->mmap, buffer, mem->reader.offset, readsize)) {
97  return 0;
98  }
99 
100  mem->reader.offset += readsize;
101 
102  return readsize;
103 }
104 
105 static void memory_close_mmap(FileReader *reader)
106 {
107  MemoryReader *mem = (MemoryReader *)reader;
108  BLI_mmap_free(mem->mmap);
109  MEM_freeN(mem);
110 }
111 
113 {
114  BLI_mmap_file *mmap = BLI_mmap_open(filedes);
115  if (mmap == NULL) {
116  return NULL;
117  }
118 
119  MemoryReader *mem = MEM_callocN(sizeof(MemoryReader), __func__);
120 
121  mem->mmap = mmap;
122  mem->length = BLI_lseek(filedes, 0, SEEK_END);
123 
125  mem->reader.seek = memory_seek;
127 
128  return (FileReader *)mem;
129 }
int64_t BLI_lseek(int fd, int64_t offset, int whence)
Definition: storage.c:169
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:178
BLI_mmap_file * BLI_mmap_open(int fd) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_mmap.c:131
void BLI_mmap_free(BLI_mmap_file *file) ATTR_NONNULL(1)
Definition: BLI_mmap.c:210
#define MIN2(a, b)
SSIZE_T ssize_t
Definition: BLI_winstuff.h:71
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
int len
Definition: draw_manager.c:108
static void memory_close_mmap(FileReader *reader)
static ssize_t memory_read_raw(FileReader *reader, void *buffer, size_t size)
static ssize_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_memory(const void *data, size_t len)
FileReader * BLI_filereader_new_mmap(int filedes)
ccl_global float * buffer
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
FileReaderSeekFn seek
off64_t offset
FileReaderCloseFn close
FileReaderReadFn read
const char * data
FileReader reader
BLI_mmap_file * mmap