Shaka Packager SDK
text_readers.cc
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/webvtt/text_readers.h"
8 
9 #include <cstring>
10 
11 #include "packager/base/logging.h"
12 
13 namespace shaka {
14 namespace media {
15 
16 LineReader::LineReader() : should_flush_(false) {}
17 
18 void LineReader::PushData(const uint8_t* data, size_t data_size) {
19  buffer_.Push(data, static_cast<int>(data_size));
20  should_flush_ = false;
21 }
22 
23 // Split lines based on https://w3c.github.io/webvtt/#webvtt-line-terminator
24 bool LineReader::Next(std::string* out) {
25  DCHECK(out);
26 
27  int i;
28  int skip = 0;
29  const uint8_t* data;
30  int data_size;
31  buffer_.Peek(&data, &data_size);
32  for (i = 0; i < data_size; i++) {
33  // Handle \n
34  if (data[i] == '\n') {
35  skip = 1;
36  break;
37  }
38 
39  // Handle \r and \r\n
40  if (data[i] == '\r') {
41  // Only read if we can see the next character; this ensures we don't get
42  // the '\n' in the next PushData.
43  if (i + 1 == data_size) {
44  if (!should_flush_)
45  return false;
46  skip = 1;
47  } else {
48  if (data[i + 1] == '\n')
49  skip = 2;
50  else
51  skip = 1;
52  }
53  break;
54  }
55  }
56 
57  if (i == data_size && (!should_flush_ || i == 0)) {
58  return false;
59  }
60 
61  // TODO(modmaker): Handle character encodings?
62  out->assign(data, data + i);
63  buffer_.Pop(i + skip);
64  return true;
65 }
66 
68  should_flush_ = true;
69 }
70 
71 BlockReader::BlockReader() : should_flush_(false) {}
72 
73 void BlockReader::PushData(const uint8_t* data, size_t data_size) {
74  source_.PushData(data, data_size);
75  should_flush_ = false;
76 }
77 
78 bool BlockReader::Next(std::vector<std::string>* out) {
79  DCHECK(out);
80 
81  bool end_block = false;
82  // Read through lines until a non-empty line is found. With a non-empty
83  // line is found, start adding the lines to the output and once an empty
84  // line if found again, stop adding lines and exit.
85  std::string line;
86  while (source_.Next(&line)) {
87  if (!temp_.empty() && line.empty()) {
88  end_block = true;
89  break;
90  }
91  if (!line.empty()) {
92  temp_.emplace_back(std::move(line));
93  }
94  }
95 
96  if (!end_block && (!should_flush_ || temp_.empty()))
97  return false;
98 
99  *out = std::move(temp_);
100  return true;
101 }
102 
104  source_.Flush();
105  should_flush_ = true;
106 }
107 
108 } // namespace media
109 } // namespace shaka
shaka::media::ByteQueue::Peek
void Peek(const uint8_t **data, int *size) const
Definition: byte_queue.cc:62
shaka::media::BlockReader::Flush
void Flush()
Definition: text_readers.cc:103
shaka
All the methods that are virtual are virtual for mocking.
Definition: gflags_hex_bytes.cc:11
shaka::media::ByteQueue::Pop
void Pop(int count)
Definition: byte_queue.cc:69
shaka::media::LineReader::PushData
void PushData(const uint8_t *data, size_t data_size)
Pushes data onto the end of the buffer.
Definition: text_readers.cc:18
shaka::media::LineReader::Flush
void Flush()
Definition: text_readers.cc:67
shaka::media::LineReader::Next
bool Next(std::string *out)
Definition: text_readers.cc:24
shaka::media::BlockReader::PushData
void PushData(const uint8_t *data, size_t data_size)
Pushes data onto the end of the buffer.
Definition: text_readers.cc:73
shaka::media::ByteQueue::Push
void Push(const uint8_t *data, int size)
Append new bytes to the end of the queue.
Definition: byte_queue.cc:29
shaka::media::BlockReader::Next
bool Next(std::vector< std::string > *out)
Definition: text_readers.cc:78