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