Usermode/ld-acess - Added two more ARM relocation types
[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(tVFS_Node *Unused, 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, void *Buffer);
14
15 // === GLOBALS ===
16 tVFS_Node       gVFS_MemRoot = {
17         .Flags = VFS_FFLAG_DIRECTORY,
18         .NumACLs = 0,
19         .FindDir = VFS_MemFile_Create
20         };
21
22 // === CODE ===
23 /**
24  * \fn tVFS_Node *VFS_MemFile_Create(tVFS_Node *Unused, const char *Path)
25  * \note Treated as finddir by VFS_ParsePath
26  */
27 tVFS_Node *VFS_MemFile_Create(tVFS_Node *Unused, const char *Path)
28 {
29         Uint    base, size;
30         const char      *str = Path;
31         tVFS_Node       *ret;
32         
33         str++;  // Eat '$'
34         
35         // Read Base address
36         base = 0;
37         for( ; ('0' <= *str && *str <= '9') || ('A' <= *str && *str <= 'F'); str++ )
38         {
39                 base *= 16;
40                 if('A' <= *str && *str <= 'F')
41                         base += *str - 'A' + 10;
42                 else
43                         base += *str - '0';
44         }
45         
46         // Check separator
47         if(*str++ != ':')       return NULL;
48         
49         // Read buffer size
50         size = 0;
51         for( ; ('0' <= *str && *str <= '9') || ('A' <= *str && *str <= 'F'); str++ )
52         {
53                 size *= 16;
54                 if('A' <= *str && *str <= 'F')
55                         size += *str - 'A' + 10;
56                 else
57                         size += *str - '0';
58         }
59         
60         // Check for NULL byte
61         if(*str != '\0')        return NULL;
62         
63         // Allocate and fill node
64         ret = malloc(sizeof(tVFS_Node));
65         memset(ret, 0, sizeof(tVFS_Node));
66         
67         // State
68         ret->ImplPtr = (void*)base;
69         ret->Size = size;
70         
71         // ACLs
72         ret->NumACLs = 1;
73         ret->ACLs = &gVFS_ACL_EveryoneRWX;
74         
75         // Functions
76         ret->Close = VFS_MemFile_Close;
77         ret->Read = VFS_MemFile_Read;
78         ret->Write = VFS_MemFile_Write;
79         
80         return ret;
81 }
82
83 /**
84  * \fn void VFS_MemFile_Close(tVFS_Node *Node)
85  * \brief Dereference and clean up a memory file
86  */
87 void VFS_MemFile_Close(tVFS_Node *Node)
88 {
89         Node->ReferenceCount --;
90         if( Node->ReferenceCount == 0 ) {
91                 Node->ImplPtr = NULL;
92                 free(Node);
93         }
94 }
95
96 /**
97  * \fn Uint64 VFS_MemFile_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
98  * \brief Read from a memory file
99  */
100 Uint64 VFS_MemFile_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
101 {
102         // Check for use of free'd file
103         if(Node->ImplPtr == NULL)       return 0;
104         
105         // Check for out of bounds read
106         if(Offset > Node->Size) return 0;
107         
108         // Truncate data read if needed
109         if(Offset + Length > Node->Size)
110                 Length = Node->Size - Offset;
111         
112         // Copy Data
113         memcpy(Buffer, (Uint8*)Node->ImplPtr + Offset, Length);
114         
115         return Length;
116 }
117
118 /**
119  * \fn Uint64 VFS_MemFile_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
120  * \brief Write to a memory file
121  */
122 Uint64 VFS_MemFile_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
123 {
124         // Check for use of free'd file
125         if(Node->ImplPtr == NULL)       return 0;
126         
127         // Check for out of bounds read
128         if(Offset > Node->Size) return 0;
129         
130         // Truncate data read if needed
131         if(Offset + Length > Node->Size)
132                 Length = Node->Size - Offset;
133         
134         // Copy Data
135         memcpy((Uint8*)Node->ImplPtr + Offset, Buffer, Length);
136         
137         return Length;
138 }

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