diff options
| author | Carl Hetherington <cth@carlh.net> | 2015-09-25 13:56:30 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2015-09-25 13:56:30 +0100 |
| commit | 35249aba26fccb83ad8dc703a3ea02d211ea840f (patch) | |
| tree | 6738a2b04ac6304ee2795390297b00cfe8974cf5 /src | |
| parent | c00435b4862971c7acd3844eaaac8ae6677f8eba (diff) | |
Support reading subrip subtitles from a string; remove UTF-16 test.
Diffstat (limited to 'src')
| -rw-r--r-- | src/subrip_reader.cc | 73 | ||||
| -rw-r--r-- | src/subrip_reader.h | 7 |
2 files changed, 62 insertions, 18 deletions
diff --git a/src/subrip_reader.cc b/src/subrip_reader.cc index a8b41ae..97d28c5 100644 --- a/src/subrip_reader.cc +++ b/src/subrip_reader.cc @@ -22,6 +22,7 @@ #include <boost/algorithm/string.hpp> #include <boost/lexical_cast.hpp> #include <boost/regex.hpp> +#include <boost/bind.hpp> #include <cstdio> #include <vector> #include <iostream> @@ -31,50 +32,88 @@ using std::vector; using std::list; using std::cout; using std::hex; +using std::stringstream; using boost::lexical_cast; using boost::to_upper; +using boost::optional; +using boost::function; using namespace sub; +/** @param s Subtitle string encoded in UTF-8 */ +SubripReader::SubripReader (string const & s) +{ + stringstream str (s); + this->read (boost::bind (&SubripReader::get_line_stringstream, this, &str)); +} + +/** @param f Subtitle file encoded in UTF-8 */ SubripReader::SubripReader (FILE* f) { + this->read (boost::bind (&SubripReader::get_line_file, this, f)); +} + +optional<string> +SubripReader::get_line_stringstream (stringstream* str) const +{ + string s; + getline (*str, s); + if (!str->good ()) { + return optional<string> (); + } + + return s; +} + +optional<string> +SubripReader::get_line_file (FILE* f) const +{ + char buffer[256]; + char* r = fgets (buffer, sizeof (buffer), f); + if (r == 0 || feof (f)) { + return optional<string> (); + } + + return string (buffer); +} + +void +SubripReader::read (function<optional<string> ()> get_line) +{ enum { COUNTER, METADATA, CONTENT } state = COUNTER; - char buffer[256]; - Time from; Time to; string line; int line_number = 0; - while (!feof (f)) { - char* r = fgets (buffer, sizeof (buffer), f); - if (r == 0 || feof (f)) { + while (true) { + optional<string> line = get_line (); + if (!line) { break; } - line = string (buffer); - trim_right_if (line, boost::is_any_of ("\n\r")); + trim_right_if (*line, boost::is_any_of ("\n\r")); if ( - line.length() >= 3 && - static_cast<unsigned char> (line[0]) == 0xef && - static_cast<unsigned char> (line[1]) == 0xbb && - static_cast<unsigned char> (line[2]) == 0xbf + line->length() >= 3 && + static_cast<unsigned char> (line.get()[0]) == 0xef && + static_cast<unsigned char> (line.get()[1]) == 0xbb && + static_cast<unsigned char> (line.get()[2]) == 0xbf ) { /* Skip Unicode byte order mark */ - line = line.substr (3); + line = line->substr (3); } switch (state) { case COUNTER: { - if (line.empty ()) { + if (line->empty ()) { /* a blank line at the start is ok */ break; } @@ -85,9 +124,9 @@ SubripReader::SubripReader (FILE* f) case METADATA: { vector<string> p; - boost::algorithm::split (p, line, boost::algorithm::is_any_of (" ")); + boost::algorithm::split (p, *line, boost::algorithm::is_any_of (" ")); if (p.size() != 3 && p.size() != 7) { - throw SubripError (line, "a time/position line"); + throw SubripError (*line, "a time/position line"); } from = convert_time (p[0]); @@ -99,11 +138,11 @@ SubripReader::SubripReader (FILE* f) break; } case CONTENT: - if (line.empty ()) { + if (line->empty ()) { state = COUNTER; line_number = 0; } else { - convert_line (line, line_number, from, to); + convert_line (*line, line_number, from, to); line_number++; } break; diff --git a/src/subrip_reader.h b/src/subrip_reader.h index a010f4a..f515356 100644 --- a/src/subrip_reader.h +++ b/src/subrip_reader.h @@ -21,6 +21,7 @@ #define LIBSUB_SUBRIP_READER_H #include "reader.h" +#include <boost/function.hpp> struct subrip_reader_convert_line_test; struct subrip_reader_convert_time_test; @@ -31,16 +32,20 @@ class SubripReader : public Reader { public: SubripReader (FILE* f); + SubripReader (std::string const & subs); private: /* For tests */ friend struct ::subrip_reader_convert_line_test; friend struct ::subrip_reader_convert_time_test; SubripReader () {} - + static Time convert_time (std::string t); void convert_line (std::string t, int line_number, Time from, Time to); void maybe_content (RawSubtitle& p); + boost::optional<std::string> get_line_stringstream (std::stringstream* str) const; + boost::optional<std::string> get_line_file (FILE* file) const; + void read (boost::function<boost::optional<std::string> ()> get_line); }; } |
