X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Flib.c;h=f6149652eeafd2285effc5254a47374f3d66841b;hb=5c46f86c5a8ceaa63a1a9919cf1f4d2889c6c233;hp=ee9f24e0f6bba679a0f977661918cd1f73b17b43;hpb=8bc40333b1401d7616b225945fee53d972c2f418;p=tpg%2Facess2.git diff --git a/Kernel/lib.c b/Kernel/lib.c index ee9f24e0..f6149652 100644 --- a/Kernel/lib.c +++ b/Kernel/lib.c @@ -5,6 +5,10 @@ #include // === CONSTANTS === +#define RANDOM_SEED 0xACE55052 +#define RANDOM_A 0x00731ADE +#define RANDOM_C 12345 +#define RANDOM_SPRUCE 0xf12b02b // Jan Feb Mar Apr May Jun Jul Aug Sept Oct Nov Dec const short DAYS_BEFORE[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; #define UNIX_TO_2K ((30*365*3600*24) + (7*3600*24)) //Normal years + leap years @@ -12,6 +16,9 @@ const short DAYS_BEFORE[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 3 // === PROTOTYPES === int ReadUTF8(Uint8 *str, Uint32 *Val); +// === GLOBALS === +static Uint giRandomState = RANDOM_SEED; + // === CODE === static const char cUCDIGITS[] = "0123456789ABCDEF"; /** @@ -49,7 +56,7 @@ void itoa(char *buf, Uint num, int base, int minLength, char pad) } /** - * \fn int tolower(int __c) + * \fn int tolower(int c) * \brief Converts a character to lower case */ int tolower(int c) @@ -63,7 +70,7 @@ int tolower(int c) * \fn int strucmp(char *Str1, char *Str2) * \brief Compare \a Str1 and \a Str2 case-insensitively */ -int strucmp(char *Str1, char *Str2) +int strucmp(const char *Str1, const char *Str2) { while(*Str1 && tolower(*Str1) == tolower(*Str2)) Str1++, Str2++; @@ -71,10 +78,10 @@ int strucmp(char *Str1, char *Str2) } /** - * \fn int strpos(char *Str, char Ch) + * \fn int strpos(const char *Str, char Ch) * \brief Search a string for an ascii character */ -int strpos(char *Str, char Ch) +int strpos(const char *Str, char Ch) { int pos; for(pos=0;Str[pos];pos++) @@ -85,6 +92,8 @@ int strpos(char *Str, char Ch) } /** + * \fn int ByteSum(void *Ptr, int Size) + * \brief Adds the bytes in a memory region and returns the sum */ int ByteSum(void *Ptr, int Size) { @@ -94,10 +103,10 @@ int ByteSum(void *Ptr, int Size) } /** - * \fn Uint strlen(char *__str) + * \fn Uint strlen(const char *__str) * \brief Get the length of string */ -Uint strlen(char *__str) +Uint strlen(const char *__str) { Uint ret = 0; while(*__str++) ret++; @@ -105,10 +114,10 @@ Uint strlen(char *__str) } /** - * \fn char *strcpy(char *__str1, char *__str2) + * \fn char *strcpy(const char *__str1, const char *__str2) * \brief Copy a string to a new location */ -char *strcpy(char *__str1, char *__str2) +char *strcpy(char *__str1, const char *__str2) { while(*__str2) *__str1++ = *__str2++; @@ -117,11 +126,11 @@ char *strcpy(char *__str1, char *__str2) } /** - * \fn int strcmp(char *str1, char *str2) + * \fn int strcmp(const char *str1, const char *str2) * \brief Compare two strings return the difference between * the first non-matching characters. */ -int strcmp(char *str1, char *str2) +int strcmp(const char *str1, const char *str2) { while(*str1 && *str1 == *str2) str1++, str2++; @@ -129,21 +138,45 @@ int strcmp(char *str1, char *str2) } /** - * \fn int strncmp(char *Str1, char *Str2, size_t num) + * \fn int strncmp(const char *Str1, const char *Str2, size_t num) * \brief Compare strings \a Str1 and \a Str2 to a maximum of \a num characters */ -int strncmp(char *Str1, char *Str2, size_t num) +int strncmp(const char *Str1, const char *Str2, size_t num) { - while(num-- && *Str1 && *Str1 == *Str2) + if(num == 0) return 0; // TODO: Check what should officially happen here + while(--num && *Str1 && *Str1 == *Str2) Str1++, Str2++; return *Str1-*Str2; } /** - * \fn int strpos8(char *str, Uint32 search) + * \fn char *strdup(const char *Str) + * \brief Duplicates a string + */ +char *strdup(const char *Str) +{ + char *ret; + ret = malloc(strlen(Str)+1); + strcpy(ret, Str); + return ret; +} + +/** + * \fn int DivUp(int num, int dem) + * \brief Divide two numbers, rounding up + * \param num Numerator + * \param dem Denominator + */ +int DivUp(int num, int dem) +{ + return (num+dem-1)/dem; +} + +/** + * \fn int strpos8(const char *str, Uint32 search) * \brief Search a string for a UTF-8 character */ -int strpos8(char *str, Uint32 Search) +int strpos8(const char *str, Uint32 Search) { int pos; Uint32 val = 0; @@ -168,6 +201,8 @@ int strpos8(char *str, Uint32 Search) */ int ReadUTF8(Uint8 *str, Uint32 *Val) { + *Val = 0xFFFD; // Assume invalid character + // ASCII if( !(*str & 0x80) ) { *Val = *str; @@ -176,7 +211,6 @@ int ReadUTF8(Uint8 *str, Uint32 *Val) // Middle of a sequence if( (*str & 0xC0) == 0x80 ) { - *Val = -1; return 1; } @@ -217,10 +251,55 @@ int ReadUTF8(Uint8 *str, Uint32 *Val) } // UTF-8 Doesn't support more than four bytes - *Val = -1; return 4; } +/** + * \fn int WriteUTF8(Uint8 *str, Uint32 Val) + * \brief Write a UTF-8 character sequence to a string + */ +int WriteUTF8(Uint8 *str, Uint32 Val) +{ + // ASCII + if( Val < 128 ) { + *str = Val; + return 1; + } + + // Two Byte + if( Val < 0x8000 ) { + *str = 0xC0 | (Val >> 6); + str ++; + *str = 0x80 | (Val & 0x3F); + return 2; + } + + // Three Byte + if( Val < 0x10000 ) { + *str = 0xE0 | (Val >> 12); + str ++; + *str = 0x80 | ((Val >> 6) & 0x3F); + str ++; + *str = 0x80 | (Val & 0x3F); + return 3; + } + + // Four Byte + if( Val < 0x110000 ) { + *str = 0xF0 | (Val >> 18); + str ++; + *str = 0x80 | ((Val >> 12) & 0x3F); + str ++; + *str = 0x80 | ((Val >> 6) & 0x3F); + str ++; + *str = 0x80 | (Val & 0x3F); + return 4; + } + + // UTF-8 Doesn't support more than four bytes + return 0; +} + /** * \fn Uint64 timestamp(int sec, int mins, int hrs, int day, int month, int year) * \brief Converts a date into an Acess Timestamp @@ -247,5 +326,110 @@ Sint64 timestamp(int sec, int mins, int hrs, int day, int month, int year) return stamp * 1000; } +/** + * \fn Uint rand() + * \brief Pseudo random number generator + * \note Unknown effectiveness (made up on the spot) + */ +Uint rand() +{ + Uint old = giRandomState; + // Get the next state value + giRandomState = (RANDOM_A*giRandomState + RANDOM_C) & 0xFFFFFFFF; + // Check if it has changed, and if it hasn't, change it + if(giRandomState == old) giRandomState += RANDOM_SPRUCE; + return giRandomState; +} + +/// \name Memory Validation +/// \{ +/** + * \brief Checks if a string resides fully in valid memory + */ +int CheckString(char *String) +{ + // Check 1st page + if( MM_IsUser( (tVAddr)String ) ) + { + // Traverse String + while( *String ) + { + if( !MM_IsUser( (tVAddr)String ) ) + return 0; + // Increment string pointer + String ++; + } + return 1; + } + else if( MM_GetPhysAddr( (tVAddr)String ) ) + { + // Traverse String + while( *String ) + { + if( !MM_GetPhysAddr( (tVAddr)String ) ) + return 0; + // Increment string pointer + String ++; + } + return 1; + } + return 0; +} + +/** + * \brief Check if a sized memory region is valid memory + */ +int CheckMem(void *Mem, int NumBytes) +{ + tVAddr addr = (tVAddr)Mem; + + if( MM_IsUser( addr ) ) + { + while( NumBytes-- ) + { + if( !MM_IsUser( addr ) ) + return 0; + addr ++; + } + return 1; + } + else if( MM_GetPhysAddr( addr ) ) + { + while( NumBytes-- ) + { + if( !MM_GetPhysAddr( addr ) ) + return 0; + addr ++; + } + return 1; + } + return 0; +} +/// \} + +/** + * \brief Search a string array for \a Needle + * \note Helper function for eTplDrv_IOCtl::DRV_IOCTL_LOOKUP + */ +int LookupString(char **Array, char *Needle) +{ + int i; + for( i = 0; Array[i]; i++ ) + { + if(strcmp(Array[i], Needle) == 0) return i; + } + return -1; +} + +EXPORT(strlen); +EXPORT(strdup); +EXPORT(strcmp); +EXPORT(strncmp); +EXPORT(strcpy); +//EXPORT(strncpy); + EXPORT(timestamp); EXPORT(ReadUTF8); +EXPORT(CheckMem); +EXPORT(CheckString); +EXPORT(LookupString);