desktop/debian: moved bsyncjail to pkglibexecdir
[barry/progweb.git] / src / r_dbdb.cc
blob1c2a1faab4becab7dc1258c387490c01495f7f39
1 ///
2 /// \file r_dbdb.cc
3 /// DatabaseDatabase record parser class
4 ///
6 /*
7 Copyright (C) 2005-2012, 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"
27 #include <algorithm>
29 using namespace std;
30 using namespace Barry::Protocol;
32 namespace Barry {
34 ///////////////////////////////////////////////////////////////////////////////
35 // DatabaseDatabase class
37 DatabaseDatabase::DatabaseDatabase()
41 DatabaseDatabase::~DatabaseDatabase()
45 template <class RecordType, class FieldType>
46 void DatabaseDatabase::ParseRec(const RecordType &rec, const unsigned char *end)
50 template <class FieldType>
51 const unsigned char* DatabaseDatabase::ParseField(const unsigned char *begin,
52 const unsigned char *end)
54 // check if there is enough data for a header
55 const unsigned char *headend = begin + sizeof(FieldType);
56 if( headend > end )
57 return headend;
59 // get our header
60 const FieldType *field = (const FieldType *) begin;
62 // advance and check size
63 begin += sizeof(FieldType) - sizeof(field->name) + ConvertHtoB(field->nameSize);
64 if( begin > end ) // if begin==end, we are ok
65 return begin;
67 if( !ConvertHtoB(field->nameSize) ) // if field has no size, something's up
68 return begin;
70 Database db;
71 db.Number = ConvertHtoB(field->dbNumber);
72 db.RecordCount = ConvertHtoB(field->dbRecordCount);
73 db.Name.assign((const char *)field->name, ConvertHtoB(field->nameSize) - 1);
74 Databases.push_back(db);
75 return begin;
78 void DatabaseDatabase::Parse(const Data &data)
80 // check size to make sure we have up to the DBAccess operation byte
81 if( data.GetSize() < (SB_PACKET_DBACCESS_HEADER_SIZE + 1) )
82 return;
84 MAKE_PACKET(pack, data);
85 const unsigned char *begin = 0;
86 const unsigned char *end = data.GetData() + data.GetSize();
88 switch( pack->u.db.u.response.operation )
90 case SB_DBOP_GET_DBDB:
91 // using the new protocol
92 if( data.GetSize() > SB_PACKET_DBDB_HEADER_SIZE ) {
93 begin = (const unsigned char *)
94 &pack->u.db.u.response.u.dbdb.field[0];
96 // this while check is ok, since ParseField checks
97 // for header size
98 while( begin < end )
99 begin = ParseField<DBDBField>(begin, end);
101 else
102 dout("DatabaseDatabase: not enough data for parsing");
103 break;
105 case SB_DBOP_OLD_GET_DBDB:
106 // using the old protocol
107 if( data.GetSize() > SB_PACKET_OLD_DBDB_HEADER_SIZE ) {
108 begin = (const unsigned char *)
109 &pack->u.db.u.response.u.old_dbdb.field[0];
111 // this while check is ok, since ParseField checks
112 // for header size
113 while( begin < end )
114 begin = ParseField<OldDBDBField>(begin, end);
116 else
117 dout("DatabaseDatabase: not enough data for parsing");
118 break;
120 default:
121 // unknown protocol
122 dout("Unknown protocol");
123 break;
129 void DatabaseDatabase::Clear()
131 Databases.clear();
134 namespace {
135 bool NameSort(const DatabaseDatabase::Database &one,
136 const DatabaseDatabase::Database &two)
138 return one.Name < two.Name;
141 bool CountSort(const DatabaseDatabase::Database &one,
142 const DatabaseDatabase::Database &two)
144 return one.RecordCount < two.RecordCount;
148 void DatabaseDatabase::SortByName()
150 std::sort(Databases.begin(), Databases.end(), NameSort);
153 void DatabaseDatabase::SortByRecordCount()
155 std::sort(Databases.begin(), Databases.end(), CountSort);
158 unsigned int DatabaseDatabase::GetTotalRecordCount() const
160 unsigned int sum = 0;
162 DatabaseArrayType::const_iterator b = Databases.begin();
163 for( ; b != Databases.end(); ++b ) {
164 sum += b->RecordCount;
166 return sum;
169 bool DatabaseDatabase::GetDBNumber(const std::string &name,
170 unsigned int &number) const
172 DatabaseArrayType::const_iterator b = Databases.begin();
173 for( ; b != Databases.end(); ++b )
174 if( b->Name == name ) {
175 number = b->Number;
176 return true;
178 return false;
181 bool DatabaseDatabase::GetDBName(unsigned int number,
182 std::string &name) const
184 DatabaseArrayType::const_iterator b = Databases.begin();
185 for( ; b != Databases.end(); ++b )
186 if( b->Number == number ) {
187 name = b->Name;
188 return true;
190 return false;
193 void DatabaseDatabase::Dump(std::ostream &os) const
195 DatabaseArrayType::const_iterator b = Databases.begin();
196 os << "Database database:\n";
197 for( ; b != Databases.end(); b++ ) {
198 os << " Database: 0x" << setbase(16) << b->Number
199 << " '" << b->Name << "' (records: "
200 << setbase(10) << b->RecordCount << ")\n";
204 } // namespace Barry