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::Dump(std::ostream &os) const
00305 {
00306 static const char *DisplayModeName[] = { "Automatic", "Enabled", "Disabled", "Unknown" };
00307 static const char *JavaScriptModeName[] = { "Automatic", "Enabled", "Disabled", "Unknown" };
00308 static const char *BrowserIdentityName[] = { "Automatic", "BlackBerry", "FireFox", "Internet Explorer", "Unknown" };
00309
00310 os << "Bookmark entry: 0x" << setbase(16) << RecordId
00311 << " (" << (unsigned int)RecType << ")"
00312 << " (index " << (unsigned int)Index << ")\n";
00313
00314
00315 for( const FieldLink<Bookmark> *b = BookmarkFieldLinks;
00316 b->type != BMKFC_END;
00317 b++ )
00318 {
00319 if( b->strMember ) {
00320 const std::string &s = this->*(b->strMember);
00321 if( s.size() )
00322 os << " " << b->name << ": " << s << "\n";
00323 }
00324 else if( b->timeMember ) {
00325 time_t t = this->*(b->timeMember);
00326 if( t > 0 )
00327 os << " " << b->name << ": " << ctime(&t);
00328 else
00329 os << " " << b->name << ": unknown\n";
00330 }
00331 }
00332
00333 if( Name.size() )
00334 os << " Name: " << Name << "\n";
00335 if( Icon.size() )
00336 os << " Icon: " << Icon << "\n";
00337 if( Url.size() )
00338 os << " Url: " << Url << "\n";
00339 os << " Display mode: " << DisplayModeName[DisplayMode] << "\n";
00340 os << " JavaScript mode: " << JavaScriptModeName[JavaScriptMode] << "\n";
00341 os << " Browser Identity mode: " << BrowserIdentityName[BrowserIdentity] << "\n";
00342
00343 os << Unknowns;
00344 os << "\n\n";
00345 }
00346
00347 bool Bookmark::operator<(const Bookmark &other) const
00348 {
00349 int cmp = Name.compare(other.Name);
00350 return cmp < 0;
00351 }
00352
00353 void Bookmark::Clear()
00354 {
00355 RecType = GetDefaultRecType();
00356 RecordId = 0;
00357 Index = 0;
00358
00359 Name.clear();
00360 Icon.clear();
00361 Url.clear();
00362
00363 BrowserIdentity = IdentityUnknown;
00364 DisplayMode = DisplayUnknown;
00365 JavaScriptMode = JavaScriptUnknown;
00366
00367 Unknowns.clear();
00368 }
00369
00370 }
00371