src/util/vfs/vfs-mem.c (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "util/vfs.h"
7
8struct VFileMem {
9 struct VFile d;
10 void* mem;
11 size_t size;
12 size_t offset;
13};
14
15static bool _vfmClose(struct VFile* vf);
16static off_t _vfmSeek(struct VFile* vf, off_t offset, int whence);
17static ssize_t _vfmRead(struct VFile* vf, void* buffer, size_t size);
18static ssize_t _vfmWrite(struct VFile* vf, const void* buffer, size_t size);
19static void* _vfmMap(struct VFile* vf, size_t size, int flags);
20static void _vfmUnmap(struct VFile* vf, void* memory, size_t size);
21static void _vfmTruncate(struct VFile* vf, size_t size);
22static ssize_t _vfmSize(struct VFile* vf);
23static bool _vfmSync(struct VFile* vf, const void* buffer, size_t size);
24
25struct VFile* VFileFromMemory(void* mem, size_t size) {
26 if (!mem || !size) {
27 return 0;
28 }
29
30 struct VFileMem* vfm = malloc(sizeof(struct VFileMem));
31 if (!vfm) {
32 return 0;
33 }
34
35 vfm->mem = mem;
36 vfm->size = size;
37 vfm->offset = 0;
38 vfm->d.close = _vfmClose;
39 vfm->d.seek = _vfmSeek;
40 vfm->d.read = _vfmRead;
41 vfm->d.readline = VFileReadline;
42 vfm->d.write = _vfmWrite;
43 vfm->d.map = _vfmMap;
44 vfm->d.unmap = _vfmUnmap;
45 vfm->d.truncate = _vfmTruncate;
46 vfm->d.size = _vfmSize;
47 vfm->d.sync = _vfmSync;
48
49 return &vfm->d;
50}
51
52bool _vfmClose(struct VFile* vf) {
53 struct VFileMem* vfm = (struct VFileMem*) vf;
54 vfm->mem = 0;
55 free(vfm);
56 return true;
57}
58
59off_t _vfmSeek(struct VFile* vf, off_t offset, int whence) {
60 struct VFileMem* vfm = (struct VFileMem*) vf;
61
62 size_t position;
63 switch (whence) {
64 case SEEK_SET:
65 position = offset;
66 break;
67 case SEEK_CUR:
68 if (offset < 0 && ((vfm->offset < (size_t) -offset) || (offset == INT_MIN))) {
69 return -1;
70 }
71 position = vfm->offset + offset;
72 break;
73 case SEEK_END:
74 if (offset < 0 && ((vfm->size < (size_t) -offset) || (offset == INT_MIN))) {
75 return -1;
76 }
77 position = vfm->size + offset;
78 break;
79 default:
80 return -1;
81 }
82
83 if (position > vfm->size) {
84 return -1;
85 }
86
87 vfm->offset = position;
88 return position;
89}
90
91ssize_t _vfmRead(struct VFile* vf, void* buffer, size_t size) {
92 struct VFileMem* vfm = (struct VFileMem*) vf;
93
94 if (size + vfm->offset >= vfm->size) {
95 size = vfm->size - vfm->offset;
96 }
97
98 memcpy(buffer, (void*) ((uintptr_t) vfm->mem + vfm->offset), size);
99 vfm->offset += size;
100 return size;
101}
102
103ssize_t _vfmWrite(struct VFile* vf, const void* buffer, size_t size) {
104 struct VFileMem* vfm = (struct VFileMem*) vf;
105
106 if (size + vfm->offset >= vfm->size) {
107 size = vfm->size - vfm->offset;
108 }
109
110 memcpy((void*) ((uintptr_t) vfm->mem + vfm->offset), buffer, size);
111 vfm->offset += size;
112 return size;
113}
114
115void* _vfmMap(struct VFile* vf, size_t size, int flags) {
116 struct VFileMem* vfm = (struct VFileMem*) vf;
117
118 UNUSED(flags);
119 if (size > vfm->size) {
120 return 0;
121 }
122
123 return vfm->mem;
124}
125
126void _vfmUnmap(struct VFile* vf, void* memory, size_t size) {
127 UNUSED(vf);
128 UNUSED(memory);
129 UNUSED(size);
130}
131
132void _vfmTruncate(struct VFile* vf, size_t size) {
133 // TODO: Return value?
134 UNUSED(vf);
135 UNUSED(size);
136}
137
138ssize_t _vfmSize(struct VFile* vf) {
139 struct VFileMem* vfm = (struct VFileMem*) vf;
140 return vfm->size;
141}
142
143bool _vfmSync(struct VFile* vf, const void* buffer, size_t size) {
144 UNUSED(vf);
145 UNUSED(buffer);
146 UNUSED(size);
147 return true;
148}