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);
23
24struct VFile* VFileFromMemory(void* mem, size_t size) {
25 if (!mem || !size) {
26 return 0;
27 }
28
29 struct VFileMem* vfm = malloc(sizeof(struct VFileMem));
30 if (!vfm) {
31 return 0;
32 }
33
34 vfm->mem = mem;
35 vfm->size = size;
36 vfm->offset = 0;
37 vfm->d.close = _vfmClose;
38 vfm->d.seek = _vfmSeek;
39 vfm->d.read = _vfmRead;
40 vfm->d.readline = VFileReadline;
41 vfm->d.write = _vfmWrite;
42 vfm->d.map = _vfmMap;
43 vfm->d.unmap = _vfmUnmap;
44 vfm->d.truncate = _vfmTruncate;
45 vfm->d.size = _vfmSize;
46
47 return &vfm->d;
48}
49
50bool _vfmClose(struct VFile* vf) {
51 struct VFileMem* vfm = (struct VFileMem*) vf;
52 vfm->mem = 0;
53 free(vfm);
54 return true;
55}
56
57off_t _vfmSeek(struct VFile* vf, off_t offset, int whence) {
58 struct VFileMem* vfm = (struct VFileMem*) vf;
59
60 size_t position;
61 switch (whence) {
62 case SEEK_SET:
63 position = offset;
64 break;
65 case SEEK_CUR:
66 if (offset < 0 && ((vfm->offset < (size_t) -offset) || (offset == INT_MIN))) {
67 return -1;
68 }
69 position = vfm->offset + offset;
70 break;
71 case SEEK_END:
72 if (offset < 0 && ((vfm->size < (size_t) -offset) || (offset == INT_MIN))) {
73 return -1;
74 }
75 position = vfm->size + offset;
76 break;
77 default:
78 return -1;
79 }
80
81 if (position > vfm->size) {
82 return -1;
83 }
84
85 vfm->offset = position;
86 return position;
87}
88
89ssize_t _vfmRead(struct VFile* vf, void* buffer, size_t size) {
90 struct VFileMem* vfm = (struct VFileMem*) vf;
91
92 if (size + vfm->offset >= vfm->size) {
93 size = vfm->size - vfm->offset;
94 }
95
96 memcpy(buffer, (void*) ((uintptr_t) vfm->mem + vfm->offset), size);
97 vfm->offset += size;
98 return size;
99}
100
101ssize_t _vfmWrite(struct VFile* vf, const void* buffer, size_t size) {
102 struct VFileMem* vfm = (struct VFileMem*) vf;
103
104 if (size + vfm->offset >= vfm->size) {
105 size = vfm->size - vfm->offset;
106 }
107
108 memcpy((void*) ((uintptr_t) vfm->mem + vfm->offset), buffer, size);
109 vfm->offset += size;
110 return size;
111}
112
113void* _vfmMap(struct VFile* vf, size_t size, int flags) {
114 struct VFileMem* vfm = (struct VFileMem*) vf;
115
116 UNUSED(flags);
117 if (size > vfm->size) {
118 return 0;
119 }
120
121 return vfm->mem;
122}
123
124void _vfmUnmap(struct VFile* vf, void* memory, size_t size) {
125 UNUSED(vf);
126 UNUSED(memory);
127 UNUSED(size);
128}
129
130void _vfmTruncate(struct VFile* vf, size_t size) {
131 // TODO: Return value?
132 UNUSED(vf);
133 UNUSED(size);
134}
135
136ssize_t _vfmSize(struct VFile* vf) {
137 struct VFileMem* vfm = (struct VFileMem*) vf;
138 return vfm->size;
139}