34 #ifndef QORE_QORE_STRING_PRIVATE_H
35 #define QORE_QORE_STRING_PRIVATE_H
39 #define MAX_INT_STRING_LEN 48
40 #define MAX_BIGINT_STRING_LEN 48
41 #define MAX_FLOAT_STRING_LEN 48
42 #define STR_CLASS_BLOCK (0x10 * 4)
43 #define STR_CLASS_EXTRA (0x10 * 3)
45 #define MIN_SPRINTF_BUFSIZE 64
49 #define QUS_FRAGMENT 2
51 typedef std::vector<int> intvec_t;
53 hashdecl qore_string_private {
62 DLLLOCAL qore_string_private() {
65 DLLLOCAL qore_string_private(
const qore_string_private &p) {
66 allocated = p.len + STR_CLASS_EXTRA;
67 allocated = (allocated / 0x10 + 1) * 0x10;
68 buf = (
char*)malloc(
sizeof(
char) * allocated);
71 memcpy(buf, p.buf, len);
73 charset = p.getEncoding();
76 DLLLOCAL ~qore_string_private() {
84 allocated = i + (d < STR_CLASS_BLOCK ? STR_CLASS_BLOCK : d);
85 allocated = (allocated / 0x10 + 1) * 0x10;
86 buf = (
char*)realloc(buf, allocated *
sizeof(
char));
92 offset = len + offset;
93 return offset < 0 ? 0 : offset;
100 n_offset = check_offset(offset);
103 num = len + num - n_offset;
123 if (!(p = strchr(buf + pos, c)))
138 const char* p = buf + pos;
157 if (!(p = strstr(buf + pos, str)))
172 const char* p = buf + pos;
174 for (
const char* t = str; *t; ++t) {
183 DLLLOCAL
static qore_offset_t index_simple(
const char* haystack,
size_t hlen,
const char* needle,
size_t nlen,
185 const char* start = haystack + pos;
186 void* ptr =
q_memmem(start, hlen - pos, needle, nlen);
190 return reinterpret_cast<const char*
>(ptr) - start + pos;
200 if (!getEncoding()->isMultiByte()) {
210 return index_simple(buf, len, needle->c_str(), needle->size(), pos);
214 if (findByteOffset(pos, xsink))
221 qore_offset_t ind = index_simple(buf + pos, len - pos, needle->c_str(), needle->size());
223 ind = getEncoding()->getCharPos(buf, buf + pos + ind, xsink);
232 if (needle.
strlen() + pos > len)
239 if (needle.size() + pos > len)
242 return bindex(needle.c_str(), pos);
255 return index_simple(buf, len, needle, strlen(needle), pos);
267 }
else if (pos >= hlen) {
272 void* ptr =
q_memrmem(haystack, pos + 1, needle, nlen);
276 return static_cast<qore_offset_t>(
reinterpret_cast<const char*
>(ptr) -
reinterpret_cast<const char*
>(haystack));
282 assert(getEncoding()->isMultiByte());
288 qore_size_t clen = getEncoding()->getLength(buf + start, buf + len, xsink);
294 pos = getEncoding()->getByteLen(buf + start, buf + len, pos, xsink);
295 return *xsink ? -1 : 0;
304 if (!getEncoding()->isMultiByte()) {
311 return rindex_simple(buf, len, needle->c_str(), needle->size(), pos);
315 if (findByteOffset(pos, xsink))
321 qore_offset_t ind = rindex_simple(buf, len, needle->c_str(), needle->size(), pos);
324 if (ind && ind != -1) {
325 ind = getEncoding()->getCharPos(buf, buf + ind, xsink);
338 return brindex(needle.c_str(), needle.size(), pos);
342 if (needle_len + pos > len)
351 return rindex_simple(buf, len, needle, needle_len, pos);
354 DLLLOCAL
bool isDataPrintableAscii()
const {
356 if (buf[i] < 32 || buf[i] > 126)
362 DLLLOCAL
bool isDataAscii()
const {
364 if ((
unsigned char)(buf[i]) > 127)
370 DLLLOCAL
void concat_intern(
const char* p,
qore_size_t plen) {
373 check_char(len + plen);
374 memcpy(buf + len, p, plen);
379 DLLLOCAL
void concat_simple(
const qore_string_private& str,
qore_offset_t pos) {
388 concat_intern(str.buf + pos, str.len - pos);
392 assert(str.getEncoding() == getEncoding());
394 if (!getEncoding()->isMultiByte()) {
395 concat_simple(str, pos);
401 if (str.findByteOffset(pos, xsink))
409 concat_intern(str.buf + pos, str.len - pos);
423 plen = str.len + plen;
430 concat_intern(str.buf + pos, plen);
434 assert(str.getEncoding() == getEncoding());
437 if (!getEncoding()->isMultiByte()) {
438 concat_simple(str, pos);
444 if (str.findByteOffset(pos, xsink))
453 if (str.findByteOffset(plen, xsink, pos))
460 concat_intern(str.buf + pos, plen);
468 rc = getEncoding()->getByteLen(buf, buf + len, i, xsink);
477 DLLLOCAL
void concat(
char c) {
485 allocated = STR_CLASS_BLOCK;
487 buf = (
char*)malloc(
sizeof(
char) * allocated);
492 DLLLOCAL
void concat(
const qore_string_private* str) {
493 assert(!str || (str->charset == charset) || !str->charset);
496 if (str && str->len) {
498 check_char(str->len + len + STR_CLASS_EXTRA);
500 memcpy(buf + len, str->buf, str->len);
506 DLLLOCAL
void concat(
const char *str) {
515 buf[len++] = str[i++];
527 DLLLOCAL
int vsprintf(
const char *fmt, va_list args) {
528 size_t fmtlen = ::strlen(fmt);
530 if ((allocated - len - fmtlen) < MIN_SPRINTF_BUFSIZE) {
531 allocated += fmtlen + MIN_SPRINTF_BUFSIZE;
532 allocated = (allocated / 0x10 + 1) * 0x10;
534 buf = (
char*)realloc(buf, allocated *
sizeof(
char));
540 int i = ::vsnprintf(buf + len, free, fmt, args);
547 allocated += STR_CLASS_EXTRA;
548 allocated = (allocated / 0x10 + 1) * 0x10;
549 buf = (
char*)realloc(buf,
sizeof(
char) * allocated);
557 allocated = len + i + STR_CLASS_EXTRA;
558 allocated = (allocated / 0x10 + 1) * 0x10;
559 buf = (
char*)realloc(buf,
sizeof(
char) * allocated);
569 DLLLOCAL
int sprintf(
const char *fmt, ...) {
573 int rc = vsprintf(fmt, args);
581 DLLLOCAL
void concatUTF8FromUnicode(
unsigned code);
583 DLLLOCAL
int concatUnicode(
unsigned code,
ExceptionSink *xsink) {
586 concatUTF8FromUnicode(code);
591 tmp.concatUTF8FromUnicode(code);
592 TempString ns(tmp.convertEncoding(getEncoding(), xsink));
599 DLLLOCAL
int trimLeading(
ExceptionSink* xsink,
const intvec_t& vec);
600 DLLLOCAL
int trimLeading(
ExceptionSink* xsink,
const qore_string_private* chars);
601 DLLLOCAL
int trimTrailing(
ExceptionSink* xsink,
const intvec_t& vec);
602 DLLLOCAL
int trimTrailing(
ExceptionSink* xsink,
const qore_string_private* chars);
604 DLLLOCAL
void terminate(
size_t size);
606 DLLLOCAL
int concatUnicode(
unsigned code);
608 DLLLOCAL
int concatDecodeUriIntern(
ExceptionSink* xsink,
const qore_string_private& str,
bool detect_query =
false);
610 DLLLOCAL
int concatEncodeUriRequest(
ExceptionSink* xsink,
const qore_string_private& str);
617 DLLLOCAL
int getUnicodeCharArray(intvec_t& vec,
ExceptionSink* xsink)
const {
621 int c = getUnicodePointFromBytePos((
qore_offset_t)j, clen, xsink);
630 DLLLOCAL
int allocate(
unsigned requested_size) {
631 if ((
unsigned)allocated >= requested_size)
633 requested_size = (requested_size / 0x10 + 1) * 0x10;
634 char* aux = (
char*)realloc(buf, requested_size *
sizeof(
char));
641 allocated = requested_size;
651 DLLLOCAL
static bool inVector(
int c,
const intvec_t& vec) {
652 for (
unsigned j = 0; j < vec.size(); ++j) {
653 if ((
int)vec[j] == c)
659 DLLLOCAL
static qore_string_private* get(
QoreString& str) {
663 DLLLOCAL
static int getHex(
const char*& p) {
664 if (*p ==
'%' && isxdigit(*(p + 1)) && isxdigit(*(p + 2))) {
665 char x[3] = { *(p + 1), *(p + 2),
'\0' };
667 return strtol(x, 0, 16);