2 /// \file r_timezone.cc
3 /// Record parsing class for the timezone database.
7 Copyright (C) 2005-2011, Net Direct Inc. (http://www.netdirect.ca/)
8 Copyright (C) 2008, Brian Edginton
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License in the COPYING file at the
20 root directory of this project for more details.
23 #include "r_timezone.h"
24 #include "record-internal.h"
25 #include "protostructs.h"
33 #include "ios_state.h"
36 using namespace Barry::Protocol
;
41 ///////////////////////////////////////////////////////////////////////////////
44 // Timezone Field Codes
45 #define TZFC_INDEX 0x01
46 #define TZFC_NAME 0x02
47 #define TZFC_OFFSET 0x03
49 #define TZFC_STARTMONTH 0x06
50 #define TZFC_ENDMONTH 0x0B
51 #define TZFC_TZTYPE 0x64
53 #define TZFC_END 0xffff
55 static FieldLink
<Timezone
> TimezoneFieldLinks
[] = {
56 { TZFC_NAME
, "Name", 0, 0, &Timezone::TimeZoneName
, 0, 0, 0, 0, true },
57 { TZFC_END
, "End of List", 0, 0, 0, 0, 0, 0, 0, false },
69 const unsigned char* Timezone::ParseField(const unsigned char *begin
,
70 const unsigned char *end
,
73 const CommonField
*field
= (const CommonField
*) begin
;
75 // advance and check size
76 begin
+= COMMON_FIELD_HEADER_SIZE
+ btohs(field
->size
);
77 if( begin
> end
) // if begin==end, we are ok
80 if( !btohs(field
->size
) ) // if field has no size, something's up
83 if( field
->type
== TZFC_TZTYPE
) {
84 if( ( TZType
= field
->u
.uint32
) != 1 ) {
85 throw Error("Timezone::ParseField: Timezone Type is not valid");
90 // cycle through the type table
91 for( FieldLink
<Timezone
> *b
= TimezoneFieldLinks
;
95 if( b
->type
== field
->type
) {
97 std::string
&s
= this->*(b
->strMember
);
98 s
= ParseFieldString(field
);
99 if( b
->iconvNeeded
&& ic
)
101 return begin
; // done!
106 switch( field
->type
)
109 Index
= btohl(field
->u
.uint32
);
113 Offset
= btohs(field
->u
.int16
);
117 OffsetFraction
= Offset
% 60;
118 Offset
= Offset
/ 60;
121 OffsetFraction
= Offset
% 60;
122 Offset
= Offset
/ 60;
128 DSTOffset
= btohl(field
->u
.uint32
);
134 case TZFC_STARTMONTH
:
135 StartMonth
= btohl(field
->u
.uint32
);
139 EndMonth
= btohl(field
->u
.uint32
);
143 // if still not handled, add to the Unknowns list
145 uf
.type
= field
->type
;
146 uf
.data
.assign((const char*)field
->u
.raw
, btohs(field
->size
));
147 Unknowns
.push_back(uf
);
149 // return new pointer for next field
153 void Timezone::ParseHeader(const Data
&data
, size_t &offset
)
155 // no header in Task records
158 void Timezone::ParseFields(const Data
&data
, size_t &offset
, const IConverter
*ic
)
160 const unsigned char *finish
= ParseCommonFields(*this,
161 data
.GetData() + offset
, data
.GetData() + data
.GetSize(), ic
);
162 offset
+= finish
- (data
.GetData() + offset
);
165 void Timezone::BuildHeader(Data
&data
, size_t &offset
) const
167 // not yet implemented
170 void Timezone::BuildFields(Data
&data
, size_t &offset
, const IConverter
*ic
) const
172 // not yet implemented
175 void Timezone::Clear()
177 RecType
= GetDefaultRecType();
190 TimeZoneName
.clear();
195 std::string
Timezone::GetDescription() const
198 oss
<< TimeZoneName
<< " ("
199 << (Left
? "-" : "+") << dec
<< Offset
<< "." << OffsetFraction
204 void Timezone::Dump(std::ostream
&os
) const
206 ios_format_state
state(os
);
208 static const char *month
[] = {
209 "Jan", "Feb", "Mar", "Apr", "May",
210 "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
213 os
<< "Task entry: 0x" << setbase(16) << RecordId
214 << " (" << (unsigned int)RecType
<< ")\n";
216 // cycle through the type table
217 for( const FieldLink
<Timezone
> *b
= TimezoneFieldLinks
;
222 const std::string
&s
= this->*(b
->strMember
);
224 os
<< " " << b
->name
<< ": " << s
<< "\n";
228 os
<< " Index: 0x" <<setw(2) << Index
<< "\n";
229 os
<< " Offset: " << (Left
? "-" : "+") << setbase(10) << Offset
<< "." << OffsetFraction
<< "\n";
230 os
<< " Use DST: " << (UseDST
? "true" : "false") << "\n";
232 if ((StartMonth
> 0) && (StartMonth
< 11))
233 os
<< "Start Month: " << month
[StartMonth
] << "\n";
235 os
<< "Start Month: unknown (" << setbase(10) << StartMonth
<< ")\n";
236 if ((EndMonth
> 0) && (EndMonth
< 11))
237 os
<< " End Month: " << month
[EndMonth
] << "\n";
239 os
<< " End Month: unknown (" << setbase(10) << EndMonth
<< ")\n";