diff --git a/panda/src/downloader/documentSpec.I b/panda/src/downloader/documentSpec.I index 9d15c325e2..4b64d6ccef 100644 --- a/panda/src/downloader/documentSpec.I +++ b/panda/src/downloader/documentSpec.I @@ -290,6 +290,13 @@ get_request_mode() const { return _request_mode; } +INLINE istream & +operator >> (istream &in, DocumentSpec &doc) { + if (!doc.input(in)) { + in.clear(ios::failbit | in.rdstate()); + } + return in; +} INLINE ostream & operator << (ostream &out, const DocumentSpec &doc) { diff --git a/panda/src/downloader/documentSpec.cxx b/panda/src/downloader/documentSpec.cxx index cac9687357..04c5a8f06e 100644 --- a/panda/src/downloader/documentSpec.cxx +++ b/panda/src/downloader/documentSpec.cxx @@ -17,6 +17,7 @@ //////////////////////////////////////////////////////////////////// #include "documentSpec.h" +#include "indent.h" //////////////////////////////////////////////////////////////////// @@ -43,6 +44,58 @@ compare_to(const DocumentSpec &other) const { return _date.compare_to(other._date); } +//////////////////////////////////////////////////////////////////// +// Function: DocumentSpec::input +// Access: Published +// Description: Can be used to read in the DocumentSpec from a stream +// generated either by output() or write(). Returns +// true on success, false on failure. +//////////////////////////////////////////////////////////////////// +bool DocumentSpec:: +input(istream &in) { + // First, clear the spec. + (*this) = DocumentSpec(); + + char ch; + in >> ch; + if (ch != '[') { + return false; + } + in >> _url; + in >> ch; + if (ch == '(') { + // Scan the tag, up to but not including the closing paren. + string tag; + in >> ch; + while (!in.fail() && !in.eof() && ch != ')') { + tag += ch; + // We want to include embedded whitespace, so we use get(). + ch = in.get(); + } + set_tag(HTTPEntityTag(tag)); + + // Now ch is the close paren following the tag; skip to the next + // character. + in >> ch; + } + + // Scan the date, up to but not including the closing bracket. + if (ch != ']') { + string date; + while (!in.fail() && !in.eof() && ch != ']') { + date += ch; + ch = in.get(); + } + + set_date(HTTPDate(date)); + if (!get_date().is_valid()) { + return false; + } + } + + return true; +} + //////////////////////////////////////////////////////////////////// // Function: DocumentSpec::output // Access: Published @@ -50,13 +103,14 @@ compare_to(const DocumentSpec &other) const { //////////////////////////////////////////////////////////////////// void DocumentSpec:: output(ostream &out) const { - out << get_url(); + out << "[ " << get_url(); if (has_tag()) { out << " (" << get_tag() << ")"; } if (has_date()) { out << " " << get_date(); } + out << " ]"; } //////////////////////////////////////////////////////////////////// @@ -65,12 +119,18 @@ output(ostream &out) const { // Description: //////////////////////////////////////////////////////////////////// void DocumentSpec:: -write(ostream &out) const { - out << get_url() << "\n"; +write(ostream &out, int indent_level) const { + indent(out, indent_level) + << "[ " << get_url(); if (has_tag()) { - out << " " << get_tag() << "\n"; + out << "\n"; + indent(out, indent_level + 2) + << "(" << get_tag() << ")"; } if (has_date()) { - out << " " << get_date() << "\n"; + out << "\n"; + indent(out, indent_level + 2) + << get_date(); } + out << " ]\n"; } diff --git a/panda/src/downloader/documentSpec.h b/panda/src/downloader/documentSpec.h index d73e25c948..06884a3824 100644 --- a/panda/src/downloader/documentSpec.h +++ b/panda/src/downloader/documentSpec.h @@ -70,8 +70,9 @@ PUBLISHED: INLINE void set_request_mode(RequestMode request_mode); INLINE RequestMode get_request_mode() const; + bool input(istream &in); void output(ostream &out) const; - void write(ostream &out) const; + void write(ostream &out, int indent_level = 0) const; private: URLSpec _url; @@ -86,6 +87,7 @@ private: int _flags; }; +INLINE istream &operator >> (istream &in, DocumentSpec &doc); INLINE ostream &operator << (ostream &out, const DocumentSpec &doc); #include "documentSpec.I" diff --git a/panda/src/downloader/httpDate.I b/panda/src/downloader/httpDate.I index a8f273f3e0..f2ac2cafe6 100644 --- a/panda/src/downloader/httpDate.I +++ b/panda/src/downloader/httpDate.I @@ -179,16 +179,14 @@ operator - (const HTTPDate &other) const { return (int)(_time - other._time); } -//////////////////////////////////////////////////////////////////// -// Function: HTTPDate::output -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void HTTPDate:: -output(ostream &out) const { - out << get_string(); -} +INLINE istream & +operator >> (istream &in, HTTPDate &date) { + if (!date.input(in)) { + in.clear(ios::failbit | in.rdstate()); + } + return in; +} INLINE ostream & operator << (ostream &out, const HTTPDate &date) { diff --git a/panda/src/downloader/httpDate.cxx b/panda/src/downloader/httpDate.cxx index ad3580073d..68c61424c4 100644 --- a/panda/src/downloader/httpDate.cxx +++ b/panda/src/downloader/httpDate.cxx @@ -253,6 +253,49 @@ get_string() const { } +//////////////////////////////////////////////////////////////////// +// Function: HTTPDate::input +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +bool HTTPDate:: +input(istream &in) { + (*this) = HTTPDate(); + + // Extract out the quoted date string. + char ch; + in >> ch; + if (ch != '"') { + return false; + } + + string date; + ch = in.get(); + while (!in.fail() && !in.eof() && ch != '"') { + date += ch; + ch = in.get(); + } + + if (ch != '"') { + return false; + } + + (*this) = HTTPDate(date); + return is_valid(); +} + +//////////////////////////////////////////////////////////////////// +// Function: HTTPDate::output +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void HTTPDate:: +output(ostream &out) const { + // We put quotes around the string on output, so we can reliably + // detect the end of the date string on input, above. + out << '"' << get_string() << '"'; +} + //////////////////////////////////////////////////////////////////// // Function: HTTPDate::get_token // Access: Published diff --git a/panda/src/downloader/httpDate.h b/panda/src/downloader/httpDate.h index e2db770669..fd1ea87d88 100644 --- a/panda/src/downloader/httpDate.h +++ b/panda/src/downloader/httpDate.h @@ -55,7 +55,8 @@ PUBLISHED: INLINE HTTPDate operator - (int seconds) const; INLINE int operator - (const HTTPDate &other) const; - INLINE void output(ostream &out) const; + bool input(istream &in); + void output(ostream &out) const; private: static string get_token(const string &str, size_t &pos); @@ -63,7 +64,8 @@ private: time_t _time; }; -INLINE ostream &operator << (ostream &out, const URLSpec &url); +INLINE istream &operator >> (istream &in, HTTPDate &date); +INLINE ostream &operator << (ostream &out, const HTTPDate &date); #include "httpDate.I" diff --git a/panda/src/downloader/urlSpec.I b/panda/src/downloader/urlSpec.I index 47337b406e..3c5f7ab278 100644 --- a/panda/src/downloader/urlSpec.I +++ b/panda/src/downloader/urlSpec.I @@ -288,6 +288,13 @@ operator [] (int n) const { return _url[n]; } +INLINE istream & +operator >> (istream &in, URLSpec &url) { + if (!url.input(in)) { + in.clear(ios::failbit | in.rdstate()); + } + return in; +} INLINE ostream & operator << (ostream &out, const URLSpec &url) { diff --git a/panda/src/downloader/urlSpec.cxx b/panda/src/downloader/urlSpec.cxx index 96110fcbb4..7c27bd217e 100644 --- a/panda/src/downloader/urlSpec.cxx +++ b/panda/src/downloader/urlSpec.cxx @@ -532,6 +532,22 @@ set_url(const string &url, bool server_name_expected) { } } +//////////////////////////////////////////////////////////////////// +// Function: URLSpec::input +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +bool URLSpec:: +input(istream &in) { + string url; + in >> url; + if (!in) { + return false; + } + set_url(url); + return true; +} + //////////////////////////////////////////////////////////////////// // Function: URLSpec::output // Access: Published @@ -655,7 +671,7 @@ unquote(const string &source) { if (isdigit(ch)) { value = ch - '0'; } else { - value = tolower(ch) - 'a'; + value = tolower(ch) - 'a' + 10; } hex = (hex << 4) | value; } @@ -693,7 +709,7 @@ unquote_plus(const string &source) { if (isdigit(ch)) { value = ch - '0'; } else { - value = tolower(ch) - 'a'; + value = tolower(ch) - 'a' + 10; } hex = (hex << 4) | value; } diff --git a/panda/src/downloader/urlSpec.h b/panda/src/downloader/urlSpec.h index 9b0350a880..566c7dfd43 100644 --- a/panda/src/downloader/urlSpec.h +++ b/panda/src/downloader/urlSpec.h @@ -81,6 +81,7 @@ PUBLISHED: INLINE size_t length() const; INLINE char operator [] (int n) const; + bool input(istream &in); void output(ostream &out) const; static string quote(const string &source, const string &safe = "/"); @@ -117,6 +118,7 @@ private: size_t _query_start; }; +INLINE istream &operator >> (istream &in, URLSpec &url); INLINE ostream &operator << (ostream &out, const URLSpec &url); #include "urlSpec.I"