debian: added giffgaff chatscripts
[barry.git] / src / r_dbdb.cc
blob0240e770bdbb756efd33e4b74615c78d0d58dd41
1 ///
2 /// \file r_dbdb.cc
3 /// DatabaseDatabase record parser class
4 ///
6 /*
7 Copyright (C) 2005-2013, 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 "i18n.h"
23 #include "record.h"
24 #include "record-internal.h"
25 #include "data.h"
26 #include "protocol.h"
27 #include "debug.h"
28 #include <algorithm>
30 using namespace std;
31 using namespace Barry::Protocol;
33 namespace Barry {
35 ///////////////////////////////////////////////////////////////////////////////
36 // DatabaseDatabase class
38 DatabaseDatabase::DatabaseDatabase()
42 DatabaseDatabase::~DatabaseDatabase()
46 template <class RecordType, class FieldType>
47 void DatabaseDatabase::ParseRec(const RecordType &rec, const unsigned char *end)
51 template <class FieldType>
52 const unsigned char* DatabaseDatabase::ParseField(const unsigned char *begin,
53 const unsigned char *end)
55 // check if there is enough data for a header
56 const unsigned char *headend = begin + sizeof(FieldType);
57 if( headend > end )
58 return headend;
60 // get our header
61 const FieldType *field = (const FieldType *) begin;
63 // advance and check size
64 begin += sizeof(FieldType) - sizeof(field->name) + ConvertHtoB(field->nameSize);
65 if( begin > end ) // if begin==end, we are ok
66 return begin;
68 if( !ConvertHtoB(field->nameSize) ) // if field has no size, something's up
69 return begin;
71 Database db;
72 db.Number = ConvertHtoB(field->dbNumber);
73 db.RecordCount = ConvertHtoB(field->dbRecordCount);
74 db.Name.assign((const char *)field->name, ConvertHtoB(field->nameSize) - 1);
75 Databases.push_back(db);
76 return begin;
79 void DatabaseDatabase::Parse(const Data &data)
81 // check size to make sure we have up to the DBAccess operation byte
82 if( data.GetSize() < (SB_PACKET_DBACCESS_HEADER_SIZE + 1) )
83 return;
85 MAKE_PACKET(pack, data);
86 const unsigned char *begin = 0;
87 const unsigned char *end = data.GetData() + data.GetSize();
89 switch( pack->u.db.u.response.operation )
91 case SB_DBOP_GET_DBDB:
92 // using the new protocol
93 if( data.GetSize() > SB_PACKET_DBDB_HEADER_SIZE ) {
94 begin = (const unsigned char *)
95 &pack->u.db.u.response.u.dbdb.field[0];
97 // this while check is ok, since ParseField checks
98 // for header size
99 while( begin < end )
100 begin = ParseField<DBDBField>(begin, end);
102 else
103 dout("DatabaseDatabase: not enough data for parsing");
104 break;
106 case SB_DBOP_OLD_GET_DBDB:
107 // using the old protocol
108 if( data.GetSize() > SB_PACKET_OLD_DBDB_HEADER_SIZE ) {
109 begin = (const unsigned char *)
110 &pack->u.db.u.response.u.old_dbdb.field[0];
112 // this while check is ok, since ParseField checks
113 // for header size
114 while( begin < end )
115 begin = ParseField<OldDBDBField>(begin, end);
117 else
118 dout(_("DatabaseDatabase: not enough data for parsing"));
119 break;
121 default:
122 // unknown protocol
123 dout(_("Unknown protocol"));
124 break;
130 void DatabaseDatabase::Clear()
132 Databases.clear();
135 namespace {
136 bool NameSort(const DatabaseDatabase::Database &one,
137 const DatabaseDatabase::Database &two)
139 return one.Name < two.Name;
142 bool CountSort(const DatabaseDatabase::Database &one,
143 const DatabaseDatabase::Database &two)
145 return one.RecordCount < two.RecordCount;
149 void DatabaseDatabase::SortByName()
151 std::sort(Databases.begin(), Databases.end(), NameSort);
154 void DatabaseDatabase::SortByRecordCount()
156 std::sort(Databases.begin(), Databases.end(), CountSort);
159 unsigned int DatabaseDatabase::GetTotalRecordCount() const
161 unsigned int sum = 0;
163 DatabaseArrayType::const_iterator b = Databases.begin();
164 for( ; b != Databases.end(); ++b ) {
165 sum += b->RecordCount;
167 return sum;
170 bool DatabaseDatabase::GetDBNumber(const std::string &name,
171 unsigned int &number) const
173 DatabaseArrayType::const_iterator b = Databases.begin();
174 for( ; b != Databases.end(); ++b )
175 if( b->Name == name ) {
176 number = b->Number;
177 return true;
179 return false;
182 bool DatabaseDatabase::GetDBName(unsigned int number,
183 std::string &name) const
185 DatabaseArrayType::const_iterator b = Databases.begin();
186 for( ; b != Databases.end(); ++b )
187 if( b->Number == number ) {
188 name = b->Name;
189 return true;
191 return false;
194 void DatabaseDatabase::Dump(std::ostream &os) const
196 DatabaseArrayType::const_iterator b = Databases.begin();
197 os << _("Database database:\n");
198 for( ; b != Databases.end(); b++ ) {
199 os << _(" Database: ") << "0x" << setbase(16) << b->Number
200 << " '" << b->Name << "' (" << _("records: ")
201 << setbase(10) << b->RecordCount << ")\n";
205 } // namespace Barry