ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/kgsueme/doc/doc2haskell.xsl
Revision: 1.2
Committed: Fri Jul 25 22:19:30 2003 UTC (20 years, 10 months ago) by pcg
Content type: application/xml
Branch: MAIN
Changes since 1.1: +19 -35 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 <!DOCTYPE xsl:stylesheet>
2     <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
3    
4     <xsl:output method="text" media-type="text/plain" encoding="utf-8"/>
5    
6     <xsl:template match="/"><![CDATA[
7     -- This is an automatically generated file.
8     -- This is an automatically generated file.
9     -- This is an automatically generated file.
10     -- This is an automatically generated file.
11     -- This is an automatically generated file.
12    
13     -- See doc/protocol.xml and doc/doc2haskell.xsl
14    
15     -- primitive enc/decoders
16    
17 pcg 1.2 import Data.Word
18     import Control.Monad.State
19 pcg 1.1
20 pcg 1.2 getU8 :: State [Word8] Int
21     getU8 = do
22     (x:xs) <- get
23     put xs
24     return x
25    
26     getU16 :: State [Word8] Int
27     getU16 = do
28     a <- getU8
29     b <- getU8
30     return $ a + b * 256
31    
32     dec_U64
33     dec_I8
34     dec_I16
35     dec_I32
36     dec_DATA
37 pcg 1.1
38     sub dec_STRING {
39     $data =~ s/^((?:..)*?)(?:\x00\x00|\Z)//s;
40     # use Encode...
41     join "", map chr, unpack "v*", $1;
42     }
43    
44     sub dec_CONSTANT {
45     $_[0];
46     }
47    
48     sub dec_password {
49     dec_U64;
50     }
51    
52     sub dec_HEX { # for debugging
53     "HEX: " . unpack "H*", $data;#d#
54     }
55    
56     #############################################################################
57    
58     sub enc_U8 {
59     $data .= pack "C", $_[0];
60     }
61    
62     sub enc_U16 {
63     $data .= pack "v", $_[0];
64     }
65    
66     sub enc_U32 {
67     $data .= pack "V", $_[0];
68     }
69    
70     sub enc_U64 {
71     enc_U32 $_[0] & 0xffffffff;
72     enc_U32 +($_[0] >> 32) & 0xffffffff;
73     }
74    
75     sub enc_I8 {
76     $data .= pack "c", $_[0];
77     }
78    
79     sub enc_I16 {
80     enc_U16 unpack "S", pack "s", $_[0];
81     }
82    
83     sub enc_I32 {
84     enc_U32 unpack "I", pack "i", $_[0];
85     }
86    
87     sub enc_DATA {
88     # a dream!
89     $data .= $_[0];
90     }
91    
92     sub enc_STRING {
93     # should use encode for speed and clarity ;)
94     $data .= pack "v*", map ord, split //, $_[0];
95     }
96    
97     sub enc_CONSTANT {
98     # nop
99     }
100    
101     sub enc_password {
102     require Math::BigInt; # I insist on 32-bit-perl.. should use C
103     # $hash must be 64 bit
104     my $hash = new Math::BigInt;
105     $hash = $hash * 1055 + ord for split //, $_[0];
106     enc_U64 $hash;
107     }
108    
109     sub enc_HEX {
110     die "enc_HEX not defined for good";
111     }
112    
113     ]]>
114    
115     #############################################################################
116     # types
117     <xsl:apply-templates select="descendant::type"/>
118    
119     #############################################################################
120     # structures
121     <xsl:apply-templates select="descendant::struct"/>
122    
123     #############################################################################
124     # "less" primitive types<![CDATA[
125    
126     my %marker_code = (
127     triangle => 1,
128     square => 2,
129     circle => 3,
130     small_b => 4,
131     small_w => 5,
132     gray => 6,
133     move => 7,
134     addstone => 8,
135     );
136    
137     my %code_marker = reverse %marker_code;
138    
139     # this was the most horrible thing to decode. still not everything is decoded correctly(?)
140     sub dec_TREE {
141     my @r;
142     while (length $data) {
143     my $type = dec_U8;
144     my $add = $type < 128;
145    
146     $type &= 127;
147    
148     if ($type == 127) {
149     dec_U8; # unused?? *sigh*
150     push @r, [add_node => dec_I32];
151    
152     } elsif ($type == 126) {
153     push @r, [set_node => dec_I32];
154    
155     } elsif ($type == 125) {
156     push @r, [set_current => dec_I32];
157    
158     } elsif ($type == 34) {
159     push @r, [score => dec_U8, dec_score1000];
160    
161     } elsif ($type == 29) {
162     push @r, [type_29 => dec_STRING];
163     warn "TYPE 29 $r[-1][1]\007 PLEASE REPORT";#d#
164     die;
165    
166     } elsif ($type == 28) {
167     # move number, only in variations it seems. oh my.
168     push @r, [movenum => dec_STRING];
169    
170     } elsif ($type == 25) {
171     push @r, [result => dec_result];
172    
173     } elsif ($type == 23) {
174     push @r, [mark => $add, MARK_GRAYED, dec_U8, dec_U8];
175    
176     } elsif ($type == 22) {
177     push @r, [mark => $add, (&dec_U8 ? MARK_SMALL_W : MARK_SMALL_B), dec_U8, dec_U8];
178    
179     } elsif ($type == 21) {
180     push @r, [mark => $add, MARK_CIRCLE, dec_U8, dec_U8];
181    
182     } elsif ($type == 20) {
183     push @r, [mark => $add, MARK_SQUARE, dec_U8, dec_U8];
184    
185     } elsif ($type == 19) {
186     push @r, [mark => $add, MARK_TRIANGLE, dec_U8, dec_U8];
187    
188     } elsif ($type == 18) {
189     push @r, [mark => $add, MARK_LABEL, dec_U8, dec_U8, dec_STRING];
190    
191     } elsif ($type == 17) {
192     push @r, [set_timer => (dec_U8, dec_U32, dec_time)[0,2,1]];
193    
194     } elsif ($type == 16) {
195     push @r, [set_stone => $add, dec_U8, dec_U8, dec_U8];
196    
197     } elsif ($type == 14) {
198     push @r, [move => $add, dec_U8, dec_U8, dec_U8];
199    
200     } elsif (($type >= 4 && $type <= 9)
201     || ($type >= 11 && $type <= 13)
202     || $type == 24) {
203    
204     push @r, [({
205     4 => "date",
206     5 => "unknown_comment5",
207     6 => "unknown_comment6",
208     7 => "unknown_comment7",
209     8 => "unknown_comment8",
210     9 => "copyright", #?
211     11 => "unknown_comment11",
212     12 => "unknown_comment12",
213     13 => "unknown_comment13",
214     24 => "comment",
215     })->{$type} => dec_STRING];
216    
217     } elsif ($type == 3) {
218     push @r, [rank => dec_U8, dec_U32];
219    
220     } elsif ($type == 2) {
221     push @r, [player => dec_U8, dec_STRING];
222    
223     } elsif ($type == 0) {
224     # as usual, wms finds yet another way to duplicate code... oh well, what a mess.
225     # (no wonder he is so keen on keeping it a secret...)
226    
227     push @r, [rules => dec_rules];
228    
229     # OLD
230    
231     } elsif (1) {
232     print STDERR KGS::Listener::Debug::dumpval(\@r);
233     open XTYPE, "|xtype"; print XTYPE $data; close XTYPE;
234     die "unknown tree type $type, PLEASE REPORT and include the game you wanted to watch. thx.";
235    
236     } elsif ($type == 30) {
237     push @r, [active_player => dec_U8];
238    
239     } elsif ($type == 0) { # label(?)
240     my $label;
241     my $c = dec_U16; $label .= chr $c if $c;
242     my $c = dec_U16; $label .= chr $c if $c;
243     my $c = dec_U16; $label .= chr $c if $c;
244    
245     # empty label == remove label
246     push @r, [label => $label, dec_U8, dec_U8];
247    
248     } elsif ($type > 0 && $type < 9) {
249     # 1 marker type triangle
250     # 2 marker type square
251     # 3 marker type circle
252     # 4 small stone b
253     # 5 small stone w
254     # 6 grayed out
255     # 7 move
256     # 8 also move(?) or preset?
257     #
258     # $a1 is probably player again (2 == remove)
259     # x is from left 0 to right boardsize-1
260     # y is from top 0 to bottom boardsize-1
261     push @r, [$code_marker{$type} => dec_U8, dec_U8, dec_U8];
262    
263     } else {
264     push @r, [unknown => $type];
265     }
266     }
267     \@r;
268     }
269    
270     sub enc_TREE {
271     die "tree encoding not yet supported again";
272     for (@{$_[0]}) {
273     my ($type, @arg) = @$_;
274    
275     if ($type eq "add_child") {
276     enc_U8 255;
277     enc_I32 $arg[0];
278    
279     } elsif ($type eq "done") {
280     enc_U8 254;
281    
282     } elsif ($type eq "more") {
283     enc_U8 253;
284    
285     } elsif ($type eq "comment") {
286     # handle other string params, too
287     enc_U8 9;
288     enc_STRING $arg[0];
289    
290     } elsif ($type eq "label") {
291     enc_U8 0;
292     enc_U16 ord substr "$arg[0]\x00\x00", 0, 1;
293     enc_U16 ord substr "$arg[0]\x00\x00", 1, 1;
294     enc_U16 ord substr "$arg[0]\x00\x00", 2, 1;
295     enc_U8 $arg[1];
296     enc_U8 $arg[2];
297    
298     } elsif ($marker_code{$type}) {
299     enc_U8 $marker_code{$type};
300     enc_U8 $arg[0];
301     enc_U8 $arg[1];
302     enc_U8 $arg[2];
303    
304     } else {
305     warn "unable to encode tree node type $type\n";
306     }
307     }
308     }
309     ]]>
310    
311     #############################################################################
312     # messages
313     <xsl:apply-templates select="descendant::message"/>
314     }
315    
316     1;
317     </xsl:template>
318    
319     <xsl:template match="type[@type = 'S']">
320     sub dec_<xsl:value-of select="@name"/> {
321     my $res = "";
322     my @r = unpack "v<xsl:value-of select="@length"/> a*", $data;
323     $data = pop @r;
324     for (@r) {
325     last unless $_;
326     $res .= chr $_;
327     }
328     # dump extra data to file for later analysis
329     #my $x = pack "v*", @r; $x =~ s/^(..)*?\x00\x00//s; open DUMP, ">>/tmp/dump"; print DUMP $x; close DUMP;#d#
330     $res;
331     }
332    
333     sub enc_<xsl:value-of select="@name"/> {
334     $data .= pack "v<xsl:value-of select="@length"/>", map ord, split //, $_[0];
335     }
336     </xsl:template>
337    
338     <xsl:template match="type[@type = 'A']">
339     sub dec_<xsl:value-of select="@name"/> {
340     (my ($r), $data) = unpack "Z<xsl:value-of select="@length"/> a*", $data; $r;
341     }
342    
343     sub enc_<xsl:value-of select="@name"/> {
344     $data .= pack "Z<xsl:value-of select="@length"/>", $_[0];
345     }
346     </xsl:template>
347    
348     <xsl:template match="type[@multiplier]">
349     sub dec_<xsl:value-of select="@name"/> {
350     (1 / <xsl:value-of select="@multiplier"/>) * dec_<xsl:value-of select="@type"/>;
351     }
352    
353     sub enc_<xsl:value-of select="@name"/> {
354     enc_<xsl:value-of select="@type"/> $_[0] * <xsl:value-of select="@multiplier"/>;
355     }
356     </xsl:template>
357    
358     <xsl:template match="member[@array = 'yes']" mode="dec">
359     $r->{<xsl:value-of select="@name"/>} = (my $array = []);
360     while (length $data) {
361     push @$array, dec_<xsl:value-of select="@type"/>
362     <xsl:text> </xsl:text>
363     <xsl:value-of select="@default"/>;
364     }
365     </xsl:template>
366    
367     <xsl:template match="member" mode="dec">
368     $r->{<xsl:value-of select="@name"/>} = dec_<xsl:value-of select="@type"/>
369     <xsl:text> </xsl:text>
370     <xsl:value-of select="@default"/>
371     <xsl:if test="@guard-cond">
372     if ($r->{<xsl:value-of select="@guard-member"/>} <xsl:value-of select="@guard-cond"/>)</xsl:if>
373     <xsl:text>;</xsl:text>
374     </xsl:template>
375    
376     <xsl:template match="member" mode="enc">
377     <!-- #d#, remove when kgs is repaired --><xsl:if test="@type = 'username'">
378     $_[0]{<xsl:value-of select="@name"/>} =~ /^[A-Za-z][A-Za-z0-9]{0,11}$/
379     or Carp::confess "FATAL: tried to send illegal username '$_[0]{<xsl:value-of select="@name"/>}'";
380     </xsl:if><!--#d#-->
381     enc_<xsl:value-of select="@type"/> defined $_[0]{<xsl:value-of select="@name"/>} ? $_[0]{<xsl:value-of select="@name"/>
382     <xsl:text>} : (</xsl:text>
383     <xsl:value-of select="@default"/>
384     <xsl:text>);</xsl:text>
385     </xsl:template>
386    
387     <xsl:template match="struct">
388     sub dec_<xsl:value-of select="@name"/> {
389     my $r = {};
390     <xsl:apply-templates select="member" mode="dec"/>
391     <xsl:if test="@class">
392     bless $r, <xsl:value-of select="@class"/>::;
393     </xsl:if>
394     $r;
395     }
396    
397     sub enc_<xsl:value-of select="@name"/> {
398     <xsl:apply-templates select="member" mode="enc"/>
399     }
400     </xsl:template>
401    
402     <xsl:template match="message">
403     # <xsl:value-of select="@name"/>
404     $dec_<xsl:value-of select="@src"/>{0x<xsl:value-of select="@type"/>} = sub {
405     $data = $_[0];
406     my $r;
407     $r->{type} = "<xsl:value-of select="@name"/>";
408     <xsl:apply-templates select="member" mode="dec"/>
409     $r;
410     };
411     $enc_<xsl:value-of select="@src"/>{<xsl:value-of select="@name"/>} = sub {
412     $data = "";
413     enc_U16 0x<xsl:value-of select="@type"/>;
414     <xsl:apply-templates select="member" mode="enc"/>
415     $data;
416     };
417     </xsl:template>
418    
419     <xsl:template match="member">
420     [<xsl:value-of select="@name"/>
421     <xsl:text>=> "</xsl:text>
422     <xsl:value-of select="@type"/>
423     <xsl:text>", "</xsl:text>
424     <xsl:value-of select="@default"/>
425     <xsl:text>", "</xsl:text>
426     <xsl:value-of select="@guard"/>
427     <xsl:text>;"],</xsl:text>
428     </xsl:template>
429    
430     <xsl:template match="text()">
431     </xsl:template>
432    
433     </xsl:stylesheet>
434