ox 1.9.0 → 1.9.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ox might be problematic. Click here for more details.
- data/README.md +4 -0
- data/ext/ox/sax.c +80 -33
- data/lib/ox/sax.rb +2 -2
- data/lib/ox/version.rb +1 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -34,6 +34,10 @@ A fast XML parser and Object marshaller as a Ruby gem.
|
|
34
34
|
|
35
35
|
## <a name="release">Release Notes</a>
|
36
36
|
|
37
|
+
### Release 1.9.1
|
38
|
+
|
39
|
+
- Fixed the line numbers to be the start of the elements in the sax parser.
|
40
|
+
|
37
41
|
### Release 1.9.0
|
38
42
|
|
39
43
|
- Added a new feature to Ox::Element.locate() that allows filtering by node Class.
|
data/ext/ox/sax.c
CHANGED
@@ -143,6 +143,20 @@ sax_drive_get(SaxDrive dr) {
|
|
143
143
|
return *dr->cur++;
|
144
144
|
}
|
145
145
|
|
146
|
+
static inline void
|
147
|
+
backup(SaxDrive dr) {
|
148
|
+
dr->cur--;
|
149
|
+
dr->col--; // should reverse wrap but not worth it
|
150
|
+
}
|
151
|
+
|
152
|
+
static inline void
|
153
|
+
reset_reader(SaxDrive dr, char *cur, int line, int col) {
|
154
|
+
dr->cur = cur;
|
155
|
+
dr->line = line;
|
156
|
+
dr->col = col;
|
157
|
+
}
|
158
|
+
|
159
|
+
|
146
160
|
/* Starts by reading a character so it is safe to use with an empty or
|
147
161
|
* compacted buffer.
|
148
162
|
*/
|
@@ -448,6 +462,8 @@ read_children(SaxDrive dr, int first) {
|
|
448
462
|
int err = 0;
|
449
463
|
int element_read = !first;
|
450
464
|
char c;
|
465
|
+
int line;
|
466
|
+
int col;
|
451
467
|
|
452
468
|
while (!err) {
|
453
469
|
dr->str = dr->cur; /* protect the start */
|
@@ -523,14 +539,19 @@ read_children(SaxDrive dr, int first) {
|
|
523
539
|
}
|
524
540
|
break;
|
525
541
|
case '/': /* element end */
|
526
|
-
|
542
|
+
line = dr->line;
|
543
|
+
col = dr->col;
|
544
|
+
err = ('\0' == read_name_token(dr));
|
545
|
+
dr->line = line;
|
546
|
+
dr->col = col;
|
547
|
+
return err;
|
527
548
|
break;
|
528
549
|
case '\0':
|
529
550
|
sax_drive_error(dr, "invalid format, document not terminated", 1);
|
530
551
|
err = 1;
|
531
552
|
break;
|
532
553
|
default:
|
533
|
-
|
554
|
+
backup(dr); /* safe since no read occurred after getting last character */
|
534
555
|
if (first && element_read) {
|
535
556
|
sax_drive_error(dr, "invalid format, multiple top level elements", 0);
|
536
557
|
}
|
@@ -578,6 +599,8 @@ read_instruction(SaxDrive dr) {
|
|
578
599
|
const char *err;
|
579
600
|
VALUE target = Qnil;
|
580
601
|
int is_xml;
|
602
|
+
int line = dr->line;
|
603
|
+
int col = dr->col - 1;
|
581
604
|
|
582
605
|
if ('\0' == (c = read_name_token(dr))) {
|
583
606
|
return -1;
|
@@ -590,18 +613,20 @@ read_instruction(SaxDrive dr) {
|
|
590
613
|
VALUE args[1];
|
591
614
|
|
592
615
|
if (dr->has_line) {
|
593
|
-
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(
|
616
|
+
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
|
594
617
|
}
|
595
618
|
if (dr->has_column) {
|
596
|
-
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(
|
619
|
+
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
|
597
620
|
}
|
598
621
|
args[0] = target;
|
599
622
|
rb_funcall2(dr->handler, ox_instruct_id, 1, args);
|
600
623
|
}
|
601
624
|
dr->str = dr->cur; /* make sure the start doesn't get compacted out */
|
625
|
+
line = dr->line;
|
626
|
+
col = dr->col;
|
602
627
|
read_content(dr, content, sizeof(content) - 1);
|
603
628
|
cend = dr->cur;
|
604
|
-
dr
|
629
|
+
reset_reader(dr, dr->str, line, col);
|
605
630
|
if (0 != (err = read_attrs(dr, c, '?', '?', is_xml))) {
|
606
631
|
if (dr->has_text) {
|
607
632
|
VALUE args[1];
|
@@ -622,15 +647,17 @@ read_instruction(SaxDrive dr) {
|
|
622
647
|
}
|
623
648
|
#endif
|
624
649
|
if (dr->has_line) {
|
625
|
-
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(
|
650
|
+
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
|
626
651
|
}
|
627
652
|
if (dr->has_column) {
|
628
|
-
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(
|
653
|
+
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
|
629
654
|
}
|
630
655
|
rb_funcall2(dr->handler, ox_text_id, 1, args);
|
631
656
|
}
|
632
657
|
dr->cur = cend;
|
633
658
|
} else {
|
659
|
+
line = dr->line;
|
660
|
+
col = dr->col;
|
634
661
|
c = next_non_white(dr);
|
635
662
|
if ('>' != c) {
|
636
663
|
sax_drive_error(dr, "invalid format, instruction not terminated", 1);
|
@@ -641,10 +668,10 @@ read_instruction(SaxDrive dr) {
|
|
641
668
|
VALUE args[1];
|
642
669
|
|
643
670
|
if (dr->has_line) {
|
644
|
-
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(
|
671
|
+
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
|
645
672
|
}
|
646
673
|
if (dr->has_column) {
|
647
|
-
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(
|
674
|
+
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
|
648
675
|
}
|
649
676
|
args[0] = target;
|
650
677
|
rb_funcall2(dr->handler, ox_end_instruct_id, 1, args);
|
@@ -659,6 +686,8 @@ read_instruction(SaxDrive dr) {
|
|
659
686
|
static int
|
660
687
|
read_doctype(SaxDrive dr) {
|
661
688
|
char c;
|
689
|
+
int line = dr->line;
|
690
|
+
int col = dr->col - 10;
|
662
691
|
|
663
692
|
dr->str = dr->cur - 1; /* mark the start */
|
664
693
|
while ('>' != (c = sax_drive_get(dr))) {
|
@@ -672,10 +701,10 @@ read_doctype(SaxDrive dr) {
|
|
672
701
|
VALUE args[1];
|
673
702
|
|
674
703
|
if (dr->has_line) {
|
675
|
-
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(
|
704
|
+
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
|
676
705
|
}
|
677
706
|
if (dr->has_column) {
|
678
|
-
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(
|
707
|
+
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
|
679
708
|
}
|
680
709
|
args[0] = rb_str_new2(dr->str);
|
681
710
|
rb_funcall2(dr->handler, ox_doctype_id, 1, args);
|
@@ -691,8 +720,10 @@ static int
|
|
691
720
|
read_cdata(SaxDrive dr) {
|
692
721
|
char c;
|
693
722
|
int end = 0;
|
723
|
+
int line = dr->line;
|
724
|
+
int col = dr->col - 10;
|
694
725
|
|
695
|
-
dr
|
726
|
+
backup(dr); /* back up to the start in case the cdata is empty */
|
696
727
|
dr->str = dr->cur; /* mark the start */
|
697
728
|
while (1) {
|
698
729
|
c = sax_drive_get(dr);
|
@@ -725,10 +756,10 @@ read_cdata(SaxDrive dr) {
|
|
725
756
|
}
|
726
757
|
#endif
|
727
758
|
if (dr->has_line) {
|
728
|
-
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(
|
759
|
+
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
|
729
760
|
}
|
730
761
|
if (dr->has_column) {
|
731
|
-
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(
|
762
|
+
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
|
732
763
|
}
|
733
764
|
rb_funcall2(dr->handler, ox_cdata_id, 1, args);
|
734
765
|
}
|
@@ -743,6 +774,8 @@ static int
|
|
743
774
|
read_comment(SaxDrive dr) {
|
744
775
|
char c;
|
745
776
|
int end = 0;
|
777
|
+
int line = dr->line;
|
778
|
+
int col = dr->col - 5;
|
746
779
|
|
747
780
|
dr->str = dr->cur - 1; /* mark the start */
|
748
781
|
while (1) {
|
@@ -779,10 +812,10 @@ read_comment(SaxDrive dr) {
|
|
779
812
|
}
|
780
813
|
#endif
|
781
814
|
if (dr->has_line) {
|
782
|
-
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(
|
815
|
+
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
|
783
816
|
}
|
784
817
|
if (dr->has_column) {
|
785
|
-
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(
|
818
|
+
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
|
786
819
|
}
|
787
820
|
rb_funcall2(dr->handler, ox_comment_id, 1, args);
|
788
821
|
}
|
@@ -801,6 +834,8 @@ read_element(SaxDrive dr) {
|
|
801
834
|
const char *err;
|
802
835
|
char c;
|
803
836
|
int closed;
|
837
|
+
int line = dr->line;
|
838
|
+
int col = dr->col - 1;
|
804
839
|
|
805
840
|
if ('\0' == (c = read_name_token(dr))) {
|
806
841
|
return -1;
|
@@ -810,10 +845,10 @@ read_element(SaxDrive dr) {
|
|
810
845
|
VALUE args[1];
|
811
846
|
|
812
847
|
if (dr->has_line) {
|
813
|
-
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(
|
848
|
+
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
|
814
849
|
}
|
815
850
|
if (dr->has_column) {
|
816
|
-
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(
|
851
|
+
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
|
817
852
|
}
|
818
853
|
args[0] = name;
|
819
854
|
rb_funcall2(dr->handler, ox_start_element_id, 1, args);
|
@@ -837,14 +872,16 @@ read_element(SaxDrive dr) {
|
|
837
872
|
}
|
838
873
|
}
|
839
874
|
if (closed) {
|
875
|
+
line = dr->line;
|
876
|
+
col = dr->col - 1;
|
840
877
|
if (dr->has_end_element) {
|
841
878
|
VALUE args[1];
|
842
879
|
|
843
880
|
if (dr->has_line) {
|
844
|
-
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(
|
881
|
+
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
|
845
882
|
}
|
846
883
|
if (dr->has_column) {
|
847
|
-
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(
|
884
|
+
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
|
848
885
|
}
|
849
886
|
args[0] = name;
|
850
887
|
rb_funcall2(dr->handler, ox_end_element_id, 1, args);
|
@@ -853,12 +890,16 @@ read_element(SaxDrive dr) {
|
|
853
890
|
if (0 != read_children(dr, 0)) {
|
854
891
|
return -1;
|
855
892
|
}
|
893
|
+
line = dr->line;
|
894
|
+
col = dr->col;
|
895
|
+
// read_children reads up to the end of the terminating element nameb
|
896
|
+
dr->col += dr->cur - dr->str;
|
856
897
|
if (0 != ename && 0 != strcmp(ename, dr->str)) {
|
857
898
|
if (dr->has_line) {
|
858
|
-
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(
|
899
|
+
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
|
859
900
|
}
|
860
901
|
if (dr->has_column) {
|
861
|
-
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(
|
902
|
+
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
|
862
903
|
}
|
863
904
|
//printf("*** ename: %s close: %s\n", ename, dr->str);
|
864
905
|
sax_drive_error(dr, "invalid format, element start and end names do not match", 1);
|
@@ -868,10 +909,10 @@ read_element(SaxDrive dr) {
|
|
868
909
|
VALUE args[1];
|
869
910
|
|
870
911
|
if (dr->has_line) {
|
871
|
-
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(
|
912
|
+
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
|
872
913
|
}
|
873
914
|
if (dr->has_column) {
|
874
|
-
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(
|
915
|
+
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col - 2));
|
875
916
|
}
|
876
917
|
args[0] = name;
|
877
918
|
rb_funcall2(dr->handler, ox_end_element_id, 1, args);
|
@@ -885,6 +926,8 @@ read_element(SaxDrive dr) {
|
|
885
926
|
static int
|
886
927
|
read_text(SaxDrive dr) {
|
887
928
|
char c;
|
929
|
+
int line = dr->line;
|
930
|
+
int col = dr->col - 1;
|
888
931
|
|
889
932
|
/* start marked in read_children */
|
890
933
|
/*dr->str = dr->cur - 1; / * mark the start */
|
@@ -899,10 +942,10 @@ read_text(SaxDrive dr) {
|
|
899
942
|
VALUE args[1];
|
900
943
|
|
901
944
|
if (dr->has_line) {
|
902
|
-
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(
|
945
|
+
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
|
903
946
|
}
|
904
947
|
if (dr->has_column) {
|
905
|
-
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(
|
948
|
+
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
|
906
949
|
}
|
907
950
|
*args = dr->value_obj;
|
908
951
|
rb_funcall2(dr->handler, ox_value_id, 1, args);
|
@@ -925,10 +968,10 @@ read_text(SaxDrive dr) {
|
|
925
968
|
}
|
926
969
|
#endif
|
927
970
|
if (dr->has_line) {
|
928
|
-
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(
|
971
|
+
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
|
929
972
|
}
|
930
973
|
if (dr->has_column) {
|
931
|
-
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(
|
974
|
+
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
|
932
975
|
}
|
933
976
|
rb_funcall2(dr->handler, ox_text_id, 1, args);
|
934
977
|
}
|
@@ -941,13 +984,17 @@ static const char*
|
|
941
984
|
read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml) {
|
942
985
|
VALUE name = Qnil;
|
943
986
|
int is_encoding = 0;
|
987
|
+
int line;
|
988
|
+
int col;
|
944
989
|
|
945
990
|
dr->str = dr->cur; /* lock it down */
|
946
991
|
if (is_white(c)) {
|
947
992
|
c = next_non_white(dr);
|
948
993
|
}
|
949
994
|
while (termc != c && term2 != c) {
|
950
|
-
dr
|
995
|
+
backup(dr);
|
996
|
+
line = dr->line;
|
997
|
+
col = dr->col;
|
951
998
|
if ('\0' == c) {
|
952
999
|
return "invalid format, attributes not terminated";
|
953
1000
|
}
|
@@ -982,10 +1029,10 @@ read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml) {
|
|
982
1029
|
VALUE args[2];
|
983
1030
|
|
984
1031
|
if (dr->has_line) {
|
985
|
-
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(
|
1032
|
+
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
|
986
1033
|
}
|
987
1034
|
if (dr->has_column) {
|
988
|
-
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(
|
1035
|
+
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
|
989
1036
|
}
|
990
1037
|
args[0] = name;
|
991
1038
|
args[1] = dr->value_obj;
|
@@ -1008,10 +1055,10 @@ read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml) {
|
|
1008
1055
|
}
|
1009
1056
|
#endif
|
1010
1057
|
if (dr->has_line) {
|
1011
|
-
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(
|
1058
|
+
rb_ivar_set(dr->handler, ox_at_line_id, INT2FIX(line));
|
1012
1059
|
}
|
1013
1060
|
if (dr->has_column) {
|
1014
|
-
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(
|
1061
|
+
rb_ivar_set(dr->handler, ox_at_column_id, INT2FIX(col));
|
1015
1062
|
}
|
1016
1063
|
rb_funcall2(dr->handler, ox_attr_id, 2, args);
|
1017
1064
|
}
|
data/lib/ox/sax.rb
CHANGED
@@ -44,8 +44,8 @@ module Ox
|
|
44
44
|
# def end_element(name); end
|
45
45
|
#
|
46
46
|
# Initializing @line in the initializer will cause that variable to be updated before each callback with the XML line
|
47
|
-
# number. The same is true for the @column but it will be updated with the column in the XML file that is the
|
48
|
-
# the element or node just read.
|
47
|
+
# number. The same is true for the @column but it will be updated with the column in the XML file that is the start of
|
48
|
+
# the element or node just read.
|
49
49
|
class Sax
|
50
50
|
# Create a new instance of the Sax handler class.
|
51
51
|
def initialize()
|
data/lib/ox/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.9.
|
4
|
+
version: 1.9.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-02-
|
12
|
+
date: 2013-02-27 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! "A fast XML parser and object serializer that uses only standard C
|
15
15
|
lib.\n \nOptimized XML (Ox), as the name implies was written to provide
|