diff --git a/paw/stos/head/ob/object.h b/paw/stos/head/ob/object.h index 786c624..2e6ad56 100644 --- a/paw/stos/head/ob/object.h +++ b/paw/stos/head/ob/object.h @@ -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. diff --git a/paw/stos/ob/ob.c b/paw/stos/ob/ob.c index 607cb32..dd1b434 100644 --- a/paw/stos/ob/ob.c +++ b/paw/stos/ob/ob.c @@ -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; +}