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

# Content
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 import Data.Word
18 import Control.Monad.State
19
20 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
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