1###########################################################################
2##
3#W client.g                The SCSCP package            Alexander Konovalov
4#W                                                             Steve Linton
5##
6###########################################################################
7
8
9###########################################################################
10#
11# PingSCSCPservice( server, port )
12#
13InstallGlobalFunction( PingSCSCPservice,
14function( server, port )
15local stream, initmessage, rt;
16if IN_SCSCP_TRACING_MODE then SCSCPTraceSendMessage( port ); fi;
17stream := InputOutputTCPStream( server, port );
18if stream <> fail then
19  initmessage := ReadLine( stream );
20  Info( InfoSCSCP, 1, "Got connection initiation message" );
21  CloseStream(stream);
22  return true;
23else
24  return fail;
25fi;
26end);
27
28
29###########################################################################
30#
31# PingStatistic( server, port, nr )
32#
33InstallGlobalFunction( PingStatistic,
34function( server, port, nr )
35local stream, initmessage, i, rt, rt1, rt2, res, t,
36      nr_good, nr_lost, min_time, max_time;
37nr_good := 0;
38nr_lost := 0;
39rt:=0;
40max_time := 0;
41min_time := infinity;
42for i in [ 1 .. nr ] do
43  rt1:=Runtime();
44  stream := InputOutputTCPStream( server, port );
45  if stream <> fail then
46    initmessage := ReadLine( stream );
47    Info( InfoSCSCP, 1, "Got connection initiation message nr ", i );
48    rt2:=Runtime();
49    t:=rt2-rt1;
50    CloseStream(stream);
51    res := true;
52  else
53    res := false;
54  fi;
55  if res then
56    nr_good := nr_good + 1;
57    rt := rt + t;
58    if t < min_time then
59      min_time := t;
60    elif t > max_time then
61      max_time := t;
62    fi;
63  else
64    nr_lost := nr_lost + 1;
65  fi;
66od;
67Print( nr, " packets transmitted, ",
68       nr_good, " received, ",
69       100*(nr_lost/nr), "% packet loss, time ", rt , "ms\n" );
70if nr_good > 0 then
71       Print( "min/avg/max = ", [ min_time, rt/nr_good, max_time], "\n" );
72fi;
73end);
74
75
76###########################################################################
77#
78# StartSCSCPsession( stream )
79#
80InstallGlobalFunction( StartSCSCPsession,
81function( stream )
82local initmessage, session_id, pos1, pos2, server_scscp_version, suggested_versions;
83initmessage := ReadLine( stream );
84NormalizeWhitespace( initmessage );
85Info( InfoSCSCP, 1, "Got connection initiation message" );
86Info( InfoSCSCP, 2, initmessage );
87session_id := initmessage{ [ PositionSublist(initmessage,"service_id=")+12 ..
88                             PositionSublist(initmessage,"\" scscp_versions")-1 ] };
89server_scscp_version:=initmessage{ [ PositionSublist(initmessage,"scscp_versions=")+16 ..
90                                     PositionSublist(initmessage,"\" ?>")-1 ] };
91server_scscp_version := SplitString( server_scscp_version, " " );
92if not SCSCP_VERSION in server_scscp_version then
93  # we select the highest compatible version of the protocol or insist on our version
94  suggested_versions := Intersection( server_scscp_version, SCSCP_COMPATIBLE_VERSIONS );
95  if Length( suggested_versions ) > 0 then
96    SCSCP_VERSION := Maximum( suggested_versions );
97  fi;
98fi;
99Info(InfoSCSCP, 1, "Requesting version ", SCSCP_VERSION, " from the server ...");
100WriteLine( stream, Concatenation( "<?scscp version=\"", SCSCP_VERSION, "\" ?>" ) );
101server_scscp_version := ReadLine( stream );
102pos1 := PositionNthOccurrence(server_scscp_version,'\"',1);
103pos2 := PositionNthOccurrence(server_scscp_version,'\"',2);
104if pos1=fail or pos2=fail then
105  CloseStream( stream );
106  Error( "Incompatible protocol versions, the server requires ", server_scscp_version );
107else
108  server_scscp_version := server_scscp_version{[ pos1+1 .. pos2-1 ]};
109  if server_scscp_version <> SCSCP_VERSION then
110    CloseStream( stream );
111    Error("Incompatible protocol versions, the server requires ", server_scscp_version );
112  else
113    Info(InfoSCSCP, 1, "Server confirmed version ", SCSCP_VERSION, " to the client ...");
114    return session_id;
115  fi;
116fi;
117end);
118
119
120###########################################################################
121#
122# EvaluateBySCSCP( command, listargs, <connection | server, port> :
123#                  output:=object/coookie/nothing/tree,
124#                  cd:="cdname", debuglevel:=N );
125#
126# Options object/coookie/nothing/tree are incompatible.
127#
128# For object/coookie/nothing see definions in the SCSCP specification.
129#
130# Option output:="tree" is used when it is necessary to suppress evaluation
131# of the XML tree representing the OpenMath object (for example, to be used
132# with "get_allowed_heads").
133#
134# The last option "cd" is used to specify the name of the OpenMath content
135# dictionary when it is different from the transient CD used by default.
136#
137InstallGlobalFunction( EvaluateBySCSCP,
138function( arg )
139
140local output_option, debug_option, opt, cdname, process, result;
141
142if ValueOption("output") <> fail then
143  output_option := ValueOption("output");
144else
145  output_option := "object";
146fi;
147
148if not output_option in
149           [ "object", "cookie", "nothing", "tree", "deferred" ] then
150	Error( "output must be one of ",
151	       [ "object", "cookie", "nothing", "tree", "deferred" ], "\n" );
152fi;
153
154if ValueOption("cd") <> fail then
155  cdname := ValueOption("cd");
156else
157  cdname := "";
158fi;
159
160if ValueOption("debuglevel") <> fail then
161  debug_option := ValueOption("debuglevel");
162else
163  debug_option := 0;
164fi;
165
166if Length(arg)=3 then
167    process := NewProcess( arg[1], arg[2], arg[3] : output := output_option,
168                                    cd:=cdname, debuglevel := debug_option );
169elif Length(arg)=4 then
170    process := NewProcess( arg[1], arg[2], arg[3], arg[4] : output := output_option,
171                                    cd:=cdname, debuglevel := debug_option );
172else
173    Error("EvaluateBySCSCP : wrong number of arguments\n");
174fi;
175
176Info( InfoSCSCP, 1, "Waiting for reply ...");
177if output_option = "tree" then
178  result := CompleteProcess( process : output:="tree" );
179else
180  result := CompleteProcess( process );
181fi;
182
183return result;
184
185end);
186
187###########################################################################
188##
189#E
190##
191