@@ -30,6 +30,7 @@ typedef struct lol_html_Element lol_html_element_t;
30
30
typedef struct lol_html_AttributesIterator lol_html_attributes_iterator_t ;
31
31
typedef struct lol_html_Attribute lol_html_attribute_t ;
32
32
typedef struct lol_html_Selector lol_html_selector_t ;
33
+ typedef struct lol_html_CStreamingHandlerSink lol_html_streaming_sink_t ;
33
34
34
35
// Library-allocated UTF8 string fat pointer.
35
36
//
@@ -116,6 +117,30 @@ typedef lol_html_rewriter_directive_t (*lol_html_end_tag_handler_t)(
116
117
void * user_data
117
118
);
118
119
120
+ // For use with streaming content handlers.
121
+ //
122
+ // Safety: the user data and the callbacks must be safe to use from a different thread (e.g. can't rely on thread-local storage).
123
+ // It doesn't have to be `Sync`, it will be used only by one thread at a time.
124
+ //
125
+ // Handler functions copy this struct. It can (and should) be created on the stack.
126
+ typedef struct lol_html_CStreamingHandler {
127
+ // Anything you like
128
+ void * user_data ;
129
+ // Called when the handler is supposed to produce its output. Return `0` for success.
130
+ // The `sink` argument is guaranteed non-`NULL`. It is valid only for the duration of this call, and can only be used on the same thread.
131
+ // The sink is for [`lol_html_streaming_sink_write_str`].
132
+ // `user_data` comes from this struct.
133
+ //
134
+ // `write_all_callback` must not be `NULL`.
135
+ int (* write_all_callback )(lol_html_streaming_sink_t * sink , void * user_data );
136
+ // Called exactly once, after the last use of this handler.
137
+ // It may be `NULL`.
138
+ // `user_data` comes from this struct.
139
+ void (* drop_callback )(void * user_data );
140
+ // *Always* initialize to `NULL`.
141
+ void * reserved ;
142
+ } lol_html_streaming_handler_t ;
143
+
119
144
// Selector
120
145
//---------------------------------------------------------------------
121
146
@@ -792,6 +817,209 @@ int lol_html_doc_end_append(
792
817
bool is_html
793
818
);
794
819
820
+
821
+
822
+ //[`Element::streaming_prepend`]
823
+ //
824
+ // The [`CStreamingHandler`] contains callbacks that will be called
825
+ // when the content needs to be written.
826
+ //
827
+ // `streaming_writer` is copied immediately, and doesn't have a stable address.
828
+ // `streaming_writer` may be used from another thread (`Send`), but it's only going
829
+ // to be used by one thread at a time (`!Sync`).
830
+ //
831
+ //`element`
832
+ // must be valid and non-`NULL`. If `streaming_writer` is `NULL`, an error will be reported.
833
+ //
834
+ // Returns 0 on success.
835
+ int lol_html_element_streaming_prepend (lol_html_element_t * element ,
836
+ lol_html_streaming_handler_t * streaming_writer );
837
+
838
+ //[`Element::streaming_append`]
839
+ //
840
+ // The [`CStreamingHandler`] contains callbacks that will be called
841
+ // when the content needs to be written.
842
+ //
843
+ // `streaming_writer` is copied immediately, and doesn't have a stable address.
844
+ // `streaming_writer` may be used from another thread (`Send`), but it's only going
845
+ // to be used by one thread at a time (`!Sync`).
846
+ //
847
+ //`element`
848
+ // must be valid and non-`NULL`. If `streaming_writer` is `NULL`, an error will be reported.
849
+ //
850
+ // Returns 0 on success.
851
+ int lol_html_element_streaming_append (lol_html_element_t * element ,
852
+ lol_html_streaming_handler_t * streaming_writer );
853
+
854
+ //[`Element::streaming_before`]
855
+ //
856
+ // The [`CStreamingHandler`] contains callbacks that will be called
857
+ // when the content needs to be written.
858
+ //
859
+ // `streaming_writer` is copied immediately, and doesn't have a stable address.
860
+ // `streaming_writer` may be used from another thread (`Send`), but it's only going
861
+ // to be used by one thread at a time (`!Sync`).
862
+ //
863
+ //`element`
864
+ // must be valid and non-`NULL`. If `streaming_writer` is `NULL`, an error will be reported.
865
+ //
866
+ // Returns 0 on success.
867
+ int lol_html_element_streaming_before (lol_html_element_t * element ,
868
+ lol_html_streaming_handler_t * streaming_writer );
869
+
870
+ //[`Element::streaming_after`]
871
+ //
872
+ // The [`CStreamingHandler`] contains callbacks that will be called
873
+ // when the content needs to be written.
874
+ //
875
+ // `streaming_writer` is copied immediately, and doesn't have a stable address.
876
+ // `streaming_writer` may be used from another thread (`Send`), but it's only going
877
+ // to be used by one thread at a time (`!Sync`).
878
+ //
879
+ //`element`
880
+ // must be valid and non-`NULL`. If `streaming_writer` is `NULL`, an error will be reported.
881
+ //
882
+ // Returns 0 on success.
883
+ int lol_html_element_streaming_after (lol_html_element_t * element ,
884
+ lol_html_streaming_handler_t * streaming_writer );
885
+
886
+ //[`Element::streaming_set_inner_content`]
887
+ //
888
+ // The [`CStreamingHandler`] contains callbacks that will be called
889
+ // when the content needs to be written.
890
+ //
891
+ // `streaming_writer` is copied immediately, and doesn't have a stable address.
892
+ // `streaming_writer` may be used from another thread (`Send`), but it's only going
893
+ // to be used by one thread at a time (`!Sync`).
894
+ //
895
+ //`element`
896
+ // must be valid and non-`NULL`. If `streaming_writer` is `NULL`, an error will be reported.
897
+ //
898
+ // Returns 0 on success.
899
+ int lol_html_element_streaming_set_inner_content (lol_html_element_t * element ,
900
+ lol_html_streaming_handler_t * streaming_writer );
901
+
902
+ //[`Element::streaming_replace`]
903
+ //
904
+ // The [`CStreamingHandler`] contains callbacks that will be called
905
+ // when the content needs to be written.
906
+ //
907
+ // `streaming_writer` is copied immediately, and doesn't have a stable address.
908
+ // `streaming_writer` may be used from another thread (`Send`), but it's only going
909
+ // to be used by one thread at a time (`!Sync`).
910
+ //
911
+ //`element`
912
+ // must be valid and non-`NULL`. If `streaming_writer` is `NULL`, an error will be reported.
913
+ //
914
+ // Returns 0 on success.
915
+ int lol_html_element_streaming_replace (lol_html_element_t * element ,
916
+ lol_html_streaming_handler_t * streaming_writer );
917
+
918
+ //[`EndTag::streaming_before`]
919
+ //
920
+ // The [`CStreamingHandler`] contains callbacks that will be called
921
+ // when the content needs to be written.
922
+ //
923
+ // `streaming_writer` is copied immediately, and doesn't have a stable address.
924
+ // `streaming_writer` may be used from another thread (`Send`), but it's only going
925
+ // to be used by one thread at a time (`!Sync`).
926
+ //
927
+ //`end_tag`
928
+ // must be valid and non-`NULL`. If `streaming_writer` is `NULL`, an error will be reported.
929
+ //
930
+ // Returns 0 on success.
931
+ int lol_html_end_tag_streaming_before (lol_html_end_tag_t * end_tag ,
932
+ lol_html_streaming_handler_t * streaming_writer );
933
+
934
+ //[`EndTag::streaming_after`]
935
+ //
936
+ // The [`CStreamingHandler`] contains callbacks that will be called
937
+ // when the content needs to be written.
938
+ //
939
+ // `streaming_writer` is copied immediately, and doesn't have a stable address.
940
+ // `streaming_writer` may be used from another thread (`Send`), but it's only going
941
+ // to be used by one thread at a time (`!Sync`).
942
+ //
943
+ //`end_tag`
944
+ // must be valid and non-`NULL`. If `streaming_writer` is `NULL`, an error will be reported.
945
+ //
946
+ // Returns 0 on success.
947
+ int lol_html_end_tag_streaming_after (lol_html_end_tag_t * end_tag ,
948
+ lol_html_streaming_handler_t * streaming_writer );
949
+
950
+ //[`EndTag::streaming_replace`]
951
+ //
952
+ // The [`CStreamingHandler`] contains callbacks that will be called
953
+ // when the content needs to be written.
954
+ //
955
+ // `streaming_writer` is copied immediately, and doesn't have a stable address.
956
+ // `streaming_writer` may be used from another thread (`Send`), but it's only going
957
+ // to be used by one thread at a time (`!Sync`).
958
+ //
959
+ //`end_tag`
960
+ // must be valid and non-`NULL`. If `streaming_writer` is `NULL`, an error will be reported.
961
+ //
962
+ // Returns 0 on success.
963
+ int lol_html_end_tag_streaming_replace (lol_html_end_tag_t * end_tag ,
964
+ lol_html_streaming_handler_t * streaming_writer );
965
+
966
+
967
+ //[`TextChunk::streaming_before`]
968
+ //
969
+ // The [`CStreamingHandler`] contains callbacks that will be called
970
+ // when the content needs to be written.
971
+ //
972
+ // `streaming_writer` is copied immediately, and doesn't have a stable address.
973
+ // `streaming_writer` may be used from another thread (`Send`), but it's only going
974
+ // to be used by one thread at a time (`!Sync`).
975
+ //
976
+ //`text_chunk`
977
+ // must be valid and non-`NULL`. If `streaming_writer` is `NULL`, an error will be reported.
978
+ //
979
+ // Returns 0 on success.
980
+ int lol_html_text_chunk_streaming_before (lol_html_text_chunk_t * text_chunk ,
981
+ lol_html_streaming_handler_t * streaming_writer );
982
+
983
+ //[`TextChunk::streaming_after`]
984
+ //
985
+ // The [`CStreamingHandler`] contains callbacks that will be called
986
+ // when the content needs to be written.
987
+ //
988
+ // `streaming_writer` is copied immediately, and doesn't have a stable address.
989
+ // `streaming_writer` may be used from another thread (`Send`), but it's only going
990
+ // to be used by one thread at a time (`!Sync`).
991
+ //
992
+ //`text_chunk`
993
+ // must be valid and non-`NULL`. If `streaming_writer` is `NULL`, an error will be reported.
994
+ //
995
+ // Returns 0 on success.
996
+ int lol_html_text_chunk_streaming_after (lol_html_text_chunk_t * text_chunk ,
997
+ lol_html_streaming_handler_t * streaming_writer );
998
+
999
+ //[`TextChunk::streaming_replace`]
1000
+ //
1001
+ // The [`CStreamingHandler`] contains callbacks that will be called
1002
+ // when the content needs to be written.
1003
+ //
1004
+ // `streaming_writer` is copied immediately, and doesn't have a stable address.
1005
+ // `streaming_writer` may be used from another thread (`Send`), but it's only going
1006
+ // to be used by one thread at a time (`!Sync`).
1007
+ //
1008
+ //`text_chunk`
1009
+ // must be valid and non-`NULL`. If `streaming_writer` is `NULL`, an error will be reported.
1010
+ //
1011
+ // Returns 0 on success.
1012
+ int lol_html_text_chunk_streaming_replace (lol_html_text_chunk_t * text_chunk ,
1013
+ lol_html_streaming_handler_t * streaming_writer );
1014
+
1015
+ // Write another piece of UTF-8 data to the output. Returns `0` on success, and `-1` if it wasn't valid UTF-8.
1016
+ // All pointers must be non-NULL.
1017
+ int lol_html_streaming_sink_write_str (lol_html_streaming_sink_t * sink ,
1018
+ const char * string_utf8 ,
1019
+ size_t string_utf8_len ,
1020
+ bool is_html );
1021
+
1022
+
795
1023
#if defined(__cplusplus )
796
1024
} // extern C
797
1025
#endif
0 commit comments