📄 hashtable.c
字号:
short result = 0x80; /* default bad result; */ switch ((ch = ptr[0]) >> 4) { default: result = ch; break; case 0x8: case 0x9: case 0xA: case 0xB: case 0xF: /* Shouldn't happen. */ break; case 0xC: case 0xD: /* 110xxxxx 10xxxxxx */ if (((ch2 = ptr[1]) & 0xC0) == 0x80) { unsigned char high_five = ch & 0x1F; unsigned char low_six = ch2 & 0x3F; result = (high_five << 6) + low_six; length = 2; } break; case 0xE: /* 1110xxxx 10xxxxxx 10xxxxxx */ if (((ch2 = ptr[1]) & 0xC0) == 0x80) { if (((ch3 = ptr[2]) & 0xC0) == 0x80) { unsigned char high_four = ch & 0x0f; unsigned char mid_six = ch2 & 0x3f; unsigned char low_six = ch3 & 0x3f; result = (((high_four << 6) + mid_six) << 6) + low_six; length = 3; } else { length = 2; } } break; } /* end of switch */ *utfstring_ptr = (char *)(ptr + length); return result;}/*========================================================================= * FUNCTION: utfStringLength * OVERVIEW: Determine the number of 16-bit characters in a UTF-8 string. * * parameters: utfstring_ptr: pointer to a UTF8 string. * length of string * returns string length *=======================================================================*/unsigned int utfStringLength(const char *utfstring, int length) { const char *ptr = utfstring; const char *end = utfstring + length; unsigned int count; for (count = 0; ptr < end; count++) { unsigned char ch = (unsigned char)ptr[0]; if (ch < 0x80) { /* 99% of the time */ ptr++; } else { switch(ch >> 4) { default: fatalError(KVM_MSG_BAD_UTF_STRING); break; case 0xC: case 0xD: ptr += 2; break; case 0xE: ptr += 3; break; } } } return count;}#if ENABLE_JAVA_DEBUGGER/* * For now, only the debugger code needs to convert back from unicode * to utf when it sends a string value back to the debugger. * So these functions are in the ENABLE_JAVA_DEBUGGER block *//* Given a unicode string and its length, convert it to a utf string. But * the result into the given buffer, whose length is buflength. The utf * string should include a null terminator. * * If both buffer and buflength are 0, then malloc an appropriately sized * buffer for the result. */char *unicode2utf(unsigned short *unistring, int length, char *buffer, int buflength){ int i; unsigned short *uniptr; char *bufptr; unsigned bufleft; bufleft = buflength - 1; /* take note of null now! */ for (i = length, uniptr = unistring, bufptr = buffer; --i >= 0; uniptr++) { unsigned short ch = *uniptr; if ((ch != 0) && (ch <=0x7f)) { if ((int)(--bufleft) < 0) /* no space for character */ break; *bufptr++ = (char)ch; } else if (ch <= 0x7FF) { /* 11 bits or less. */ unsigned char high_five = ch >> 6; unsigned char low_six = ch & 0x3F; if ((int)(bufleft -= 2) < 0) /* no space for character */ break; *bufptr++ = high_five | 0xC0; /* 110xxxxx */ *bufptr++ = low_six | 0x80; /* 10xxxxxx */ } else { /* possibly full 16 bits. */ char high_four = ch >> 12; char mid_six = (ch >> 6) & 0x3F; char low_six = ch & 0x3f; if ((int)(bufleft -= 3) < 0) /* no space for character */ break; *bufptr++ = high_four | 0xE0; /* 1110xxxx */ *bufptr++ = mid_six | 0x80; /* 10xxxxxx */ *bufptr++ = low_six | 0x80; /* 10xxxxxx*/ } } *bufptr = 0; return buffer;}/* Return the number of characters that would be needed to hold the unicode * string in utf. */int unicode2utfstrlen(unsigned short *unistring, int unilength){ int result_length = 0; for (; unilength > 0; unistring++, unilength--) { unsigned short ch = *unistring; if ((ch != 0) && (ch <= 0x7f)) /* 1 byte */ result_length++; else if (ch <= 0x7FF) result_length += 2; /* 2 byte character */ else result_length += 3; /* 3 byte character */ } return result_length;}#endif /* ENABLE_JAVA_DEBUGGER *//*========================================================================= * FUNCTION: change_Name_to_Key, change_Key_to_Name * OVERVIEW: Converts between an array of bytes, and a unique 16-bit * number (the Key) * * INTERFACE: change_Name_to_key * parameters: string: Pointer to an array of characters * stringLength: Length of array * returns A unique 16-bit key * * INTERFACE: change_key_to_Name * parameters: key: A unique 16-bit key * lengthP: If non-NULL, the length of the result is returned here. * * returns A pointer to the array of characters. *=======================================================================*/NameKeychange_Name_to_Key(CONST_CHAR_HANDLE nameH, int offset, int length) { UString UName = getUStringX(nameH, offset, length); return UName->key;}char *change_Key_to_Name(NameKey key, int *lengthP) { HASHTABLE table = UTFStringTable; int index = key % table->bucketCount; UTF_HASH_ENTRY *bucketPtr = (UTF_HASH_ENTRY *)&table->bucket[index]; UTF_HASH_ENTRY bucket; /* Search the bucket for the corresponding string. */ for (bucket = *bucketPtr; bucket != NULL; bucket = bucket->next) { if (key == bucket->key) { if (lengthP) { *lengthP = bucket->length; } return UStringInfo(bucket); } } return NULL;}/*========================================================================= * FUNCTION: change_Name_to_CLASS, change_Key_to_CLASS * OVERVIEW: Internal function used by internString and internClass. * It maps a C string to a specific location capable of * holding a value. This location is initially NULL. * INTERFACE: * parameters: table: A hashtable whose buckets are MAPPING_HASH_ENTRY. * string: A C string * returns: A unique location, capable of holding a value, corresponding * to that string. *=======================================================================*/CLASSchange_Name_to_CLASS(UString packageName, UString baseName) { HASHTABLE table = ClassTable; unsigned int hash; unsigned int index; unsigned int lastKey = 0; CLASS *clazzPtr, clazz; hash = stringHash(UStringInfo(baseName), baseName->length) + 37; if (packageName != NULL) { hash += stringHash(UStringInfo(packageName), packageName->length) * 3; } index = hash % table->bucketCount; clazzPtr = (CLASS *)&table->bucket[index]; for (clazz = *clazzPtr; clazz != NULL; clazz = clazz->next) { if (clazz->packageName == packageName && clazz->baseName == baseName) {#if EXCESSIVE_GARBAGE_COLLECTION && !ASYNCHRONOUS_NATIVE_FUNCTIONS if (excessivegc) { /* We might garbage collect, so we do */ garbageCollect(0); }#endif /* EXCESSIVE_GARBAGE_COLLECTION && !ASYNCHRONOUS_NATIVE_FUNCTIONS */ return clazz; } if (lastKey == 0) { unsigned thisKey = clazz->key; int pseudoDepth = thisKey >> FIELD_KEY_ARRAY_SHIFT; if (pseudoDepth == 0 || pseudoDepth == MAX_FIELD_KEY_ARRAY_DEPTH) { lastKey = thisKey & 0x1FFF; } } } if (UStringInfo(baseName)[0] == '[') { clazz = (CLASS)callocPermanentObject(SIZEOF_ARRAY_CLASS); } else { clazz = (CLASS)callocPermanentObject(SIZEOF_INSTANCE_CLASS); } clazz->next = *clazzPtr; *clazzPtr = clazz; clazz->packageName = packageName; clazz->baseName = baseName; /* The caller may change this value to be one of the values with * depth 1 <= depth <= MAX_FIELD_KEY_ARRAY_DEPTH. */ clazz->key = lastKey == 0 ? (256 + index) : (lastKey + table->bucketCount); if (clazz->key & ITEM_NewObject_Flag) { fatalError(KVM_MSG_TOO_MANY_CLASS_KEYS); } table->count++; return clazz;} CLASSchange_Key_to_CLASS(FieldTypeKey key) { int depth = key >> FIELD_KEY_ARRAY_SHIFT; if (depth == 0 || depth == MAX_FIELD_KEY_ARRAY_DEPTH) { HASHTABLE table = ClassTable; int index = ((key & 0x1FFF) - 256) % table->bucketCount; CLASS *clazzPtr = (CLASS *)&table->bucket[index]; CLASS clazz; /* Search the clazz for the corresponding string. */ for (clazz = *clazzPtr; clazz != NULL; clazz = clazz->next) { if (key == clazz->key) { return clazz; } } return NULL; } else { FieldTypeKey baseClassKey = key & 0x1FFF; if (baseClassKey <= 255) { return (CLASS)getArrayClass(depth, NULL, (char)baseClassKey); } else { CLASS temp = change_Key_to_CLASS(baseClassKey); return (CLASS)getArrayClass(depth, (INSTANCE_CLASS)temp, '\0'); } }}/*========================================================================= * Printing and debugging operations *=======================================================================*/#if INCLUDEDEBUGCODEvoidprintUTFStringTable() { HASHTABLE table = UTFStringTable; int count = table->bucketCount; while (--count >= 0) { UString bucket = (UString)table->bucket[count]; for ( ; bucket != NULL; bucket = bucket->next) { int length = bucket->length; char *string = bucket->string; if (length > 0 && string[0] < 20) { change_Key_to_MethodSignature_inBuffer(bucket->key, str_buffer); fprintf(stdout, "*** \"%s\"\n", str_buffer); } else { fprintf(stdout, " \"%s\"\n", string); } } }}#endif /* INCLUDEDEBUGCODE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -