stos: ob: Add directory object operations
This commit adds operations for appending directories and top-level lookups. Signed-off-by: Chloe M. <chloe@mensia.org>
This commit is contained in:
@@ -35,6 +35,7 @@ typedef enum {
|
||||
* @Type: Object type
|
||||
* @Data: Object data
|
||||
* @CacheNext: Used when reclaiming object
|
||||
* @DirecNext: Directory link
|
||||
*/
|
||||
typedef struct _ST_OBJECT {
|
||||
CHAR Name[OBJECT_NAMESZ];
|
||||
@@ -42,6 +43,7 @@ typedef struct _ST_OBJECT {
|
||||
OBJECT_TYPE Type;
|
||||
VOID *Data;
|
||||
struct _ST_OBJECT *CacheNext;
|
||||
struct _ST_OBJECT *DirecNext;
|
||||
} ST_OBJECT;
|
||||
|
||||
/*
|
||||
@@ -66,6 +68,14 @@ typedef struct {
|
||||
*/
|
||||
ST_STATUS ObCreateDirectory(const CHAR *Name, ST_OBJECT **Result);
|
||||
|
||||
/*
|
||||
* Append an object to a directory
|
||||
*
|
||||
* @DirecParent: Parent of directory to append to
|
||||
* @Object: Object to append to directory
|
||||
*/
|
||||
ST_STATUS ObAppendDirectory(ST_OBJECT *DirecParent, ST_OBJECT *Object);
|
||||
|
||||
/*
|
||||
* Allocate and create a new objec
|
||||
*
|
||||
@@ -84,6 +94,15 @@ ST_STATUS ObCreateObject(
|
||||
*/
|
||||
VOID ObInitManager(VOID);
|
||||
|
||||
/*
|
||||
* Look up an object from a parent directory
|
||||
*
|
||||
* @Parent: Parent directly to look up from
|
||||
* @Name: Name of object to lookup
|
||||
* @Result: Result is written here
|
||||
*/
|
||||
ST_STATUS ObLookupFromTop(ST_OBJECT *Parent, const CHAR *Name, ST_OBJECT **Result);
|
||||
|
||||
/*
|
||||
* Reclaim an object after use, if its reference count is > 1, simply
|
||||
* bump it down. Once it hits zero, the object is returned to the cache.
|
||||
|
||||
@@ -104,3 +104,83 @@ ObReclaimObject(ST_OBJECT *Object)
|
||||
ObReclaimToCache(&gObCache, Object);
|
||||
}
|
||||
}
|
||||
|
||||
ST_STATUS
|
||||
ObAppendDirectory(ST_OBJECT *DirecParent, ST_OBJECT *Object)
|
||||
{
|
||||
OBJECT_DIRECTORY *Directory;
|
||||
ST_OBJECT *Last;
|
||||
|
||||
if (DirecParent == NULL || Object == NULL) {
|
||||
return STATUS_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (DirecParent->Type != OBJECT_TYPE_DIRECTORY) {
|
||||
return STATUS_NOT_DIRECTORY;
|
||||
}
|
||||
|
||||
Directory = DirecParent->Data;
|
||||
if (Directory == NULL) {
|
||||
return STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
/* TODO: Place lock here */
|
||||
if (Directory->First == NULL || Directory->Last == NULL) {
|
||||
Directory->First = Object;
|
||||
Directory->Last = Object;
|
||||
} else {
|
||||
Last = Directory->Last;
|
||||
Last->DirecNext = Object;
|
||||
Directory->Last = Object;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ST_STATUS
|
||||
ObLookupFromTop(ST_OBJECT *Parent, const CHAR *Name, ST_OBJECT **Result)
|
||||
{
|
||||
ST_OBJECT *Entry;
|
||||
OBJECT_DIRECTORY *ParentDirec;
|
||||
USIZE NameLen;
|
||||
|
||||
if (Parent == NULL || Name == NULL) {
|
||||
return STATUS_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (Result == NULL) {
|
||||
return STATUS_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/* Must be a directory */
|
||||
if (Parent->Type != OBJECT_TYPE_DIRECTORY) {
|
||||
return STATUS_NOT_DIRECTORY;
|
||||
}
|
||||
|
||||
ParentDirec = Parent->Data;
|
||||
if (ParentDirec == NULL) {
|
||||
return STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
Entry = ParentDirec->First;
|
||||
NameLen = RtlStrLen(Name);
|
||||
if (NameLen >= OBJECT_NAMESZ - 1) {
|
||||
return STATUS_NAME_TOO_LONG;
|
||||
}
|
||||
|
||||
while (Entry != NULL) {
|
||||
if (*Entry->Name != *Name) {
|
||||
Entry = Entry->DirecNext;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RtlMemCmp(Entry->Name, Name, NameLen) == 0) {
|
||||
*Result = Entry;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
Entry = Entry->DirecNext;
|
||||
}
|
||||
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user