r_bookmark.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_bookmark.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 #include <iostream>
00033
00034 using namespace std;
00035 using namespace Barry::Protocol;
00036
00037 namespace Barry {
00038
00039
00040
00041
00042
00043 #define BMKFC_BOOKMARK_TYPE 0x01
00044 #define BMKFC_STRUCT1 0x11
00045 #define BMKFC_STRUCT2 0x12
00046
00047 #define BMKFC_END 0xffff
00048
00049
00050 #define BMK1SC_HOMEPAGE_KEY 0x85 // default section on 9550...
00051
00052
00053 #define BMK1SC_BOOKMARK_ID 0x87 // when user adds a bookmark
00054 #define BMK1SC_BOOKMARK_ID2 0x84 // only Nicolas sees this?
00055 #define BMK1SC_NAME 0x04
00056 #define BMK1SC_ICON 0x05
00057 #define BMK1SC_FOLDERS 0x81
00058
00059 static FieldLink<Bookmark> BookmarkFieldLinks[] = {
00060 { BMKFC_END, "End of List", 0, 0, 0, 0, 0, 0, 0, false }
00061 };
00062
00063 Bookmark::Bookmark()
00064 {
00065 Clear();
00066 }
00067
00068 Bookmark::~Bookmark()
00069 {
00070 }
00071
00072 const unsigned char* Bookmark::ParseStruct1Field(const unsigned char *begin,
00073 const unsigned char *end,
00074 const IConverter *ic)
00075 {
00076
00077 const uint8_t type = *begin;
00078 begin += 1;
00079 if( begin > end )
00080 return begin;
00081
00082 switch( type )
00083 {
00084 case BMK1SC_HOMEPAGE_KEY:
00085 case BMK1SC_BOOKMARK_ID:
00086 case BMK1SC_BOOKMARK_ID2:
00087 {
00088 const BookmarkId *id = (const BookmarkId*) begin;
00089 begin += BOOKMARK_ID_SIZE;
00090 if( begin > end )
00091 return begin;
00092
00093
00094
00095 Index = id->index;
00096 }
00097 return begin;
00098
00099 case BMK1SC_NAME:
00100 case BMK1SC_ICON:
00101 {
00102 const VarStringField *f = (const VarStringField*) begin;
00103 begin += VARSTRING_FIELD_HEADER_SIZE;
00104 if( begin > end )
00105 return begin;
00106
00107 const uint16_t size = be_btohs(f->be_size);
00108
00109 if( f->present == 1) {
00110 begin += size;
00111 if( begin > end )
00112 return begin;
00113
00114 switch( type )
00115 {
00116 case BMK1SC_NAME:
00117 Name = ParseFieldString(f->data, size);
00118 break;
00119 case BMK1SC_ICON:
00120 Icon = ParseFieldString(f->data, size);
00121 break;
00122 default:
00123 throw std::logic_error("Check cases");
00124 break;
00125 }
00126 }
00127 else if( f->present == 0 && size > 0xA0 ) {
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 begin += size & 0x0F;
00149 }
00150 }
00151 return begin;
00152
00153 case BMK1SC_FOLDERS:
00154 {
00155
00156 begin += BOOKMARK_FOLDERS_HEADER_SIZE;
00157 if( begin > end )
00158 return begin;
00159
00160
00161
00162 }
00163 return begin;
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 default:
00178
00179
00180
00181 if( (end - begin) == 2 ) {
00182 if ((Barry::Bookmark::DisplayModeType) *(begin - 3) > Barry::Bookmark::DisplayUnknown)
00183 DisplayMode = Barry::Bookmark::DisplayUnknown;
00184 else
00185 DisplayMode = (Barry::Bookmark::DisplayModeType) *(begin - 3);
00186
00187 if ((Barry::Bookmark::JavaScriptModeType) *(begin - 2) > Barry::Bookmark::JavaScriptUnknown)
00188 JavaScriptMode = Barry::Bookmark::JavaScriptUnknown;
00189 else
00190 JavaScriptMode = (Barry::Bookmark::JavaScriptModeType) *(begin - 2);
00191
00192 if ((Barry::Bookmark::BrowserIdentityType) *(begin - 1) > Barry::Bookmark::IdentityUnknown)
00193 BrowserIdentity = Barry::Bookmark::IdentityUnknown;
00194 else
00195 BrowserIdentity = (Barry::Bookmark::BrowserIdentityType) *(begin - 1);
00196 }
00197
00198
00199
00200
00201
00202
00203
00204 else if( (begin + 3) < end && begin[3] == 0 ) {
00205
00206 return ParseStruct1Field(begin + 4, end, ic);
00207 }
00208 else {
00209 ddout("Bookmark parser: unknown section type: "
00210 << std::hex << (unsigned int) type);
00211 }
00212 break;
00213 }
00214
00215 return begin;
00216 }
00217
00218 const unsigned char* Bookmark::ParseStruct2(const unsigned char *begin,
00219 const unsigned char *end,
00220 const IConverter *ic)
00221 {
00222
00223
00224
00225 const StringField *field = (const StringField*) begin;
00226 begin += STRING_FIELD_HEADER_SIZE;
00227 if( begin > end )
00228 return begin;
00229
00230 const uint16_t size = be_btohs(field->be_size);
00231 begin += sizeof(uint16_t) + size;
00232 if( begin > end )
00233 return begin;
00234
00235 Url = ParseFieldString(field->data, size);
00236
00237
00238
00239 return begin;
00240 }
00241
00242 const unsigned char* Bookmark::ParseField(const unsigned char *begin,
00243 const unsigned char *end,
00244 const IConverter *ic)
00245 {
00246 const CommonField *field = (const CommonField *) begin;
00247
00248
00249 begin += COMMON_FIELD_HEADER_SIZE + btohs(field->size);
00250 if( begin > end )
00251 return begin;
00252
00253 if( !btohs(field->size) )
00254 return begin;
00255
00256
00257 const unsigned char *b = field->u.raw;
00258 const unsigned char *e = begin;
00259
00260
00261 switch( field->type )
00262 {
00263 case BMKFC_STRUCT1:
00264 while (b <= e) {
00265 b = ParseStruct1Field(b, e, ic);
00266 }
00267 return b;
00268
00269 case BMKFC_BOOKMARK_TYPE:
00270
00271
00272 if( field->u.raw[0] != 'D' ) {
00273 throw Error( "Bookmark::ParseField: BookmarkType is not 'D'" );
00274 }
00275 return begin;
00276
00277 case BMKFC_STRUCT2:
00278 begin = ParseStruct2(b, e, ic);
00279 return begin;
00280 }
00281
00282
00283 UnknownField uf;
00284 uf.type = field->type;
00285 uf.data.assign((const char*)field->u.raw, btohs(field->size));
00286 Unknowns.push_back(uf);
00287
00288
00289 return begin;
00290 }
00291
00292 void Bookmark::ParseHeader(const Data &data, size_t &offset)
00293 {
00294
00295 }
00296
00297 void Bookmark::ParseFields(const Data &data, size_t &offset, const IConverter *ic)
00298 {
00299 const unsigned char *finish = ParseCommonFields(*this,
00300 data.GetData() + offset, data.GetData() + data.GetSize(), ic);
00301 offset += finish - (data.GetData() + offset);
00302 }
00303
00304 void Bookmark::BuildHeader(Data &data, size_t &offset) const
00305 {
00306
00307 }
00308
00309 void Bookmark::BuildFields(Data &data, size_t &offset, const IConverter *ic) const
00310 {
00311
00312 }
00313
00314 void Bookmark::Dump(std::ostream &os) const
00315 {
00316 static const char *DisplayModeName[] = { "Automatic", "Enabled", "Disabled", "Unknown" };
00317 static const char *JavaScriptModeName[] = { "Automatic", "Enabled", "Disabled", "Unknown" };
00318 static const char *BrowserIdentityName[] = { "Automatic", "BlackBerry", "FireFox", "Internet Explorer", "Unknown" };
00319
00320 os << "Bookmark entry: 0x" << setbase(16) << RecordId
00321 << " (" << (unsigned int)RecType << ")"
00322 << " (index " << (unsigned int)Index << ")\n";
00323
00324
00325 for( const FieldLink<Bookmark> *b = BookmarkFieldLinks;
00326 b->type != BMKFC_END;
00327 b++ )
00328 {
00329 if( b->strMember ) {
00330 const std::string &s = this->*(b->strMember);
00331 if( s.size() )
00332 os << " " << b->name << ": " << s << "\n";
00333 }
00334 else if( b->timeMember ) {
00335 time_t t = this->*(b->timeMember);
00336 if( t > 0 )
00337 os << " " << b->name << ": " << ctime(&t);
00338 else
00339 os << " " << b->name << ": unknown\n";
00340 }
00341 }
00342
00343 if( Name.size() )
00344 os << " Name: " << Name << "\n";
00345 if( Icon.size() )
00346 os << " Icon: " << Icon << "\n";
00347 if( Url.size() )
00348 os << " Url: " << Url << "\n";
00349 os << " Display mode: " << DisplayModeName[DisplayMode] << "\n";
00350 os << " JavaScript mode: " << JavaScriptModeName[JavaScriptMode] << "\n";
00351 os << " Browser Identity mode: " << BrowserIdentityName[BrowserIdentity] << "\n";
00352
00353 os << Unknowns;
00354 os << "\n\n";
00355 }
00356
00357 bool Bookmark::operator<(const Bookmark &other) const
00358 {
00359 int cmp = Name.compare(other.Name);
00360 return cmp < 0;
00361 }
00362
00363 void Bookmark::Clear()
00364 {
00365 RecType = GetDefaultRecType();
00366 RecordId = 0;
00367 Index = 0;
00368
00369 Name.clear();
00370 Icon.clear();
00371 Url.clear();
00372
00373 BrowserIdentity = IdentityUnknown;
00374 DisplayMode = DisplayUnknown;
00375 JavaScriptMode = JavaScriptUnknown;
00376
00377 Unknowns.clear();
00378 }
00379
00380 std::string Bookmark::GetDescription() const
00381 {
00382 return Name;
00383 }
00384
00385 }
00386