Commit 91fb61eda5ae66736ae9e5975ae6f2e0867366e6

Authored by m-holger
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