2 #if !defined _CRT_SECURE_NO_WARNINGS
3 #define _CRT_SECURE_NO_WARNINGS /* NOLINT */
4 #endif /* _CRT_SECURE_NO_WARNINGS */
10 a_str
*const ctx
= (a_str
*)a_alloc(A_NULL
, sizeof(a_str
));
11 if (ctx
) { a_str_ctor(ctx
); }
15 void a_str_die(a_str
*ctx
)
24 void a_str_ctor(a_str
*ctx
)
31 void a_str_dtor(a_str
*ctx
)
35 a_alloc(ctx
->ptr_
, 0);
42 int a_str_init(a_str
*ctx
, void const *pdata
, a_size nbyte
)
45 ctx
->mem_
= ctx
->num_
+ 1;
46 ctx
->mem_
= a_size_up(sizeof(void *), ctx
->mem_
);
47 ctx
->ptr_
= (char *)a_alloc(A_NULL
, ctx
->mem_
);
48 if (a_unlikely(!ctx
->ptr_
)) { return A_FAILURE
; }
51 a_copy(ctx
->ptr_
, pdata
, nbyte
);
53 ctx
->ptr_
[ctx
->num_
] = 0;
57 int a_str_copy(a_str
*ctx
, a_str
const *obj
)
59 return a_str_init(ctx
, obj
->ptr_
, obj
->num_
);
62 void a_str_move(a_str
*ctx
, a_str
*obj
)
64 a_copy(ctx
, obj
, sizeof(*obj
));
65 a_zero(obj
, sizeof(*obj
));
68 char *a_str_exit(a_str
*ctx
)
70 char *const str
= ctx
->ptr_
;
73 ctx
->ptr_
[ctx
->num_
] = 0;
81 int a_str_cmp(a_str
const *lhs
, a_str
const *rhs
)
84 if (lhs
->ptr_
&& rhs
->ptr_
)
86 ok
= memcmp(lhs
->ptr_
, rhs
->ptr_
, A_MIN(lhs
->num_
, rhs
->num_
));
87 if (ok
) { return ok
; }
89 if (lhs
->num_
== rhs
->num_
) { return 0; }
90 return lhs
->num_
< rhs
->num_
? -1 : +1;
93 int a_str_alloc_(a_str
*ctx
, a_size mem
)
96 mem
= a_size_up(sizeof(void *), mem
);
97 ptr
= (char *)a_alloc(ctx
->ptr_
, mem
);
98 if (a_unlikely(!ptr
&& mem
)) { return A_FAILURE
; }
104 int a_str_alloc(a_str
*ctx
, a_size mem
)
106 return ctx
->mem_
< mem
? a_str_alloc_(ctx
, mem
) : A_SUCCESS
;
109 int a_str_getc_(a_str
*ctx
)
114 c
= (int)ctx
->ptr_
[--ctx
->num_
];
119 int a_str_getc(a_str
*ctx
)
124 c
= (int)ctx
->ptr_
[--ctx
->num_
];
125 ctx
->ptr_
[ctx
->num_
] = 0;
130 int a_str_putc_(a_str
*ctx
, int c
)
132 if (a_unlikely(a_str_alloc(ctx
, ctx
->num_
+ 1))) { return ~0; }
133 ctx
->ptr_
[ctx
->num_
++] = (char)c
;
137 int a_str_putc(a_str
*ctx
, int c
)
139 if (a_unlikely(a_str_alloc(ctx
, ctx
->num_
+ 2))) { return ~0; }
140 ctx
->ptr_
[ctx
->num_
++] = (char)c
;
141 ctx
->ptr_
[ctx
->num_
] = 0;
145 a_size
a_str_getn_(a_str
*ctx
, void *pdata
, a_size nbyte
)
147 if (nbyte
> ctx
->num_
) { nbyte
= ctx
->num_
; }
151 a_copy(pdata
, ctx
->ptr_
+ ctx
->num_
, nbyte
);
156 a_size
a_str_getn(a_str
*ctx
, void *pdata
, a_size nbyte
)
158 if (nbyte
> ctx
->num_
) { nbyte
= ctx
->num_
; }
162 a_copy(pdata
, ctx
->ptr_
+ ctx
->num_
, nbyte
);
163 ctx
->ptr_
[ctx
->num_
] = 0;
168 int a_str_putn_(a_str
*ctx
, void const *pdata
, a_size nbyte
)
172 if (a_unlikely(a_str_alloc(ctx
, ctx
->num_
+ nbyte
))) { return A_FAILURE
; }
173 a_copy(ctx
->ptr_
+ ctx
->num_
, pdata
, nbyte
);
179 int a_str_putn(a_str
*ctx
, void const *pdata
, a_size nbyte
)
183 if (a_unlikely(a_str_alloc(ctx
, ctx
->num_
+ nbyte
+ 1))) { return A_FAILURE
; }
184 a_copy(ctx
->ptr_
+ ctx
->num_
, pdata
, nbyte
);
186 ctx
->ptr_
[ctx
->num_
] = 0;
191 int a_str_puts_(a_str
*ctx
, void const *str
)
193 return a_str_putn_(ctx
, str
, strlen((char const *)str
));
196 int a_str_puts(a_str
*ctx
, void const *str
)
198 return a_str_putn(ctx
, str
, strlen((char const *)str
));
201 int a_str_cat_(a_str
*ctx
, a_str
const *obj
)
203 return a_str_putn_(ctx
, obj
->ptr_
, obj
->num_
);
206 int a_str_cat(a_str
*ctx
, a_str
const *obj
)
208 return a_str_putn(ctx
, obj
->ptr_
, obj
->num_
);
213 int a_str_putf_(a_str
*ctx
, char const *fmt
, va_list va
)
218 char *ptr
= ctx
->ptr_
? ctx
->ptr_
+ ctx
->num_
: ctx
->ptr_
;
220 mem
= ctx
->mem_
- ctx
->num_
;
221 res
= vsnprintf(ptr
, mem
, fmt
, ap
);
222 mem
= ctx
->num_
+ (size_t)(res
+ 1);
226 if (a_unlikely(a_str_alloc_(ctx
, mem
))) { return 0; }
228 ptr
= ctx
->ptr_
+ ctx
->num_
;
229 mem
= ctx
->mem_
- ctx
->num_
;
230 res
= vsnprintf(ptr
, mem
, fmt
, ap
);
233 if (res
> 0) { ctx
->num_
+= (size_t)res
; }
237 int a_str_putf(a_str
*ctx
, char const *fmt
, ...)
242 res
= a_str_putf_(ctx
, fmt
, va
);
249 a_size
a_str_utflen(a_str
const *ctx
)
254 char const *head
= ctx
->ptr_
;
255 char const *const tail
= head
+ ctx
->num_
;
256 unsigned int offset
= a_utf_decode(head
, A_NULL
);
257 for (; offset
; offset
= a_utf_decode(head
, A_NULL
))
261 if (head
>= tail
) { break; }