1
1
use std:: mem;
2
+ use std:: ops:: Index ;
3
+ use std:: ops:: IndexMut ;
2
4
use std:: str;
3
5
4
6
use super :: grapheme_iterator:: GraphemeClusters ;
@@ -51,7 +53,7 @@ pub trait EventHandler {
51
53
/// * `end_pos` - The end position of the current parse.
52
54
pub struct SAXParser < ' a > {
53
55
// Configuration and State
54
- pub events : u32 ,
56
+ pub events : [ bool ; 10 ] ,
55
57
state : State ,
56
58
brace_ct : u32 ,
57
59
quote : u8 ,
@@ -129,7 +131,7 @@ impl<'a> SAXParser<'a> {
129
131
pub fn new ( event_handler : & ' a dyn EventHandler ) -> SAXParser < ' a > {
130
132
SAXParser {
131
133
// Configuration and State
132
- events : 0 ,
134
+ events : [ false ; 10 ] ,
133
135
state : State :: Begin ,
134
136
brace_ct : 0 ,
135
137
quote : 0 ,
@@ -399,8 +401,8 @@ impl<'a> SAXParser<'a> {
399
401
return ;
400
402
}
401
403
402
- if self . events & Event :: OpenTagStart as u32 != 0 {
403
- self . event_handler . handle_event ( Event :: OpenTagStart , Entity :: Tag ( & mut self . tag ) ) ;
404
+ if self . events [ Event :: OpenTagStart ] {
405
+ self . event_handler . handle_event ( Event :: OpenTagStart , Entity :: Tag ( & self . tag ) ) ;
404
406
}
405
407
match current. 0 {
406
408
">" => self . process_open_tag ( false , current) ,
@@ -439,11 +441,11 @@ impl<'a> SAXParser<'a> {
439
441
440
442
let mut text = mem:: replace ( & mut self . text , Text :: new ( [ line, character] ) ) ;
441
443
text. end = [ line, character - 1 ] ;
442
- if self . events & Event :: Text as u32 != 0 {
443
- self . event_handler . handle_event ( Event :: Text , Entity :: Text ( & mut text) ) ;
444
+ if self . events [ Event :: Text ] {
445
+ self . event_handler . handle_event ( Event :: Text , Entity :: Text ( & text) ) ;
444
446
}
445
447
// Store these only if we're interested in CloseTag events
446
- if len != 0 && self . events & Event :: CloseTag as u32 != 0 {
448
+ if len != 0 && self . events [ Event :: CloseTag ] {
447
449
self . tags [ len - 1 ] . text_nodes . push ( text) ;
448
450
}
449
451
}
@@ -481,10 +483,10 @@ impl<'a> SAXParser<'a> {
481
483
482
484
if current. 0 == ">" {
483
485
let mut sgml_decl = mem:: replace ( & mut self . sgml_decl , Text :: new ( [ 0 , 0 ] ) ) ;
484
- if self . events & Event :: SGMLDeclaration as u32 != 0 {
486
+ if self . events [ Event :: SGMLDeclaration ] {
485
487
sgml_decl. value . extend_from_slice ( current. 0 . as_bytes ( ) ) ;
486
488
sgml_decl. end = [ current. 1 , current. 2 - 1 ] ;
487
- self . event_handler . handle_event ( Event :: SGMLDeclaration , Entity :: Text ( & mut sgml_decl) ) ;
489
+ self . event_handler . handle_event ( Event :: SGMLDeclaration , Entity :: Text ( & sgml_decl) ) ;
488
490
}
489
491
490
492
self . new_text ( current) ;
@@ -514,10 +516,10 @@ impl<'a> SAXParser<'a> {
514
516
fn doctype ( & mut self , current : & GraphemeResult ) {
515
517
if current. 0 == ">" {
516
518
self . new_text ( current) ;
517
- if self . events & Event :: Doctype as u32 != 0 {
519
+ if self . events [ Event :: Doctype ] {
518
520
let mut doctype = mem:: replace ( & mut self . doctype , Text :: new ( [ 0 , 0 ] ) ) ;
519
521
doctype. end = [ current. 1 , current. 2 - 1 ] ;
520
- self . event_handler . handle_event ( Event :: Doctype , Entity :: Text ( & mut doctype) ) ;
522
+ self . event_handler . handle_event ( Event :: Doctype , Entity :: Text ( & doctype) ) ;
521
523
}
522
524
return ;
523
525
}
@@ -568,7 +570,7 @@ impl<'a> SAXParser<'a> {
568
570
if let Some ( comment) = comment_result {
569
571
comment_str = comment. 0 ;
570
572
}
571
- if self . events & Event :: Comment as u32 != 0 {
573
+ if self . events [ Event :: Comment ] {
572
574
self . comment . value . extend_from_slice ( current. 0 . as_bytes ( ) ) ;
573
575
self . comment . value . extend_from_slice ( comment_str. as_bytes ( ) ) ;
574
576
}
@@ -579,7 +581,7 @@ impl<'a> SAXParser<'a> {
579
581
self . state = State :: CommentEnded ;
580
582
return ;
581
583
}
582
- if self . events & Event :: Comment as u32 != 0 {
584
+ if self . events [ Event :: Comment ] {
583
585
self . comment . value . push ( b'-' ) ;
584
586
self . comment . value . extend_from_slice ( current. 0 . as_bytes ( ) ) ;
585
587
}
@@ -588,15 +590,15 @@ impl<'a> SAXParser<'a> {
588
590
589
591
fn comment_ended ( & mut self , current : & GraphemeResult ) {
590
592
if current. 0 == ">" {
591
- if self . events & Event :: Comment as u32 != 0 {
593
+ if self . events [ Event :: Comment ] {
592
594
let mut comment = mem:: replace ( & mut self . comment , Text :: new ( [ 0 , 0 ] ) ) ;
593
595
comment. end = [ current. 1 , current. 2 - 1 ] ;
594
- self . event_handler . handle_event ( Event :: Comment , Entity :: Text ( & mut comment) ) ;
596
+ self . event_handler . handle_event ( Event :: Comment , Entity :: Text ( & comment) ) ;
595
597
}
596
598
self . state = State :: BeginWhitespace ;
597
599
return ;
598
600
}
599
- if self . events & Event :: Comment as u32 != 0 {
601
+ if self . events [ Event :: Comment ] {
600
602
self . comment . value . extend_from_slice ( "--" . as_bytes ( ) ) ;
601
603
self . comment . value . extend_from_slice ( current. 0 . as_bytes ( ) ) ;
602
604
}
@@ -627,10 +629,10 @@ impl<'a> SAXParser<'a> {
627
629
fn cdata_ending_2 ( & mut self , current : & GraphemeResult ) {
628
630
if current. 0 == ">" {
629
631
self . new_text ( current) ;
630
- if self . events & Event :: Cdata as u32 != 0 {
632
+ if self . events [ Event :: Cdata ] {
631
633
let mut cdata = mem:: replace ( & mut self . cdata , Text :: new ( [ 0 , 0 ] ) ) ;
632
634
cdata. end = [ current. 1 , current. 2 - 1 ] ;
633
- self . event_handler . handle_event ( Event :: Cdata , Entity :: Text ( & mut cdata) ) ;
635
+ self . event_handler . handle_event ( Event :: Cdata , Entity :: Text ( & cdata) ) ;
634
636
}
635
637
return ;
636
638
} else if current. 0 == "]" {
@@ -683,9 +685,9 @@ impl<'a> SAXParser<'a> {
683
685
if current. 0 == ">" {
684
686
self . new_text ( current) ;
685
687
let mut proc_inst = mem:: replace ( & mut self . proc_inst , ProcInst :: new ( ) ) ;
686
- if self . events & Event :: ProcessingInstruction as u32 != 0 {
688
+ if self . events [ Event :: ProcessingInstruction ] {
687
689
proc_inst. end = [ current. 1 , current. 2 ] ;
688
- self . event_handler . handle_event ( Event :: ProcessingInstruction , Entity :: ProcInst ( & mut proc_inst) ) ;
690
+ self . event_handler . handle_event ( Event :: ProcessingInstruction , Entity :: ProcInst ( & proc_inst) ) ;
689
691
}
690
692
return ;
691
693
}
@@ -852,13 +854,13 @@ impl<'a> SAXParser<'a> {
852
854
}
853
855
854
856
fn process_attribute ( & mut self ) {
855
- let mut attr = mem:: replace ( & mut self . attribute , Attribute :: new ( ) ) ;
856
- let attribute_event = self . events & Event :: Attribute as u32 != 0 ;
857
+ let attr = mem:: replace ( & mut self . attribute , Attribute :: new ( ) ) ;
858
+ let attribute_event = self . events [ Event :: Attribute ] ;
857
859
if attribute_event {
858
- self . event_handler . handle_event ( Event :: Attribute , Entity :: Attribute ( & mut attr) ) ;
860
+ self . event_handler . handle_event ( Event :: Attribute , Entity :: Attribute ( & attr) ) ;
859
861
}
860
862
// Store them only if we're interested in Open and Close tag events
861
- if attribute_event || self . events & Event :: CloseTag as u32 != 0 {
863
+ if attribute_event || self . events [ Event :: CloseTag ] {
862
864
self . tag . attributes . push ( attr) ;
863
865
}
864
866
}
@@ -868,8 +870,8 @@ impl<'a> SAXParser<'a> {
868
870
tag. self_closing = self_closing;
869
871
tag. open_end = [ current. 1 , current. 2 ] ;
870
872
871
- if self . events & Event :: OpenTag as u32 != 0 {
872
- self . event_handler . handle_event ( Event :: OpenTag , Entity :: Tag ( & mut tag) ) ;
873
+ if self . events [ Event :: OpenTag ] {
874
+ self . event_handler . handle_event ( Event :: OpenTag , Entity :: Tag ( & tag) ) ;
873
875
}
874
876
if !self_closing {
875
877
self . new_text ( current) ;
@@ -881,7 +883,7 @@ impl<'a> SAXParser<'a> {
881
883
self . new_text ( current) ;
882
884
let mut tags_len = self . tags . len ( ) ;
883
885
884
- let close_tag_name = if self . close_tag_name . is_empty ( ) && self . tag . self_closing {
886
+ let close_tag_name = if self . tag . self_closing && self . close_tag_name . is_empty ( ) {
885
887
& self . tag . name
886
888
} else {
887
889
& mem:: take ( & mut self . close_tag_name )
@@ -909,7 +911,7 @@ impl<'a> SAXParser<'a> {
909
911
return ;
910
912
}
911
913
912
- if self . events & Event :: CloseTag as u32 == 0 {
914
+ if ! self . events [ Event :: CloseTag ] {
913
915
if tag_index > 1 {
914
916
self . tags . truncate ( tag_index) ;
915
917
return ;
@@ -925,7 +927,7 @@ impl<'a> SAXParser<'a> {
925
927
let mut tag = self . tags . remove ( tags_len) ;
926
928
tag. close_end = [ current. 1 , current. 2 ] ;
927
929
928
- self . event_handler . handle_event ( Event :: CloseTag , Entity :: Tag ( & mut tag) ) ;
930
+ self . event_handler . handle_event ( Event :: CloseTag , Entity :: Tag ( & tag) ) ;
929
931
self . tag = tag;
930
932
}
931
933
}
@@ -956,14 +958,14 @@ impl<'a> SAXParser<'a> {
956
958
}
957
959
958
960
fn new_text ( & mut self , current : & GraphemeResult ) {
959
- if self . events & Event :: Text as u32 != 0 || self . events & Event :: CloseTag as u32 != 0 {
961
+ if self . events [ Event :: Text ] || self . events [ Event :: CloseTag ] {
960
962
self . text = Text :: new ( [ current. 1 , current. 2 ] ) ;
961
963
}
962
964
self . state = State :: Text ;
963
965
}
964
966
965
967
fn write_text ( & mut self , grapheme : & [ u8 ] ) {
966
- if self . events & Event :: Text as u32 == 0 && self . events & Event :: CloseTag as u32 == 0 {
968
+ if ! self . events [ Event :: Text ] && ! self . events [ Event :: CloseTag ] {
967
969
return ;
968
970
}
969
971
self . text . value . extend_from_slice ( grapheme) ;
@@ -973,25 +975,40 @@ impl<'a> SAXParser<'a> {
973
975
#[ derive( PartialEq , Clone , Copy ) ]
974
976
pub enum Event {
975
977
// 1
976
- Text = 0b0000000001 ,
978
+ Text = 0 ,
977
979
// 2
978
- ProcessingInstruction = 0b0000000010 ,
980
+ ProcessingInstruction = 1 ,
979
981
// 4
980
- SGMLDeclaration = 0b0000000100 ,
982
+ SGMLDeclaration = 2 ,
981
983
// 8
982
- Doctype = 0b0000001000 ,
984
+ Doctype = 3 ,
983
985
// 16
984
- Comment = 0b0000010000 ,
986
+ Comment = 4 ,
985
987
// 32
986
- OpenTagStart = 0b0000100000 ,
988
+ OpenTagStart = 5 ,
987
989
// 64
988
- Attribute = 0b0001000000 ,
990
+ Attribute = 6 ,
989
991
// 128
990
- OpenTag = 0b0010000000 ,
992
+ OpenTag = 7 ,
991
993
// 256
992
- CloseTag = 0b0100000000 ,
994
+ CloseTag = 8 ,
993
995
// 512
994
- Cdata = 0b1000000000 ,
996
+ Cdata = 9 ,
997
+ }
998
+
999
+ impl Index < Event > for [ bool ; 10 ] {
1000
+ type Output = bool ;
1001
+ #[ inline( always) ]
1002
+ fn index ( & self , event : Event ) -> & Self :: Output {
1003
+ unsafe { & self . get_unchecked ( event as usize ) }
1004
+ }
1005
+ }
1006
+
1007
+ impl IndexMut < Event > for [ bool ; 10 ] {
1008
+ #[ inline( always) ]
1009
+ fn index_mut ( & mut self , event : Event ) -> & mut Self :: Output {
1010
+ unsafe { self . get_unchecked_mut ( event as usize ) }
1011
+ }
995
1012
}
996
1013
997
1014
#[ derive( PartialEq ) ]
@@ -1104,7 +1121,9 @@ mod tests {
1104
1121
fn stream_very_large_xml ( ) -> Result < ( ) > {
1105
1122
let event_handler = TextEventHandler :: new ( ) ;
1106
1123
let mut sax = SAXParser :: new ( & event_handler) ;
1107
- sax. events = Event :: Text as u32 ;
1124
+ let mut events = [ false ; 10 ] ;
1125
+ events[ Event :: Text ] = true ;
1126
+ sax. events = events;
1108
1127
let f = File :: open ( "src/js/__test__/xml.xml" ) ?;
1109
1128
let mut reader = BufReader :: new ( f) ;
1110
1129
const BUFFER_LEN : usize = 32 * 1024 ;
@@ -1124,7 +1143,9 @@ mod tests {
1124
1143
fn test_comment ( ) -> Result < ( ) > {
1125
1144
let event_handler = TextEventHandler :: new ( ) ;
1126
1145
let mut sax = SAXParser :: new ( & event_handler) ;
1127
- sax. events = Event :: Comment as u32 ;
1146
+ let mut events = [ false ; 10 ] ;
1147
+ events[ Event :: Comment ] = true ;
1148
+ sax. events = events;
1128
1149
let str = "<!--name='test 3 attr' some comment--> <-- name='test 3 attr' some comment -->" ;
1129
1150
1130
1151
sax. write ( str. as_bytes ( ) ) ;
@@ -1142,7 +1163,9 @@ mod tests {
1142
1163
fn test_4_bytes ( ) -> Result < ( ) > {
1143
1164
let event_handler = TextEventHandler :: new ( ) ;
1144
1165
let mut sax = SAXParser :: new ( & event_handler) ;
1145
- sax. events = Event :: Text as u32 ;
1166
+ let mut events = [ false ; 10 ] ;
1167
+ events[ Event :: Text ] = true ;
1168
+ sax. events = events;
1146
1169
let str = "🏴📚📚🏴📚📚🏴📚📚🏴📚📚🏴📚📚🏴📚📚🏴📚📚🏴📚📚🏴📚📚🏴📚📚" ;
1147
1170
let bytes = str. as_bytes ( ) ;
1148
1171
sax. write ( & bytes[ 0 ..14 ] ) ;
@@ -1161,7 +1184,9 @@ mod tests {
1161
1184
fn count_grapheme_length ( ) -> Result < ( ) > {
1162
1185
let event_handler = TextEventHandler :: new ( ) ;
1163
1186
let mut sax = SAXParser :: new ( & event_handler) ;
1164
- sax. events = Event :: Text as u32 ;
1187
+ let mut events = [ false ; 10 ] ;
1188
+ events[ Event :: Text ] = true ;
1189
+ sax. events = events;
1165
1190
let str = "🏴📚📚<div href=\" ./123/123\" >hey there</div>" ;
1166
1191
1167
1192
sax. write ( str. as_bytes ( ) ) ;
@@ -1179,7 +1204,9 @@ mod tests {
1179
1204
fn parse_jsx_expression ( ) -> Result < ( ) > {
1180
1205
let event_handler = TextEventHandler :: new ( ) ;
1181
1206
let mut sax = SAXParser :: new ( & event_handler) ;
1182
- sax. events = Event :: Text as u32 ;
1207
+ let mut events = [ false ; 10 ] ;
1208
+ events[ Event :: Text ] = true ;
1209
+ sax. events = events;
1183
1210
let str = "<foo>{bar < baz ? <div></div> : <></>}</foo>" ;
1184
1211
1185
1212
sax. write ( str. as_bytes ( ) ) ;
@@ -1202,7 +1229,9 @@ mod tests {
1202
1229
fn parse_empty_cdata ( ) -> Result < ( ) > {
1203
1230
let event_handler = TextEventHandler :: new ( ) ;
1204
1231
let mut sax = SAXParser :: new ( & event_handler) ;
1205
- sax. events = Event :: Cdata as u32 ;
1232
+ let mut events = [ false ; 10 ] ;
1233
+ events[ Event :: Cdata ] = true ;
1234
+ sax. events = events;
1206
1235
let str = "<div>
1207
1236
<div>
1208
1237
<![CDATA[]]>
0 commit comments