| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2011, 2012 Apple 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 | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 if (!m_url.hasFragmentIdentifier()) | 89 if (!m_url.hasFragmentIdentifier()) |
| 90 return; | 90 return; |
| 91 String fragmentString = m_url.fragmentIdentifier(); | 91 String fragmentString = m_url.fragmentIdentifier(); |
| 92 if (fragmentString.isEmpty()) | 92 if (fragmentString.isEmpty()) |
| 93 return; | 93 return; |
| 94 | 94 |
| 95 unsigned offset = 0; | 95 unsigned offset = 0; |
| 96 unsigned end = fragmentString.length(); | 96 unsigned end = fragmentString.length(); |
| 97 while (offset < end) { | 97 while (offset < end) { |
| 98 // http://www.w3.org/2008/WebVideo/Fragments/WD-media-fragments-spec/#proces
sing-name-value-components | 98 // http://www.w3.org/2008/WebVideo/Fragments/WD-media-fragments-spec/#proces
sing-name-value-components |
| 99 // 1. Parse the octet string according to the namevalues syntax, yielding a
list of | 99 // 1. Parse the octet string according to the namevalues syntax, yielding a |
| 100 // name-value pairs, where name and value are both octet string. In accor
dance | 100 // list of name-value pairs, where name and value are both octet string. |
| 101 // with RFC 3986, the name and value components must be parsed and separa
ted before | 101 // In accordance with RFC 3986, the name and value components must be |
| 102 // percent-encoded octets are decoded. | 102 // parsed and separated before percent-encoded octets are decoded. |
| 103 size_t parameterStart = offset; | 103 size_t parameterStart = offset; |
| 104 size_t parameterEnd = fragmentString.find('&', offset); | 104 size_t parameterEnd = fragmentString.find('&', offset); |
| 105 if (parameterEnd == kNotFound) | 105 if (parameterEnd == kNotFound) |
| 106 parameterEnd = end; | 106 parameterEnd = end; |
| 107 | 107 |
| 108 size_t equalOffset = fragmentString.find('=', offset); | 108 size_t equalOffset = fragmentString.find('=', offset); |
| 109 if (equalOffset == kNotFound || equalOffset > parameterEnd) { | 109 if (equalOffset == kNotFound || equalOffset > parameterEnd) { |
| 110 offset = parameterEnd + 1; | 110 offset = parameterEnd + 1; |
| 111 continue; | 111 continue; |
| 112 } | 112 } |
| 113 | 113 |
| 114 // 2. For each name-value pair: | 114 // 2. For each name-value pair: |
| 115 // a. Decode percent-encoded octets in name and value as defined by RFC 398
6. If either | 115 // a. Decode percent-encoded octets in name and value as defined by RFC |
| 116 // name or value are not valid percent-encoded strings, then remove the
name-value pair | 116 // 3986. If either name or value are not valid percent-encoded strings, |
| 117 // from the list. | 117 // then remove the name-value pair from the list. |
| 118 String name = decodeURLEscapeSequences( | 118 String name = decodeURLEscapeSequences( |
| 119 fragmentString.substring(parameterStart, equalOffset - parameterStart)); | 119 fragmentString.substring(parameterStart, equalOffset - parameterStart)); |
| 120 String value; | 120 String value; |
| 121 if (equalOffset != parameterEnd) | 121 if (equalOffset != parameterEnd) |
| 122 value = decodeURLEscapeSequences(fragmentString.substring( | 122 value = decodeURLEscapeSequences(fragmentString.substring( |
| 123 equalOffset + 1, parameterEnd - equalOffset - 1)); | 123 equalOffset + 1, parameterEnd - equalOffset - 1)); |
| 124 | 124 |
| 125 // b. Convert name and value to Unicode strings by interpreting them as UTF
-8. If either | 125 // b. Convert name and value to Unicode strings by interpreting them as |
| 126 // name or value are not valid UTF-8 strings, then remove the name-value
pair from the list. | 126 // UTF-8. If either name or value are not valid UTF-8 strings, then |
| 127 // remove the name-value pair from the list. |
| 127 bool validUTF8 = true; | 128 bool validUTF8 = true; |
| 128 if (!name.isEmpty()) { | 129 if (!name.isEmpty()) { |
| 129 name = name.utf8(StrictUTF8Conversion).data(); | 130 name = name.utf8(StrictUTF8Conversion).data(); |
| 130 validUTF8 = !name.isEmpty(); | 131 validUTF8 = !name.isEmpty(); |
| 131 } | 132 } |
| 132 if (validUTF8 && !value.isEmpty()) { | 133 if (validUTF8 && !value.isEmpty()) { |
| 133 value = value.utf8(StrictUTF8Conversion).data(); | 134 value = value.utf8(StrictUTF8Conversion).data(); |
| 134 validUTF8 = !value.isEmpty(); | 135 validUTF8 = !value.isEmpty(); |
| 135 } | 136 } |
| 136 | 137 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 149 | 150 |
| 150 m_timeFormat = Invalid; | 151 m_timeFormat = Invalid; |
| 151 | 152 |
| 152 for (unsigned i = 0; i < m_fragments.size(); ++i) { | 153 for (unsigned i = 0; i < m_fragments.size(); ++i) { |
| 153 std::pair<String, String>& fragment = m_fragments[i]; | 154 std::pair<String, String>& fragment = m_fragments[i]; |
| 154 | 155 |
| 155 DCHECK(fragment.first.is8Bit()); | 156 DCHECK(fragment.first.is8Bit()); |
| 156 DCHECK(fragment.second.is8Bit()); | 157 DCHECK(fragment.second.is8Bit()); |
| 157 | 158 |
| 158 // http://www.w3.org/2008/WebVideo/Fragments/WD-media-fragments-spec/#naming
-time | 159 // http://www.w3.org/2008/WebVideo/Fragments/WD-media-fragments-spec/#naming
-time |
| 159 // Temporal clipping is denoted by the name t, and specified as an interval
with a begin | 160 // Temporal clipping is denoted by the name t, and specified as an interval |
| 160 // time and an end time | 161 // with a begin time and an end time |
| 161 if (fragment.first != "t") | 162 if (fragment.first != "t") |
| 162 continue; | 163 continue; |
| 163 | 164 |
| 164 // http://www.w3.org/2008/WebVideo/Fragments/WD-media-fragments-spec/#npt-ti
me | 165 // http://www.w3.org/2008/WebVideo/Fragments/WD-media-fragments-spec/#npt-ti
me |
| 165 // Temporal clipping can be specified either as Normal Play Time (npt) RFC 2
326, as SMPTE timecodes, | 166 // Temporal clipping can be specified either as Normal Play Time (npt) RFC |
| 166 // SMPTE, or as real-world clock time (clock) RFC 2326. Begin and end times
are always specified | 167 // 2326, as SMPTE timecodes, SMPTE, or as real-world clock time (clock) RFC |
| 167 // in the same format. The format is specified by name, followed by a colon
(:), with npt: being | 168 // 2326. Begin and end times are always specified in the same format. The |
| 168 // the default. | 169 // format is specified by name, followed by a colon (:), with npt: being the |
| 170 // default. |
| 169 | 171 |
| 170 double start = std::numeric_limits<double>::quiet_NaN(); | 172 double start = std::numeric_limits<double>::quiet_NaN(); |
| 171 double end = std::numeric_limits<double>::quiet_NaN(); | 173 double end = std::numeric_limits<double>::quiet_NaN(); |
| 172 if (parseNPTFragment(fragment.second.characters8(), | 174 if (parseNPTFragment(fragment.second.characters8(), |
| 173 fragment.second.length(), start, end)) { | 175 fragment.second.length(), start, end)) { |
| 174 m_startTime = start; | 176 m_startTime = start; |
| 175 m_endTime = end; | 177 m_endTime = end; |
| 176 m_timeFormat = NormalPlayTime; | 178 m_timeFormat = NormalPlayTime; |
| 177 | 179 |
| 178 // Although we have a valid fragment, don't return yet because when a frag
ment dimensions | 180 // Although we have a valid fragment, don't return yet because when a |
| 179 // occurs multiple times, only the last occurrence of that dimension is us
ed: | 181 // fragment dimensions occurs multiple times, only the last occurrence of |
| 182 // that dimension is used: |
| 180 // http://www.w3.org/2008/WebVideo/Fragments/WD-media-fragments-spec/#erro
r-uri-general | 183 // http://www.w3.org/2008/WebVideo/Fragments/WD-media-fragments-spec/#erro
r-uri-general |
| 181 // Multiple occurrences of the same dimension: only the last valid occurre
nce of a dimension | 184 // Multiple occurrences of the same dimension: only the last valid |
| 182 // (e.g., t=10 in #t=2&t=10) is interpreted, all previous occurrences (val
id or invalid) | 185 // occurrence of a dimension (e.g., t=10 in #t=2&t=10) is interpreted, all |
| 183 // SHOULD be ignored by the UA. | 186 // previous occurrences (valid or invalid) SHOULD be ignored by the UA. |
| 184 } | 187 } |
| 185 } | 188 } |
| 186 m_fragments.clear(); | 189 m_fragments.clear(); |
| 187 } | 190 } |
| 188 | 191 |
| 189 bool MediaFragmentURIParser::parseNPTFragment(const LChar* timeString, | 192 bool MediaFragmentURIParser::parseNPTFragment(const LChar* timeString, |
| 190 unsigned length, | 193 unsigned length, |
| 191 double& startTime, | 194 double& startTime, |
| 192 double& endTime) { | 195 double& endTime) { |
| 193 unsigned offset = 0; | 196 unsigned offset = 0; |
| 194 if (length >= nptIdentiferLength && timeString[0] == 'n' && | 197 if (length >= nptIdentiferLength && timeString[0] == 'n' && |
| 195 timeString[1] == 'p' && timeString[2] == 't' && timeString[3] == ':') | 198 timeString[1] == 'p' && timeString[2] == 't' && timeString[3] == ':') |
| 196 offset += nptIdentiferLength; | 199 offset += nptIdentiferLength; |
| 197 | 200 |
| 198 if (offset == length) | 201 if (offset == length) |
| 199 return false; | 202 return false; |
| 200 | 203 |
| 201 // http://www.w3.org/2008/WebVideo/Fragments/WD-media-fragments-spec/#naming-t
ime | 204 // http://www.w3.org/2008/WebVideo/Fragments/WD-media-fragments-spec/#naming-t
ime |
| 202 // If a single number only is given, this corresponds to the begin time except
if it is preceded | 205 // If a single number only is given, this corresponds to the begin time except |
| 203 // by a comma that would in this case indicate the end time. | 206 // if it is preceded by a comma that would in this case indicate the end time. |
| 204 if (timeString[offset] == ',') { | 207 if (timeString[offset] == ',') { |
| 205 startTime = 0; | 208 startTime = 0; |
| 206 } else { | 209 } else { |
| 207 if (!parseNPTTime(timeString, length, offset, startTime)) | 210 if (!parseNPTTime(timeString, length, offset, startTime)) |
| 208 return false; | 211 return false; |
| 209 } | 212 } |
| 210 | 213 |
| 211 if (offset == length) | 214 if (offset == length) |
| 212 return true; | 215 return true; |
| 213 | 216 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 243 // fractional part to indicate miliseconds, or as colon-separated hours, | 246 // fractional part to indicate miliseconds, or as colon-separated hours, |
| 244 // minutes and seconds (again with an optional fraction). Minutes and | 247 // minutes and seconds (again with an optional fraction). Minutes and |
| 245 // seconds must be specified as exactly two digits, hours and fractional | 248 // seconds must be specified as exactly two digits, hours and fractional |
| 246 // seconds can be any number of digits. The hours, minutes and seconds | 249 // seconds can be any number of digits. The hours, minutes and seconds |
| 247 // specification for NPT is a convenience only, it does not signal frame | 250 // specification for NPT is a convenience only, it does not signal frame |
| 248 // accuracy. The specification of the "npt:" identifier is optional since | 251 // accuracy. The specification of the "npt:" identifier is optional since |
| 249 // NPT is the default time scheme. This specification builds on the RTSP | 252 // NPT is the default time scheme. This specification builds on the RTSP |
| 250 // specification of NPT RFC 2326. | 253 // specification of NPT RFC 2326. |
| 251 // | 254 // |
| 252 // ; defined in RFC 2326 | 255 // ; defined in RFC 2326 |
| 253 // npt-sec = 1*DIGIT [ "." *DIGIT ] ; definitions ta
ken | 256 // npt-sec = 1*DIGIT [ "." *DIGIT ] |
| 254 // npt-hhmmss = npt-hh ":" npt-mm ":" npt-ss [ "." *DIGIT] ; from RFC 2326 | 257 // npt-hhmmss = npt-hh ":" npt-mm ":" npt-ss [ "." *DIGIT] |
| 255 // npt-mmss = npt-mm ":" npt-ss [ "." *DIGIT] | 258 // npt-mmss = npt-mm ":" npt-ss [ "." *DIGIT] |
| 256 // npt-hh = 1*DIGIT ; any positive number | 259 // npt-hh = 1*DIGIT ; any positive number |
| 257 // npt-mm = 2DIGIT ; 0-59 | 260 // npt-mm = 2DIGIT ; 0-59 |
| 258 // npt-ss = 2DIGIT ; 0-59 | 261 // npt-ss = 2DIGIT ; 0-59 |
| 259 | 262 |
| 260 String digits1 = collectDigits(timeString, length, offset); | 263 String digits1 = collectDigits(timeString, length, offset); |
| 261 int value1 = digits1.toInt(); | 264 int value1 = digits1.toInt(); |
| 262 if (offset >= length || timeString[offset] == ',') { | 265 if (offset >= length || timeString[offset] == ',') { |
| 263 time = value1; | 266 time = value1; |
| 264 return true; | 267 return true; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 | 311 |
| 309 if (offset < length && timeString[offset] == '.') | 312 if (offset < length && timeString[offset] == '.') |
| 310 fraction = collectFraction(timeString, length, offset).toDouble(); | 313 fraction = collectFraction(timeString, length, offset).toDouble(); |
| 311 | 314 |
| 312 time = (value1 * secondsPerHour) + (value2 * secondsPerMinute) + value3 + | 315 time = (value1 * secondsPerHour) + (value2 * secondsPerMinute) + value3 + |
| 313 fraction; | 316 fraction; |
| 314 return true; | 317 return true; |
| 315 } | 318 } |
| 316 | 319 |
| 317 } // namespace blink | 320 } // namespace blink |
| OLD | NEW |