diff options
Diffstat (limited to 'lib/server/makeprotocol.pl')
-rwxr-xr-x | lib/server/makeprotocol.pl | 1087 |
1 files changed, 0 insertions, 1087 deletions
diff --git a/lib/server/makeprotocol.pl b/lib/server/makeprotocol.pl deleted file mode 100755 index d84848a7..00000000 --- a/lib/server/makeprotocol.pl +++ /dev/null @@ -1,1087 +0,0 @@ -#!/usr/bin/perl -# distribution boxbackup-0.11rc2 (svn version: 2072) -# -# Copyright (c) 2003 - 2008 -# Ben Summers and contributors. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. All use of this software and associated advertising materials must -# display the following acknowledgment: -# This product includes software developed by Ben Summers. -# 4. The names of the Authors may not be used to endorse or promote -# products derived from this software without specific prior written -# permission. -# -# [Where legally impermissible the Authors do not disclaim liability for -# direct physical injury or death caused solely by defects in the software -# unless it is modified by a third party.] -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, -# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -# -# -use strict; - -use lib "../../infrastructure"; -use BoxPlatform; - -# Make protocol C++ classes from a protocol description file - -# built in type info (values are is basic type, C++ typename) -# may get stuff added to it later if protocol uses extra types -my %translate_type_info = -( - 'int64' => [1, 'int64_t'], - 'int32' => [1, 'int32_t'], - 'int16' => [1, 'int16_t'], - 'int8' => [1, 'int8_t'], - 'bool' => [1, 'bool'], - 'string' => [0, 'std::string'] -); - -# built in instructions for logging various types -# may be added to -my %log_display_types = -( - 'int64' => ['0x%llx', 'VAR'], - 'int32' => ['0x%x', 'VAR'], - 'int16' => ['0x%x', 'VAR'], - 'int8' => ['0x%x', 'VAR'], - 'bool' => ['%s', '((VAR)?"true":"false")'], - 'string' => ['%s', 'VAR.c_str()'] -); - - - -my ($type, $file) = @ARGV; - -if($type ne 'Server' && $type ne 'Client') -{ - die "Neither Server or Client is specified on command line\n"; -} - -open IN, $file or die "Can't open input file $file\n"; - -print "Making $type protocol classes from $file...\n"; - -my @extra_header_files; - -my $implement_syslog = 0; -my $implement_filelog = 0; - -# read attributes -my %attr; -while(<IN>) -{ - # get and clean line - my $l = $_; $l =~ s/#.*\Z//; $l =~ s/\A\s+//; $l =~ s/\s+\Z//; next unless $l =~ m/\S/; - - last if $l eq 'BEGIN_OBJECTS'; - - my ($k,$v) = split /\s+/,$l,2; - - if($k eq 'ClientType') - { - add_type($v) if $type eq 'Client'; - } - elsif($k eq 'ServerType') - { - add_type($v) if $type eq 'Server'; - } - elsif($k eq 'ImplementLog') - { - my ($log_if_type,$log_type) = split /\s+/,$v; - if($type eq $log_if_type) - { - if($log_type eq 'syslog') - { - $implement_syslog = 1; - } - elsif($log_type eq 'file') - { - $implement_filelog = 1; - } - else - { - printf("ERROR: Unknown log type for implementation: $log_type\n"); - exit(1); - } - } - } - elsif($k eq 'LogTypeToText') - { - my ($log_if_type,$type_name,$printf_format,$arg_template) = split /\s+/,$v; - if($type eq $log_if_type) - { - $log_display_types{$type_name} = [$printf_format,$arg_template] - } - } - else - { - $attr{$k} = $v; - } -} - -sub add_type -{ - my ($protocol_name, $cpp_name, $header_file) = split /\s+/,$_[0]; - - $translate_type_info{$protocol_name} = [0, $cpp_name]; - push @extra_header_files, $header_file; -} - -# check attributes -for(qw/Name ServerContextClass IdentString/) -{ - if(!exists $attr{$_}) - { - die "Attribute $_ is required, but not specified\n"; - } -} - -my $protocol_name = $attr{'Name'}; -my ($context_class, $context_class_inc) = split /\s+/,$attr{'ServerContextClass'}; -my $ident_string = $attr{'IdentString'}; - -my $current_cmd = ''; -my %cmd_contents; -my %cmd_attributes; -my %cmd_constants; -my %cmd_id; -my @cmd_list; - -# read in the command definitions -while(<IN>) -{ - # get and clean line - my $l = $_; $l =~ s/#.*\Z//; $l =~ s/\s+\Z//; next unless $l =~ m/\S/; - - # definitions or new command thing? - if($l =~ m/\A\s+/) - { - die "No command defined yet" if $current_cmd eq ''; - - # definition of component - $l =~ s/\A\s+//; - - my ($type,$name,$value) = split /\s+/,$l; - if($type eq 'CONSTANT') - { - push @{$cmd_constants{$current_cmd}},"$name = $value" - } - else - { - push @{$cmd_contents{$current_cmd}},$type,$name; - } - } - else - { - # new command - my ($name,$id,@attributes) = split /\s+/,$l; - $cmd_attributes{$name} = [@attributes]; - $cmd_id{$name} = int($id); - $current_cmd = $name; - push @cmd_list,$name; - } -} - -close IN; - - - -# open files -my $h_filename = 'autogen_'.$protocol_name.'Protocol'.$type.'.h'; -open CPP,'>autogen_'.$protocol_name.'Protocol'.$type.'.cpp'; -open H,">$h_filename"; - -print CPP <<__E; - -// Auto-generated file -- do not edit - -#include "Box.h" -#include "$h_filename" -#include "IOStream.h" - -__E - -if($implement_syslog) -{ - print H <<EOF; -#ifndef WIN32 -#include <syslog.h> -#endif -EOF -} - - -my $guardname = uc 'AUTOGEN_'.$protocol_name.'Protocol'.$type.'_H'; -print H <<__E; - -// Auto-generated file -- do not edit - -#ifndef $guardname -#define $guardname - -#include "Protocol.h" -#include "ProtocolObject.h" -#include "ServerException.h" - -class IOStream; - -__E - -if($implement_filelog) -{ - print H qq~#include <stdio.h>\n~; -} - -# extra headers -for(@extra_header_files) -{ - print H qq~#include "$_"\n~ -} -print H "\n"; - -if($type eq 'Server') -{ - # need utils file for the server - print H '#include "Utils.h"',"\n\n" -} - - -my $derive_objects_from = 'ProtocolObject'; -my $objects_extra_h = ''; -my $objects_extra_cpp = ''; -if($type eq 'Server') -{ - # define the context - print H "class $context_class;\n\n"; - print CPP "#include \"$context_class_inc\"\n\n"; - - # change class we derive the objects from - $derive_objects_from = $protocol_name.'ProtocolObject'; - - $objects_extra_h = <<__E; - virtual std::auto_ptr<ProtocolObject> DoCommand(${protocol_name}ProtocolServer &rProtocol, $context_class &rContext); -__E - $objects_extra_cpp = <<__E; -std::auto_ptr<ProtocolObject> ${derive_objects_from}::DoCommand(${protocol_name}ProtocolServer &rProtocol, $context_class &rContext) -{ - THROW_EXCEPTION(ConnectionException, Conn_Protocol_TriedToExecuteReplyCommand) -} -__E -} - -print CPP qq~#include "MemLeakFindOn.h"\n~; - -if($type eq 'Client' && ($implement_syslog || $implement_filelog)) -{ - # change class we derive the objects from - $derive_objects_from = $protocol_name.'ProtocolObjectCl'; -} -if($implement_syslog) -{ - $objects_extra_h .= <<__E; - virtual void LogSysLog(const char *Action) const = 0; -__E -} -if($implement_filelog) -{ - $objects_extra_h .= <<__E; - virtual void LogFile(const char *Action, FILE *file) const = 0; -__E -} - -if($derive_objects_from ne 'ProtocolObject') -{ - # output a definition for the protocol object derviced class - print H <<__E; -class ${protocol_name}ProtocolServer; - -class $derive_objects_from : public ProtocolObject -{ -public: - $derive_objects_from(); - virtual ~$derive_objects_from(); - $derive_objects_from(const $derive_objects_from &rToCopy); - -$objects_extra_h -}; -__E - - # and some cpp definitions - print CPP <<__E; -${derive_objects_from}::${derive_objects_from}() -{ -} -${derive_objects_from}::~${derive_objects_from}() -{ -} -${derive_objects_from}::${derive_objects_from}(const $derive_objects_from &rToCopy) -{ -} -$objects_extra_cpp -__E -} - - - -my $classname_base = $protocol_name.'Protocol'.$type; - -# output the classes -for my $cmd (@cmd_list) -{ - print H <<__E; -class $classname_base$cmd : public $derive_objects_from -{ -public: - $classname_base$cmd(); - $classname_base$cmd(const $classname_base$cmd &rToCopy); - ~$classname_base$cmd(); - int GetType() const; - enum - { - TypeID = $cmd_id{$cmd} - }; -__E - # constants - if(exists $cmd_constants{$cmd}) - { - print H "\tenum\n\t{\n\t\t"; - print H join(",\n\t\t",@{$cmd_constants{$cmd}}); - print H "\n\t};\n"; - } - # flags - if(obj_is_type($cmd,'EndsConversation')) - { - print H "\tbool IsConversationEnd() const;\n"; - } - if(obj_is_type($cmd,'IsError')) - { - print H "\tbool IsError(int &rTypeOut, int &rSubTypeOut) const;\n"; - } - if($type eq 'Server' && obj_is_type($cmd, 'Command')) - { - print H "\tstd::auto_ptr<ProtocolObject> DoCommand(${protocol_name}ProtocolServer &rProtocol, $context_class &rContext); // IMPLEMENT THIS\n" - } - - # want to be able to read from streams? - my $read_from_streams = (obj_is_type($cmd,'Command') && $type eq 'Server') || (obj_is_type($cmd,'Reply') && $type eq 'Client'); - my $write_to_streams = (obj_is_type($cmd,'Command') && $type eq 'Client') || (obj_is_type($cmd,'Reply') && $type eq 'Server'); - - if($read_from_streams) - { - print H "\tvoid SetPropertiesFromStreamData(Protocol &rProtocol);\n"; - - # write Get functions - for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) - { - my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - - print H "\t".translate_type_to_arg_type($ty)." Get$nm() {return m$nm;}\n"; - } - } - my $param_con_args = ''; - if($write_to_streams) - { - # extra constructor? - if($#{$cmd_contents{$cmd}} >= 0) - { - my @a; - for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) - { - my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - - push @a,translate_type_to_arg_type($ty)." $nm"; - } - $param_con_args = join(', ',@a); - print H "\t$classname_base$cmd(".$param_con_args.");\n"; - } - print H "\tvoid WritePropertiesToStreamData(Protocol &rProtocol) const;\n"; - # set functions - for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) - { - my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - - print H "\tvoid Set$nm(".translate_type_to_arg_type($ty)." $nm) {m$nm = $nm;}\n"; - } - } - - if($implement_syslog) - { - print H "\tvirtual void LogSysLog(const char *Action) const;\n"; - } - if($implement_filelog) - { - print H "\tvirtual void LogFile(const char *Action, FILE *file) const;\n"; - } - - - # write member variables and setup for cpp file - my @def_constructor_list; - my @copy_constructor_list; - my @param_constructor_list; - - print H "private:\n"; - for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) - { - my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - - print H "\t".translate_type_to_member_type($ty)." m$nm;\n"; - - my ($basic,$typename) = translate_type($ty); - if($basic) - { - push @def_constructor_list, "m$nm(0)"; - } - push @copy_constructor_list, "m$nm(rToCopy.m$nm)"; - push @param_constructor_list, "m$nm($nm)"; - } - - # finish off - print H "};\n\n"; - - # now the cpp file... - my $def_con_vars = join(",\n\t ",@def_constructor_list); - $def_con_vars = "\n\t: ".$def_con_vars if $def_con_vars ne ''; - my $copy_con_vars = join(",\n\t ",@copy_constructor_list); - $copy_con_vars = "\n\t: ".$copy_con_vars if $copy_con_vars ne ''; - my $param_con_vars = join(",\n\t ",@param_constructor_list); - $param_con_vars = "\n\t: ".$param_con_vars if $param_con_vars ne ''; - - my $class = "$classname_base$cmd".'::'; - print CPP <<__E; -$class$classname_base$cmd()$def_con_vars -{ -} -$class$classname_base$cmd(const $classname_base$cmd &rToCopy)$copy_con_vars -{ -} -$class~$classname_base$cmd() -{ -} -int ${class}GetType() const -{ - return $cmd_id{$cmd}; -} -__E - if($read_from_streams) - { - print CPP "void ${class}SetPropertiesFromStreamData(Protocol &rProtocol)\n{\n"; - for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) - { - my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - if($ty =~ m/\Avector/) - { - print CPP "\trProtocol.ReadVector(m$nm);\n"; - } - else - { - print CPP "\trProtocol.Read(m$nm);\n"; - } - } - print CPP "}\n"; - } - if($write_to_streams) - { - # implement extra constructor? - if($param_con_vars ne '') - { - print CPP "$class$classname_base$cmd($param_con_args)$param_con_vars\n{\n}\n"; - } - print CPP "void ${class}WritePropertiesToStreamData(Protocol &rProtocol) const\n{\n"; - for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) - { - my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - if($ty =~ m/\Avector/) - { - print CPP "\trProtocol.WriteVector(m$nm);\n"; - } - else - { - print CPP "\trProtocol.Write(m$nm);\n"; - } - } - print CPP "}\n"; - } - if(obj_is_type($cmd,'EndsConversation')) - { - print CPP "bool ${class}IsConversationEnd() const\n{\n\treturn true;\n}\n"; - } - if(obj_is_type($cmd,'IsError')) - { - # get parameters - my ($mem_type,$mem_subtype) = split /,/,obj_get_type_params($cmd,'IsError'); - print CPP <<__E; -bool ${class}IsError(int &rTypeOut, int &rSubTypeOut) const -{ - rTypeOut = m$mem_type; - rSubTypeOut = m$mem_subtype; - return true; -} -__E - } - - if($implement_syslog) - { - my ($log) = make_log_strings_framework($cmd); - print CPP <<__E; -void ${class}LogSysLog(const char *Action) const -{ - BOX_TRACE($log); -} -__E - } - if($implement_filelog) - { - my ($format,$args) = make_log_strings($cmd); - print CPP <<__E; -void ${class}LogFile(const char *Action, FILE *File) const -{ - ::fprintf(File,"%s $format\\n",Action$args); - ::fflush(File); -} -__E - } -} - -# finally, the protocol object itself -print H <<__E; -class $classname_base : public Protocol -{ -public: - $classname_base(IOStream &rStream); - virtual ~$classname_base(); - - std::auto_ptr<$derive_objects_from> Receive(); - void Send(const ${derive_objects_from} &rObject); -__E -if($implement_syslog) -{ - print H "\tvoid SetLogToSysLog(bool Log = false) {mLogToSysLog = Log;}\n"; -} -if($implement_filelog) -{ - print H "\tvoid SetLogToFile(FILE *File = 0) {mLogToFile = File;}\n"; -} -if($type eq 'Server') -{ - # need to put in the conversation function - print H "\tvoid DoServer($context_class &rContext);\n\n"; - # and the send vector thing - print H "\tvoid SendStreamAfterCommand(IOStream *pStream);\n\n"; -} -if($type eq 'Client') -{ - # add plain object taking query functions - my $with_params; - for my $cmd (@cmd_list) - { - if(obj_is_type($cmd,'Command')) - { - my $has_stream = obj_is_type($cmd,'StreamWithCommand'); - my $argextra = $has_stream?', IOStream &rStream':''; - my $queryextra = $has_stream?', rStream':''; - my $reply = obj_get_type_params($cmd,'Command'); - print H "\tstd::auto_ptr<$classname_base$reply> Query(const $classname_base$cmd &rQuery$argextra);\n"; - my @a; - my @na; - for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) - { - my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - push @a,translate_type_to_arg_type($ty)." $nm"; - push @na,"$nm"; - } - my $ar = join(', ',@a); - my $nar = join(', ',@na); - $nar = "($nar)" if $nar ne ''; - - $with_params .= "\tinline std::auto_ptr<$classname_base$reply> Query$cmd($ar$argextra)\n\t{\n"; - $with_params .= "\t\t$classname_base$cmd send$nar;\n"; - $with_params .= "\t\treturn Query(send$queryextra);\n"; - $with_params .= "\t}\n"; - } - } - # quick hack to correct bad argument lists for commands with zero paramters but with streams - $with_params =~ s/\(, /(/g; - print H "\n",$with_params,"\n"; -} -print H <<__E; -private: - $classname_base(const $classname_base &rToCopy); -__E -if($type eq 'Server') -{ - # need to put the streams to send vector - print H "\tstd::vector<IOStream*> mStreamsToSend;\n\tvoid DeleteStreamsToSend();\n"; -} - -if($implement_filelog || $implement_syslog) -{ - print H <<__E; - virtual void InformStreamReceiving(u_int32_t Size); - virtual void InformStreamSending(u_int32_t Size); -__E -} - -if($implement_syslog) -{ - print H "private:\n\tbool mLogToSysLog;\n"; -} -if($implement_filelog) -{ - print H "private:\n\tFILE *mLogToFile;\n"; -} -print H <<__E; - -protected: - virtual std::auto_ptr<ProtocolObject> MakeProtocolObject(int ObjType); - virtual const char *GetIdentString(); -}; - -__E - -my $construtor_extra = ''; -$construtor_extra .= ', mLogToSysLog(false)' if $implement_syslog; -$construtor_extra .= ', mLogToFile(0)' if $implement_filelog; - -my $destructor_extra = ($type eq 'Server')?"\n\tDeleteStreamsToSend();":''; - -my $prefix = $classname_base.'::'; -print CPP <<__E; -$prefix$classname_base(IOStream &rStream) - : Protocol(rStream)$construtor_extra -{ -} -$prefix~$classname_base() -{$destructor_extra -} -const char *${prefix}GetIdentString() -{ - return "$ident_string"; -} -std::auto_ptr<ProtocolObject> ${prefix}MakeProtocolObject(int ObjType) -{ - switch(ObjType) - { -__E - -# do objects within this -for my $cmd (@cmd_list) -{ - print CPP <<__E; - case $cmd_id{$cmd}: - return std::auto_ptr<ProtocolObject>(new $classname_base$cmd); - break; -__E -} - -print CPP <<__E; - default: - THROW_EXCEPTION(ConnectionException, Conn_Protocol_UnknownCommandRecieved) - } -} -__E -# write receieve and send functions -print CPP <<__E; -std::auto_ptr<$derive_objects_from> ${prefix}Receive() -{ - std::auto_ptr<${derive_objects_from}> preply((${derive_objects_from}*)(Protocol::Receive().release())); - -__E - if($implement_syslog) - { - print CPP <<__E; - if(mLogToSysLog) - { - preply->LogSysLog("Receive"); - } -__E - } - if($implement_filelog) - { - print CPP <<__E; - if(mLogToFile != 0) - { - preply->LogFile("Receive", mLogToFile); - } -__E - } -print CPP <<__E; - - return preply; -} - -void ${prefix}Send(const ${derive_objects_from} &rObject) -{ -__E - if($implement_syslog) - { - print CPP <<__E; - if(mLogToSysLog) - { - rObject.LogSysLog("Send"); - } -__E - } - if($implement_filelog) - { - print CPP <<__E; - if(mLogToFile != 0) - { - rObject.LogFile("Send", mLogToFile); - } -__E - } - -print CPP <<__E; - Protocol::Send(rObject); -} - -__E -# write server function? -if($type eq 'Server') -{ - print CPP <<__E; -void ${prefix}DoServer($context_class &rContext) -{ - // Handshake with client - Handshake(); - - // Command processing loop - bool inProgress = true; - while(inProgress) - { - // Get an object from the conversation - std::auto_ptr<${derive_objects_from}> pobj(Receive()); - -__E - if($implement_syslog) - { - print CPP <<__E; - if(mLogToSysLog) - { - pobj->LogSysLog("Receive"); - } -__E - } - if($implement_filelog) - { - print CPP <<__E; - if(mLogToFile != 0) - { - pobj->LogFile("Receive", mLogToFile); - } -__E - } - print CPP <<__E; - - // Run the command - std::auto_ptr<${derive_objects_from}> preply((${derive_objects_from}*)(pobj->DoCommand(*this, rContext).release())); - -__E - if($implement_syslog) - { - print CPP <<__E; - if(mLogToSysLog) - { - preply->LogSysLog("Send"); - } -__E - } - if($implement_filelog) - { - print CPP <<__E; - if(mLogToFile != 0) - { - preply->LogFile("Send", mLogToFile); - } -__E - } - print CPP <<__E; - - // Send the reply - Send(*(preply.get())); - - // Send any streams - for(unsigned int s = 0; s < mStreamsToSend.size(); s++) - { - // Send the streams - SendStream(*mStreamsToSend[s]); - } - // Delete these streams - DeleteStreamsToSend(); - - // Does this end the conversation? - if(pobj->IsConversationEnd()) - { - inProgress = false; - } - } -} - -void ${prefix}SendStreamAfterCommand(IOStream *pStream) -{ - ASSERT(pStream != NULL); - mStreamsToSend.push_back(pStream); -} - -void ${prefix}DeleteStreamsToSend() -{ - for(std::vector<IOStream*>::iterator i(mStreamsToSend.begin()); i != mStreamsToSend.end(); ++i) - { - delete (*i); - } - mStreamsToSend.clear(); -} - -__E -} - -# write logging functions? -if($implement_filelog || $implement_syslog) -{ - my ($fR,$fS); - - if($implement_syslog) - { - $fR .= qq~\tif(mLogToSysLog) { ::syslog(LOG_INFO, (Size==Protocol::ProtocolStream_SizeUncertain)?"Receiving stream, size uncertain":"Receiving stream, size %d", Size); }\n~; - $fS .= qq~\tif(mLogToSysLog) { ::syslog(LOG_INFO, (Size==Protocol::ProtocolStream_SizeUncertain)?"Sending stream, size uncertain":"Sending stream, size %d", Size); }\n~; - } - if($implement_filelog) - { - $fR .= qq~\tif(mLogToFile) { ::fprintf(mLogToFile, (Size==Protocol::ProtocolStream_SizeUncertain)?"Receiving stream, size uncertain\\n":"Receiving stream, size %d\\n", Size); ::fflush(mLogToFile); }\n~; - $fS .= qq~\tif(mLogToFile) { ::fprintf(mLogToFile, (Size==Protocol::ProtocolStream_SizeUncertain)?"Sending stream, size uncertain\\n":"Sending stream, size %d\\n", Size); ::fflush(mLogToFile); }\n~; - } - - print CPP <<__E; - -void ${prefix}InformStreamReceiving(u_int32_t Size) -{ -$fR} - -void ${prefix}InformStreamSending(u_int32_t Size) -{ -$fS} - -__E -} - - -# write client Query functions? -if($type eq 'Client') -{ - for my $cmd (@cmd_list) - { - if(obj_is_type($cmd,'Command')) - { - my $reply = obj_get_type_params($cmd,'Command'); - my $reply_id = $cmd_id{$reply}; - my $has_stream = obj_is_type($cmd,'StreamWithCommand'); - my $argextra = $has_stream?', IOStream &rStream':''; - my $send_stream_extra = ''; - if($has_stream) - { - $send_stream_extra = <<__E; - - // Send stream after the command - SendStream(rStream); -__E - } - print CPP <<__E; -std::auto_ptr<$classname_base$reply> ${classname_base}::Query(const $classname_base$cmd &rQuery$argextra) -{ - // Send query - Send(rQuery); - $send_stream_extra - // Wait for the reply - std::auto_ptr<${derive_objects_from}> preply(Receive().release()); - - if(preply->GetType() == $reply_id) - { - // Correct response - return std::auto_ptr<$classname_base$reply>(($classname_base$reply*)preply.release()); - } - else - { - // Set protocol error - int type, subType; - if(preply->IsError(type, subType)) - { - SetError(type, subType); - TRACE2("Protocol: Error received %d/%d\\n", type, subType); - } - else - { - SetError(Protocol::UnknownError, Protocol::UnknownError); - } - - // Throw an exception - THROW_EXCEPTION(ConnectionException, Conn_Protocol_UnexpectedReply) - } -} -__E - } - } -} - - - -print H <<__E; -#endif // $guardname - -__E - -# close files -close H; -close CPP; - - -sub obj_is_type -{ - my ($c,$ty) = @_; - for(@{$cmd_attributes{$c}}) - { - return 1 if $_ =~ m/\A$ty/; - } - - return 0; -} - -sub obj_get_type_params -{ - my ($c,$ty) = @_; - for(@{$cmd_attributes{$c}}) - { - return $1 if $_ =~ m/\A$ty\((.+?)\)\Z/; - } - die "Can't find attribute $ty\n" -} - -# returns (is basic type, typename) -sub translate_type -{ - my $ty = $_[0]; - - if($ty =~ m/\Avector\<(.+?)\>\Z/) - { - my $v_type = $1; - my (undef,$v_ty) = translate_type($v_type); - return (0, 'std::vector<'.$v_ty.'>') - } - else - { - if(!exists $translate_type_info{$ty}) - { - die "Don't know about type name $ty\n"; - } - return @{$translate_type_info{$ty}} - } -} - -sub translate_type_to_arg_type -{ - my ($basic,$typename) = translate_type(@_); - return $basic?$typename:'const '.$typename.'&' -} - -sub translate_type_to_member_type -{ - my ($basic,$typename) = translate_type(@_); - return $typename -} - -sub make_log_strings -{ - my ($cmd) = @_; - - my @str; - my @arg; - for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) - { - my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - - if(exists $log_display_types{$ty}) - { - # need to translate it - my ($format,$arg) = @{$log_display_types{$ty}}; - $arg =~ s/VAR/m$nm/g; - - if ($format eq "0x%llx" and $target_windows) - { - $format = "0x%I64x"; - $arg = "(uint64_t)$arg"; - } - - push @str,$format; - push @arg,$arg; - } - else - { - # is opaque - push @str,'OPAQUE'; - } - } - return ($cmd.'('.join(',',@str).')', join(',','',@arg)); -} - -sub make_log_strings_framework -{ - my ($cmd) = @_; - - my @args; - - for(my $x = 0; $x < $#{$cmd_contents{$cmd}}; $x+=2) - { - my ($ty,$nm) = (${$cmd_contents{$cmd}}[$x], ${$cmd_contents{$cmd}}[$x+1]); - - if(exists $log_display_types{$ty}) - { - # need to translate it - my ($format,$arg) = @{$log_display_types{$ty}}; - $arg =~ s/VAR/m$nm/g; - - if ($format =~ m'x$') - { - $arg = "std::hex << std::showbase " . - "<< $arg << std::dec"; - } - - push @args, $arg; - } - else - { - # is opaque - push @args, '"OPAQUE"'; - } - } - - my $log_cmd = "Action << \" $cmd(\" "; - foreach my $arg (@args) - { - $arg = "<< $arg "; - } - $log_cmd .= join('<< "," ',@args); - $log_cmd .= '<< ")"'; - return $log_cmd; -} - - |