Kernel - Slight reworks to timer code
[tpg/acess2.git] / Kernel / vfs / memfile.c
1 /* 
2  * Acess 2
3  * Virtual File System
4  * - Memory Pseudo Files
5  */
6 #include <acess.h>
7 #include <vfs.h>
8
9 // === PROTOTYPES ===
10 tVFS_Node       *VFS_MemFile_Create(const char *Path);
11 void    VFS_MemFile_Close(tVFS_Node *Node);
12 Uint64  VFS_MemFile_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
13 Uint64  VFS_MemFile_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer);
14
15 // === GLOBALS ===
16 tVFS_NodeType   gVFS_MemFileType = {
17         .Close = VFS_MemFile_Close,
18         .Read = VFS_MemFile_Read,
19         .Write = VFS_MemFile_Write
20         };
21
22 // === CODE ===
23 /**
24  * \fn tVFS_Node *VFS_MemFile_Create(const char *Path)
25  */
26 tVFS_Node *VFS_MemFile_Create(const char *Path)
27 {
28         Uint    base, size;
29         const char      *str = Path;
30         tVFS_Node       *ret;
31         
32         str++;  // Eat '$'
33         
34         // Read Base address
35         base = 0;
36         for( ; ('0' <= *str && *str <= '9') || ('A' <= *str && *str <= 'F'); str++ )
37         {
38                 base *= 16;
39                 if('A' <= *str && *str <= 'F')
40                         base += *str - 'A' + 10;
41                 else
42                         base += *str - '0';
43         }
44         
45         // Check separator
46         if(*str++ != ':')       return NULL;
47         
48         // Read buffer size
49         size = 0;
50         for( ; ('0' <= *str && *str <= '9') || ('A' <= *str && *str <= 'F'); str++ )
51         {
52                 size *= 16;
53                 if('A' <= *str && *str <= 'F')
54                         size += *str - 'A' + 10;
55                 else
56                         size += *str - '0';
57         }
58         
59         // Check for NULL byte
60         if(*str != '\0')        return NULL;
61         
62         // Allocate and fill node
63         ret = malloc(sizeof(tVFS_Node));
64         memset(ret, 0, sizeof(tVFS_Node));
65         
66         // State
67         ret->ImplPtr = (void*)base;
68         ret->Size = size;
69         
70         // ACLs
71         ret->NumACLs = 1;
72         ret->ACLs = &gVFS_ACL_EveryoneRWX;
73         
74         // Functions
75         ret->Type = &gVFS_MemFileType;
76         
77         return ret;
78 }
79
80 /**
81  * \fn void VFS_MemFile_Close(tVFS_Node *Node)
82  * \brief Dereference and clean up a memory file
83  */
84 void VFS_MemFile_Close(tVFS_Node *Node)
85 {
86         Node->ReferenceCount --;
87         if( Node->ReferenceCount == 0 ) {
88                 Node->ImplPtr = NULL;
89                 free(Node);
90         }
91 }
92
93 /**
94  * \fn Uint64 VFS_MemFile_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
95  * \brief Read from a memory file
96  */
97 Uint64 VFS_MemFile_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
98 {
99         // Check for use of free'd file
100         if(Node->ImplPtr == NULL)       return 0;
101         
102         // Check for out of bounds read
103         if(Offset > Node->Size) return 0;
104         
105         // Truncate data read if needed
106         if(Offset + Length > Node->Size)
107                 Length = Node->Size - Offset;
108         
109         // Copy Data
110         memcpy(Buffer, (Uint8*)Node->ImplPtr + Offset, Length);
111         
112         return Length;
113 }
114
115 /**
116  * \fn Uint64 VFS_MemFile_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
117  * \brief Write to a memory file
118  */
119 Uint64 VFS_MemFile_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer)
120 {
121         // Check for use of free'd file
122         if(Node->ImplPtr == NULL)       return 0;
123         
124         // Check for out of bounds read
125         if(Offset > Node->Size) return 0;
126         
127         // Truncate data read if needed
128         if(Offset + Length > Node->Size)
129                 Length = Node->Size - Offset;
130         
131         // Copy Data
132         memcpy((Uint8*)Node->ImplPtr + Offset, Buffer, Length);
133         
134         return Length;
135 }

UCC git Repository :: git.ucc.asn.au