@@ -914,6 +914,112 @@ static struct stream_filter lf_to_crlf_filter_singleton = {
914
914
};
915
915
916
916
917
+ /*
918
+ * Cascade filter
919
+ */
920
+ #define FILTER_BUFFER 1024
921
+ struct cascade_filter {
922
+ struct stream_filter filter ;
923
+ struct stream_filter * one ;
924
+ struct stream_filter * two ;
925
+ char buf [FILTER_BUFFER ];
926
+ int end , ptr ;
927
+ };
928
+
929
+ static int cascade_filter_fn (struct stream_filter * filter ,
930
+ const char * input , size_t * isize_p ,
931
+ char * output , size_t * osize_p )
932
+ {
933
+ struct cascade_filter * cas = (struct cascade_filter * ) filter ;
934
+ size_t filled = 0 ;
935
+ size_t sz = * osize_p ;
936
+ size_t to_feed , remaining ;
937
+
938
+ /*
939
+ * input -- (one) --> buf -- (two) --> output
940
+ */
941
+ while (filled < sz ) {
942
+ remaining = sz - filled ;
943
+
944
+ /* do we already have something to feed two with? */
945
+ if (cas -> ptr < cas -> end ) {
946
+ to_feed = cas -> end - cas -> ptr ;
947
+ if (stream_filter (cas -> two ,
948
+ cas -> buf + cas -> ptr , & to_feed ,
949
+ output + filled , & remaining ))
950
+ return -1 ;
951
+ cas -> ptr += (cas -> end - cas -> ptr ) - to_feed ;
952
+ filled = sz - remaining ;
953
+ continue ;
954
+ }
955
+
956
+ /* feed one from upstream and have it emit into our buffer */
957
+ to_feed = input ? * isize_p : 0 ;
958
+ if (input && !to_feed )
959
+ break ;
960
+ remaining = sizeof (cas -> buf );
961
+ if (stream_filter (cas -> one ,
962
+ input , & to_feed ,
963
+ cas -> buf , & remaining ))
964
+ return -1 ;
965
+ cas -> end = sizeof (cas -> buf ) - remaining ;
966
+ cas -> ptr = 0 ;
967
+ if (input ) {
968
+ size_t fed = * isize_p - to_feed ;
969
+ * isize_p -= fed ;
970
+ input += fed ;
971
+ }
972
+
973
+ /* do we know that we drained one completely? */
974
+ if (input || cas -> end )
975
+ continue ;
976
+
977
+ /* tell two to drain; we have nothing more to give it */
978
+ to_feed = 0 ;
979
+ remaining = sz - filled ;
980
+ if (stream_filter (cas -> two ,
981
+ NULL , & to_feed ,
982
+ output + filled , & remaining ))
983
+ return -1 ;
984
+ if (remaining == (sz - filled ))
985
+ break ; /* completely drained two */
986
+ filled = sz - remaining ;
987
+ }
988
+ * osize_p -= filled ;
989
+ return 0 ;
990
+ }
991
+
992
+ static void cascade_free_fn (struct stream_filter * filter )
993
+ {
994
+ struct cascade_filter * cas = (struct cascade_filter * )filter ;
995
+ free_stream_filter (cas -> one );
996
+ free_stream_filter (cas -> two );
997
+ free (filter );
998
+ }
999
+
1000
+ static struct stream_filter_vtbl cascade_vtbl = {
1001
+ cascade_filter_fn ,
1002
+ cascade_free_fn ,
1003
+ };
1004
+
1005
+ static struct stream_filter * cascade_filter (struct stream_filter * one ,
1006
+ struct stream_filter * two )
1007
+ {
1008
+ struct cascade_filter * cascade ;
1009
+
1010
+ if (!one || is_null_stream_filter (one ))
1011
+ return two ;
1012
+ if (!two || is_null_stream_filter (two ))
1013
+ return one ;
1014
+
1015
+ cascade = xmalloc (sizeof (* cascade ));
1016
+ cascade -> one = one ;
1017
+ cascade -> two = two ;
1018
+ cascade -> end = cascade -> ptr = 0 ;
1019
+ cascade -> filter .vtbl = & cascade_vtbl ;
1020
+ return (struct stream_filter * )cascade ;
1021
+ }
1022
+
917
1023
/*
918
1024
* ident filter
919
1025
*/
@@ -1083,20 +1189,12 @@ struct stream_filter *get_stream_filter(const char *path, const unsigned char *s
1083
1189
crlf_action = input_crlf_action (ca .crlf_action , ca .eol_attr );
1084
1190
1085
1191
if ((crlf_action == CRLF_BINARY ) || (crlf_action == CRLF_INPUT ) ||
1086
- (crlf_action == CRLF_GUESS && auto_crlf == AUTO_CRLF_FALSE )) {
1087
- if (filter ) {
1088
- free_stream_filter (filter );
1089
- return NULL ;
1090
- }
1091
- return & null_filter_singleton ;
1092
- } else if (output_eol (crlf_action ) == EOL_CRLF &&
1093
- !(crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS )) {
1094
- if (filter ) {
1095
- free_stream_filter (filter );
1096
- return NULL ;
1097
- }
1098
- return & lf_to_crlf_filter_singleton ;
1099
- }
1192
+ (crlf_action == CRLF_GUESS && auto_crlf == AUTO_CRLF_FALSE ))
1193
+ filter = cascade_filter (filter , & null_filter_singleton );
1194
+
1195
+ else if (output_eol (crlf_action ) == EOL_CRLF &&
1196
+ !(crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS ))
1197
+ filter = cascade_filter (filter , & lf_to_crlf_filter_singleton );
1100
1198
1101
1199
return filter ;
1102
1200
}
0 commit comments