00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef CUTEXT_SINK_H
00019 #define CUTEXT_SINK_H
00020
00021 #include <cutext/fwd.h>
00022 #include <cu/buffer.h>
00023 #include <cu/box.h>
00024 #include <stdarg.h>
00025
00026 CU_BEGIN_DECLARATIONS
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 typedef enum {
00053 CUTEXT_SINK_INFO_ENCODING = 1,
00054 CUTEXT_SINK_INFO_NCOLUMNS = 3,
00055 CUTEXT_SINK_INFO_DEBUG_STATE = 0x70
00056 } cutext_sink_info_key_t;
00057
00058 typedef char const *cutext_sink_info_encoding_t;
00059 typedef cu_str_t cutext_sink_info_debug_state_t;
00060
00061 CU_SINLINE cu_bool_t
00062 cutext_sink_info_key_inherits(cutext_sink_info_key_t key)
00063 { return key & 1; }
00064
00065 struct cufo_tag;
00066 struct cufo_attrbind;
00067
00068 typedef struct cutext_sink_descriptor *cutext_sink_descriptor_t;
00069 struct cutext_sink_descriptor
00070 {
00071 unsigned int flags;
00072
00073 size_t (*write)(cutext_sink_t, void const *, size_t);
00074 cu_bool_t (*flush)(cutext_sink_t);
00075 cu_box_t (*finish)(cutext_sink_t);
00076 void (*discard)(cutext_sink_t);
00077 cu_bool_t (*iterA_subsinks)(cutext_sink_t, cu_clop(f, cu_bool_t, cutext_sink_t));
00078 cu_box_t (*info)(cutext_sink_t, cutext_sink_info_key_t);
00079 cu_bool_t (*enter)(cutext_sink_t, struct cufo_tag *,
00080 struct cufo_attrbind *);
00081 void (*leave)(cutext_sink_t, struct cufo_tag *);
00082 };
00083
00084 #define CUTEXT_SINK_FLAG_CLOGFREE 1
00085
00086 #define CUTEXT_SINK_DESCRIPTOR_DEFAULTS \
00087 .flags = 0, \
00088 .write = cutext_sink_noop_write, \
00089 .flush = cutext_sink_noop_flush, \
00090 .finish = cutext_sink_noop_finish, \
00091 .discard = cutext_sink_noop_discard, \
00092 .iterA_subsinks = cutext_sink_empty_iterA_subsinks, \
00093 .info = cutext_sink_default_info, \
00094 .enter = cutext_sink_noop_enter, \
00095 .leave = cutext_sink_noop_leave
00096
00097
00098 struct cutext_sink
00099 {
00100 cutext_sink_descriptor_t descriptor;
00101 };
00102
00103 CU_SINLINE cutext_sink_descriptor_t
00104 cutext_sink_descriptor(cutext_sink_t sink)
00105 { return sink->descriptor; }
00106
00107
00108 CU_SINLINE void
00109 cutext_sink_init(cutext_sink_t sink, cutext_sink_descriptor_t descriptor)
00110 {
00111 sink->descriptor = descriptor;
00112 }
00113
00114
00115 #define CU_DSINK_WRITE_ERROR ((size_t)-1)
00116
00117
00118
00119
00120
00121 CU_SINLINE size_t
00122 cutext_sink_write(cutext_sink_t sink, void const *buf, size_t max_size)
00123 {
00124 return (*sink->descriptor->write)(sink, buf, max_size);
00125 }
00126
00127 CU_SINLINE unsigned int
00128 cutext_sink_flags(cutext_sink_t sink)
00129 { return sink->descriptor->flags; }
00130
00131
00132
00133 CU_SINLINE cu_bool_t cutext_sink_is_clogfree(cutext_sink_t sink)
00134 { return sink->descriptor->flags & CUTEXT_SINK_FLAG_CLOGFREE; }
00135
00136
00137
00138
00139 void cutext_sink_assert_clogfree(cutext_sink_t sink);
00140
00141 CU_SINLINE cu_box_t
00142 cutext_sink_info(cutext_sink_t sink, cutext_sink_info_key_t key)
00143 { return (*sink->descriptor->info)(sink, key); }
00144
00145
00146
00147 cu_box_t cutext_sink_info_inherit(cutext_sink_t sink,
00148 cutext_sink_info_key_t key,
00149 cutext_sink_t subsink);
00150
00151 CU_SINLINE char const *
00152 cutext_sink_encoding(cutext_sink_t sink)
00153 { return cu_unbox_ptr(cutext_sink_info_encoding_t,
00154 cutext_sink_info(sink, CUTEXT_SINK_INFO_ENCODING)); }
00155
00156
00157
00158 CU_SINLINE cu_bool_t
00159 cutext_sink_flush(cutext_sink_t sink)
00160 {
00161 return (*sink->descriptor->flush)(sink);
00162 }
00163
00164
00165
00166
00167 CU_SINLINE cu_box_t
00168 cutext_sink_finish(cutext_sink_t sink)
00169 {
00170 return (*sink->descriptor->finish)(sink);
00171 }
00172
00173
00174
00175
00176
00177 CU_SINLINE void
00178 cutext_sink_discard(cutext_sink_t sink)
00179 {
00180 (*sink->descriptor->discard)(sink);
00181 }
00182
00183
00184 CU_SINLINE cu_bool_t
00185 cutext_sink_iterA_subsinks(cutext_sink_t sink, cu_clop(f, cu_bool_t, cutext_sink_t))
00186 {
00187 return (*sink->descriptor->iterA_subsinks)(sink, f);
00188 }
00189
00190 void cutext_sink_debug_dump(cutext_sink_t sink);
00191
00192
00193
00194
00195 size_t cutext_sink_noop_write(cutext_sink_t, void const *, size_t);
00196 cu_bool_t cutext_sink_noop_flush(cutext_sink_t);
00197 cu_box_t cutext_sink_noop_finish(cutext_sink_t);
00198 void cutext_sink_noop_discard(cutext_sink_t);
00199 size_t cutext_sink_subsinks_write(cutext_sink_t, void const *, size_t);
00200 cu_bool_t cutext_sink_subsinks_flush(cutext_sink_t);
00201 cu_bool_t cutext_sink_empty_iterA_subsinks(cutext_sink_t,
00202 cu_clop(f, cu_bool_t, cutext_sink_t));
00203 cu_box_t cutext_sink_default_info(cutext_sink_t, cutext_sink_info_key_t);
00204 cu_bool_t cutext_sink_noop_enter(cutext_sink_t, struct cufo_tag *,
00205 struct cufo_attrbind *);
00206 void cutext_sink_noop_leave(cutext_sink_t, struct cufo_tag *);
00207
00208
00209
00210
00211
00212
00213
00214
00215 cutext_sink_t cutext_sink_new_str(void);
00216
00217
00218
00219
00220 cutext_sink_t cutext_sink_new_wstring(void);
00221
00222 cutext_sink_t cutext_sink_fdopen(char const *encoding, int fd,
00223 cu_bool_t close_fd);
00224
00225 cutext_sink_t cutext_sink_fopen(char const *encoding, char const *path);
00226
00227
00228 cutext_sink_t cutext_sink_stack_buffer(cutext_sink_t subsink);
00229
00230
00231
00232 cutext_sink_t cutext_sink_stack_iconv(char const *new_encoding,
00233 cutext_sink_t subsink);
00234
00235
00236 struct cutext_countsink
00237 {
00238 cu_inherit (cutext_sink);
00239 size_t count;
00240 };
00241
00242 CU_SINLINE cutext_sink_t
00243 cutext_countsink_to_sink(cutext_countsink_t sink)
00244 { return cu_to(cutext_sink, sink); }
00245
00246
00247 void cutext_countsink_init(cutext_countsink_t sink);
00248
00249
00250 CU_SINLINE size_t
00251 cutext_countsink_count(cutext_countsink_t sink)
00252 { return sink->count; }
00253
00254
00255 struct cutext_buffersink
00256 {
00257 cu_inherit (cutext_sink);
00258 struct cu_buffer buffer;
00259 };
00260
00261 CU_SINLINE cutext_sink_t
00262 cutext_buffersink_to_sink(cutext_buffersink_t sink)
00263 { return cu_to(cutext_sink, sink); }
00264
00265
00266 void cutext_buffersink_init(cutext_buffersink_t sink);
00267
00268
00269 CU_SINLINE cu_buffer_t
00270 cutext_buffersink_buffer(cutext_buffersink_t sink)
00271 { return &sink->buffer; }
00272
00273
00274
00275 CU_END_DECLARATIONS
00276
00277 #endif