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 "packager/base/logging.h"
10 #include "packager/file/file.h"
11 
12 namespace shaka {
13 namespace media {
14 
15 Status FileReader::Open(const std::string& filename,
16  std::unique_ptr<FileReader>* out) {
17  const char* kReadOnly = "r";
18 
19  std::unique_ptr<File, FileCloser> file(
20  File::Open(filename.c_str(), kReadOnly));
21 
22  if (!file) {
23  return Status(error::INVALID_ARGUMENT,
24  "Could not open input file " + filename);
25  }
26 
27  *out = std::unique_ptr<FileReader>(new FileReader(std::move(file)));
28 
29  return Status::OK;
30 }
31 
32 bool FileReader::Next(char* out) {
33  // TODO(vaage): If file reading performance is poor, change this to buffer
34  // data and read from the buffer.
35  return file_->Read(out, 1) == 1;
36 }
37 
38 FileReader::FileReader(std::unique_ptr<File, FileCloser> file)
39  : file_(std::move(file)) {
40  DCHECK(file_);
41 }
42 
43 PeekingReader::PeekingReader(std::unique_ptr<FileReader> source)
44  : source_(std::move(source)) {}
45 
46 bool PeekingReader::Next(char* out) {
47  DCHECK(out);
48  if (Peek(out)) {
49  has_cached_next_ = false;
50  return true;
51  }
52  return false;
53 }
54 
55 bool PeekingReader::Peek(char* out) {
56  DCHECK(out);
57  if (!has_cached_next_ && source_->Next(&cached_next_)) {
58  has_cached_next_ = true;
59  }
60  if (has_cached_next_) {
61  *out = cached_next_;
62  return true;
63  }
64  return false;
65 }
66 
67 LineReader::LineReader(std::unique_ptr<FileReader> source)
68  : source_(std::move(source)) {}
69 
70 // Split lines based on https://w3c.github.io/webvtt/#webvtt-line-terminator
71 bool LineReader::Next(std::string* out) {
72  DCHECK(out);
73  out->clear();
74  bool read_something = false;
75  char now;
76  while (source_.Next(&now)) {
77  read_something = true;
78  // handle \n
79  if (now == '\n') {
80  break;
81  }
82  // handle \r and \r\n
83  if (now == '\r') {
84  char next;
85  if (source_.Peek(&next) && next == '\n') {
86  source_.Next(&next); // Read in the '\n' that was just seen via |Peek|
87  }
88  break;
89  }
90  out->push_back(now);
91  }
92  return read_something;
93 }
94 
95 BlockReader::BlockReader(std::unique_ptr<FileReader> source)
96  : source_(std::move(source)) {}
97 
98 bool BlockReader::Next(std::vector<std::string>* out) {
99  DCHECK(out);
100 
101  out->clear();
102 
103  bool in_block = false;
104 
105  // Read through lines until a non-empty line is found. With a non-empty
106  // line is found, start adding the lines to the output and once an empty
107  // line if found again, stop adding lines and exit.
108  std::string line;
109  while (source_.Next(&line)) {
110  if (in_block && line.empty()) {
111  break;
112  }
113  if (in_block || !line.empty()) {
114  out->push_back(line);
115  in_block = true;
116  }
117  }
118 
119  return in_block;
120 }
121 } // namespace media
122 } // namespace shaka
All the methods that are virtual are virtual for mocking.
bool Next(char *out)
Definition: text_readers.cc:32
Class to read character-by-character from a file.
Definition: text_readers.h:23
virtual bool Open()=0
Internal open. Should not be used directly.
static Status Open(const std::string &filename, std::unique_ptr< FileReader > *out)
Definition: text_readers.cc:15