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