Fix missing version string when Popen communicate returns byte strings.
[libdcp.git] / src / local_time.cc
index fa810a92d719f8b4819e0803ffea3361a2aaf17b..647ff35dd45e2032775a75ff9c7a2b62f2a13f34 100644 (file)
     You should have received a copy of the GNU General Public License
     along with libdcp.  If not, see <http://www.gnu.org/licenses/>.
 
+    In addition, as a special exception, the copyright holders give
+    permission to link the code of portions of this program with the
+    OpenSSL library under certain conditions as described in each
+    individual source file, and distribute linked combinations
+    including the two.
+
+    You must obey the GNU General Public License in all respects
+    for all of the code used other than OpenSSL.  If you modify
+    file(s) with this exception, you may extend this exception to your
+    version of the file(s), but you are not obligated to do so.  If you
+    do not wish to do so, delete this exception statement from your
+    version.  If you delete this exception statement from all source
+    files in the program, then also delete it here.
 */
 
 /** @file  src/local_time.cc
@@ -96,22 +109,45 @@ LocalTime::set_local_time_zone ()
        _tz_minute = offset.minutes ();
 }
 
-/** @param s A string of the form 2013-01-05T18:06:59[.123]+04:00 */
+/** @param s A string of the form 2013-01-05T18:06:59[.123][+04:00] */
 LocalTime::LocalTime (string s)
 {
-       /* 2013-01-05T18:06:59+04:00 or 2013-01-05T18:06:59.123+04:00 */
-        /* 0123456789012345678901234 or 01234567890123456789012345678 */
+       /* 2013-01-05T18:06:59 or 2013-01-05T18:06:59.123 or 2013-01-05T18:06:59+04:00 or 2013-01-05T18:06:59.123+04:00 */
+       /* 0123456789012345678 or 01234567890123456789012 or 0123456789012345678901234 or 01234567890123456789012345678 */
 
-       if (s.length() < 25) {
+       if (s.length() < 19) {
                throw TimeFormatError (s);
        }
 
-       /* Check incidental characters */
-       bool const common = s[4] == '-' && s[7] == '-' && s[10] == 'T' && s[13] == ':' && s[16] == ':';
-       bool const without_millisecond = common && s[22] == ':';
-       bool const with_millisecond = common && s[19] == '.' && s[26] == ':';
+       bool with_millisecond = false;
+       bool with_tz = false;
+
+       switch (s.length ()) {
+       case 19:
+               break;
+       case 23:
+               with_millisecond = true;
+               break;
+       case 25:
+               with_tz = true;
+               break;
+       case 29:
+               with_millisecond = with_tz = true;
+               break;
+       default:
+               throw TimeFormatError (s);
+       }
+
+       int const tz_pos = with_millisecond ? 23 : 19;
 
-       if (!with_millisecond && !without_millisecond) {
+       /* Check incidental characters */
+       if (s[4] != '-' || s[7] != '-' || s[10] != 'T' || s[13] != ':' || s[16] != ':') {
+               throw TimeFormatError (s);
+       }
+       if (with_millisecond && s[19] != '.') {
+               throw TimeFormatError (s);
+       }
+       if (with_tz && s[tz_pos] != '+' && s[tz_pos] != '-') {
                throw TimeFormatError (s);
        }
 
@@ -121,22 +157,12 @@ LocalTime::LocalTime (string s)
        _hour = lexical_cast<int> (s.substr (11, 2));
        _minute = lexical_cast<int> (s.substr (14, 2));
        _second = lexical_cast<int> (s.substr (17, 2));
-       if (without_millisecond) {
-               _millisecond = 0;
-               _tz_hour = lexical_cast<int> (s.substr (20, 2));
-               _tz_minute = lexical_cast<int> (s.substr (23, 2));
-       } else {
-               _millisecond = lexical_cast<int> (s.substr (20, 3));
-               _tz_hour = lexical_cast<int> (s.substr (24, 2));
-               _tz_minute = lexical_cast<int> (s.substr (27, 2));
-       }
-
-       int const plus_minus_position = with_millisecond ? 23 : 19;
+       _millisecond = with_millisecond ? lexical_cast<int> (s.substr (20, 3)) : 0;
+       _tz_hour = with_tz ? lexical_cast<int> (s.substr (tz_pos + 1, 2)) : 0;
+       _tz_minute = with_tz ? lexical_cast<int> (s.substr (tz_pos + 4, 2)) : 0;
 
-       if (s[plus_minus_position] == '-') {
+       if (with_tz && s[tz_pos] == '-') {
                _tz_hour = -_tz_hour;
-       } else if (s[plus_minus_position] != '+') {
-               throw TimeFormatError (s);
        }
 }
 
@@ -148,7 +174,7 @@ LocalTime::as_string (bool with_millisecond) const
        snprintf (
                buffer, sizeof (buffer),
                "%sT%s%s%02d:%02d",
-               date().c_str(), time_of_day(with_millisecond).c_str(), (_tz_hour >= 0 ? "+" : "-"), abs (_tz_hour), _tz_minute
+               date().c_str(), time_of_day(true, with_millisecond).c_str(), (_tz_hour >= 0 ? "+" : "-"), abs (_tz_hour), _tz_minute
                );
        return buffer;
 }
@@ -164,13 +190,16 @@ LocalTime::date () const
 
 /** @return The time in the form HH:MM:SS or HH:MM:SS.mmm */
 string
-LocalTime::time_of_day (bool with_millisecond) const
+LocalTime::time_of_day (bool with_second, bool with_millisecond) const
 {
        char buffer[32];
+       DCP_ASSERT(!(with_millisecond && !with_second));
        if (with_millisecond) {
                snprintf (buffer, sizeof (buffer), "%02d:%02d:%02d.%03d", _hour, _minute, _second, _millisecond);
-       } else {
+       } else if (with_second) {
                snprintf (buffer, sizeof (buffer), "%02d:%02d:%02d", _hour, _minute, _second);
+       } else {
+               snprintf (buffer, sizeof (buffer), "%02d:%02d", _hour, _minute);
        }
        return buffer;
 }