jchar HashtableTextDump::unescape(const char* from, const char* end, int count) { jchar value = 0; corrupted_if(from + count > end); for (int i=0; i<count; i++) { char c = *from++; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': value = (value << 4) + c - '0'; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': value = (value << 4) + 10 + c - 'a'; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': value = (value << 4) + 10 + c - 'A'; break; default: ShouldNotReachHere(); } } return value; }
void HashtableTextDump::skip_past(char c) { for (;;) { corrupted_if(remain() < 1); if (*_p++ == c) { return; } } }
void HashtableTextDump::check_version(const char* ver) { int len = (int)strlen(ver); corrupted_if(remain() < len); if (strncmp(_p, ver, len) != 0) { quit("wrong version of hashtable dump file", _filename); } _p += len; skip_newline(); }
void HashtableTextDump::get_utf8(char* utf8_buffer, int utf8_length) { // cache in local vars const char* from = _p; const char* end = _end; char* to = utf8_buffer; int n = utf8_length; for (; n > 0 && from < end; n--) { if (*from != '\\') { *to++ = *from++; } else { corrupted_if(from + 2 > end); char c = from[1]; from += 2; switch (c) { case 'x': { jchar value = unescape(from, end, 2); from += 2; assert(value <= 0xff, "sanity"); *to++ = (char)(value & 0xff); } break; case 't': *to++ = '\t'; break; case 'n': *to++ = '\n'; break; case 'r': *to++ = '\r'; break; case '\\': *to++ = '\\'; break; default: corrupted(_p, "Unsupported character"); } } } corrupted_if(n > 0); // expected more chars but file has ended _p = from; skip_newline(); }
int HashtableTextDump::skip(char must_be_char) { corrupted_if(remain() < 1); corrupted_if(*_p++ != must_be_char); return 0; }
int HashtableTextDump::skip(char must_be_char) { corrupted_if(remain() < 1, "Truncated"); corrupted_if(*_p++ != must_be_char, "Unexpected character"); return 0; }