]> gitweb.factorcode.org Git - factor.git/blob - basis/xml/autoencoding/autoencoding.factor
Merge branch 'master' into new_ui
[factor.git] / basis / xml / autoencoding / autoencoding.factor
1 ! Copyright (C) 2005, 2009 Daniel Ehrenberg
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: kernel namespaces xml.name io.encodings.utf8 xml.elements
4 io.encodings.utf16 xml.tokenize xml.state math ascii sequences
5 io.encodings.string io.encodings combinators accessors
6 xml.data io.encodings.iana ;
7 IN: xml.autoencoding
8
9 : continue-make-tag ( str -- tag )
10     parse-name-starting middle-tag end-tag ;
11
12 : start-utf16le ( -- tag )
13     utf16le decode-input
14     "?\0" expect
15     check instruct ;
16
17 : 10xxxxxx? ( ch -- ? )
18     -6 shift 3 bitand 2 = ;
19           
20 : start<name ( ch -- tag )
21     ! This is unfortunate, and exists for the corner case
22     ! that the first letter of the document is < and second is
23     ! not ASCII
24     ascii?
25     [ utf8 decode-input next make-tag ] [
26         next
27         [ get-next 10xxxxxx? not ] take-until
28         get-char suffix utf8 decode
29         utf8 decode-input next
30         continue-make-tag
31     ] if ;
32
33 : prolog-encoding ( prolog -- )
34     encoding>> dup "UTF-16" =
35     [ drop ] [ name>encoding [ decode-input ] when* ] if ;
36
37 : instruct-encoding ( instruct/prolog -- )
38     dup prolog?
39     [ prolog-encoding ]
40     [ drop utf8 decode-input ] if ;
41
42 : go-utf8 ( -- )
43     check utf8 decode-input next next ;
44
45 : start< ( -- tag )
46     ! What if first letter of processing instruction is non-ASCII?
47     get-next {
48         { 0 [ next next start-utf16le ] }
49         { CHAR: ? [ go-utf8 instruct dup instruct-encoding ] }
50         { CHAR: ! [ go-utf8 direct ] }
51         [ check start<name ]
52     } case ;
53
54 : skip-utf8-bom ( -- tag )
55     "\u0000bb\u0000bf" expect utf8 decode-input
56     "<" expect check make-tag ;
57
58 : decode-expecting ( encoding string -- tag )
59     [ decode-input next ] [ expect ] bi* check make-tag ;
60
61 : start-utf16be ( -- tag )
62     utf16be "<" decode-expecting ;
63
64 : skip-utf16le-bom ( -- tag )
65     utf16le "\u0000fe<" decode-expecting ;
66
67 : skip-utf16be-bom ( -- tag )
68     utf16be "\u0000ff<" decode-expecting ;
69
70 : start-document ( -- tag )
71     get-char {
72         { CHAR: < [ start< ] }
73         { 0 [ start-utf16be ] }
74         { HEX: EF [ skip-utf8-bom ] }
75         { HEX: FF [ skip-utf16le-bom ] }
76         { HEX: FE [ skip-utf16be-bom ] }
77         [ drop utf8 decode-input check f ]
78     } case ;
79