lib: show offset and rectype in HexDumpParser
[barry.git] / src / r_dbdb.cc
blob6ed4f924d7a1ac025a19e7c5c7c5b99e21c3620b
1 ///
2 /// \file r_dbdb.cc
3 /// DatabaseDatabase record parser class
4 ///
6 /*
7 Copyright (C) 2005-2010, Net Direct Inc. (http://www.netdirect.ca/)
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
22 #include "record.h"
23 #include "record-internal.h"
24 #include "data.h"
25 #include "protocol.h"
26 #include "debug.h"
28 using namespace std;
29 using namespace Barry::Protocol;
31 namespace Barry {
33 ///////////////////////////////////////////////////////////////////////////////
34 // DatabaseDatabase class
36 DatabaseDatabase::DatabaseDatabase()
40 DatabaseDatabase::~DatabaseDatabase()
44 template <class RecordType, class FieldType>
45 void DatabaseDatabase::ParseRec(const RecordType &rec, const unsigned char *end)
49 template <class FieldType>
50 const unsigned char* DatabaseDatabase::ParseField(const unsigned char *begin,
51 const unsigned char *end)
53 // check if there is enough data for a header
54 const unsigned char *headend = begin + sizeof(FieldType);
55 if( headend > end )
56 return headend;
58 // get our header
59 const FieldType *field = (const FieldType *) begin;
61 // advance and check size
62 begin += sizeof(FieldType) - sizeof(field->name) + ConvertHtoB(field->nameSize);
63 if( begin > end ) // if begin==end, we are ok
64 return begin;
66 if( !ConvertHtoB(field->nameSize) ) // if field has no size, something's up
67 return begin;
69 Database db;
70 db.Number = ConvertHtoB(field->dbNumber);
71 db.RecordCount = ConvertHtoB(field->dbRecordCount);
72 db.Name.assign((const char *)field->name, ConvertHtoB(field->nameSize) - 1);
73 Databases.push_back(db);
74 return begin;
77 void DatabaseDatabase::Parse(const Data &data)
79 // check size to make sure we have up to the DBAccess operation byte
80 if( data.GetSize() < (SB_PACKET_DBACCESS_HEADER_SIZE + 1) )
81 return;
83 MAKE_PACKET(pack, data);
84 const unsigned char *begin = 0;
85 const unsigned char *end = data.GetData() + data.GetSize();
87 switch( pack->u.db.u.response.operation )
89 case SB_DBOP_GET_DBDB:
90 // using the new protocol
91 if( data.GetSize() > SB_PACKET_DBDB_HEADER_SIZE ) {
92 begin = (const unsigned char *)
93 &pack->u.db.u.response.u.dbdb.field[0];
95 // this while check is ok, since ParseField checks
96 // for header size
97 while( begin < end )
98 begin = ParseField<DBDBField>(begin, end);
100 else
101 dout("DatabaseDatabase: not enough data for parsing");
102 break;
104 case SB_DBOP_OLD_GET_DBDB:
105 // using the old protocol
106 if( data.GetSize() > SB_PACKET_OLD_DBDB_HEADER_SIZE ) {
107 begin = (const unsigned char *)
108 &pack->u.db.u.response.u.old_dbdb.field[0];
110 // this while check is ok, since ParseField checks
111 // for header size
112 while( begin < end )
113 begin = ParseField<OldDBDBField>(begin, end);
115 else
116 dout("DatabaseDatabase: not enough data for parsing");
117 break;
119 default:
120 // unknown protocol
121 dout("Unknown protocol");
122 break;
128 void DatabaseDatabase::Clear()
130 Databases.clear();
133 bool DatabaseDatabase::GetDBNumber(const std::string &name,
134 unsigned int &number) const
136 DatabaseArrayType::const_iterator b = Databases.begin();
137 for( ; b != Databases.end(); b++ )
138 if( b->Name == name ) {
139 number = b->Number;
140 return true;
142 return false;
145 bool DatabaseDatabase::GetDBName(unsigned int number,
146 std::string &name) const
148 DatabaseArrayType::const_iterator b = Databases.begin();
149 for( ; b != Databases.end(); b++ )
150 if( b->Number == number ) {
151 name = b->Name;
152 return true;
154 return false;
157 void DatabaseDatabase::Dump(std::ostream &os) const
159 DatabaseArrayType::const_iterator b = Databases.begin();
160 os << "Database database:\n";
161 for( ; b != Databases.end(); b++ ) {
162 os << " Database: 0x" << setbase(16) << b->Number
163 << " '" << b->Name << "' (records: "
164 << setbase(10) << b->RecordCount << ")\n";
168 } // namespace Barry