r_timezone.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "r_timezone.h"
00024 #include "record-internal.h"
00025 #include "protostructs.h"
00026 #include "data.h"
00027 #include "time.h"
00028 #include "debug.h"
00029 #include <ostream>
00030 #include <iomanip>
00031
00032 using namespace std;
00033 using namespace Barry::Protocol;
00034
00035 namespace Barry
00036 {
00037
00038
00039
00040
00041
00042 #define TZFC_INDEX 0x01
00043 #define TZFC_NAME 0x02
00044 #define TZFC_OFFSET 0x03
00045 #define TZFC_DST 0x04
00046 #define TZFC_STARTMONTH 0x06
00047 #define TZFC_ENDMONTH 0x0B
00048 #define TZFC_TZTYPE 0x64
00049
00050 #define TZFC_END 0xffff
00051
00052 static FieldLink<Timezone> TimezoneFieldLinks[] = {
00053 { TZFC_NAME, "Name", 0, 0, &Timezone::TimeZoneName, 0, 0 },
00054 { TZFC_END, "End of List", 0, 0, 0, 0, 0 },
00055 };
00056
00057 Timezone::Timezone()
00058 {
00059 Clear();
00060 }
00061
00062 Timezone::~Timezone()
00063 {
00064 }
00065
00066 const unsigned char* Timezone::ParseField(const unsigned char *begin,
00067 const unsigned char *end,
00068 const IConverter *ic)
00069 {
00070 const CommonField *field = (const CommonField *) begin;
00071
00072
00073 begin += COMMON_FIELD_HEADER_SIZE + btohs(field->size);
00074 if( begin > end )
00075 return begin;
00076
00077 if( !btohs(field->size) )
00078 return begin;
00079
00080 if( field->type == TZFC_TZTYPE ) {
00081 if( ( TZType = field->u.uint32 ) != 1 ) {
00082 throw Error("Timezone::ParseField: Timezone Type is not valid");
00083 }
00084 return begin;
00085 }
00086
00087
00088 for( FieldLink<Timezone> *b = TimezoneFieldLinks;
00089 b->type != TZFC_END;
00090 b++ )
00091 {
00092 if( b->type == field->type ) {
00093 if( b->strMember ) {
00094 std::string &s = this->*(b->strMember);
00095 s = ParseFieldString(field);
00096 return begin;
00097 }
00098 }
00099 }
00100
00101 switch( field->type )
00102 {
00103 case TZFC_INDEX:
00104 Index = btohl(field->u.uint32);
00105 return begin;
00106
00107 case TZFC_OFFSET:
00108 Offset = btohs(field->u.int16);
00109 if (Offset < 0) {
00110 Offset =~ Offset;
00111 Offset++;
00112 OffsetFraction = Offset % 60;
00113 Offset = Offset / 60;
00114 Left = true;
00115 } else {
00116 OffsetFraction = Offset % 60;
00117 Offset = Offset / 60;
00118 Left = false;
00119 }
00120 return begin;
00121
00122 case TZFC_DST:
00123 DSTOffset = btohl(field->u.uint32);
00124 if (DSTOffset) {
00125 UseDST = true;
00126 }
00127 return begin;
00128
00129 case TZFC_STARTMONTH:
00130 StartMonth = btohl(field->u.uint32);
00131 return begin;
00132
00133 case TZFC_ENDMONTH:
00134 EndMonth = btohl(field->u.uint32);
00135 return begin;
00136 }
00137
00138
00139 UnknownField uf;
00140 uf.type = field->type;
00141 uf.data.assign((const char*)field->u.raw, btohs(field->size));
00142 Unknowns.push_back(uf);
00143
00144
00145 return begin;
00146 }
00147
00148 void Timezone::ParseHeader(const Data &data, size_t &offset)
00149 {
00150
00151 }
00152
00153 void Timezone::ParseFields(const Data &data, size_t &offset, const IConverter *ic)
00154 {
00155 const unsigned char *finish = ParseCommonFields(*this,
00156 data.GetData() + offset, data.GetData() + data.GetSize(), ic);
00157 offset += finish - (data.GetData() + offset);
00158 }
00159
00160 void Timezone::Clear()
00161 {
00162 TimeZoneName.clear();
00163
00164 Index = 0;
00165 Left = false;
00166 UseDST = false;
00167 Offset = 0;
00168 OffsetFraction = 0;
00169 DSTOffset = 0;
00170 StartMonth = -1;
00171 EndMonth = -1;
00172
00173 Unknowns.clear();
00174 }
00175
00176 void Timezone::Dump(std::ostream &os) const
00177 {
00178 static const char *month[] = {
00179 "Jan", "Feb", "Mar", "Apr", "May",
00180 "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
00181 };
00182
00183 os << "Task entry: 0x" << setbase(16) << RecordId
00184 << " (" << (unsigned int)RecType << ")\n";
00185
00186
00187 for( const FieldLink<Timezone> *b = TimezoneFieldLinks;
00188 b->type != TZFC_END;
00189 b++ )
00190 {
00191 if( b->strMember ) {
00192 const std::string &s = this->*(b->strMember);
00193 if( s.size() )
00194 os << " " << b->name << ": " << s << "\n";
00195 }
00196 }
00197
00198 os << " Index: 0x" <<setw(2) << Index << "\n";
00199 os << " Offset: " << (Left ? "-" : "+") << setbase(10) << Offset << "." << OffsetFraction << "\n";
00200 os << " Use DST: " << (UseDST ? "true" : "false") << "\n";
00201 if (UseDST) {
00202 if ((StartMonth > 0) && (StartMonth < 11))
00203 os << "Start Month: " << month[StartMonth] << "\n";
00204 else
00205 os << "Start Month: unknown (" << setbase(10) << StartMonth << ")\n";
00206 if ((EndMonth > 0) && (EndMonth < 11))
00207 os << " End Month: " << month[EndMonth] << "\n";
00208 else
00209 os << " End Month: unknown (" << setbase(10) << EndMonth << ")\n";
00210 }
00211
00212 os << Unknowns;
00213 os << "\n\n";
00214 }
00215
00216 }