# 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-2011, 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