refactor: clean up the virtual memory mappings
[lunaix-os.git] / lunaix-os / kernel / fs / twifs / twimap.c
1 #include <lunaix/fs/twifs.h>
2 #include <lunaix/mm/valloc.h>
3
4 #include <klibc/stdio.h>
5 #include <klibc/string.h>
6
7 #define TWIMAP_BUFFER_SIZE 1024
8
9 void
10 __twimap_default_reset(struct twimap* map)
11 {
12     map->index = NULL;
13 }
14
15 int
16 __twimap_default_gonext(struct twimap* map)
17 {
18     return 0;
19 }
20
21 int
22 __twimap_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
23 {
24     struct twimap* map = twinode_getdata(inode, struct twimap*);
25     map->buffer = valloc(TWIMAP_BUFFER_SIZE);
26     map->reset(map);
27
28     // FIXME what if TWIMAP_BUFFER_SIZE is not big enough?
29
30     size_t pos = 0;
31     do {
32         map->size_acc = 0;
33         map->read(map);
34         pos += map->size_acc;
35     } while (pos < fpos && map->go_next(map));
36
37     if (pos < fpos) {
38         vfree(map->buffer);
39         return 0;
40     }
41
42     if (!fpos) {
43         pos = 0;
44     }
45
46     size_t acc_size = MIN(len, map->size_acc - (pos - fpos)), rdlen = acc_size;
47     memcpy(buffer, map->buffer + (pos - fpos), acc_size);
48
49     while (acc_size < len && map->go_next(map)) {
50         map->size_acc = 0;
51         map->read(map);
52         rdlen = MIN(len - acc_size, map->size_acc);
53         memcpy(buffer + acc_size, map->buffer, rdlen);
54         acc_size += rdlen;
55     }
56
57     vfree(map->buffer);
58     return acc_size;
59 }
60
61 struct twimap*
62 twifs_mapping(struct twifs_node* parent, void* data, const char* fmt, ...)
63 {
64     va_list args;
65     va_start(args, fmt);
66
67     struct twimap* map = vzalloc(sizeof(struct twimap));
68     struct twifs_node* node = twifs_file_node_vargs(parent, fmt, args);
69     node->ops.read = __twimap_read;
70     node->data = map;
71
72     map->reset = __twimap_default_reset;
73     map->go_next = __twimap_default_gonext;
74     map->data = data;
75
76     return map;
77 }
78
79 void
80 twimap_printf(struct twimap* mapping, const char* fmt, ...)
81 {
82     va_list args;
83     va_start(args, fmt);
84
85     char* buf = mapping->buffer + mapping->size_acc;
86
87     mapping->size_acc +=
88       __ksprintf_internal(buf, fmt, TWIMAP_BUFFER_SIZE, args);
89
90     va_end(args);
91 }
92
93 int
94 twimap_memcpy(struct twimap* mapping, const void* src, const size_t len)
95 {
96     mapping->size_acc = MIN(TWIMAP_BUFFER_SIZE, len);
97     memcpy(mapping->buffer, src, mapping->size_acc);
98
99     return mapping->size_acc;
100 }
101
102 int
103 twimap_memappend(struct twimap* mapping, const void* src, const size_t len)
104 {
105     size_t cpy_len = MIN(TWIMAP_BUFFER_SIZE - mapping->size_acc, len);
106     memcpy(mapping->buffer + mapping->size_acc, src, cpy_len);
107     mapping->size_acc += cpy_len;
108
109     return cpy_len;
110 }