r_timezone.h

Go to the documentation of this file.
00001 ///
00002 /// \file       r_timezone.h
00003 ///             Record parsing class for the timezone database.
00004 ///
00005 
00006 /*
00007     Copyright (C) 2005-2012, Net Direct Inc. (http://www.netdirect.ca/)
00008     Copyright (C) 2008, Brian Edginton
00009 
00010     This program is free software; you can redistribute it and/or modify
00011     it under the terms of the GNU General Public License as published by
00012     the Free Software Foundation; either version 2 of the License, or
00013     (at your option) any later version.
00014 
00015     This program is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00018 
00019     See the GNU General Public License in the COPYING file at the
00020     root directory of this project for more details.
00021 */
00022 
00023 #ifndef __BARRY_RECORD_TIMEZONE_H__
00024 #define __BARRY_RECORD_TIMEZONE_H__
00025 
00026 #include "dll.h"
00027 #include "record.h"
00028 #include <vector>
00029 #include <string>
00030 #include <stdint.h>
00031 
00032 namespace Barry {
00033 
00034 // forward declarations
00035 class IConverter;
00036 
00037 class BXEXPORT TimeZone
00038 {
00039 public:
00040         typedef Barry::UnknownsType                     UnknownsType;
00041 
00042         uint8_t RecType;
00043         uint32_t RecordId;
00044 
00045         std::string Name;               //< name of time zone
00046 
00047         int32_t Index;                  //< index of entry in time zone table...
00048                                         //< matches Code in hard coded TimeZone
00049                                         //< table in Barry
00050 
00051         int32_t UTCOffset;              //< Timezone offset from UTC in minutes.
00052                                         //< Will be a negative value for west
00053                                         //< of UTC (North America, etc), and
00054                                         //< a positive value for east (Europe).
00055                                         //< i.e. -210 for St. John's, which is
00056                                         //< -3.5 hours from UTC.
00057 
00058         bool UseDST;                    //< true this timezone uses DST
00059         uint32_t DSTOffset;             //< minutes of DST, if UseDST is true.
00060                                         //< This value will almost always be 60.
00061         uint32_t StartMonth;            //< index, 0-11, of month to start DST
00062         uint32_t EndMonth;              //< index, 0-11, of month to end DST
00063 
00064         uint8_t TZType;                 //< unknown
00065 
00066         UnknownsType Unknowns;
00067 
00068 public:
00069         TimeZone();
00070 
00071         /// Creates a new timezone based on utc_offset minutes.
00072         /// Use same semantics as UTCOffset.  For example, a -3.5 hour
00073         /// timezone (which is west of UTC) would be constructed
00074         /// as: TimeZone(-210)
00075         explicit TimeZone(int utc_offset);
00076 
00077         /// Creates a new timezone based on negative/positive hours,
00078         /// and positive minutes.  For example, a -3.5 hour timezone
00079         /// (which is west of UTC) would be constructed as: TimeZone(-3, 30)
00080         /// Note that minutes can be negative, and it will be handled
00081         /// correctly.  i.e. TimeZone(-3, 30) == TimeZone(-3, -30)
00082         TimeZone(int hours, int minutes);
00083 
00084         virtual ~TimeZone();
00085 
00086         //
00087         // TimeZone related utility functions
00088         //
00089 
00090         bool IsWest() const { return UTCOffset < 0; }
00091 
00092         /// Splits UTCOffset minutes into hours and minutes.  hours can be
00093         /// negative.  minutes is always positive.
00094         void Split(int *hours, int *minutes) const;
00095 
00096         /// Splits UTCOffset minutes into absolute values of hours and minutes,
00097         /// and sets the west flag appropriately.  This is to mimic the
00098         /// old behaviour of the Left, Offset and OffsetFraction member
00099         /// variables.
00100         void SplitAbsolute(bool *west,
00101                 unsigned int *hours, unsigned int *minutes) const;
00102 
00103         /// Creates a timezone string suitable for a Unix / POSIX TZ
00104         /// environment variable.  Expects a time zone prefix.
00105         /// For example, New Zealand Standard/Daylight Time is NZST/NZDT, so
00106         /// the prefix would be "NZ".  Eastern Standard/Daylight Time
00107         /// is EST/EDT, so the prefix would be "E".
00108         ///
00109         /// Should be able to use this string to achieve time zone conversions
00110         /// using the TzWrapper class.
00111         std::string GetTz(const std::string &prefix) const;
00112 
00113 
00114         // common Barry record functions
00115         void Validate() const;
00116         const unsigned char* ParseField(const unsigned char *begin,
00117                 const unsigned char *end, const IConverter *ic = 0);
00118         void ParseRecurrenceData(const void *data);
00119         void BuildRecurrenceData(void *data);
00120         uint8_t GetRecType() const { return RecType; }
00121         uint32_t GetUniqueId() const { return RecordId; }
00122         void SetIds(uint8_t Type, uint32_t Id) { RecType = Type; RecordId = Id; }
00123         void ParseHeader(const Data &data, size_t &offset);
00124         void ParseFields(const Data &data, size_t &offset, const IConverter *ic = 0);
00125         void BuildHeader(Data &data, size_t &offset) const;
00126         void BuildFields(Data &data, size_t &offset, const IConverter *ic = 0) const;
00127 
00128         // operations (common among record classes)
00129         void Clear();
00130         void Dump(std::ostream &os) const;
00131         std::string GetDescription() const;
00132 
00133         bool operator<(const TimeZone &other) const { return SortByName(*this, other); }
00134 
00135         // sort options - suitable for use in std::sort()
00136         static bool SortByName(const TimeZone &a, const TimeZone &b)
00137         {
00138                 return a.Name < b.Name;
00139         }
00140         static bool SortByZone(const TimeZone &a, const TimeZone &b)
00141         {
00142                 return a.UTCOffset < b.UTCOffset;
00143         }
00144 
00145         // database name
00146         static const char * GetDBName() { return "Time Zones"; }
00147         static uint8_t GetDefaultRecType() { return 2; }
00148 
00149         // Generic Field Handle support
00150         static const FieldHandle<TimeZone>::ListT& GetFieldHandles();
00151 };
00152 
00153 BXEXPORT inline std::ostream& operator<<(std::ostream &os, const TimeZone &msg) {
00154         msg.Dump(os);
00155         return os;
00156 }
00157 
00158 
00159 // forward declarations
00160 namespace Mode {
00161         class Desktop;
00162 }
00163 
00164 //
00165 // TimeZones
00166 //
00167 /// Creates a vector of TimeZone objects either based on the library's
00168 /// hard coded StaticTimeZone list, or by extracting the time zone database
00169 /// from a given device.
00170 ///
00171 /// After construction, the vector will be sorted according to time zone,
00172 /// with west-most first.
00173 ///
00174 class BXEXPORT TimeZones
00175 {
00176 public:
00177         typedef std::vector<TimeZone>                   ListType;
00178         typedef ListType::iterator                      iterator;
00179         typedef ListType::const_iterator                const_iterator;
00180 
00181 private:
00182         ListType m_list;
00183 
00184 public:
00185         /// Creates the list based on the library's hard coded StaticTimeZone
00186         /// list.
00187         TimeZones();
00188 
00189         /// Extracts the time zone database from the given device.
00190         /// Throws an exception if the device does not have a time zones
00191         /// database.
00192         explicit TimeZones(Barry::Mode::Desktop &desktop);
00193 
00194         /// Static helper function that returns true if the device
00195         /// referenced by desktop has a time zone database
00196         static bool IsLoadable(Barry::Mode::Desktop &desktop);
00197 
00198         ListType& GetList() { return m_list; }
00199         const ListType& GetList() const { return m_list; }
00200 
00201         iterator begin() { return m_list.begin(); }
00202         const_iterator begin() const { return m_list.begin(); }
00203 
00204         iterator end() { return m_list.end(); }
00205         const_iterator end() const { return m_list.end(); }
00206 
00207         TimeZone& operator[](int i) { return m_list[i]; }
00208         const TimeZone& operator[](int i) const { return m_list[i]; }
00209 
00210         // utility functions - return end() if not found
00211         iterator Find(int index);
00212         const_iterator Find(int index) const;
00213 
00214         iterator FindByOffset(int utc_offset);
00215         const_iterator FindByOffset(int utc_offset) const;
00216 
00217         void Dump(std::ostream &os) const;
00218 };
00219 
00220 BXEXPORT inline std::ostream& operator<<(std::ostream &os, const TimeZones &l)
00221 {
00222         l.Dump(os);
00223         return os;
00224 }
00225 
00226 } // namespace Barry
00227 
00228 #endif /* __BARRY_RECORD_TIMEZONE_H__*/
00229