Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_utf8_writer.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Adaptive Framework Value UTF-8 Writer
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
14 #include "afw_internal.h"
15 
16 
17 
18 typedef struct {
19  afw_writer_t pub;
20  apr_array_header_t *ary;
21  afw_boolean_t needs_leading_white_space;
23 
24 
25 #define AFW_IMPLEMENTATION_ID "afw_utf8_writer"
27 
28 /*
29  * Implementation of method write_eol for interface afw_writer.
30  */
31 static afw_size_t
32 impl_afw_writer_write_raw_cb(
33  void *context,
34  const void *buffer,
35  afw_size_t size,
36  const afw_pool_t *p,
37  afw_xctx_t *xctx)
38 {
40  afw_size_t i;
41 
42  for (i = 0; i < size; i++) {
43  APR_ARRAY_PUSH(self->ary, char) =
44  ((const afw_octet_t *)buffer)[i];
45  }
46  return size;
47 }
48 
49 
50 /* Create UTF-8 writer */
51 AFW_DEFINE(const afw_writer_t *)
53  const afw_utf8_t *tab,
54  const afw_pool_t *p,
55  afw_xctx_t *xctx)
56 {
58 
59  /* Create self and ary in its own pool. */
60  p = afw_pool_create(p, xctx);
61  self = afw_pool_calloc_type(p,
63  xctx);
64  self->pub.inf = &impl_afw_writer_inf;
65  self->pub.p = p;
66  self->pub.write_raw_cb = impl_afw_writer_write_raw_cb;
67  self->ary = apr_array_make(afw_pool_get_apr_pool(p), 4000, 1);
68  self->pub.tab = tab;
69 
70  /* Return new instance. */
71  return (const afw_writer_t *)self;
72 }
73 
74 
75 
76 /* Get the current string in a UTF-8 writer. */
77 AFW_DEFINE(void)
79  const afw_writer_t *writer,
80  afw_utf8_t *current_string,
81  afw_xctx_t *xctx)
82 {
84 
85  if (writer->inf != &impl_afw_writer_inf) {
86  AFW_THROW_ERROR_Z(general,
87  "afw_utf8_writer_get_string() can only be called by writer "
88  "created by afw_utf8_writer_create()", xctx);
89  }
90  current_string->s = self->ary->elts;
91  current_string->len = self->ary->nelts;
92 }
93 
94 
95 /*
96  * Implementation of method release for interface afw_writer.
97  */
98 void
99 impl_afw_writer_release(
100  const afw_writer_t * instance,
101  afw_xctx_t *xctx)
102 {
104  (impl_utf8_writer_self_t *)instance;
105 
106  /* Release writer resources. */
107  afw_pool_release(self->pub.p, xctx);
108 }
109 
110 /*
111  * Implementation of method flush for interface afw_writer.
112  */
113 void
114 impl_afw_writer_flush(
115  const afw_writer_t *instance,
116  afw_xctx_t *xctx)
117 {
118  /* Ignore flush. */
119 }
120 
121 /*
122  * Implementation of method write for interface afw_writer.
123  */
124 void
126  const afw_writer_t * instance,
127  const void * buffer,
128  afw_size_t size,
129  afw_xctx_t *xctx)
130 {
132  (impl_utf8_writer_self_t *)instance;
133  afw_size_t count, i;
134  const afw_octet_t *c;
135 
136  if (size == 0) {
137  return;
138  }
139 
140  if (self->needs_leading_white_space) {
141  for (count = 0; count < self->pub.indent; count++) {
142  for (i = 0; i < self->pub.tab->len; i++) {
143  APR_ARRAY_PUSH(self->ary, char) = self->pub.tab->s[i];
144  }
145  }
146  self->needs_leading_white_space = false;
147  }
148 
149  c = (const afw_octet_t *)buffer;
150  for (count = 0; count < size; count++) {
151  APR_ARRAY_PUSH(self->ary, char) = *c++;
152  }
153 }
154 
155 
156 /*
157  * Implementation of method write_eol for interface afw_writer.
158  */
159 void
161  const afw_writer_t * instance,
162  afw_xctx_t *xctx)
163 {
165  (impl_utf8_writer_self_t *)instance;
166 
167  if (self->pub.tab) {
168  APR_ARRAY_PUSH(self->ary, char) = '\n';
169  self->needs_leading_white_space = true;
170  }
171 }
172 
173 /*
174  * Implementation of method increment_indent for interface afw_writer.
175  */
176 void
177 impl_afw_writer_increment_indent(
178  const afw_writer_t * instance,
179  afw_xctx_t *xctx)
180 {
182  (impl_utf8_writer_self_t *)instance;
183 
184  self->pub.indent++;
185 }
186 
187 /*
188  * Implementation of method decrement_indent for interface afw_writer.
189  */
190 void
191 impl_afw_writer_decrement_indent(
192  const afw_writer_t * instance,
193  afw_xctx_t *xctx)
194 {
196  (impl_utf8_writer_self_t *)instance;
197 
198  self->pub.indent--;
199 }
AFW_DEFINE(const afw_object_t *)
Adaptive Framework Core Internal.
Interface afw_interface implementation declares.
_Bool afw_boolean_t
Definition: afw_common.h:373
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
unsigned char afw_octet_t
8 bits (unsigned).
Definition: afw_common.h:211
#define AFW_THROW_ERROR_Z(code, message_z, xctx)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:283
#define afw_pool_get_apr_pool(instance)
Call method get_apr_pool of interface afw_pool.
#define afw_pool_release(instance, xctx)
Call method release of interface afw_pool.
#define afw_pool_calloc_type(instance, type, xctx)
Macro to allocate cleared memory to hold type in pool.
Definition: afw_pool.h:167
const afw_pool_t * afw_pool_create(const afw_pool_t *parent, afw_xctx_t *xctx)
Create a new pool.
afw_utf8_writer_current_string(const afw_writer_t *writer, afw_utf8_t *current_string, afw_xctx_t *xctx)
Get the current string in a UTF-8 writer.
afw_utf8_writer_create(const afw_utf8_t *tab, const afw_pool_t *p, afw_xctx_t *xctx)
Create UTF-8 writer.
impl_afw_writer_write(const afw_writer_t *instance, const void *buffer, afw_size_t size, afw_xctx_t *xctx)
impl_afw_writer_write_eol(const afw_writer_t *instance, afw_xctx_t *xctx)
Interface afw_pool public struct.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
Interface afw_writer public struct.
Interface afw_xctx public struct.