Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Side by Side Diff: Source/core/html/track/vtt/VTTParser.cpp

Issue 119143002: Introduce VTTScanner - a parser helper for various VTT parsing needs (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: struct Run -> class Run; explicit constructor; make non-copyable. Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/html/track/vtt/VTTParser.h ('k') | Source/core/html/track/vtt/VTTScanner.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 17 matching lines...) Expand all
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 #include "core/html/track/vtt/VTTParser.h" 32 #include "core/html/track/vtt/VTTParser.h"
33 33
34 #include "core/dom/Document.h" 34 #include "core/dom/Document.h"
35 #include "core/dom/ProcessingInstruction.h" 35 #include "core/dom/ProcessingInstruction.h"
36 #include "core/dom/Text.h" 36 #include "core/dom/Text.h"
37 #include "core/html/track/vtt/VTTElement.h" 37 #include "core/html/track/vtt/VTTElement.h"
38 #include "core/html/track/vtt/VTTScanner.h"
38 #include "platform/text/SegmentedString.h" 39 #include "platform/text/SegmentedString.h"
39 #include "wtf/text/WTFString.h" 40 #include "wtf/text/WTFString.h"
40 41
41 namespace WebCore { 42 namespace WebCore {
42 43
43 const double secondsPerHour = 3600; 44 const double secondsPerHour = 3600;
44 const double secondsPerMinute = 60; 45 const double secondsPerMinute = 60;
45 const double secondsPerMillisecond = 0.001; 46 const double secondsPerMillisecond = 0.001;
46 const unsigned fileIdentifierLength = 6; 47 const unsigned fileIdentifierLength = 6;
47 48
48 static unsigned scanDigits(const String& input, unsigned* position) 49 static unsigned scanDigits(const String& input, unsigned* position)
49 { 50 {
50 unsigned startPosition = *position; 51 unsigned startPosition = *position;
51 while (*position < input.length() && isASCIIDigit(input[*position])) 52 while (*position < input.length() && isASCIIDigit(input[*position]))
52 (*position)++; 53 (*position)++;
53 return *position - startPosition; 54 return *position - startPosition;
54 } 55 }
55 56
56 unsigned VTTParser::collectDigitsToInt(const String& input, unsigned* position, int& number) 57 unsigned VTTParser::collectDigitsToInt(const String& input, unsigned* position, int& number)
57 { 58 {
58 unsigned startPosition = *position; 59 VTTLegacyScanner inputScanner(input, position);
59 unsigned numDigits = scanDigits(input, position); 60 return inputScanner.scanDigits(number);
60 if (!numDigits) {
61 number = 0;
62 return 0;
63 }
64 bool validNumber;
65 if (input.is8Bit())
66 number = charactersToInt(input.characters8() + startPosition, numDigits, &validNumber);
67 else
68 number = charactersToInt(input.characters16() + startPosition, numDigits , &validNumber);
69
70 // Since we know that scanDigits only scanned valid (ASCII) digits (and
71 // hence that's what got passed to charactersToInt()), the remaining
72 // failure mode for charactersToInt() is overflow, so if |validNumber| is
73 // not true, then set |number| to the maximum int value.
74 if (!validNumber)
75 number = std::numeric_limits<int>::max();
76 return numDigits;
77 } 61 }
78 62
79 String VTTParser::collectWord(const String& input, unsigned* position) 63 String VTTParser::collectWord(const String& input, unsigned* position)
80 { 64 {
81 StringBuilder string; 65 StringBuilder string;
82 while (*position < input.length() && !isASpace(input[*position])) 66 while (*position < input.length() && !isASpace(input[*position]))
83 string.append(input[(*position)++]); 67 string.append(input[(*position)++]);
84 return string.toString(); 68 return string.toString();
85 } 69 }
86 70
87 void VTTParser::skipWhiteSpace(const String& line, unsigned* position)
88 {
89 while (*position < line.length() && isASpace(line[*position]))
90 (*position)++;
91 }
92
93 bool VTTParser::parseFloatPercentageValue(const String& value, float& percentage ) 71 bool VTTParser::parseFloatPercentageValue(const String& value, float& percentage )
94 { 72 {
95 // '%' must be present and at the end of the setting value. 73 // '%' must be present and at the end of the setting value.
96 if (value.isEmpty() || value[value.length() - 1] != '%') 74 if (value.isEmpty() || value[value.length() - 1] != '%')
97 return false; 75 return false;
98 76
99 unsigned position = 0; 77 unsigned position = 0;
100 unsigned digitsBeforeDot = scanDigits(value, &position); 78 unsigned digitsBeforeDot = scanDigits(value, &position);
101 unsigned digitsAfterDot = 0; 79 unsigned digitsAfterDot = 0;
102 if (value[position] == '.') { 80 if (value[position] == '.') {
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 VTTParser::ParseState VTTParser::collectCueId(const String& line) 278 VTTParser::ParseState VTTParser::collectCueId(const String& line)
301 { 279 {
302 if (line.contains("-->")) 280 if (line.contains("-->"))
303 return collectTimingsAndSettings(line); 281 return collectTimingsAndSettings(line);
304 m_currentId = line; 282 m_currentId = line;
305 return TimingsAndSettings; 283 return TimingsAndSettings;
306 } 284 }
307 285
308 VTTParser::ParseState VTTParser::collectTimingsAndSettings(const String& line) 286 VTTParser::ParseState VTTParser::collectTimingsAndSettings(const String& line)
309 { 287 {
288 VTTScanner input(line);
289
310 // Collect WebVTT cue timings and settings. (5.3 WebVTT cue timings and sett ings parsing.) 290 // Collect WebVTT cue timings and settings. (5.3 WebVTT cue timings and sett ings parsing.)
311 // Steps 1 - 3 - Let input be the string being parsed and position be a poin ter into input. 291 // Steps 1 - 3 - Let input be the string being parsed and position be a poin ter into input.
312 unsigned position = 0; 292 input.skipWhile<isASpace>();
313 skipWhiteSpace(line, &position);
314 293
315 // Steps 4 - 5 - Collect a WebVTT timestamp. If that fails, then abort and r eturn failure. Otherwise, let cue's text track cue start time be the collected t ime. 294 // Steps 4 - 5 - Collect a WebVTT timestamp. If that fails, then abort and r eturn failure. Otherwise, let cue's text track cue start time be the collected t ime.
316 if (!collectTimeStamp(line, &position, m_currentStartTime)) 295 if (!collectTimeStamp(input, m_currentStartTime))
317 return BadCue; 296 return BadCue;
318 if (position >= line.length()) 297 input.skipWhile<isASpace>();
319 return BadCue;
320
321 skipWhiteSpace(line, &position);
322 298
323 // Steps 6 - 9 - If the next three characters are not "-->", abort and retur n failure. 299 // Steps 6 - 9 - If the next three characters are not "-->", abort and retur n failure.
324 if (line.find("-->", position) == kNotFound) 300 if (!input.scan("-->"))
325 return BadCue; 301 return BadCue;
326 position += 3; 302 input.skipWhile<isASpace>();
327 if (position >= line.length())
328 return BadCue;
329
330 skipWhiteSpace(line, &position);
331 303
332 // Steps 10 - 11 - Collect a WebVTT timestamp. If that fails, then abort and return failure. Otherwise, let cue's text track cue end time be the collected t ime. 304 // Steps 10 - 11 - Collect a WebVTT timestamp. If that fails, then abort and return failure. Otherwise, let cue's text track cue end time be the collected t ime.
333 if (!collectTimeStamp(line, &position, m_currentEndTime)) 305 if (!collectTimeStamp(input, m_currentEndTime))
334 return BadCue; 306 return BadCue;
335 skipWhiteSpace(line, &position); 307 input.skipWhile<isASpace>();
336 308
337 // Step 12 - Parse the WebVTT settings for the cue (conducted in TextTrackCu e). 309 // Step 12 - Parse the WebVTT settings for the cue (conducted in TextTrackCu e).
338 m_currentSettings = line.substring(position, line.length()-1); 310 m_currentSettings = input.restOfInputAsString();
339 return CueText; 311 return CueText;
340 } 312 }
341 313
342 VTTParser::ParseState VTTParser::collectCueText(const String& line) 314 VTTParser::ParseState VTTParser::collectCueText(const String& line)
343 { 315 {
344 // Step 34. 316 // Step 34.
345 if (line.isEmpty()) { 317 if (line.isEmpty()) {
346 createNewCue(); 318 createNewCue();
347 return Id; 319 return Id;
348 } 320 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 break; 435 break;
464 } 436 }
465 } 437 }
466 438
467 // Step 12.5.11 439 // Step 12.5.11
468 m_regionList.append(region); 440 m_regionList.append(region);
469 } 441 }
470 442
471 bool VTTParser::collectTimeStamp(const String& line, unsigned* position, double& timeStamp) 443 bool VTTParser::collectTimeStamp(const String& line, unsigned* position, double& timeStamp)
472 { 444 {
445 VTTLegacyScanner input(line, position);
446 return collectTimeStamp(input, timeStamp);
447 }
448
449 bool VTTParser::collectTimeStamp(VTTScanner& input, double& timeStamp)
450 {
473 // Collect a WebVTT timestamp (5.3 WebVTT cue timings and settings parsing.) 451 // Collect a WebVTT timestamp (5.3 WebVTT cue timings and settings parsing.)
474 // Steps 1 - 4 - Initial checks, let most significant units be minutes. 452 // Steps 1 - 4 - Initial checks, let most significant units be minutes.
475 enum Mode { Minutes, Hours }; 453 enum Mode { Minutes, Hours };
476 Mode mode = Minutes; 454 Mode mode = Minutes;
477 455
478 // Steps 5 - 7 - Collect a sequence of characters that are 0-9. 456 // Steps 5 - 7 - Collect a sequence of characters that are 0-9.
479 // If not 2 characters or value is greater than 59, interpret as hours. 457 // If not 2 characters or value is greater than 59, interpret as hours.
480 int value1; 458 int value1;
481 unsigned value1Digits = collectDigitsToInt(line, position, value1); 459 unsigned value1Digits = input.scanDigits(value1);
482 if (!value1Digits) 460 if (!value1Digits)
483 return false; 461 return false;
484 if (value1Digits != 2 || value1 > 59) 462 if (value1Digits != 2 || value1 > 59)
485 mode = Hours; 463 mode = Hours;
486 464
487 // Steps 8 - 11 - Collect the next sequence of 0-9 after ':' (must be 2 char s). 465 // Steps 8 - 11 - Collect the next sequence of 0-9 after ':' (must be 2 char s).
488 if (*position >= line.length() || line[(*position)++] != ':')
489 return false;
490 int value2; 466 int value2;
491 if (collectDigitsToInt(line, position, value2) != 2) 467 if (!input.scan(':') || input.scanDigits(value2) != 2)
492 return false; 468 return false;
493 469
494 // Step 12 - Detect whether this timestamp includes hours. 470 // Step 12 - Detect whether this timestamp includes hours.
495 int value3; 471 int value3;
496 if (mode == Hours || (*position < line.length() && line[*position] == ':')) { 472 if (mode == Hours || input.match(':')) {
497 if (*position >= line.length() || line[(*position)++] != ':') 473 if (!input.scan(':') || input.scanDigits(value3) != 2)
498 return false;
499 if (collectDigitsToInt(line, position, value3) != 2)
500 return false; 474 return false;
501 } else { 475 } else {
502 value3 = value2; 476 value3 = value2;
503 value2 = value1; 477 value2 = value1;
504 value1 = 0; 478 value1 = 0;
505 } 479 }
506 480
507 // Steps 13 - 17 - Collect next sequence of 0-9 after '.' (must be 3 chars). 481 // Steps 13 - 17 - Collect next sequence of 0-9 after '.' (must be 3 chars).
508 if (*position >= line.length() || line[(*position)++] != '.')
509 return false;
510 int value4; 482 int value4;
511 if (collectDigitsToInt(line, position, value4) != 3) 483 if (!input.scan('.') || input.scanDigits(value4) != 3)
512 return false; 484 return false;
513 if (value2 > 59 || value3 > 59) 485 if (value2 > 59 || value3 > 59)
514 return false; 486 return false;
515 487
516 // Steps 18 - 19 - Calculate result. 488 // Steps 18 - 19 - Calculate result.
517 timeStamp = (value1 * secondsPerHour) + (value2 * secondsPerMinute) + value3 + (value4 * secondsPerMillisecond); 489 timeStamp = (value1 * secondsPerHour) + (value2 * secondsPerMinute) + value3 + (value4 * secondsPerMillisecond);
518 return true; 490 return true;
519 } 491 }
520 492
521 static VTTNodeType tokenToNodeType(VTTToken& token) 493 static VTTNodeType tokenToNodeType(VTTToken& token)
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 m_currentNode->parserAppendChild(ProcessingInstruction::create(docum ent, "timestamp", charactersString)); 590 m_currentNode->parserAppendChild(ProcessingInstruction::create(docum ent, "timestamp", charactersString));
619 break; 591 break;
620 } 592 }
621 default: 593 default:
622 break; 594 break;
623 } 595 }
624 } 596 }
625 597
626 } 598 }
627 599
OLDNEW
« no previous file with comments | « Source/core/html/track/vtt/VTTParser.h ('k') | Source/core/html/track/vtt/VTTScanner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698