GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
###########################################################################
##
#W client.g The SCSCP package Alexander Konovalov
#W Steve Linton
##
###########################################################################
###########################################################################
#
# PingSCSCPservice( server, port )
#
InstallGlobalFunction( PingSCSCPservice,
function( server, port )
local stream, initmessage, rt;
if IN_SCSCP_TRACING_MODE then SCSCPTraceSendMessage( port ); fi;
stream := InputOutputTCPStream( server, port );
if stream <> fail then
initmessage := ReadLine( stream );
Info( InfoSCSCP, 1, "Got connection initiation message" );
CloseStream(stream);
return true;
else
return fail;
fi;
end);
###########################################################################
#
# PingStatistic( server, port, nr )
#
InstallGlobalFunction( PingStatistic,
function( server, port, nr )
local stream, initmessage, i, rt, rt1, rt2, res, t,
nr_good, nr_lost, min_time, max_time;
nr_good := 0;
nr_lost := 0;
rt:=0;
max_time := 0;
min_time := infinity;
for i in [ 1 .. nr ] do
rt1:=Runtime();
stream := InputOutputTCPStream( server, port );
if stream <> fail then
initmessage := ReadLine( stream );
Info( InfoSCSCP, 1, "Got connection initiation message nr ", i );
rt2:=Runtime();
t:=rt2-rt1;
CloseStream(stream);
res := true;
else
res := false;
fi;
if res then
nr_good := nr_good + 1;
rt := rt + t;
if t < min_time then
min_time := t;
elif t > max_time then
max_time := t;
fi;
else
nr_lost := nr_lost + 1;
fi;
od;
Print( nr, " packets transmitted, ",
nr_good, " received, ",
100*(nr_lost/nr), "% packet loss, time ", rt , "ms\n" );
if nr_good > 0 then
Print( "min/avg/max = ", [ min_time, rt/nr_good, max_time], "\n" );
fi;
end);
###########################################################################
#
# StartSCSCPsession( stream )
#
InstallGlobalFunction( StartSCSCPsession,
function( stream )
local initmessage, session_id, pos1, pos2, server_scscp_version, suggested_versions;
initmessage := ReadLine( stream );
NormalizeWhitespace( initmessage );
Info( InfoSCSCP, 1, "Got connection initiation message" );
Info( InfoSCSCP, 2, initmessage );
session_id := initmessage{ [ PositionSublist(initmessage,"service_id=")+12 ..
PositionSublist(initmessage,"\" scscp_versions")-1 ] };
server_scscp_version:=initmessage{ [ PositionSublist(initmessage,"scscp_versions=")+16 ..
PositionSublist(initmessage,"\" ?>")-1 ] };
server_scscp_version := SplitString( server_scscp_version, " " );
if not SCSCP_VERSION in server_scscp_version then
# we select the highest compatible version of the protocol or insist on our version
suggested_versions := Intersection( server_scscp_version, SCSCP_COMPATIBLE_VERSIONS );
if Length( suggested_versions ) > 0 then
SCSCP_VERSION := Maximum( suggested_versions );
fi;
fi;
Info(InfoSCSCP, 1, "Requesting version ", SCSCP_VERSION, " from the server ...");
WriteLine( stream, Concatenation( "<?scscp version=\"", SCSCP_VERSION, "\" ?>" ) );
server_scscp_version := ReadLine( stream );
pos1 := PositionNthOccurrence(server_scscp_version,'\"',1);
pos2 := PositionNthOccurrence(server_scscp_version,'\"',2);
if pos1=fail or pos2=fail then
CloseStream( stream );
Error( "Incompatible protocol versions, the server requires ", server_scscp_version );
else
server_scscp_version := server_scscp_version{[ pos1+1 .. pos2-1 ]};
if server_scscp_version <> SCSCP_VERSION then
CloseStream( stream );
Error("Incompatible protocol versions, the server requires ", server_scscp_version );
else
Info(InfoSCSCP, 1, "Server confirmed version ", SCSCP_VERSION, " to the client ...");
return session_id;
fi;
fi;
end);
###########################################################################
#
# EvaluateBySCSCP( command, listargs, <connection | server, port> :
# output:=object/coookie/nothing/tree,
# cd:="cdname", debuglevel:=N );
#
# Options object/coookie/nothing/tree are incompatible.
#
# For object/coookie/nothing see definions in the SCSCP specification.
#
# Option output:="tree" is used when it is necessary to suppress evaluation
# of the XML tree representing the OpenMath object (for example, to be used
# with "get_allowed_heads").
#
# The last option "cd" is used to specify the name of the OpenMath content
# dictionary when it is different from the transient CD used by default.
#
InstallGlobalFunction( EvaluateBySCSCP,
function( arg )
local output_option, debug_option, opt, cdname, process, result;
if ValueOption("output") <> fail then
output_option := ValueOption("output");
else
output_option := "object";
fi;
if not output_option in
[ "object", "cookie", "nothing", "tree", "deferred" ] then
Error( "output must be one of ",
[ "object", "cookie", "nothing", "tree", "deferred" ], "\n" );
fi;
if ValueOption("cd") <> fail then
cdname := ValueOption("cd");
else
cdname := "";
fi;
if ValueOption("debuglevel") <> fail then
debug_option := ValueOption("debuglevel");
else
debug_option := 0;
fi;
if Length(arg)=3 then
process := NewProcess( arg[1], arg[2], arg[3] : output := output_option,
cd:=cdname, debuglevel := debug_option );
elif Length(arg)=4 then
process := NewProcess( arg[1], arg[2], arg[3], arg[4] : output := output_option,
cd:=cdname, debuglevel := debug_option );
else
Error("EvaluateBySCSCP : wrong number of arguments\n");
fi;
Info( InfoSCSCP, 1, "Waiting for reply ...");
if output_option = "tree" then
result := CompleteProcess( process : output:="tree" );
else
result := CompleteProcess( process );
fi;
return result;
end);
###########################################################################
##
#E
##