3 /// DatabaseDatabase record parser class
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.
24 #include "record-internal.h"
31 using namespace Barry::Protocol
;
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
);
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
68 if( !ConvertHtoB(field
->nameSize
) ) // if field has no size, something's up
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
);
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) )
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
100 begin
= ParseField
<DBDBField
>(begin
, end
);
103 dout("DatabaseDatabase: not enough data for parsing");
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
115 begin
= ParseField
<OldDBDBField
>(begin
, end
);
118 dout(_("DatabaseDatabase: not enough data for parsing"));
123 dout(_("Unknown protocol"));
130 void DatabaseDatabase::Clear()
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
;
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
) {
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
) {
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";