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