2fc38e76846d57157ffff786870015f84db129ac
[tpg/acess2.git] / Kernel / vfs / memfile.c
1 /*
2  */
3 #include <common.h>
4 #include <vfs.h>
5
6 // === PROTOTYPES ===
7 tVFS_Node       *VFS_MemFile_Create(tVFS_Node *Unused, char *Path);
8 void    VFS_MemFile_Close(tVFS_Node *Node);
9 Uint64  VFS_MemFile_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
10 Uint64  VFS_MemFile_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
11
12 // === GLOBALS ===
13 tVFS_Node       gVFS_MemRoot = {
14         .Flags = VFS_FFLAG_DIRECTORY,
15         .NumACLs = 0,
16         .FindDir = VFS_MemFile_Create
17         };
18
19 // === CODE ===
20 /**
21  * \fn tVFS_Node *VFS_MemFile_Create(tVFS_Node *Unused, char *Path)
22  * \note Treated as finddir by VFS_ParsePath
23  */
24 tVFS_Node *VFS_MemFile_Create(tVFS_Node *Unused, char *Path)
25 {
26         Uint    base, size;
27         char    *str = Path;
28         tVFS_Node       *ret;
29         
30         str++;  // Eat '$'
31         
32         // Read Base address
33         base = 0;
34         for( ; ('0' <= *str && *str <= '9') || ('A' <= *str && *str <= 'F'); str++ )
35         {
36                 base *= 16;
37                 if('A' <= *str && *str <= 'F')
38                         base += *str - 'A' + 10;
39                 else
40                         base += *str - '0';
41         }
42         
43         // Check separator
44         if(*str++ != ':')       return NULL;
45         
46         // Read buffer size
47         size = 0;
48         for( ; ('0' <= *str && *str <= '9') || ('A' <= *str && *str <= 'F'); str++ )
49         {
50                 size *= 16;
51                 if('A' <= *str && *str <= 'F')
52                         size += *str - 'A' + 10;
53                 else
54                         size += *str - '0';
55         }
56         
57         // Check for NULL byte
58         if(*str != '\0')        return NULL;
59         
60         Log(" VFS_MemFile_Create: base=0x%x, size=0x%x", base, size);
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->Close = VFS_MemFile_Close;
76         ret->Read = VFS_MemFile_Read;
77         ret->Write = VFS_MemFile_Write;
78         
79         return ret;
80 }
81
82 /**
83  * \fn void VFS_MemFile_Close(tVFS_Node *Node)
84  * \brief Dereference and clean up a memory file
85  */
86 void VFS_MemFile_Close(tVFS_Node *Node)
87 {
88         Node->ReferenceCount --;
89         if( Node->ReferenceCount == 0 ) {
90                 Node->ImplPtr = NULL;
91                 free(Node);
92         }
93 }
94
95 /**
96  * \fn Uint64 VFS_MemFile_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
97  * \brief Read from a memory file
98  */
99 Uint64 VFS_MemFile_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
100 {
101         // Check for use of free'd file
102         if(Node->ImplPtr == NULL)       return 0;
103         
104         // Check for out of bounds read
105         if(Offset > Node->Size) return 0;
106         
107         // Truncate data read if needed
108         if(Offset + Length > Node->Size)
109                 Length = Node->Size - Offset;
110         
111         // Copy Data
112         memcpy(Buffer, Node->ImplPtr+Offset, Length);
113         
114         return Length;
115 }
116
117 /**
118  * \fn Uint64 VFS_MemFile_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
119  * \brief Write to a memory file
120  */
121 Uint64 VFS_MemFile_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
122 {
123         // Check for use of free'd file
124         if(Node->ImplPtr == NULL)       return 0;
125         
126         // Check for out of bounds read
127         if(Offset > Node->Size) return 0;
128         
129         // Truncate data read if needed
130         if(Offset + Length > Node->Size)
131                 Length = Node->Size - Offset;
132         
133         // Copy Data
134         memcpy(Node->ImplPtr+Offset, Buffer, Length);
135         
136         return Length;
137 }

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