/* "kernel_string_pool.c" created by: grayspace aka J. Leveille for: UbixOS Project date: May 11, 2002 purpose: to provide a mechanism for maintaining a pool of strings for use by the kernel without unnecessary waste of memory NOTEs: - for now only ASCII is supported - done quickly, pretty hacky TODO: - expand to support unicode - use huffman encoding instead $Id$ */ #include "../../grayspace-misc/gsdefines.h" #include "../../sys/include/misc/kernel_string_pool.h" // returns pointer to character *after* substring read static char * ReadSubString( char * p_dst, const BYTEg * p_substr ) { char * p_retval; char * p_curdst; const char * p_cursubstr; p_curdst = p_dst; p_retval = p_dst + (*p_substr) + 1; p_cursubstr = (const char *) (p_substr + 1); do { *p_curdst = *p_cursubstr; p_cursubstr++; p_curdst++; } while( p_curdst < p_retval ); return p_retval; } // returns pointer to character *after* space appended after substring read static char * ReadSubStringAppendSpace( char * p_dst, const BYTEg * p_substr ) { char * p_retval; p_retval = ReadSubString( p_dst, p_substr ); *p_retval = ' '; p_retval++; return p_retval; } // scans through all substrings until we arrive at the one we want // returns pointer to the substring static const BYTEg * FindSubString( const BYTEg * p_substrs, DWORDg substr_idx ) { DWORDg toskip; const BYTEg * p_substr; p_substr = p_substrs; toskip = substr_idx; while( toskip ) { p_substr += (*p_substr); toskip--; } return p_substr; } // p_substr_idx_o <- sub-string index // returns next BYTE after substring index BYTEs static const BYTEg * GetSubStringIndex( DWORDg * p_substr_idx_o, const BYTEg * p_subidxbytes ) { const BYTEg * p_idxbyte; p_idxbyte = p_subidxbytes; /* 'KRNWORD': - [BYTE] 'key1' - if key1 == [0,63]: - key1 is the index of the 'sub-string' in the pool - otherwise - if key1 has bit 7 set - [BYTE] 'key2' - [BYTE] 'key3' - the index of the 'sub-string' in the pool is: (key1&0x7F) * 65536 + key2 * 256 + key3 - (index is in [16384,(2^23-1)] - otherwise - [BYTE] 'key2' - the index of the 'sub-string' in the pool is: (key1&0x3F) * 256 + key2 - (index is in [64,16383]) */ if( (*p_idxbyte) < 64 ) { (*p_substr_idx_o) = (DWORDg) (*p_idxbyte); return p_idxbyte + 1; } if( !( (*p_idxbyte) & (1<<7) ) ) { (*p_substr_idx_o) = (DWORDg) (*p_idxbyte); (*p_substr_idx_o) &= 0x7F; p_idxbyte++; (*p_substr_idx_o) <<= 8; (*p_substr_idx_o) += (DWORDg) (*p_idxbyte); return p_idxbyte + 1; } (*p_substr_idx_o) = (DWORDg) (*p_idxbyte); (*p_substr_idx_o) &= 0x3F; p_idxbyte++; (*p_substr_idx_o) <<= 8; (*p_substr_idx_o) += (DWORDg) (*p_idxbyte); p_idxbyte++; (*p_substr_idx_o) <<= 8; (*p_substr_idx_o) += (DWORDg) (*p_idxbyte); return p_idxbyte + 1; } // gets the substring indicated by 'id' from the pool 'p_ksp' into 'p_dst' // - returns pointer to 'p_dst' char * KSTR_POOL_GetString( KSTR_POOL * p_ksp, char * p_dst, DWORDg id ) { DWORDg i; DWORDg substr_idx; char * p_curdst; const BYTEg * p_substr; const BYTEg * p_krnstr; const BYTEg * p_over_krnstr; // scan through *every* kernel string until we find the one we want p_krnstr = p_ksp->p_krnstrs; for( i = 0; i < id; i++ ) { p_krnstr += (*p_krnstr); } // get end of kernel string p_over_krnstr = (++p_krnstr) + (*p_krnstr); while( 1 ) { // find substring p_krnstr = GetSubStringIndex( &substr_idx, p_krnstr ); p_substr = FindSubString( p_ksp->p_substrs, substr_idx ); if( p_krnstr < p_over_krnstr ) { // append to destination and also append a space p_curdst = ReadSubStringAppendSpace( p_curdst, p_substr ); continue; } // append to destination p_curdst = ReadSubString( p_curdst, p_substr ); break; } return p_dst; }