/usr/share/mozart/doc/demo/node37.html is in mozart-doc 1.4.0-8ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>Network Connection: NetDictionary.oz</TITLE><LINK href="ozdoc.css" rel="stylesheet" type="text/css"></HEAD><BODY><TABLE align="center" border="0" cellpadding="6" cellspacing="6" class="nav"><TR bgcolor="#DDDDDD"><TD><A href="dict-client.html">- Up -</A></TD><TD><A href="node38.html#code.dict-client.tkdictionary">Next >></A></TD></TR></TABLE><DIV class="unnumbered" id="code.dict-client.netdictionary"><H3><A name="code.dict-client.netdictionary">Network Connection: <CODE>NetDictionary.oz</CODE></A></H3><DIV class="apropos"><P class="margin"><A href="DictClient/NetDictionary.oz">Source File</A></P><P> </P><BLOCKQUOTE><PRE>%%<SPAN class="comment"> <BR></SPAN>%% <SPAN class="comment">This functor defines a class encapsulating the whole of<BR></SPAN>%% <SPAN class="comment">the DICT protocol.<BR></SPAN>%%<SPAN class="comment"> <BR></SPAN>%% <SPAN class="comment">Not implemented yet:<BR></SPAN>%% <SPAN class="comment">-- interpretation of the server banner<BR></SPAN>%% <SPAN class="comment">-- authentication<BR></SPAN>%% <SPAN class="comment">-- OPTION MIME<BR></SPAN>%%<SPAN class="comment"> <BR></SPAN> <BR><SPAN class="keyword">functor</SPAN> <BR><SPAN class="keyword">import</SPAN> <BR> Error(registerFormatter)<BR> Open(socket text)<BR><SPAN class="keyword">export</SPAN> <BR> <SPAN class="string">'class'</SPAN>: NetDictionary<BR> defaultServer: DEFAULT_SERVER<BR> defaultPort: DEFAULT_PORT<BR><SPAN class="keyword">prepare</SPAN> <BR> %% <SPAN class="comment">Name of default server to connect to<BR></SPAN> DEFAULT_SERVER = <SPAN class="string">'dict.org'</SPAN> <BR> %% <SPAN class="comment">Default port to connect to<BR></SPAN> DEFAULT_PORT = 2628<BR> <BR> %% <SPAN class="comment">String sent by the client to identify itself<BR></SPAN> CLIENT_TEXT = <SPAN class="string">'Mozart client, http://www.mozart-oz.org/'</SPAN> <BR> <BR> <SPAN class="keyword">fun</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">DropCR</SPAN> S}<BR> %% <SPAN class="comment">Discard the final return character of a line.<BR></SPAN> <SPAN class="keyword">case</SPAN> S <SPAN class="keyword">of</SPAN> <SPAN class="string">"\r"</SPAN> <SPAN class="keyword">then</SPAN> <SPAN class="string">""</SPAN> <BR> <SPAN class="keyword">elseof</SPAN> C1<SPAN class="keyword">|</SPAN>Cr <SPAN class="keyword">then</SPAN> C1<SPAN class="keyword">|</SPAN>{DropCR Cr}<BR> <SPAN class="keyword">[]</SPAN> nil <SPAN class="keyword">then</SPAN> <SPAN class="string">""</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <BR> <SPAN class="keyword">fun</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">DropSpace</SPAN> S}<BR> %% <SPAN class="comment">Discard leading whitespace.<BR></SPAN> {List<SPAN class="keyword">.</SPAN>dropWhile S<BR> <SPAN class="keyword">fun</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">$</SPAN> C} C <SPAN class="keyword">==</SPAN> <SPAN class="string">& </SPAN> <SPAN class="keyword">orelse</SPAN> C <SPAN class="keyword">==</SPAN> <SPAN class="string">&\t</SPAN> <SPAN class="keyword">end</SPAN>}<BR> <SPAN class="keyword">end</SPAN> <BR> <BR> %%<SPAN class="comment"> <BR></SPAN> %% <SPAN class="comment">Converting between UTF-8 and UCS-4 [RFC2044]<BR></SPAN> %%<SPAN class="comment"> <BR></SPAN> %% <SPAN class="comment">UCS-4 range (hex.) UTF-8 octet sequence (binary)<BR></SPAN> %% <SPAN class="comment">0000 0000-0000 007F 0xxxxxxx<BR></SPAN> %% <SPAN class="comment">0000 0080-0000 07FF 110xxxxx 10xxxxxx<BR></SPAN> %% <SPAN class="comment">0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx<BR></SPAN> %% <SPAN class="comment">0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx<BR></SPAN> %% <SPAN class="comment">0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx<BR></SPAN> %% <SPAN class="comment">0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx<BR></SPAN> %%<SPAN class="comment"> <BR></SPAN> <BR> <SPAN class="keyword">local</SPAN> <BR> SixBits = 0b1000000<BR> <BR> <SPAN class="keyword">fun</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">CharToSeq</SPAN> C Acc}<BR> <SPAN class="keyword">case</SPAN> C <SPAN class="keyword">of</SPAN> 0 <SPAN class="keyword">then</SPAN> Acc<BR> <SPAN class="keyword">else</SPAN> <BR> {CharToSeq (C <SPAN class="keyword">div</SPAN> SixBits) (C <SPAN class="keyword">mod</SPAN> SixBits)<SPAN class="keyword">|</SPAN>Acc}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <BR> <SPAN class="keyword">fun</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">AppendSeq</SPAN> Seq N Rest}<BR> <SPAN class="keyword">case</SPAN> Seq <SPAN class="keyword">of</SPAN> I<SPAN class="keyword">|</SPAN>Ir <SPAN class="keyword">then</SPAN> <BR> (I <SPAN class="keyword">+</SPAN> N)<SPAN class="keyword">|</SPAN>{AppendSeq Ir 0b10000000 Rest}<BR> <SPAN class="keyword">else</SPAN> <BR> Rest<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">in</SPAN> <BR> <SPAN class="keyword">fun</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">UCS4toUTF8</SPAN> S}<BR> <SPAN class="keyword">case</SPAN> S <SPAN class="keyword">of</SPAN> C<SPAN class="keyword">|</SPAN>Cr <SPAN class="keyword">then</SPAN> <BR> <SPAN class="keyword">if</SPAN> C <SPAN class="keyword">=<</SPAN> 0x0000007F <SPAN class="keyword">then</SPAN> <BR> C<SPAN class="keyword">|</SPAN>{UCS4toUTF8 Cr}<BR> <SPAN class="keyword">elseif</SPAN> C <SPAN class="keyword">=<</SPAN> 0x000007FF <SPAN class="keyword">then</SPAN> <BR> {AppendSeq {CharToSeq C nil} 0b11000000 {UCS4toUTF8 Cr}}<BR> <SPAN class="keyword">elseif</SPAN> C <SPAN class="keyword">=<</SPAN> 0x0000FFFF <SPAN class="keyword">then</SPAN> <BR> {AppendSeq {CharToSeq C nil} 0b11100000 {UCS4toUTF8 Cr}}<BR> <SPAN class="keyword">elseif</SPAN> C <SPAN class="keyword">=<</SPAN> 0x001FFFFF <SPAN class="keyword">then</SPAN> <BR> {AppendSeq {CharToSeq C nil} 0b11110000 {UCS4toUTF8 Cr}}<BR> <SPAN class="keyword">elseif</SPAN> C <SPAN class="keyword">=<</SPAN> 0x03FFFFFF <SPAN class="keyword">then</SPAN> <BR> {AppendSeq {CharToSeq C nil} 0b11111000 {UCS4toUTF8 Cr}}<BR> <SPAN class="keyword">elseif</SPAN> C <SPAN class="keyword">=<</SPAN> 0x7FFFFFFF <SPAN class="keyword">then</SPAN> <BR> {AppendSeq {CharToSeq C nil} 0b11111100 {UCS4toUTF8 Cr}}<BR> <SPAN class="keyword">else</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(nonUCS4character C)} <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">[]</SPAN> nil <SPAN class="keyword">then</SPAN> nil<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <BR> <SPAN class="keyword">local</SPAN> <BR> SixBits = 0b1000000<BR> <BR> <SPAN class="keyword">fun</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">SeqToChar</SPAN> N Seq Acc ?Rest}<BR> <SPAN class="keyword">case</SPAN> N <SPAN class="keyword">of</SPAN> 0 <SPAN class="keyword">then</SPAN> <BR> Rest = Seq<BR> Acc<BR> <SPAN class="keyword">elsecase</SPAN> Seq <SPAN class="keyword">of</SPAN> I<SPAN class="keyword">|</SPAN>Ir <SPAN class="keyword">then</SPAN> <BR> <SPAN class="keyword">if</SPAN> I <SPAN class="keyword"><</SPAN> 0b1000000 <SPAN class="keyword">orelse</SPAN> I <SPAN class="keyword">>=</SPAN> 0b11000000 <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(nonUTF8element I)}<BR> <SPAN class="keyword">end</SPAN> <BR> {SeqToChar N <SPAN class="keyword">-</SPAN> 1 Ir Acc <SPAN class="keyword">*</SPAN> SixBits <SPAN class="keyword">+</SPAN> (I <SPAN class="keyword">-</SPAN> 0b10000000) ?Rest}<BR> <SPAN class="keyword">[]</SPAN> nil <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(tooShortUTF8character)} <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">in</SPAN> <BR> <SPAN class="keyword">fun</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">UTF8toUCS4</SPAN> Seq}<BR> <SPAN class="keyword">case</SPAN> Seq <SPAN class="keyword">of</SPAN> I<SPAN class="keyword">|</SPAN>Ir <SPAN class="keyword">then</SPAN> <BR> <SPAN class="keyword">if</SPAN> I <SPAN class="keyword">>=</SPAN> 0b11111100 <SPAN class="keyword">then</SPAN> Rest <SPAN class="keyword">in</SPAN> <BR> {SeqToChar 5 Ir I <SPAN class="keyword">-</SPAN> 0b11111100 ?Rest}<SPAN class="keyword">|</SPAN>{UTF8toUCS4 Rest}<BR> <SPAN class="keyword">elseif</SPAN> I <SPAN class="keyword">>=</SPAN> 0b11111000 <SPAN class="keyword">then</SPAN> Rest <SPAN class="keyword">in</SPAN> <BR> {SeqToChar 4 Ir I <SPAN class="keyword">-</SPAN> 0b11111000 ?Rest}<SPAN class="keyword">|</SPAN>{UTF8toUCS4 Rest}<BR> <SPAN class="keyword">elseif</SPAN> I <SPAN class="keyword">>=</SPAN> 0b11110000 <SPAN class="keyword">then</SPAN> Rest <SPAN class="keyword">in</SPAN> <BR> {SeqToChar 3 Ir I <SPAN class="keyword">-</SPAN> 0b11110000 ?Rest}<SPAN class="keyword">|</SPAN>{UTF8toUCS4 Rest}<BR> <SPAN class="keyword">elseif</SPAN> I <SPAN class="keyword">>=</SPAN> 0b11100000 <SPAN class="keyword">then</SPAN> Rest <SPAN class="keyword">in</SPAN> <BR> {SeqToChar 2 Ir I <SPAN class="keyword">-</SPAN> 0b11100000 ?Rest}<SPAN class="keyword">|</SPAN>{UTF8toUCS4 Rest}<BR> <SPAN class="keyword">elseif</SPAN> I <SPAN class="keyword">>=</SPAN> 0b11000000 <SPAN class="keyword">then</SPAN> Rest <SPAN class="keyword">in</SPAN> <BR> {SeqToChar 1 Ir I <SPAN class="keyword">-</SPAN> 0b11000000 ?Rest}<SPAN class="keyword">|</SPAN>{UTF8toUCS4 Rest}<BR> <SPAN class="keyword">elseif</SPAN> I <SPAN class="keyword">>=</SPAN> 0b10000000 <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(nonUTF8character Seq)} <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">else</SPAN> <BR> I<SPAN class="keyword">|</SPAN>{UTF8toUCS4 Ir}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">[]</SPAN> nil <SPAN class="keyword">then</SPAN> nil<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR><SPAN class="keyword">define</SPAN> <BR> %%<SPAN class="comment"> <BR></SPAN> %% <SPAN class="comment">Extended Socket Class for Protocol Basics<BR></SPAN> %%<SPAN class="comment"> <BR></SPAN> <BR> <SPAN class="keyword">class</SPAN> <SPAN class="type">TextSocket</SPAN> <SPAN class="keyword">from</SPAN><SPAN class="type"> Open.socket Open.text</SPAN> <BR> <SPAN class="keyword">prop</SPAN> final<BR> <SPAN class="keyword">feat</SPAN> crash % <SPAN class="comment">nullary procedure to invoke when server closes connection<BR></SPAN> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">getS</SPAN>($)<BR> %% <SPAN class="comment">Override `Open.socket,getS' to discard the final return character.<BR></SPAN> <SPAN class="keyword">case</SPAN> Open<SPAN class="keyword">.</SPAN>text<SPAN class="keyword">,</SPAN> getS($) <SPAN class="keyword">of</SPAN> <SPAN class="keyword">false</SPAN> <SPAN class="keyword">then</SPAN> <SPAN class="keyword">false</SPAN> <BR> <SPAN class="keyword">elseof</SPAN> S <SPAN class="keyword">then</SPAN> {DropCR {UTF8toUCS4 S}}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">getTextLine</SPAN>($)<BR> %% <SPAN class="comment">Read a single line of a (multi-line) text response.<BR></SPAN> %% <SPAN class="comment">A single period on a line has special meaning; return 'period'.<BR></SPAN> %% <SPAN class="comment">Other periods at the beginning of the line are doubled.<BR></SPAN> %% <SPAN class="comment">If the connection has been closed, return 'closed'.<BR></SPAN> <SPAN class="keyword">case</SPAN> TextSocket<SPAN class="keyword">,</SPAN> getS($) <SPAN class="keyword">of</SPAN> <SPAN class="keyword">false</SPAN> <SPAN class="keyword">then</SPAN> closed<BR> <SPAN class="keyword">elseof</SPAN> <SPAN class="string">"."</SPAN> <SPAN class="keyword">then</SPAN> period<BR> <SPAN class="keyword">elseof</SPAN> <SPAN class="string">&.</SPAN><SPAN class="keyword">|</SPAN>(S=<SPAN class="string">&.</SPAN><SPAN class="keyword">|</SPAN>_) <SPAN class="keyword">then</SPAN> S<BR> <SPAN class="keyword">elseof</SPAN> S <SPAN class="keyword">then</SPAN> S<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">getTextual</SPAN>($)<BR> %% <SPAN class="comment">Read a multi-line text response.<BR></SPAN> <SPAN class="keyword">case</SPAN> TextSocket<SPAN class="keyword">,</SPAN> getTextLine($) <SPAN class="keyword">of</SPAN> closed <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(serverClosed <SPAN class="keyword">unit</SPAN>)}<BR> {<SPAN class="keyword">self.</SPAN>crash}<BR> <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">[]</SPAN> period <SPAN class="keyword">then</SPAN> <SPAN class="string">""</SPAN> <BR> <SPAN class="keyword">elseof</SPAN> S <SPAN class="keyword">then</SPAN> <BR> S<SPAN class="keyword">#</SPAN><SPAN class="string">'\n'</SPAN><SPAN class="keyword">#</SPAN>TextSocket<SPAN class="keyword">,</SPAN> getTextual($)<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">expect</SPAN>(Ns ?N ?Rest)<BR> %% <SPAN class="comment">Read a status response from the server.<BR></SPAN> %% <SPAN class="comment">A status response is a line starting with a three-digit<BR></SPAN> %% <SPAN class="comment">response code. Ns is a list of the handled response codes;<BR></SPAN> %% <SPAN class="comment">return the actual response code in N and the rest of the<BR></SPAN> %% <SPAN class="comment">line in Rest.<BR></SPAN> <SPAN class="keyword">case</SPAN> TextSocket<SPAN class="keyword">,</SPAN> getS($) <SPAN class="keyword">of</SPAN> <SPAN class="keyword">false</SPAN> <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(serverClosed <SPAN class="keyword">unit</SPAN>)}<BR> {<SPAN class="keyword">self.</SPAN>crash}<BR> <SPAN class="keyword">elseof</SPAN> S=(A<SPAN class="keyword">|</SPAN>_) <SPAN class="keyword">andthen</SPAN> {Char<SPAN class="keyword">.</SPAN>isDigit A} <SPAN class="keyword">then</SPAN> <BR> N = {String<SPAN class="keyword">.</SPAN>toInt {List<SPAN class="keyword">.</SPAN>takeDropWhile S Char<SPAN class="keyword">.</SPAN>isDigit $ ?Rest}}<BR> <SPAN class="keyword">if</SPAN> N <SPAN class="keyword">==</SPAN> 420 <SPAN class="keyword">orelse</SPAN> N <SPAN class="keyword">==</SPAN> 421 <SPAN class="keyword">then</SPAN> % <SPAN class="comment">general error codes<BR></SPAN> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(serverClosed <SPAN class="string">'Error '</SPAN><SPAN class="keyword">#</SPAN>N)}<BR> {<SPAN class="keyword">self.</SPAN>crash}<BR> <SPAN class="keyword">elseif</SPAN> {Member N Ns} <SPAN class="keyword">then</SPAN> <SPAN class="keyword">skip</SPAN> <BR> <SPAN class="keyword">else</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(unexpectedResponse Ns N<BR> {DropSpace S})}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">elseof</SPAN> S <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(unexpectedResponse Ns <SPAN class="keyword">unit</SPAN> S)}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">writeLine</SPAN>(S) V <SPAN class="keyword">in</SPAN> <BR> %% <SPAN class="comment">Write a command S to the server.<BR></SPAN> %% <SPAN class="comment">Append the required return/linefeed character sequence.<BR></SPAN> %% <SPAN class="comment">Raise an exception if the connection has been closed.<BR></SPAN> V = {UCS4toUTF8 {VirtualString<SPAN class="keyword">.</SPAN>toString S<SPAN class="keyword">#</SPAN><SPAN class="string">'\r\n'</SPAN>}}<BR> <SPAN class="keyword">try</SPAN> <BR> TextSocket<SPAN class="keyword">,</SPAN> write(vs: V)<BR> <SPAN class="keyword">catch</SPAN> system(os(os 4: Text <SPAN class="keyword">...</SPAN>) <SPAN class="keyword">...</SPAN>) <SPAN class="keyword">then</SPAN> <BR> {<SPAN class="keyword">self.</SPAN>crash}<BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(serverClosed Text)}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <BR> %%<SPAN class="comment"> <BR></SPAN> %% <SPAN class="comment">Parsing a Status Response<BR></SPAN> %%<SPAN class="comment"> <BR></SPAN> <BR> <SPAN class="keyword">local</SPAN> <BR> <SPAN class="keyword">proc</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">GetArg</SPAN> S Quote ?Arg ?Rest}<BR> <SPAN class="keyword">case</SPAN> S <SPAN class="keyword">of</SPAN> C1<SPAN class="keyword">|</SPAN>Cr <SPAN class="keyword">then</SPAN> <BR> <SPAN class="keyword">if</SPAN> C1 <SPAN class="keyword">==</SPAN> <SPAN class="string">&\\</SPAN> <SPAN class="keyword">then</SPAN> <BR> <SPAN class="keyword">case</SPAN> Cr <SPAN class="keyword">of</SPAN> C2<SPAN class="keyword">|</SPAN>Crr <SPAN class="keyword">then</SPAN> Argr <SPAN class="keyword">in</SPAN> <BR> Arg = C2<SPAN class="keyword">|</SPAN>Argr<BR> {GetArg Crr Quote ?Argr ?Rest}<BR> <SPAN class="keyword">[]</SPAN> nil <SPAN class="keyword">then</SPAN> {Raise error}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">elseif</SPAN> C1 <SPAN class="keyword">==</SPAN> <SPAN class="string">&"</SPAN> <SPAN class="keyword">orelse</SPAN> C1 <SPAN class="keyword">==</SPAN> <SPAN class="string">&'</SPAN> <SPAN class="keyword">then</SPAN> <BR> <SPAN class="keyword">if</SPAN> C1 <SPAN class="keyword">==</SPAN> Quote <SPAN class="keyword">then</SPAN> <BR> {GetArg Cr <SPAN class="keyword">unit</SPAN> ?Arg ?Rest}<BR> <SPAN class="keyword">elseif</SPAN> Quote <SPAN class="keyword">==</SPAN> <SPAN class="keyword">unit</SPAN> <SPAN class="keyword">then</SPAN> <BR> {GetArg Cr C1 ?Arg ?Rest}<BR> <SPAN class="keyword">else</SPAN> Argr <SPAN class="keyword">in</SPAN> <BR> Arg = C1<SPAN class="keyword">|</SPAN>Argr<BR> {GetArg Cr Quote ?Argr ?Rest}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">elseif</SPAN> (C1 <SPAN class="keyword">==</SPAN> <SPAN class="string">& </SPAN> <SPAN class="keyword">orelse</SPAN> C1 <SPAN class="keyword">==</SPAN> <SPAN class="string">&\t</SPAN>) <SPAN class="keyword">andthen</SPAN> Quote <SPAN class="keyword">==</SPAN> <SPAN class="keyword">unit</SPAN> <SPAN class="keyword">then</SPAN> <BR> Arg = nil<BR> Rest = Cr<BR> <SPAN class="keyword">else</SPAN> Argr <SPAN class="keyword">in</SPAN> <BR> Arg = C1<SPAN class="keyword">|</SPAN>Argr<BR> {GetArg Cr Quote ?Argr ?Rest}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">[]</SPAN> nil <SPAN class="keyword">then</SPAN> <BR> Arg = nil<BR> Rest = nil<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <BR> <SPAN class="keyword">fun</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">GetArgs</SPAN> S} T <SPAN class="keyword">in</SPAN> <BR> T = {DropSpace S}<BR> <SPAN class="keyword">case</SPAN> T <SPAN class="keyword">of</SPAN> nil <SPAN class="keyword">then</SPAN> nil<BR> <SPAN class="keyword">else</SPAN> Arg Rest <SPAN class="keyword">in</SPAN> <BR> {GetArg T <SPAN class="keyword">unit</SPAN> ?Arg ?Rest}<BR> Arg<SPAN class="keyword">|</SPAN>{GetArgs Rest}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">in</SPAN> <BR> <SPAN class="keyword">fun</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">Argify</SPAN> S}<BR> <SPAN class="keyword">try</SPAN> <BR> {GetArgs S}<BR> <SPAN class="keyword">catch</SPAN> error <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(illegalArgString S)} <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <BR> %%<SPAN class="comment"> <BR></SPAN> %% <SPAN class="comment">Escaping Strings in Commands<BR></SPAN> %%<SPAN class="comment"> <BR></SPAN> <BR> <SPAN class="keyword">local</SPAN> <BR> <SPAN class="keyword">fun</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">IsAtomChar</SPAN> C}<BR> <SPAN class="keyword">case</SPAN> C <SPAN class="keyword">of</SPAN> <SPAN class="string">&"</SPAN> <SPAN class="keyword">then</SPAN> <SPAN class="keyword">false</SPAN> <BR> <SPAN class="keyword">[]</SPAN> <SPAN class="string">&'</SPAN> <SPAN class="keyword">then</SPAN> <SPAN class="keyword">false</SPAN> <BR> <SPAN class="keyword">[]</SPAN> <SPAN class="string">&\\</SPAN> <SPAN class="keyword">then</SPAN> <SPAN class="keyword">false</SPAN> <BR> <SPAN class="keyword">else</SPAN> <SPAN class="string">& </SPAN> <SPAN class="keyword"><</SPAN> C<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <BR> <SPAN class="keyword">fun</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">EscapeSub</SPAN> S}<BR> <SPAN class="keyword">case</SPAN> S <SPAN class="keyword">of</SPAN> C<SPAN class="keyword">|</SPAN>Cr <SPAN class="keyword">then</SPAN> <BR> <SPAN class="keyword">if</SPAN> C <SPAN class="keyword">==</SPAN> <SPAN class="string">&"</SPAN> <SPAN class="keyword">orelse</SPAN> C <SPAN class="keyword">==</SPAN> <SPAN class="string">&\\</SPAN> <SPAN class="keyword">orelse</SPAN> C <SPAN class="keyword"><</SPAN> <SPAN class="string">& </SPAN> <SPAN class="keyword">then</SPAN> <BR> <SPAN class="string">&\\</SPAN><SPAN class="keyword">|</SPAN>C<SPAN class="keyword">|</SPAN>{EscapeSub Cr}<BR> <SPAN class="keyword">else</SPAN> <BR> C<SPAN class="keyword">|</SPAN>{EscapeSub Cr}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">[]</SPAN> nil <SPAN class="keyword">then</SPAN> <SPAN class="string">"\""</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">in</SPAN> <BR> <SPAN class="keyword">fun</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">Escape</SPAN> VS} S <SPAN class="keyword">in</SPAN> <BR> S = {VirtualString<SPAN class="keyword">.</SPAN>toString VS}<BR> <SPAN class="keyword">if</SPAN> S <SPAN class="keyword">\=</SPAN> <SPAN class="string">""</SPAN> <SPAN class="keyword">andthen</SPAN> {All S IsAtomChar} <SPAN class="keyword">then</SPAN> S<BR> <SPAN class="keyword">else</SPAN> <SPAN class="string">&"</SPAN><SPAN class="keyword">|</SPAN>{EscapeSub S}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <BR> %%<SPAN class="comment"> <BR></SPAN> %% <SPAN class="comment">Main Class Encapsulating the DICT Protocol<BR></SPAN> %%<SPAN class="comment"> <BR></SPAN> <BR> <SPAN class="keyword">class</SPAN> <SPAN class="type">NetDictionary</SPAN> <BR> <SPAN class="keyword">prop</SPAN> locking<BR> <SPAN class="keyword">attr</SPAN> socket serverBanner<BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">init</SPAN>(Server <SPAN class="keyword"><=</SPAN> <SPAN class="keyword">unit</SPAN> Port <SPAN class="keyword"><=</SPAN> DEFAULT_PORT)<BR> %% <SPAN class="comment">If Server is non-unit, open a connection to it at Port.<BR></SPAN> socket <SPAN class="keyword"><-</SPAN> <SPAN class="keyword">unit</SPAN> <BR> serverBanner <SPAN class="keyword"><-</SPAN> <SPAN class="string">""</SPAN> <BR> <SPAN class="keyword">if</SPAN> Server <SPAN class="keyword">\=</SPAN> <SPAN class="keyword">unit</SPAN> <SPAN class="keyword">then</SPAN> <BR> NetDictionary<SPAN class="keyword">,</SPAN> connect(Server Port)<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">connect</SPAN>(Server <SPAN class="keyword"><=</SPAN> DEFAULT_SERVER Port <SPAN class="keyword"><=</SPAN> DEFAULT_PORT) Socket <SPAN class="keyword">in</SPAN> <BR> %% <SPAN class="comment">Open a connection to Server at Port.<BR></SPAN> %% <SPAN class="comment">If a connection is currently open, close it before.<BR></SPAN> <SPAN class="keyword">lock</SPAN> <BR> <SPAN class="keyword">if</SPAN> <SPAN class="keyword">@</SPAN>socket <SPAN class="keyword">\=</SPAN> <SPAN class="keyword">unit</SPAN> <SPAN class="keyword">then</SPAN> <BR> NetDictionary<SPAN class="keyword">,</SPAN> close()<BR> <SPAN class="keyword">end</SPAN> <BR> Socket = {New TextSocket client(host: Server port: Port)}<BR> Socket<SPAN class="keyword">.</SPAN>crash = <SPAN class="keyword">proc</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">$</SPAN>} NetDictionary<SPAN class="keyword">,</SPAN> Crash() <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">try</SPAN> <BR> serverBanner <SPAN class="keyword"><-</SPAN> {Socket expect([220] _ $)}<BR> {Socket writeLine(<SPAN class="string">'CLIENT '</SPAN><SPAN class="keyword">#</SPAN>CLIENT_TEXT)}<BR> {Socket expect([250] _ _)}<BR> socket <SPAN class="keyword"><-</SPAN> Socket<BR> <SPAN class="keyword">catch</SPAN> E <SPAN class="keyword">then</SPAN> <BR> {Socket close()}<BR> {Raise E}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">getBanner</SPAN>($)<BR> %% <SPAN class="comment">Return the banner sent by the server upon connection.<BR></SPAN> <SPAN class="keyword">case</SPAN> <SPAN class="keyword">@</SPAN>socket <SPAN class="keyword">of</SPAN> <SPAN class="keyword">unit</SPAN> <SPAN class="keyword">then</SPAN> <SPAN class="string">""</SPAN> <BR> <SPAN class="keyword">else</SPAN> <SPAN class="keyword">@</SPAN>serverBanner<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">close</SPAN>()<BR> %% <SPAN class="comment">Close the current connection (if any).<BR></SPAN> %% <SPAN class="comment">Send a QUIT command and wait for the status response.<BR></SPAN> <SPAN class="keyword">lock</SPAN> <BR> <SPAN class="keyword">case</SPAN> <SPAN class="keyword">@</SPAN>socket <SPAN class="keyword">of</SPAN> <SPAN class="keyword">unit</SPAN> <SPAN class="keyword">then</SPAN> <SPAN class="keyword">skip</SPAN> <BR> <SPAN class="keyword">elseof</SPAN> Socket <SPAN class="keyword">then</SPAN> <BR> {Socket writeLine(<SPAN class="string">'QUIT'</SPAN>)}<BR> <SPAN class="keyword">try</SPAN> <BR> {Socket expect([221] _ _)}<BR> <SPAN class="keyword">finally</SPAN> <BR> {Socket close()}<BR> socket <SPAN class="keyword"><-</SPAN> <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">Crash</SPAN>()<BR> socket <SPAN class="keyword"><-</SPAN> <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">status</SPAN>($)<BR> %% <SPAN class="comment">Send a STATUS command and return the status response.<BR></SPAN> <SPAN class="keyword">lock</SPAN> <BR> <SPAN class="keyword">case</SPAN> <SPAN class="keyword">@</SPAN>socket <SPAN class="keyword">of</SPAN> <SPAN class="keyword">unit</SPAN> <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(notConnected)} <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">elseof</SPAN> Socket <SPAN class="keyword">then</SPAN> <BR> {Socket writeLine(<SPAN class="string">'STATUS'</SPAN>)}<BR> {DropSpace {Socket expect([210] _ $)}}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">showServer</SPAN>(?Text)<BR> %% <SPAN class="comment">Send a SHOW SERVER command and return the text reponse.<BR></SPAN> <SPAN class="keyword">lock</SPAN> <BR> <SPAN class="keyword">case</SPAN> <SPAN class="keyword">@</SPAN>socket <SPAN class="keyword">of</SPAN> <SPAN class="keyword">unit</SPAN> <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(notConnected)}<BR> <SPAN class="keyword">elseof</SPAN> Socket <SPAN class="keyword">then</SPAN> <BR> {Socket writeLine(<SPAN class="string">'SHOW SERVER'</SPAN>)}<BR> {Socket expect([114] _ _)}<BR> {Socket getTextual(?Text)}<BR> {Socket expect([250] _ _)}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">showInfo</SPAN>(DBName ?Text)<BR> %% <SPAN class="comment">Send a SHOW INFO command and return the text reponse.<BR></SPAN> <SPAN class="keyword">lock</SPAN> <BR> <SPAN class="keyword">case</SPAN> <SPAN class="keyword">@</SPAN>socket <SPAN class="keyword">of</SPAN> <SPAN class="keyword">unit</SPAN> <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(notConnected)}<BR> <SPAN class="keyword">elseof</SPAN> Socket <SPAN class="keyword">then</SPAN> <BR> {Socket writeLine(<SPAN class="string">'SHOW INFO '</SPAN><SPAN class="keyword">#</SPAN>DBName)}<BR> {Socket expect([112] _ _)}<BR> {Socket getTextual(?Text)}<BR> {Socket expect([250] _ _)}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="string">'define'</SPAN>(Word db: DB <SPAN class="keyword"><=</SPAN> <SPAN class="string">'*'</SPAN> count: Count <SPAN class="keyword"><=</SPAN> _ $)<BR> %% <SPAN class="comment">Query for definitions for Word in database DB.<BR></SPAN> <SPAN class="keyword">lock</SPAN> <BR> <SPAN class="keyword">case</SPAN> <SPAN class="keyword">@</SPAN>socket <SPAN class="keyword">of</SPAN> <SPAN class="keyword">unit</SPAN> <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(notConnected)} <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">elseof</SPAN> Socket <SPAN class="keyword">then</SPAN> Rest <SPAN class="keyword">in</SPAN> <BR> {Socket writeLine(<SPAN class="string">'DEFINE '</SPAN><SPAN class="keyword">#</SPAN>DB<SPAN class="keyword">#</SPAN><SPAN class="string">' '</SPAN><SPAN class="keyword">#</SPAN>{Escape Word})}<BR> <SPAN class="keyword">case</SPAN> {Socket expect([150 552] $ ?Rest)} <SPAN class="keyword">of</SPAN> 150 <SPAN class="keyword">then</SPAN> <BR> <SPAN class="keyword">try</SPAN> <BR> Count = {String<SPAN class="keyword">.</SPAN>toInt {Argify Rest}<SPAN class="keyword">.</SPAN>1}<BR> <SPAN class="keyword">catch</SPAN> error(<SPAN class="keyword">...</SPAN>) <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(malformedResponse 150 Rest)}<BR> <SPAN class="keyword">end</SPAN> <BR> NetDictionary<SPAN class="keyword">,</SPAN> GetDefinitions($)<BR> <SPAN class="keyword">[]</SPAN> 552 <SPAN class="keyword">then</SPAN> <BR> Count = 0<BR> <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">GetDefinitions</SPAN>(?Ds) Rest <SPAN class="keyword">in</SPAN> <BR> <SPAN class="keyword">case</SPAN> {<SPAN class="keyword">@</SPAN>socket expect([151 250] $ ?Rest)} <SPAN class="keyword">of</SPAN> 151 <SPAN class="keyword">then</SPAN> <BR> <SPAN class="keyword">case</SPAN> {Argify Rest} <SPAN class="keyword">of</SPAN> [Word DB DBName] <SPAN class="keyword">then</SPAN> Dr Body <SPAN class="keyword">in</SPAN> <BR> Ds = definition(word: Word db: DB dbname: DBName body: Body)<SPAN class="keyword">|</SPAN>Dr<BR> {<SPAN class="keyword">@</SPAN>socket getTextual(?Body)}<BR> NetDictionary<SPAN class="keyword">,</SPAN> GetDefinitions(?Dr)<BR> <SPAN class="keyword">else</SPAN> <BR> Ds = nil<BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(malformedDefinition Rest)}<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">[]</SPAN> 250 <SPAN class="keyword">then</SPAN> <BR> Ds = nil<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">match</SPAN>(Word db: DB <SPAN class="keyword"><=</SPAN> <SPAN class="string">'*'</SPAN> strategy: Strategy <SPAN class="keyword"><=</SPAN> <SPAN class="string">'.'</SPAN> <BR> count: Count <SPAN class="keyword"><=</SPAN> _ $)<BR> %% <SPAN class="comment">Query for matches for Word in database DB using Strategy.<BR></SPAN> <SPAN class="keyword">lock</SPAN> <BR> <SPAN class="keyword">case</SPAN> <SPAN class="keyword">@</SPAN>socket <SPAN class="keyword">of</SPAN> <SPAN class="keyword">unit</SPAN> <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(notConnected)} <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">elseof</SPAN> Socket <SPAN class="keyword">then</SPAN> Rest <SPAN class="keyword">in</SPAN> <BR> {Socket writeLine(<SPAN class="string">'MATCH '</SPAN><SPAN class="keyword">#</SPAN>DB<SPAN class="keyword">#</SPAN><SPAN class="string">' '</SPAN><SPAN class="keyword">#</SPAN>Strategy<SPAN class="keyword">#</SPAN><SPAN class="string">' '</SPAN><SPAN class="keyword">#</SPAN>{Escape Word})}<BR> <SPAN class="keyword">case</SPAN> {Socket expect([152 552] $ ?Rest)} <SPAN class="keyword">of</SPAN> 152 <SPAN class="keyword">then</SPAN> <BR> <SPAN class="keyword">try</SPAN> <BR> Count = {String<SPAN class="keyword">.</SPAN>toInt {Argify Rest}<SPAN class="keyword">.</SPAN>1}<BR> <SPAN class="keyword">catch</SPAN> error(<SPAN class="keyword">...</SPAN>) <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(malformedResponse 152 Rest)}<BR> <SPAN class="keyword">end</SPAN> <BR> NetDictionary<SPAN class="keyword">,</SPAN> GetPairList($)<BR> <SPAN class="keyword">[]</SPAN> 552 <SPAN class="keyword">then</SPAN> <BR> Count = 0<BR> <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">showDatabases</SPAN>($)<BR> %% <SPAN class="comment">Send a SHOW DATABASES command and return the text response.<BR></SPAN> %% <SPAN class="comment">This consists of a list of pairs ID#Name.<BR></SPAN> <SPAN class="keyword">lock</SPAN> <BR> <SPAN class="keyword">case</SPAN> <SPAN class="keyword">@</SPAN>socket <SPAN class="keyword">of</SPAN> <SPAN class="keyword">unit</SPAN> <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(notConnected)} <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">elseof</SPAN> Socket <SPAN class="keyword">then</SPAN> <BR> {Socket writeLine(<SPAN class="string">'SHOW DATABASES'</SPAN>)}<BR> {Socket expect([110] _ _)}<BR> NetDictionary<SPAN class="keyword">,</SPAN> GetPairList($)<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">showStrategies</SPAN>($)<BR> %% <SPAN class="comment">Send a SHOW STRATEGIES command and return the text response.<BR></SPAN> %% <SPAN class="comment">This consists of a list of pairs ID#Name.<BR></SPAN> <SPAN class="keyword">lock</SPAN> <BR> <SPAN class="keyword">case</SPAN> <SPAN class="keyword">@</SPAN>socket <SPAN class="keyword">of</SPAN> <SPAN class="keyword">unit</SPAN> <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(notConnected)} <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">elseof</SPAN> Socket <SPAN class="keyword">then</SPAN> <BR> {Socket writeLine(<SPAN class="string">'SHOW STRATEGIES'</SPAN>)}<BR> {Socket expect([111] _ _)}<BR> NetDictionary<SPAN class="keyword">,</SPAN> GetPairList($)<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">meth</SPAN> <SPAN class="functionname">GetPairList</SPAN>($)<BR> <SPAN class="keyword">case</SPAN> {<SPAN class="keyword">@</SPAN>socket getTextLine($)} <SPAN class="keyword">of</SPAN> closed <SPAN class="keyword">then</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(serverClosed <SPAN class="keyword">unit</SPAN>)}<BR> NetDictionary<SPAN class="keyword">,</SPAN> Crash()<BR> <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">[]</SPAN> period <SPAN class="keyword">then</SPAN> <BR> {<SPAN class="keyword">@</SPAN>socket expect([250] _ _)} nil<BR> <SPAN class="keyword">elseof</SPAN> S <SPAN class="keyword">then</SPAN> <BR> <SPAN class="keyword">case</SPAN> {Argify S} <SPAN class="keyword">of</SPAN> [A B] <SPAN class="keyword">then</SPAN> A<SPAN class="keyword">#</SPAN>B<SPAN class="keyword">|</SPAN>NetDictionary<SPAN class="keyword">,</SPAN> GetPairList($)<BR> <SPAN class="keyword">else</SPAN> <BR> {Exception<SPAN class="keyword">.</SPAN>raiseError netdict(malformedPair S)} <SPAN class="keyword">unit</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN> <BR> <BR> %%<SPAN class="comment"> <BR></SPAN> %% <SPAN class="comment">Formatting Error Exceptions<BR></SPAN> %%<SPAN class="comment"> <BR></SPAN> <BR> {Error<SPAN class="keyword">.</SPAN>registerFormatter netdict<BR> <SPAN class="keyword">fun</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">$</SPAN> E} T <SPAN class="keyword">in</SPAN> <BR> T = <SPAN class="string">'net dictionary error'</SPAN> <BR> <SPAN class="keyword">case</SPAN> E <SPAN class="keyword">of</SPAN> netdict(serverClosed Reason) <SPAN class="keyword">then</SPAN> <BR> error(kind: T<BR> msg: <SPAN class="string">'Server closed connection'</SPAN> <BR> items: <SPAN class="keyword">case</SPAN> Reason <SPAN class="keyword">of</SPAN> <SPAN class="keyword">unit</SPAN> <SPAN class="keyword">then</SPAN> nil<BR> <SPAN class="keyword">else</SPAN> [hint(l: <SPAN class="string">'Reason'</SPAN> m: Reason)]<BR> <SPAN class="keyword">end</SPAN>)<BR> <SPAN class="keyword">elseof</SPAN> netdict(illegalArgString ArgString) <SPAN class="keyword">then</SPAN> <BR> error(kind: T<BR> msg: <SPAN class="string">'Illegal argument string received from server'</SPAN> <BR> items: [hint(l: <SPAN class="string">'Got'</SPAN> m: ArgString)])<BR> <SPAN class="keyword">elseof</SPAN> netdict(serverError Response) <SPAN class="keyword">then</SPAN> <BR> error(kind: T<BR> msg: <SPAN class="string">'Server error'</SPAN> <BR> items: [hint(l: <SPAN class="string">'Response'</SPAN> m: Response)])<BR> <SPAN class="keyword">elseof</SPAN> netdict(notConnected) <SPAN class="keyword">then</SPAN> <BR> error(kind: T<BR> msg: <SPAN class="string">'Not connected'</SPAN>)<BR> <SPAN class="keyword">elseof</SPAN> netdict(unexpectedResponse Expected N Response) <SPAN class="keyword">then</SPAN> <BR> error(kind: T<BR> msg: <SPAN class="string">'Unexpected response from server'</SPAN> <BR> items: [<SPAN class="keyword">case</SPAN> Expected <SPAN class="keyword">of</SPAN> I1<SPAN class="keyword">|</SPAN>Ir <SPAN class="keyword">then</SPAN> <BR> hint(l: <SPAN class="string">'Expected one of'</SPAN> <BR> m: {FoldL Ir<BR> <SPAN class="keyword">fun</SPAN><SPAN class="variablename"> </SPAN>{<SPAN class="functionname">$</SPAN> In I} In<SPAN class="keyword">#</SPAN><SPAN class="string">' or '</SPAN><SPAN class="keyword">#</SPAN>I <SPAN class="keyword">end</SPAN> I1})<BR> <SPAN class="keyword">else</SPAN> hint(l: <SPAN class="string">'Expected'</SPAN> m: Expected)<BR> <SPAN class="keyword">end</SPAN> <BR> hint(l: <SPAN class="string">'Response'</SPAN> m: <SPAN class="keyword">case</SPAN> N <SPAN class="keyword">of</SPAN> <SPAN class="keyword">unit</SPAN> <SPAN class="keyword">then</SPAN> Response<BR> <SPAN class="keyword">else</SPAN> N<SPAN class="keyword">#</SPAN><SPAN class="string">' '</SPAN><SPAN class="keyword">#</SPAN>Response<BR> <SPAN class="keyword">end</SPAN>)])<BR> <SPAN class="keyword">elseof</SPAN> netdict(malformedResponse Code Rest) <SPAN class="keyword">then</SPAN> <BR> error(kind: T<BR> msg: <SPAN class="string">'Malformed response'</SPAN> <BR> items: [hint(l: <SPAN class="string">'Response code'</SPAN> m: Code)<BR> hint(l: <SPAN class="string">'Response text'</SPAN> m: Rest)])<BR> <SPAN class="keyword">elseof</SPAN> netdict(malformedDefinition Rest) <SPAN class="keyword">then</SPAN> <BR> error(kind: T<BR> msg: <SPAN class="string">'Malformed definition response'</SPAN> <BR> items: [hint(l: <SPAN class="string">'Response'</SPAN> m: Rest)])<BR> <SPAN class="keyword">elseof</SPAN> netdict(malformedPair String) <SPAN class="keyword">then</SPAN> <BR> error(kind: T<BR> msg: <SPAN class="string">'Malformed pair'</SPAN> <BR> items: [hint(l: <SPAN class="string">'Got'</SPAN> m: String)])<BR> <SPAN class="keyword">else</SPAN> <BR> error(kind: T<BR> items: [line(oz(E))])<BR> <SPAN class="keyword">end</SPAN> <BR> <SPAN class="keyword">end</SPAN>}<BR><SPAN class="keyword">end</SPAN> <BR></PRE></BLOCKQUOTE><P> </P></DIV></DIV><TABLE align="center" border="0" cellpadding="6" cellspacing="6" class="nav"><TR bgcolor="#DDDDDD"><TD><A href="dict-client.html">- Up -</A></TD><TD><A href="node38.html#code.dict-client.tkdictionary">Next >></A></TD></TR></TABLE><HR><ADDRESS><SPAN class="version">Version 1.4.0 (20110908185330)</SPAN></ADDRESS></BODY></HTML>
|