r_command.cc

Go to the documentation of this file.
00001 ///
00002 /// \file       r_command.cc
00003 ///             Internal implementation of CommandTable parser class
00004 ///
00005 
00006 /*
00007     Copyright (C) 2005-2012, Net Direct Inc. (http://www.netdirect.ca/)
00008 
00009     This program is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     This program is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018     See the GNU General Public License in the COPYING file at the
00019     root directory of this project for more details.
00020 */
00021 
00022 #include "record.h"
00023 #include "record-internal.h"
00024 #include "data.h"
00025 #include <sstream>
00026 #include <iomanip>
00027 
00028 using namespace std;
00029 using namespace Barry::Protocol;
00030 
00031 namespace Barry {
00032 
00033 ///////////////////////////////////////////////////////////////////////////////
00034 // CommandTable class
00035 
00036 CommandTable::CommandTable()
00037 {
00038 }
00039 
00040 CommandTable::~CommandTable()
00041 {
00042 }
00043 
00044 const unsigned char* CommandTable::ParseField(const unsigned char *begin,
00045                                               const unsigned char *end)
00046 {
00047         // check if there is enough data for a header
00048         const unsigned char *headend = begin + sizeof(CommandTableField);
00049         if( headend > end )
00050                 return headend;
00051 
00052         const CommandTableField *field = (const CommandTableField *) begin;
00053 
00054         // advance and check size
00055         begin += COMMAND_FIELD_HEADER_SIZE + field->size;       // size is byte
00056         if( begin > end )               // if begin==end, we are ok
00057                 return begin;
00058 
00059         if( !field->size )              // if field has no size, something's up
00060                 return begin;
00061 
00062         Command command;
00063         command.Code = field->code;
00064         command.Name.assign((const char *)field->name, field->size);
00065         Commands.push_back(command);
00066         return begin;
00067 }
00068 
00069 void CommandTable::Parse(const Data &data, size_t offset)
00070 {
00071         if( offset >= data.GetSize() )
00072                 return;
00073 
00074         const unsigned char *begin = data.GetData() + offset;
00075         const unsigned char *end = data.GetData() + data.GetSize();
00076 
00077         while( begin < end )
00078                 begin = ParseField(begin, end);
00079 }
00080 
00081 void CommandTable::Clear()
00082 {
00083         Commands.clear();
00084 }
00085 
00086 unsigned int CommandTable::GetCommand(const std::string &name) const
00087 {
00088         CommandArrayType::const_iterator b = Commands.begin();
00089         for( ; b != Commands.end(); b++ )
00090                 if( b->Name == name )
00091                         return b->Code;
00092         return 0;
00093 }
00094 
00095 void CommandTable::Dump(std::ostream &os) const
00096 {
00097         CommandArrayType::const_iterator b = Commands.begin();
00098         os << "Command table:\n";
00099         for( ; b != Commands.end(); b++ ) {
00100                 os << "    Command: 0x" << setbase(16) << b->Code
00101                    << " '" << b->Name << "'\n";
00102         }
00103 }
00104 
00105 
00106 } // namespace Barry
00107