OLD | NEW |
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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 } | 55 } |
56 | 56 |
57 String WebVTTParser::collectWord(const String& input, unsigned* position) | 57 String WebVTTParser::collectWord(const String& input, unsigned* position) |
58 { | 58 { |
59 StringBuilder string; | 59 StringBuilder string; |
60 while (*position < input.length() && !isASpace(input[*position])) | 60 while (*position < input.length() && !isASpace(input[*position])) |
61 string.append(input[(*position)++]); | 61 string.append(input[(*position)++]); |
62 return string.toString(); | 62 return string.toString(); |
63 } | 63 } |
64 | 64 |
65 #if ENABLE(WEBVTT_REGIONS) | |
66 float WebVTTParser::parseFloatPercentageValue(const String& value, bool& isValid
Setting) | 65 float WebVTTParser::parseFloatPercentageValue(const String& value, bool& isValid
Setting) |
67 { | 66 { |
68 // '%' must be present and at the end of the setting value. | 67 // '%' must be present and at the end of the setting value. |
69 if (value.find('%', 1) != value.length() - 1) { | 68 if (value.find('%', 1) != value.length() - 1) { |
70 isValidSetting = false; | 69 isValidSetting = false; |
71 return 0; | 70 return 0; |
72 } | 71 } |
73 | 72 |
74 unsigned position = 0; | 73 unsigned position = 0; |
75 | 74 |
(...skipping 27 matching lines...) Expand all Loading... |
103 | 102 |
104 bool isFirstValueValid; | 103 bool isFirstValueValid; |
105 float firstCoord = parseFloatPercentageValue(value.substring(0, delimiterOff
set), isFirstValueValid); | 104 float firstCoord = parseFloatPercentageValue(value.substring(0, delimiterOff
set), isFirstValueValid); |
106 | 105 |
107 bool isSecondValueValid; | 106 bool isSecondValueValid; |
108 float secondCoord = parseFloatPercentageValue(value.substring(delimiterOffse
t + 1, value.length() - 1), isSecondValueValid); | 107 float secondCoord = parseFloatPercentageValue(value.substring(delimiterOffse
t + 1, value.length() - 1), isSecondValueValid); |
109 | 108 |
110 isValidSetting = isFirstValueValid && isSecondValueValid; | 109 isValidSetting = isFirstValueValid && isSecondValueValid; |
111 return FloatPoint(firstCoord, secondCoord); | 110 return FloatPoint(firstCoord, secondCoord); |
112 } | 111 } |
113 #endif | |
114 | 112 |
115 WebVTTParser::WebVTTParser(WebVTTParserClient* client, ExecutionContext* context
) | 113 WebVTTParser::WebVTTParser(WebVTTParserClient* client, ExecutionContext* context
) |
116 : m_executionContext(context) | 114 : m_executionContext(context) |
117 , m_state(Initial) | 115 , m_state(Initial) |
118 , m_currentStartTime(0) | 116 , m_currentStartTime(0) |
119 , m_currentEndTime(0) | 117 , m_currentEndTime(0) |
120 , m_tokenizer(WebVTTTokenizer::create()) | 118 , m_tokenizer(WebVTTTokenizer::create()) |
121 , m_client(client) | 119 , m_client(client) |
122 { | 120 { |
123 } | 121 } |
124 | 122 |
125 void WebVTTParser::getNewCues(Vector<RefPtr<TextTrackCue> >& outputCues) | 123 void WebVTTParser::getNewCues(Vector<RefPtr<TextTrackCue> >& outputCues) |
126 { | 124 { |
127 outputCues = m_cuelist; | 125 outputCues = m_cuelist; |
128 m_cuelist.clear(); | 126 m_cuelist.clear(); |
129 } | 127 } |
130 | 128 |
131 #if ENABLE(WEBVTT_REGIONS) | |
132 void WebVTTParser::getNewRegions(Vector<RefPtr<TextTrackRegion> >& outputRegions
) | 129 void WebVTTParser::getNewRegions(Vector<RefPtr<TextTrackRegion> >& outputRegions
) |
133 { | 130 { |
134 outputRegions = m_regionList; | 131 outputRegions = m_regionList; |
135 m_regionList.clear(); | 132 m_regionList.clear(); |
136 } | 133 } |
137 #endif | |
138 | 134 |
139 void WebVTTParser::parseBytes(const char* data, unsigned length) | 135 void WebVTTParser::parseBytes(const char* data, unsigned length) |
140 { | 136 { |
141 // 4.8.10.13.3 WHATWG WebVTT Parser algorithm. | 137 // 4.8.10.13.3 WHATWG WebVTT Parser algorithm. |
142 // 1-3 - Initial setup. | 138 // 1-3 - Initial setup. |
143 unsigned position = 0; | 139 unsigned position = 0; |
144 | 140 |
145 while (position < length) { | 141 while (position < length) { |
146 String line = collectNextLine(data, length, &position); | 142 String line = collectNextLine(data, length, &position); |
147 | 143 |
148 switch (m_state) { | 144 switch (m_state) { |
149 case Initial: | 145 case Initial: |
150 // Buffer up at least 9 bytes before proceeding with checking for th
e file identifier. | 146 // Buffer up at least 9 bytes before proceeding with checking for th
e file identifier. |
151 m_identifierData.append(data, length); | 147 m_identifierData.append(data, length); |
152 if (m_identifierData.size() < bomLength + fileIdentifierLength) | 148 if (m_identifierData.size() < bomLength + fileIdentifierLength) |
153 return; | 149 return; |
154 | 150 |
155 // 4-12 - Collect the first line and check for "WEBVTT". | 151 // 4-12 - Collect the first line and check for "WEBVTT". |
156 if (!hasRequiredFileIdentifier()) { | 152 if (!hasRequiredFileIdentifier()) { |
157 if (m_client) | 153 if (m_client) |
158 m_client->fileFailedToParse(); | 154 m_client->fileFailedToParse(); |
159 return; | 155 return; |
160 } | 156 } |
161 | 157 |
162 m_state = Header; | 158 m_state = Header; |
163 m_identifierData.clear(); | 159 m_identifierData.clear(); |
164 break; | 160 break; |
165 | 161 |
166 case Header: | 162 case Header: |
| 163 collectMetadataHeader(line); |
| 164 |
167 // 13-18 - Allow a header (comment area) under the WEBVTT line. | 165 // 13-18 - Allow a header (comment area) under the WEBVTT line. |
168 #if ENABLE(WEBVTT_REGIONS) | |
169 if (line.isEmpty()) { | 166 if (line.isEmpty()) { |
170 if (m_client && m_regionList.size()) | 167 if (m_client && m_regionList.size()) |
171 m_client->newRegionsParsed(); | 168 m_client->newRegionsParsed(); |
172 | 169 |
173 m_state = Id; | 170 m_state = Id; |
174 break; | 171 break; |
175 } | 172 } |
176 collectHeader(line); | |
177 | 173 |
178 break; | 174 break; |
179 | 175 |
180 case Metadata: | |
181 #endif | |
182 if (line.isEmpty()) | |
183 m_state = Id; | |
184 break; | |
185 | |
186 case Id: | 176 case Id: |
187 // 19-29 - Allow any number of line terminators, then initialize new
cue values. | 177 // 19-29 - Allow any number of line terminators, then initialize new
cue values. |
188 if (line.isEmpty()) | 178 if (line.isEmpty()) |
189 break; | 179 break; |
190 resetCueValues(); | 180 resetCueValues(); |
191 | 181 |
192 // 30-39 - Check if this line contains an optional identifier or tim
ing data. | 182 // 30-39 - Check if this line contains an optional identifier or tim
ing data. |
193 m_state = collectCueId(line); | 183 m_state = collectCueId(line); |
194 break; | 184 break; |
195 | 185 |
(...skipping 28 matching lines...) Expand all Loading... |
224 if (line.length() < fileIdentifierLength) | 214 if (line.length() < fileIdentifierLength) |
225 return false; | 215 return false; |
226 if (line.substring(0, fileIdentifierLength) != "WEBVTT") | 216 if (line.substring(0, fileIdentifierLength) != "WEBVTT") |
227 return false; | 217 return false; |
228 if (line.length() > fileIdentifierLength && line[fileIdentifierLength] != '
' && line[fileIdentifierLength] != '\t') | 218 if (line.length() > fileIdentifierLength && line[fileIdentifierLength] != '
' && line[fileIdentifierLength] != '\t') |
229 return false; | 219 return false; |
230 | 220 |
231 return true; | 221 return true; |
232 } | 222 } |
233 | 223 |
234 #if ENABLE(WEBVTT_REGIONS) | 224 void WebVTTParser::collectMetadataHeader(const String& line) |
235 void WebVTTParser::collectHeader(const String& line) | |
236 { | 225 { |
237 // 4.1 Extension of WebVTT header parsing (11 - 15) | 226 // 4.1 Extension of WebVTT header parsing (11 - 15) |
238 DEFINE_STATIC_LOCAL(const AtomicString, regionHeaderName, ("Region", AtomicS
tring::ConstructFromLiteral)); | 227 DEFINE_STATIC_LOCAL(const AtomicString, regionHeaderName, ("Region", AtomicS
tring::ConstructFromLiteral)); |
239 | 228 |
240 // 15.4 If line contains the character ":" (A U+003A COLON), then set metada
ta's | 229 // 15.4 If line contains the character ":" (A U+003A COLON), then set metada
ta's |
241 // name to the substring of line before the first ":" character and | 230 // name to the substring of line before the first ":" character and |
242 // metadata's value to the substring after this character. | 231 // metadata's value to the substring after this character. |
243 if (!line.contains(":")) | 232 if (!RuntimeEnabledFeatures::webVTTRegionsEnabled() || !line.contains(":")) |
244 return; | 233 return; |
245 | 234 |
246 unsigned colonPosition = line.find(":"); | 235 unsigned colonPosition = line.find(":"); |
247 m_currentHeaderName = line.substring(0, colonPosition); | 236 m_currentHeaderName = line.substring(0, colonPosition); |
248 | 237 |
249 // 15.5 If metadata's name equals "Region": | 238 // 15.5 If metadata's name equals "Region": |
250 if (m_currentHeaderName == regionHeaderName) { | 239 if (m_currentHeaderName == regionHeaderName) { |
251 m_currentHeaderValue = line.substring(colonPosition + 1, line.length() -
1); | 240 m_currentHeaderValue = line.substring(colonPosition + 1, line.length() -
1); |
252 // 15.5.1 - 15.5.8 Region creation: Let region be a new text track regio
n [...] | 241 // 15.5.1 - 15.5.8 Region creation: Let region be a new text track regio
n [...] |
253 createNewRegion(); | 242 createNewRegion(); |
254 } | 243 } |
255 } | 244 } |
256 #endif | |
257 | 245 |
258 WebVTTParser::ParseState WebVTTParser::collectCueId(const String& line) | 246 WebVTTParser::ParseState WebVTTParser::collectCueId(const String& line) |
259 { | 247 { |
260 if (line.contains("-->")) | 248 if (line.contains("-->")) |
261 return collectTimingsAndSettings(line); | 249 return collectTimingsAndSettings(line); |
262 m_currentId = line; | 250 m_currentId = line; |
263 return TimingsAndSettings; | 251 return TimingsAndSettings; |
264 } | 252 } |
265 | 253 |
266 WebVTTParser::ParseState WebVTTParser::collectTimingsAndSettings(const String& l
ine) | 254 WebVTTParser::ParseState WebVTTParser::collectTimingsAndSettings(const String& l
ine) |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 | 355 |
368 void WebVTTParser::resetCueValues() | 356 void WebVTTParser::resetCueValues() |
369 { | 357 { |
370 m_currentId = emptyString(); | 358 m_currentId = emptyString(); |
371 m_currentSettings = emptyString(); | 359 m_currentSettings = emptyString(); |
372 m_currentStartTime = 0; | 360 m_currentStartTime = 0; |
373 m_currentEndTime = 0; | 361 m_currentEndTime = 0; |
374 m_currentContent.clear(); | 362 m_currentContent.clear(); |
375 } | 363 } |
376 | 364 |
377 #if ENABLE(WEBVTT_REGIONS) | |
378 void WebVTTParser::createNewRegion() | 365 void WebVTTParser::createNewRegion() |
379 { | 366 { |
380 if (!m_currentHeaderValue.length()) | 367 if (!m_currentHeaderValue.length()) |
381 return; | 368 return; |
382 | 369 |
383 RefPtr<TextTrackRegion> region = TextTrackRegion::create(m_executionContext)
; | 370 RefPtr<TextTrackRegion> region = TextTrackRegion::create(m_executionContext)
; |
384 region->setRegionSettings(m_currentHeaderValue); | 371 region->setRegionSettings(m_currentHeaderValue); |
385 | 372 |
386 // 15.5.10 If the text track list of regions regions contains a region | 373 // 15.5.10 If the text track list of regions regions contains a region |
387 // with the same region identifier value as region, remove that region. | 374 // with the same region identifier value as region, remove that region. |
388 for (size_t i = 0; i < m_regionList.size(); ++i) | 375 for (size_t i = 0; i < m_regionList.size(); ++i) |
389 if (m_regionList[i]->id() == region->id()) { | 376 if (m_regionList[i]->id() == region->id()) { |
390 m_regionList.remove(i); | 377 m_regionList.remove(i); |
391 break; | 378 break; |
392 } | 379 } |
393 | 380 |
394 m_regionList.append(region); | 381 m_regionList.append(region); |
395 } | 382 } |
396 #endif | |
397 | 383 |
398 double WebVTTParser::collectTimeStamp(const String& line, unsigned* position) | 384 double WebVTTParser::collectTimeStamp(const String& line, unsigned* position) |
399 { | 385 { |
400 // 4.8.10.13.3 Collect a WebVTT timestamp. | 386 // 4.8.10.13.3 Collect a WebVTT timestamp. |
401 // 1-4 - Initial checks, let most significant units be minutes. | 387 // 1-4 - Initial checks, let most significant units be minutes. |
402 enum Mode { minutes, hours }; | 388 enum Mode { minutes, hours }; |
403 Mode mode = minutes; | 389 Mode mode = minutes; |
404 if (*position >= line.length() || !isASCIIDigit(line[*position])) | 390 if (*position >= line.length() || !isASCIIDigit(line[*position])) |
405 return malformedTime; | 391 return malformedTime; |
406 | 392 |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 unsigned oldPosition = *position; | 552 unsigned oldPosition = *position; |
567 while (*position < length && data[*position] != '\r' && data[*position] != '
\n') | 553 while (*position < length && data[*position] != '\r' && data[*position] != '
\n') |
568 (*position)++; | 554 (*position)++; |
569 String line = String::fromUTF8(data + oldPosition, *position - oldPosition); | 555 String line = String::fromUTF8(data + oldPosition, *position - oldPosition); |
570 skipLineTerminator(data, length, position); | 556 skipLineTerminator(data, length, position); |
571 return line; | 557 return line; |
572 } | 558 } |
573 | 559 |
574 } | 560 } |
575 | 561 |
OLD | NEW |