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 | 198 | void |
| 199 | 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 | 201 | char orig_ch = ch; |
| 208 | 202 | |
| 209 | 203 | // State machine is implemented such that some characters may be |
| ... | ... | @@ -211,7 +205,14 @@ QPDFTokenizer::presentCharacter(char ch) |
| 211 | 205 | // the character that caused a state change in the new state. |
| 212 | 206 | |
| 213 | 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 | 216 | // Note: we specifically do not use ctype here. It is |
| 216 | 217 | // locale-dependent. |
| 217 | 218 | if (isSpace(ch)) { |
| ... | ... | @@ -258,7 +259,9 @@ QPDFTokenizer::presentCharacter(char ch) |
| 258 | 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 | 265 | // We only enter this state if include_ignorable is true. |
| 263 | 266 | if (!isSpace(ch)) { |
| 264 | 267 | this->type = tt_space; |
| ... | ... | @@ -268,7 +271,9 @@ QPDFTokenizer::presentCharacter(char ch) |
| 268 | 271 | } else { |
| 269 | 272 | this->val += ch; |
| 270 | 273 | } |
| 271 | - } else if (this->state == st_in_comment) { | |
| 274 | + break; | |
| 275 | + | |
| 276 | + case st_in_comment: | |
| 272 | 277 | if ((ch == '\r') || (ch == '\n')) { |
| 273 | 278 | if (this->include_ignorable) { |
| 274 | 279 | this->type = tt_comment; |
| ... | ... | @@ -281,7 +286,9 @@ QPDFTokenizer::presentCharacter(char ch) |
| 281 | 286 | } else if (this->include_ignorable) { |
| 282 | 287 | this->val += ch; |
| 283 | 288 | } |
| 284 | - } else if (this->state == st_lt) { | |
| 289 | + break; | |
| 290 | + | |
| 291 | + case st_lt: | |
| 285 | 292 | if (ch == '<') { |
| 286 | 293 | this->val += "<<"; |
| 287 | 294 | this->type = tt_dict_open; |
| ... | ... | @@ -290,7 +297,9 @@ QPDFTokenizer::presentCharacter(char ch) |
| 290 | 297 | handled = false; |
| 291 | 298 | this->state = st_in_hexstring; |
| 292 | 299 | } |
| 293 | - } else if (this->state == st_gt) { | |
| 300 | + break; | |
| 301 | + | |
| 302 | + case st_gt: | |
| 294 | 303 | if (ch == '>') { |
| 295 | 304 | this->val += ">>"; |
| 296 | 305 | this->type = tt_dict_close; |
| ... | ... | @@ -304,91 +313,99 @@ QPDFTokenizer::presentCharacter(char ch) |
| 304 | 313 | this->char_to_unread = ch; |
| 305 | 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 | 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 | 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 | 409 | if (isDelimiter(ch)) { |
| 393 | 410 | // A C-locale whitespace character or delimiter terminates |
| 394 | 411 | // token. It is important to unread the whitespace |
| ... | ... | @@ -405,16 +422,19 @@ QPDFTokenizer::presentCharacter(char ch) |
| 405 | 422 | } else { |
| 406 | 423 | this->val += ch; |
| 407 | 424 | } |
| 408 | - } else if (this->state == st_inline_image) { | |
| 425 | + break; | |
| 426 | + | |
| 427 | + case st_inline_image: | |
| 409 | 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 | 430 | QTC::TC("qpdf", "QPDFTokenizer found EI by byte count"); |
| 413 | 431 | this->type = tt_inline_image; |
| 414 | 432 | this->inline_image_bytes = 0; |
| 415 | 433 | this->state = st_token_ready; |
| 416 | 434 | } |
| 417 | - } else { | |
| 435 | + break; | |
| 436 | + | |
| 437 | + default: | |
| 418 | 438 | handled = false; |
| 419 | 439 | } |
| 420 | 440 | ... | ... |