190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file.
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "media/webm/webm_webvtt_parser.h"
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace media {
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WebMWebVTTParser::Parse(const uint8* payload, int payload_size,
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                             std::string* id,
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                             std::string* settings,
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                             std::string* content) {
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  WebMWebVTTParser parser(payload, payload_size);
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  parser.Parse(id, settings, content);
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)WebMWebVTTParser::WebMWebVTTParser(const uint8* payload, int payload_size)
1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : ptr_(payload),
1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ptr_end_(payload + payload_size) {
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WebMWebVTTParser::Parse(std::string* id,
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                             std::string* settings,
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                             std::string* content) {
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ParseLine(id);
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ParseLine(settings);
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  content->assign(ptr_, ptr_end_);
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool WebMWebVTTParser::GetByte(uint8* byte) {
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (ptr_ >= ptr_end_)
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return false;  // indicates end-of-stream
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  *byte = *ptr_++;
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return true;
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WebMWebVTTParser::UngetByte() {
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  --ptr_;
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WebMWebVTTParser::ParseLine(std::string* line) {
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  line->clear();
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Consume characters from the stream, until we reach end-of-line.
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // The WebVTT spec states that lines may be terminated in any of the following
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // three ways:
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //  LF
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //  CR
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //  CR LF
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // The spec is here:
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  //  http://wiki.webmproject.org/webm-metadata/temporal-metadata/webvtt-in-webm
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  enum {
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    kLF = '\x0A',
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    kCR = '\x0D'
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  };
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (;;) {
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    uint8 byte;
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!GetByte(&byte) || byte == kLF)
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (byte == kCR) {
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (GetByte(&byte) && byte != kLF)
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        UngetByte();
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return;
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    line->push_back(byte);
7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace media
79