Commit 91fb61eda5ae66736ae9e5975ae6f2e0867366e6
1 parent
cf945eea
Code tidy: replace if with case statement in QPDFTokenizer::presentCharacter
Showing
1 changed file
with
112 additions
and
92 deletions
libqpdf/QPDFTokenizer.cc
| @@ -198,12 +198,6 @@ QPDFTokenizer::resolveLiteral() | @@ -198,12 +198,6 @@ QPDFTokenizer::resolveLiteral() | ||
| 198 | void | 198 | void |
| 199 | QPDFTokenizer::presentCharacter(char ch) | 199 | QPDFTokenizer::presentCharacter(char ch) |
| 200 | { | 200 | { |
| 201 | - if (this->state == st_token_ready) { | ||
| 202 | - throw std::logic_error( | ||
| 203 | - "INTERNAL ERROR: QPDF tokenizer presented character " | ||
| 204 | - "while token is waiting"); | ||
| 205 | - } | ||
| 206 | - | ||
| 207 | char orig_ch = ch; | 201 | char orig_ch = ch; |
| 208 | 202 | ||
| 209 | // State machine is implemented such that some characters may be | 203 | // State machine is implemented such that some characters may be |
| @@ -211,7 +205,14 @@ QPDFTokenizer::presentCharacter(char ch) | @@ -211,7 +205,14 @@ QPDFTokenizer::presentCharacter(char ch) | ||
| 211 | // the character that caused a state change in the new state. | 205 | // the character that caused a state change in the new state. |
| 212 | 206 | ||
| 213 | bool handled = true; | 207 | bool handled = true; |
| 214 | - if (this->state == st_top) { | 208 | + |
| 209 | + switch (this->state) { | ||
| 210 | + case (st_token_ready): | ||
| 211 | + throw std::logic_error( | ||
| 212 | + "INTERNAL ERROR: QPDF tokenizer presented character " | ||
| 213 | + "while token is waiting"); | ||
| 214 | + | ||
| 215 | + case (st_top): | ||
| 215 | // Note: we specifically do not use ctype here. It is | 216 | // Note: we specifically do not use ctype here. It is |
| 216 | // locale-dependent. | 217 | // locale-dependent. |
| 217 | if (isSpace(ch)) { | 218 | if (isSpace(ch)) { |
| @@ -258,7 +259,9 @@ QPDFTokenizer::presentCharacter(char ch) | @@ -258,7 +259,9 @@ QPDFTokenizer::presentCharacter(char ch) | ||
| 258 | this->state = st_literal; | 259 | this->state = st_literal; |
| 259 | } | 260 | } |
| 260 | } | 261 | } |
| 261 | - } else if (this->state == st_in_space) { | 262 | + break; |
| 263 | + | ||
| 264 | + case st_in_space: | ||
| 262 | // We only enter this state if include_ignorable is true. | 265 | // We only enter this state if include_ignorable is true. |
| 263 | if (!isSpace(ch)) { | 266 | if (!isSpace(ch)) { |
| 264 | this->type = tt_space; | 267 | this->type = tt_space; |
| @@ -268,7 +271,9 @@ QPDFTokenizer::presentCharacter(char ch) | @@ -268,7 +271,9 @@ QPDFTokenizer::presentCharacter(char ch) | ||
| 268 | } else { | 271 | } else { |
| 269 | this->val += ch; | 272 | this->val += ch; |
| 270 | } | 273 | } |
| 271 | - } else if (this->state == st_in_comment) { | 274 | + break; |
| 275 | + | ||
| 276 | + case st_in_comment: | ||
| 272 | if ((ch == '\r') || (ch == '\n')) { | 277 | if ((ch == '\r') || (ch == '\n')) { |
| 273 | if (this->include_ignorable) { | 278 | if (this->include_ignorable) { |
| 274 | this->type = tt_comment; | 279 | this->type = tt_comment; |
| @@ -281,7 +286,9 @@ QPDFTokenizer::presentCharacter(char ch) | @@ -281,7 +286,9 @@ QPDFTokenizer::presentCharacter(char ch) | ||
| 281 | } else if (this->include_ignorable) { | 286 | } else if (this->include_ignorable) { |
| 282 | this->val += ch; | 287 | this->val += ch; |
| 283 | } | 288 | } |
| 284 | - } else if (this->state == st_lt) { | 289 | + break; |
| 290 | + | ||
| 291 | + case st_lt: | ||
| 285 | if (ch == '<') { | 292 | if (ch == '<') { |
| 286 | this->val += "<<"; | 293 | this->val += "<<"; |
| 287 | this->type = tt_dict_open; | 294 | this->type = tt_dict_open; |
| @@ -290,7 +297,9 @@ QPDFTokenizer::presentCharacter(char ch) | @@ -290,7 +297,9 @@ QPDFTokenizer::presentCharacter(char ch) | ||
| 290 | handled = false; | 297 | handled = false; |
| 291 | this->state = st_in_hexstring; | 298 | this->state = st_in_hexstring; |
| 292 | } | 299 | } |
| 293 | - } else if (this->state == st_gt) { | 300 | + break; |
| 301 | + | ||
| 302 | + case st_gt: | ||
| 294 | if (ch == '>') { | 303 | if (ch == '>') { |
| 295 | this->val += ">>"; | 304 | this->val += ">>"; |
| 296 | this->type = tt_dict_close; | 305 | this->type = tt_dict_close; |
| @@ -304,91 +313,99 @@ QPDFTokenizer::presentCharacter(char ch) | @@ -304,91 +313,99 @@ QPDFTokenizer::presentCharacter(char ch) | ||
| 304 | this->char_to_unread = ch; | 313 | this->char_to_unread = ch; |
| 305 | this->state = st_token_ready; | 314 | this->state = st_token_ready; |
| 306 | } | 315 | } |
| 307 | - } else if (this->state == st_in_string) { | ||
| 308 | - if (this->string_ignoring_newline && (ch != '\n')) { | ||
| 309 | - this->string_ignoring_newline = false; | ||
| 310 | - } | ||
| 311 | - | ||
| 312 | - size_t bs_num_count = strlen(this->bs_num_register); | ||
| 313 | - bool ch_is_octal = ((ch >= '0') && (ch <= '7')); | ||
| 314 | - if ((bs_num_count == 3) || ((bs_num_count > 0) && (!ch_is_octal))) { | ||
| 315 | - // We've accumulated \ddd. PDF Spec says to ignore | ||
| 316 | - // high-order overflow. | ||
| 317 | - this->val += | ||
| 318 | - static_cast<char>(strtol(this->bs_num_register, nullptr, 8)); | ||
| 319 | - memset(this->bs_num_register, '\0', sizeof(this->bs_num_register)); | ||
| 320 | - bs_num_count = 0; | ||
| 321 | - } | ||
| 322 | - | ||
| 323 | - if (this->string_ignoring_newline && (ch == '\n')) { | ||
| 324 | - // ignore | ||
| 325 | - this->string_ignoring_newline = false; | ||
| 326 | - } else if ( | ||
| 327 | - ch_is_octal && (this->last_char_was_bs || (bs_num_count > 0))) { | ||
| 328 | - this->bs_num_register[bs_num_count++] = ch; | ||
| 329 | - } else if (this->last_char_was_bs) { | ||
| 330 | - switch (ch) { | ||
| 331 | - case 'n': | ||
| 332 | - this->val += '\n'; | ||
| 333 | - break; | ||
| 334 | - | ||
| 335 | - case 'r': | ||
| 336 | - this->val += '\r'; | ||
| 337 | - break; | ||
| 338 | - | ||
| 339 | - case 't': | ||
| 340 | - this->val += '\t'; | ||
| 341 | - break; | ||
| 342 | - | ||
| 343 | - case 'b': | ||
| 344 | - this->val += '\b'; | ||
| 345 | - break; | ||
| 346 | - | ||
| 347 | - case 'f': | ||
| 348 | - this->val += '\f'; | ||
| 349 | - break; | 316 | + break; |
| 350 | 317 | ||
| 351 | - case '\n': | ||
| 352 | - break; | 318 | + case st_in_string: |
| 319 | + { | ||
| 320 | + if (this->string_ignoring_newline && (ch != '\n')) { | ||
| 321 | + this->string_ignoring_newline = false; | ||
| 322 | + } | ||
| 353 | 323 | ||
| 354 | - case '\r': | ||
| 355 | - this->string_ignoring_newline = true; | ||
| 356 | - break; | 324 | + size_t bs_num_count = strlen(this->bs_num_register); |
| 325 | + bool ch_is_octal = ((ch >= '0') && (ch <= '7')); | ||
| 326 | + if ((bs_num_count == 3) || ((bs_num_count > 0) && (!ch_is_octal))) { | ||
| 327 | + // We've accumulated \ddd. PDF Spec says to ignore | ||
| 328 | + // high-order overflow. | ||
| 329 | + this->val += static_cast<char>( | ||
| 330 | + strtol(this->bs_num_register, nullptr, 8)); | ||
| 331 | + memset( | ||
| 332 | + this->bs_num_register, '\0', sizeof(this->bs_num_register)); | ||
| 333 | + bs_num_count = 0; | ||
| 334 | + } | ||
| 357 | 335 | ||
| 358 | - default: | ||
| 359 | - // PDF spec says backslash is ignored before anything else | 336 | + if (this->string_ignoring_newline && (ch == '\n')) { |
| 337 | + // ignore | ||
| 338 | + this->string_ignoring_newline = false; | ||
| 339 | + } else if ( | ||
| 340 | + ch_is_octal && (this->last_char_was_bs || (bs_num_count > 0))) { | ||
| 341 | + this->bs_num_register[bs_num_count++] = ch; | ||
| 342 | + } else if (this->last_char_was_bs) { | ||
| 343 | + switch (ch) { | ||
| 344 | + case 'n': | ||
| 345 | + this->val += '\n'; | ||
| 346 | + break; | ||
| 347 | + | ||
| 348 | + case 'r': | ||
| 349 | + this->val += '\r'; | ||
| 350 | + break; | ||
| 351 | + | ||
| 352 | + case 't': | ||
| 353 | + this->val += '\t'; | ||
| 354 | + break; | ||
| 355 | + | ||
| 356 | + case 'b': | ||
| 357 | + this->val += '\b'; | ||
| 358 | + break; | ||
| 359 | + | ||
| 360 | + case 'f': | ||
| 361 | + this->val += '\f'; | ||
| 362 | + break; | ||
| 363 | + | ||
| 364 | + case '\n': | ||
| 365 | + break; | ||
| 366 | + | ||
| 367 | + case '\r': | ||
| 368 | + this->string_ignoring_newline = true; | ||
| 369 | + break; | ||
| 370 | + | ||
| 371 | + default: | ||
| 372 | + // PDF spec says backslash is ignored before anything else | ||
| 373 | + this->val += ch; | ||
| 374 | + break; | ||
| 375 | + } | ||
| 376 | + } else if (ch == '\\') { | ||
| 377 | + // last_char_was_bs is set/cleared below as appropriate | ||
| 378 | + if (bs_num_count) { | ||
| 379 | + throw std::logic_error( | ||
| 380 | + "INTERNAL ERROR: QPDFTokenizer: bs_num_count != 0 " | ||
| 381 | + "when ch == '\\'"); | ||
| 382 | + } | ||
| 383 | + } else if (ch == '(') { | ||
| 360 | this->val += ch; | 384 | this->val += ch; |
| 361 | - break; | ||
| 362 | - } | ||
| 363 | - } else if (ch == '\\') { | ||
| 364 | - // last_char_was_bs is set/cleared below as appropriate | ||
| 365 | - if (bs_num_count) { | ||
| 366 | - throw std::logic_error( | ||
| 367 | - "INTERNAL ERROR: QPDFTokenizer: bs_num_count != 0 " | ||
| 368 | - "when ch == '\\'"); | ||
| 369 | - } | ||
| 370 | - } else if (ch == '(') { | ||
| 371 | - this->val += ch; | ||
| 372 | - ++this->string_depth; | ||
| 373 | - } else if ((ch == ')') && (--this->string_depth == 0)) { | ||
| 374 | - this->type = tt_string; | ||
| 375 | - this->state = st_token_ready; | ||
| 376 | - } else if (ch == '\r') { | ||
| 377 | - // CR by itself is converted to LF | ||
| 378 | - this->val += '\n'; | ||
| 379 | - } else if (ch == '\n') { | ||
| 380 | - // CR LF is converted to LF | ||
| 381 | - if (!this->last_char_was_cr) { | 385 | + ++this->string_depth; |
| 386 | + } else if ((ch == ')') && (--this->string_depth == 0)) { | ||
| 387 | + this->type = tt_string; | ||
| 388 | + this->state = st_token_ready; | ||
| 389 | + } else if (ch == '\r') { | ||
| 390 | + // CR by itself is converted to LF | ||
| 391 | + this->val += '\n'; | ||
| 392 | + } else if (ch == '\n') { | ||
| 393 | + // CR LF is converted to LF | ||
| 394 | + if (!this->last_char_was_cr) { | ||
| 395 | + this->val += ch; | ||
| 396 | + } | ||
| 397 | + } else { | ||
| 382 | this->val += ch; | 398 | this->val += ch; |
| 383 | } | 399 | } |
| 384 | - } else { | ||
| 385 | - this->val += ch; | 400 | + |
| 401 | + this->last_char_was_cr = | ||
| 402 | + ((!this->string_ignoring_newline) && (ch == '\r')); | ||
| 403 | + this->last_char_was_bs = | ||
| 404 | + ((!this->last_char_was_bs) && (ch == '\\')); | ||
| 386 | } | 405 | } |
| 406 | + break; | ||
| 387 | 407 | ||
| 388 | - this->last_char_was_cr = | ||
| 389 | - ((!this->string_ignoring_newline) && (ch == '\r')); | ||
| 390 | - this->last_char_was_bs = ((!this->last_char_was_bs) && (ch == '\\')); | ||
| 391 | - } else if (this->state == st_literal) { | 408 | + case st_literal: |
| 392 | if (isDelimiter(ch)) { | 409 | if (isDelimiter(ch)) { |
| 393 | // A C-locale whitespace character or delimiter terminates | 410 | // A C-locale whitespace character or delimiter terminates |
| 394 | // token. It is important to unread the whitespace | 411 | // token. It is important to unread the whitespace |
| @@ -405,16 +422,19 @@ QPDFTokenizer::presentCharacter(char ch) | @@ -405,16 +422,19 @@ QPDFTokenizer::presentCharacter(char ch) | ||
| 405 | } else { | 422 | } else { |
| 406 | this->val += ch; | 423 | this->val += ch; |
| 407 | } | 424 | } |
| 408 | - } else if (this->state == st_inline_image) { | 425 | + break; |
| 426 | + | ||
| 427 | + case st_inline_image: | ||
| 409 | this->val += ch; | 428 | this->val += ch; |
| 410 | - size_t len = this->val.length(); | ||
| 411 | - if (len == this->inline_image_bytes) { | 429 | + if (this->val.length() == this->inline_image_bytes) { |
| 412 | QTC::TC("qpdf", "QPDFTokenizer found EI by byte count"); | 430 | QTC::TC("qpdf", "QPDFTokenizer found EI by byte count"); |
| 413 | this->type = tt_inline_image; | 431 | this->type = tt_inline_image; |
| 414 | this->inline_image_bytes = 0; | 432 | this->inline_image_bytes = 0; |
| 415 | this->state = st_token_ready; | 433 | this->state = st_token_ready; |
| 416 | } | 434 | } |
| 417 | - } else { | 435 | + break; |
| 436 | + | ||
| 437 | + default: | ||
| 418 | handled = false; | 438 | handled = false; |
| 419 | } | 439 | } |
| 420 | 440 |