2
1
mirror of https://github.com/qpdf/qpdf.git synced 2025-01-23 07:08:30 +00:00

Code tidy: replace if with case statement in QPDFTokenizer::presentCharacter

This commit is contained in:
m-holger 2022-08-18 16:53:16 +01:00
parent cf945eeabf
commit 91fb61eda5

View File

@ -198,12 +198,6 @@ QPDFTokenizer::resolveLiteral()
void void
QPDFTokenizer::presentCharacter(char ch) QPDFTokenizer::presentCharacter(char ch)
{ {
if (this->state == st_token_ready) {
throw std::logic_error(
"INTERNAL ERROR: QPDF tokenizer presented character "
"while token is waiting");
}
char orig_ch = ch; char orig_ch = ch;
// State machine is implemented such that some characters may be // State machine is implemented such that some characters may be
@ -211,7 +205,14 @@ QPDFTokenizer::presentCharacter(char ch)
// the character that caused a state change in the new state. // the character that caused a state change in the new state.
bool handled = true; bool handled = true;
if (this->state == st_top) {
switch (this->state) {
case (st_token_ready):
throw std::logic_error(
"INTERNAL ERROR: QPDF tokenizer presented character "
"while token is waiting");
case (st_top):
// Note: we specifically do not use ctype here. It is // Note: we specifically do not use ctype here. It is
// locale-dependent. // locale-dependent.
if (isSpace(ch)) { if (isSpace(ch)) {
@ -258,7 +259,9 @@ QPDFTokenizer::presentCharacter(char ch)
this->state = st_literal; this->state = st_literal;
} }
} }
} else if (this->state == st_in_space) { break;
case st_in_space:
// We only enter this state if include_ignorable is true. // We only enter this state if include_ignorable is true.
if (!isSpace(ch)) { if (!isSpace(ch)) {
this->type = tt_space; this->type = tt_space;
@ -268,7 +271,9 @@ QPDFTokenizer::presentCharacter(char ch)
} else { } else {
this->val += ch; this->val += ch;
} }
} else if (this->state == st_in_comment) { break;
case st_in_comment:
if ((ch == '\r') || (ch == '\n')) { if ((ch == '\r') || (ch == '\n')) {
if (this->include_ignorable) { if (this->include_ignorable) {
this->type = tt_comment; this->type = tt_comment;
@ -281,7 +286,9 @@ QPDFTokenizer::presentCharacter(char ch)
} else if (this->include_ignorable) { } else if (this->include_ignorable) {
this->val += ch; this->val += ch;
} }
} else if (this->state == st_lt) { break;
case st_lt:
if (ch == '<') { if (ch == '<') {
this->val += "<<"; this->val += "<<";
this->type = tt_dict_open; this->type = tt_dict_open;
@ -290,7 +297,9 @@ QPDFTokenizer::presentCharacter(char ch)
handled = false; handled = false;
this->state = st_in_hexstring; this->state = st_in_hexstring;
} }
} else if (this->state == st_gt) { break;
case st_gt:
if (ch == '>') { if (ch == '>') {
this->val += ">>"; this->val += ">>";
this->type = tt_dict_close; this->type = tt_dict_close;
@ -304,91 +313,99 @@ QPDFTokenizer::presentCharacter(char ch)
this->char_to_unread = ch; this->char_to_unread = ch;
this->state = st_token_ready; this->state = st_token_ready;
} }
} else if (this->state == st_in_string) { break;
if (this->string_ignoring_newline && (ch != '\n')) {
this->string_ignoring_newline = false;
}
size_t bs_num_count = strlen(this->bs_num_register); case st_in_string:
bool ch_is_octal = ((ch >= '0') && (ch <= '7')); {
if ((bs_num_count == 3) || ((bs_num_count > 0) && (!ch_is_octal))) { if (this->string_ignoring_newline && (ch != '\n')) {
// We've accumulated \ddd. PDF Spec says to ignore this->string_ignoring_newline = false;
// high-order overflow. }
this->val +=
static_cast<char>(strtol(this->bs_num_register, nullptr, 8));
memset(this->bs_num_register, '\0', sizeof(this->bs_num_register));
bs_num_count = 0;
}
if (this->string_ignoring_newline && (ch == '\n')) { size_t bs_num_count = strlen(this->bs_num_register);
// ignore bool ch_is_octal = ((ch >= '0') && (ch <= '7'));
this->string_ignoring_newline = false; if ((bs_num_count == 3) || ((bs_num_count > 0) && (!ch_is_octal))) {
} else if ( // We've accumulated \ddd. PDF Spec says to ignore
ch_is_octal && (this->last_char_was_bs || (bs_num_count > 0))) { // high-order overflow.
this->bs_num_register[bs_num_count++] = ch; this->val += static_cast<char>(
} else if (this->last_char_was_bs) { strtol(this->bs_num_register, nullptr, 8));
switch (ch) { memset(
case 'n': this->bs_num_register, '\0', sizeof(this->bs_num_register));
bs_num_count = 0;
}
if (this->string_ignoring_newline && (ch == '\n')) {
// ignore
this->string_ignoring_newline = false;
} else if (
ch_is_octal && (this->last_char_was_bs || (bs_num_count > 0))) {
this->bs_num_register[bs_num_count++] = ch;
} else if (this->last_char_was_bs) {
switch (ch) {
case 'n':
this->val += '\n';
break;
case 'r':
this->val += '\r';
break;
case 't':
this->val += '\t';
break;
case 'b':
this->val += '\b';
break;
case 'f':
this->val += '\f';
break;
case '\n':
break;
case '\r':
this->string_ignoring_newline = true;
break;
default:
// PDF spec says backslash is ignored before anything else
this->val += ch;
break;
}
} else if (ch == '\\') {
// last_char_was_bs is set/cleared below as appropriate
if (bs_num_count) {
throw std::logic_error(
"INTERNAL ERROR: QPDFTokenizer: bs_num_count != 0 "
"when ch == '\\'");
}
} else if (ch == '(') {
this->val += ch;
++this->string_depth;
} else if ((ch == ')') && (--this->string_depth == 0)) {
this->type = tt_string;
this->state = st_token_ready;
} else if (ch == '\r') {
// CR by itself is converted to LF
this->val += '\n'; this->val += '\n';
break; } else if (ch == '\n') {
// CR LF is converted to LF
case 'r': if (!this->last_char_was_cr) {
this->val += '\r'; this->val += ch;
break; }
} else {
case 't':
this->val += '\t';
break;
case 'b':
this->val += '\b';
break;
case 'f':
this->val += '\f';
break;
case '\n':
break;
case '\r':
this->string_ignoring_newline = true;
break;
default:
// PDF spec says backslash is ignored before anything else
this->val += ch;
break;
}
} else if (ch == '\\') {
// last_char_was_bs is set/cleared below as appropriate
if (bs_num_count) {
throw std::logic_error(
"INTERNAL ERROR: QPDFTokenizer: bs_num_count != 0 "
"when ch == '\\'");
}
} else if (ch == '(') {
this->val += ch;
++this->string_depth;
} else if ((ch == ')') && (--this->string_depth == 0)) {
this->type = tt_string;
this->state = st_token_ready;
} else if (ch == '\r') {
// CR by itself is converted to LF
this->val += '\n';
} else if (ch == '\n') {
// CR LF is converted to LF
if (!this->last_char_was_cr) {
this->val += ch; this->val += ch;
} }
} else {
this->val += ch; this->last_char_was_cr =
((!this->string_ignoring_newline) && (ch == '\r'));
this->last_char_was_bs =
((!this->last_char_was_bs) && (ch == '\\'));
} }
break;
this->last_char_was_cr = case st_literal:
((!this->string_ignoring_newline) && (ch == '\r'));
this->last_char_was_bs = ((!this->last_char_was_bs) && (ch == '\\'));
} else if (this->state == st_literal) {
if (isDelimiter(ch)) { if (isDelimiter(ch)) {
// A C-locale whitespace character or delimiter terminates // A C-locale whitespace character or delimiter terminates
// token. It is important to unread the whitespace // token. It is important to unread the whitespace
@ -405,16 +422,19 @@ QPDFTokenizer::presentCharacter(char ch)
} else { } else {
this->val += ch; this->val += ch;
} }
} else if (this->state == st_inline_image) { break;
case st_inline_image:
this->val += ch; this->val += ch;
size_t len = this->val.length(); if (this->val.length() == this->inline_image_bytes) {
if (len == this->inline_image_bytes) {
QTC::TC("qpdf", "QPDFTokenizer found EI by byte count"); QTC::TC("qpdf", "QPDFTokenizer found EI by byte count");
this->type = tt_inline_image; this->type = tt_inline_image;
this->inline_image_bytes = 0; this->inline_image_bytes = 0;
this->state = st_token_ready; this->state = st_token_ready;
} }
} else { break;
default:
handled = false; handled = false;
} }