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