Qore Programming Language 1.19.1
Loading...
Searching...
No Matches
qore_string_private.h
1/* -*- mode: c++; indent-tabs-mode: nil -*- */
2/*
3 qore_string_private.h
4
5 QoreString private implementation
6
7 Qore Programming Language
8
9 Copyright (C) 2003 - 2023 Qore Technologies, s.r.o.
10
11 Permission is hereby granted, free of charge, to any person obtaining a
12 copy of this software and associated documentation files (the "Software"),
13 to deal in the Software without restriction, including without limitation
14 the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 and/or sell copies of the Software, and to permit persons to whom the
16 Software is furnished to do so, subject to the following conditions:
17
18 The above copyright notice and this permission notice shall be included in
19 all copies or substantial portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 DEALINGS IN THE SOFTWARE.
28
29 Note that the Qore library is released under a choice of three open-source
30 licenses: MIT (as above), LGPL 2+, or GPL 2+; see README-LICENSE for more
31 information.
32*/
33
34#ifndef QORE_QORE_STRING_PRIVATE_H
35#define QORE_QORE_STRING_PRIVATE_H
36
37#include <vector>
38
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)
44
45#define MIN_SPRINTF_BUFSIZE 64
46
47#define QUS_PATH 0
48#define QUS_QUERY 1
49#define QUS_FRAGMENT 2
50
51typedef std::vector<int> intvec_t;
52
53hashdecl qore_string_private {
54public:
55 size_t len = 0;
56 size_t allocated = 0;
57 char* buf = nullptr;
58 const QoreEncoding* encoding = nullptr;
59
60 DLLLOCAL qore_string_private() {
61 }
62
63 DLLLOCAL qore_string_private(const qore_string_private &p) {
64 allocated = p.len + STR_CLASS_EXTRA;
65 allocated = (allocated / 0x10 + 1) * 0x10; // use complete cache line
66 buf = (char*)malloc(sizeof(char) * allocated);
67 len = p.len;
68 if (len)
69 memcpy(buf, p.buf, len);
70 buf[len] = '\0';
71 encoding = p.getEncoding();
72 }
73
74 DLLLOCAL ~qore_string_private() {
75 if (buf) {
76 free(buf);
77 }
78 }
79
80 DLLLOCAL void check_char(size_t i) {
81 if (i >= allocated) {
82 size_t d = i >> 2;
83 allocated = i + (d < STR_CLASS_BLOCK ? STR_CLASS_BLOCK : d);
84 allocated = (allocated / 0x10 + 1) * 0x10; // use complete cache line
85 buf = (char*)realloc(buf, allocated * sizeof(char));
86 }
87 }
88
89 DLLLOCAL size_t check_offset(qore_offset_t offset) {
90 if (offset < 0) {
91 offset = len + offset;
92 return offset < 0 ? 0 : offset;
93 }
94
95 return ((size_t)offset > len) ? len : offset;
96 }
97
98 DLLLOCAL void check_offset(qore_offset_t offset, qore_offset_t num, size_t &n_offset, size_t &n_num) {
99 n_offset = check_offset(offset);
100
101 if (num < 0) {
102 num = len + num - n_offset;
103 if (num < 0)
104 n_num = 0;
105 else
106 n_num = num;
107 return;
108 }
109 n_num = num;
110 }
111
112 // NOTE: this is purely byte oriented - no character semantics here
113 DLLLOCAL qore_offset_t find(char c, qore_offset_t pos = 0) {
114 if (pos < 0) {
115 pos = len + pos;
116 if (pos < 0)
117 pos = 0;
118 } else if (pos > 0 && pos > (qore_offset_t)len)
119 return -1;
120 const char* p;
121 if (!(p = strchr(buf + pos, c)))
122 return -1;
123 return (qore_offset_t)(p - buf);
124 }
125
126 // NOTE: this is purely byte oriented - no character semantics here
127 DLLLOCAL qore_offset_t rfind(char c, qore_offset_t pos = -1) {
128 if (pos < 0) {
129 pos = len + pos;
130 if (pos < 0)
131 return -1;
132 } else if (pos > 0 && pos > (qore_offset_t)len)
133 pos = len - 1;
134
135 const char* p = buf + pos;
136 while (p >= buf) {
137 if (*p == c)
138 return (qore_offset_t)(p - buf);
139 --p;
140 }
141 return -1;
142 }
143
144 // NOTE: this is purely byte oriented - no character semantics here
145 DLLLOCAL qore_offset_t findAny(const char* str, qore_offset_t pos = 0) {
146 if (pos < 0) {
147 pos = len + pos;
148 if (pos < 0)
149 pos = 0;
150 } else if (pos > 0 && pos > (qore_offset_t)len)
151 return -1;
152 const char* p;
153 if (!(p = strstr(buf + pos, str)))
154 return -1;
155 return (qore_offset_t)(p - buf);
156 }
157
158 // NOTE: this is purely byte oriented - no character semantics here
159 DLLLOCAL qore_offset_t rfindAny(const char* str, qore_offset_t pos = -1) {
160 if (pos < 0) {
161 pos = len + pos;
162 if (pos < 0)
163 return -1;
164 } else if (pos > 0 && pos > (qore_offset_t)len)
165 pos = len - 1;
166
167 const char* p = buf + pos;
168 while (p >= buf) {
169 for (const char* t = str; *t; ++t) {
170 if (*p == *t)
171 return (qore_offset_t)(p - buf);
172 }
173 --p;
174 }
175 return -1;
176 }
177
178 DLLLOCAL static qore_offset_t index_simple(const char* haystack, size_t hlen, const char* needle, size_t nlen,
179 qore_offset_t pos = 0) {
180 const char* start = haystack + pos;
181 void* ptr = q_memmem(start, hlen - pos, needle, nlen);
182 if (!ptr) {
183 return -1;
184 }
185 return reinterpret_cast<const char*>(ptr) - start + pos;
186 }
187
188 DLLLOCAL qore_offset_t index(const QoreString &orig_needle, qore_offset_t pos, ExceptionSink *xsink) const {
189 assert(xsink);
190 TempEncodingHelper needle(orig_needle, getEncoding(), xsink);
191 if (!needle)
192 return -1;
193
194 // do simple index
195 if (!getEncoding()->isMultiByte()) {
196 if (pos < 0) {
197 pos = len + pos;
198 if (pos < 0) {
199 pos = 0;
200 }
201 } else if (pos >= (qore_offset_t)len) {
202 return -1;
203 }
204
205 return index_simple(buf, len, needle->c_str(), needle->size(), pos);
206 }
207
208 // do multibyte index()
209 if (findByteOffset(pos, xsink))
210 return -1;
211 if (pos < 0)
212 pos = 0;
213 else if (pos >= (qore_offset_t)len)
214 return -1;
215
216 qore_offset_t ind = index_simple(buf + pos, len - pos, needle->c_str(), needle->size());
217 if (ind != -1) {
218 ind = getEncoding()->getCharPos(buf, buf + pos + ind, xsink);
219 if (*xsink)
220 return -1;
221 }
222
223 return ind;
224 }
225
226 DLLLOCAL qore_offset_t bindex(const QoreString &needle, qore_offset_t pos) const {
227 if (needle.strlen() + pos > len)
228 return -1;
229
230 return bindex(needle.c_str(), pos, needle.size());
231 }
232
233 DLLLOCAL qore_offset_t bindex(const std::string &needle, qore_offset_t pos) const {
234 if (needle.size() + pos > len)
235 return -1;
236
237 return bindex(needle.c_str(), pos, needle.size());
238 }
239
240 DLLLOCAL qore_offset_t bindex(const char *needle, qore_offset_t pos, size_t nsize = 0) const {
241 if (pos < 0) {
242 pos = len + pos;
243 if (pos < 0) {
244 pos = 0;
245 }
246 } else if (pos >= (qore_offset_t)len) {
247 return -1;
248 }
249
250 if (!nsize) {
251 nsize = strlen(needle);
252 }
253 return index_simple(buf, len, needle, nsize, pos);
254 }
255
256 // finds the last occurrence of needle in haystack at or before position pos
257 // pos must be a non-negative valid byte offset in haystack
258 DLLLOCAL static qore_offset_t rindex_simple(const char* haystack, size_t hlen, const char* needle,
259 size_t nlen, qore_offset_t pos = -1) {
260 if (pos < 0) {
261 pos = hlen + pos;
262 if (pos < 0) {
263 return -1;
264 }
265 } else if (pos >= (qore_offset_t)hlen) {
266 pos = hlen - 1;
267 }
268
269 assert(pos < (qore_offset_t)hlen);
270 void* ptr = q_memrmem(haystack, pos + 1, needle, nlen);
271 if (!ptr) {
272 return -1;
273 }
274 return static_cast<qore_offset_t>(reinterpret_cast<const char*>(ptr) -
275 reinterpret_cast<const char*>(haystack));
276 }
277
278 // start is a byte offset that has to point to the start of a valid character
279 DLLLOCAL int findByteOffset(qore_offset_t& pos, ExceptionSink* xsink, size_t start = 0) const {
280 assert(xsink);
281 assert(getEncoding()->isMultiByte());
282 if (!pos)
283 return 0;
284 // get positive character offset if negative
285 if (pos < 0) {
286 // get the length of the string in characters
287 size_t clen = getEncoding()->getLength(buf + start, buf + len, xsink);
288 if (*xsink)
289 return -1;
290 pos = clen + pos;
291 }
292 // now get the byte position from this character offset
293 pos = getEncoding()->getByteLen(buf + start, buf + len, pos, xsink);
294 return *xsink ? -1 : 0;
295 }
296
297 DLLLOCAL qore_offset_t rindex(const QoreString &orig_needle, qore_offset_t pos, ExceptionSink *xsink) const {
298 assert(xsink);
299 TempEncodingHelper needle(orig_needle, getEncoding(), xsink);
300 if (!needle)
301 return -1;
302
303 if (!getEncoding()->isMultiByte()) {
304 if (pos < 0) {
305 pos = len + pos;
306 if (pos < 0)
307 return -1;
308 }
309
310 return rindex_simple(buf, len, needle->c_str(), needle->size(), pos);
311 }
312
313 // do multi-byte rindex
314 if (findByteOffset(pos, xsink))
315 return -1;
316 if (pos < 0)
317 return -1;
318
319 // get byte rindex position
320 qore_offset_t ind = rindex_simple(buf, len, needle->c_str(), needle->size(), pos);
321
322 // calculate character position from byte position
323 if (ind && ind != -1) {
324 ind = getEncoding()->getCharPos(buf, buf + ind, xsink);
325 if (*xsink)
326 return 0;
327 }
328
329 return ind;
330 }
331
332 DLLLOCAL qore_offset_t brindex(const QoreString &needle, qore_offset_t pos) const {
333 return brindex(needle.getBuffer(), needle.strlen(), pos);
334 }
335
336 DLLLOCAL qore_offset_t brindex(const std::string &needle, qore_offset_t pos) const {
337 return brindex(needle.c_str(), needle.size(), pos);
338 }
339
340 DLLLOCAL qore_offset_t brindex(const char *needle, size_t needle_len, qore_offset_t pos) const {
341 if (pos < 0)
342 pos = len + pos;
343
344 if (pos >= (qore_offset_t)len) {
345 pos = len - 1;
346 }
347
348 if (pos < 0) {
349 if (pos == -1 && !len && !needle_len) {
350 return 0;
351 }
352 return -1;
353 }
354
355 if (needle_len + (len - pos) > len)
356 return -1;
357
358 return rindex_simple(buf, len, needle, needle_len, pos);
359 }
360
361 DLLLOCAL bool startsWith(const char* str, size_t ssize) const {
362 return !strncmp(str, buf, ssize);
363 }
364
365 DLLLOCAL bool endsWith(const char* str, size_t ssize) const {
366 if (ssize > len) {
367 return false;
368 }
369 return strncmp(str, buf + len - ssize, ssize);
370 }
371
372 DLLLOCAL bool isDataPrintableAscii() const {
373 for (size_t i = 0; i < len; ++i) {
374 if (buf[i] < 32 || buf[i] > 126)
375 return false;
376 }
377 return true;
378 }
379
380 DLLLOCAL bool isDataAscii() const {
381 for (size_t i = 0; i < len; ++i) {
382 if ((unsigned char)(buf[i]) > 127)
383 return false;
384 }
385 return true;
386 }
387
388 DLLLOCAL void concat_intern(const char* p, size_t plen) {
389 assert(p);
390 assert(plen);
391 check_char(len + plen);
392 memcpy(buf + len, p, plen);
393 len += plen;
394 buf[len] = '\0';
395 }
396
397 DLLLOCAL void concat_simple(const qore_string_private& str, qore_offset_t pos) {
398 if (pos < 0) {
399 pos = str.len + pos;
400 if (pos < 0)
401 pos = 0;
402 }
403 else if (pos >= (qore_offset_t)str.len)
404 return;
405
406 concat_intern(str.buf + pos, str.len - pos);
407 }
408
409 DLLLOCAL int concat(const qore_string_private& str, qore_offset_t pos, ExceptionSink* xsink) {
410 assert(str.getEncoding() == getEncoding());
411
412 if (!getEncoding()->isMultiByte()) {
413 concat_simple(str, pos);
414 return 0;
415 }
416
417 // find byte positions from character positions
418 if (pos) {
419 if (str.findByteOffset(pos, xsink))
420 return -1;
421 if (pos < 0)
422 pos = 0;
423 else if (pos > (qore_offset_t)str.len)
424 return 0;
425 }
426
427 concat_intern(str.buf + pos, str.len - pos);
428 return 0;
429 }
430
431 DLLLOCAL void concat_simple(const qore_string_private& str, qore_offset_t pos, qore_offset_t plen) {
432 if (pos < 0) {
433 pos = str.len + pos;
434 if (pos < 0)
435 pos = 0;
436 } else if (pos >= (qore_offset_t)str.len)
437 return;
438
439 if (plen < 0) {
440 plen = str.len + plen;
441 if (plen <= 0)
442 return;
443 } else if (plen > (qore_offset_t)str.len)
444 plen = str.len;
445
446 concat_intern(str.buf + pos, plen);
447 }
448
449 DLLLOCAL int concat(const qore_string_private& str, qore_offset_t pos, qore_offset_t plen, ExceptionSink* xsink) {
450 assert(str.getEncoding() == getEncoding());
451 assert(plen);
452
453 if (!getEncoding()->isMultiByte()) {
454 concat_simple(str, pos);
455 return 0;
456 }
457
458 // find byte positions from character positions
459 if (pos) {
460 if (str.findByteOffset(pos, xsink))
461 return -1;
462 if (pos < 0)
463 pos = 0;
464 else if (pos > (qore_offset_t)str.len)
465 return 0;
466 }
467
468 // find the byte position from the starting byte
469 if (str.findByteOffset(plen, xsink, pos))
470 return -1;
471 if (plen <= 0)
472 return 0;
473 if (plen > (qore_offset_t)str.len)
474 plen = str.len;
475
476 concat_intern(str.buf + pos, plen);
477 return 0;
478 }
479
480 DLLLOCAL qore_offset_t getByteOffset(size_t i, ExceptionSink* xsink) const {
481 assert(xsink);
482 size_t rc;
483 if (i) {
484 rc = getEncoding()->getByteLen(buf, buf + len, i, xsink);
485 if (*xsink)
486 return -1;
487 } else
488 rc = 0;
489 return rc > len ? -1 : (qore_offset_t)rc;
490 }
491
492 DLLLOCAL void concat(char c) {
493 if (allocated) {
494 buf[len] = c;
495 check_char(++len);
496 buf[len] = '\0';
497 return;
498 }
499 // allocate new string buffer
500 allocated = STR_CLASS_BLOCK;
501 len = 1;
502 buf = (char*)malloc(sizeof(char) * allocated);
503 buf[0] = c;
504 buf[1] = '\0';
505 }
506
507 DLLLOCAL void concat(const qore_string_private* str) {
508 assert(!str || (str->encoding == encoding) || !str->encoding);
509
510 // if it's not a null string
511 if (str && str->len) {
512 // if priv->buffer needs to be resized
513 check_char(str->len + len + STR_CLASS_EXTRA);
514 // concatenate new string
515 memcpy(buf + len, str->buf, str->len);
516 len += str->len;
517 buf[len] = '\0';
518 }
519 }
520
521 DLLLOCAL void concat(const char *str) {
522 // if it's not a null string
523 if (str) {
524 size_t i = 0;
525 // iterate through new string
526 while (str[i]) {
527 // if priv->buffer needs to be resized
528 check_char(len);
529 // concatenate one character at a time
530 buf[len++] = str[i++];
531 }
532 // see if priv->buffer needs to be resized for '\0'
533 check_char(len);
534 // terminate string
535 buf[len] = '\0';
536 }
537 }
538
539 DLLLOCAL int concat(const QoreString* str, ExceptionSink* xsink);
540
541 // return 0 for success
542 DLLLOCAL int vsprintf(const char *fmt, va_list args) {
543 size_t fmtlen = ::strlen(fmt);
544 // ensure minimum space is free
545 if ((allocated - len - fmtlen) < MIN_SPRINTF_BUFSIZE) {
546 allocated += fmtlen + MIN_SPRINTF_BUFSIZE;
547 allocated = (allocated / 0x10 + 1) * 0x10; // use complete cache line
548 // resize buffer
549 buf = (char*)realloc(buf, allocated * sizeof(char));
550 }
551 // set free buffer size
552 qore_offset_t free = allocated - len;
553
554 // copy formatted string to buffer
555 int i = ::vsnprintf(buf + len, free, fmt, args);
556
557#ifdef HPUX
558 // vsnprintf failed but didn't tell us how big the buffer should be
559 if (i < 0) {
560 //printf("DEBUG: vsnprintf() failed: i=%d allocated=" QSD " len=" QSD " buf=%p fmtlen=" QSD
561 // " (new=i+%d = %d)\n", i, allocated, len, buf, fmtlen, STR_CLASS_EXTRA, i + STR_CLASS_EXTRA);
562 // resize buffer
563 allocated += STR_CLASS_EXTRA;
564 allocated = (allocated / 0x10 + 1) * 0x10; // use complete cache line
565 buf = (char*)realloc(buf, sizeof(char) * allocated);
566 *(buf + len) = '\0';
567 return -1;
568 }
569#else
570 if (i >= free) {
571 //printf("DEBUG: vsnprintf() failed: i=%d allocated=" QSD " len=" QSD " buf=%p fmtlen=" QSD
572 // " (new=i+%d = %d)\n", i, allocated, len, buf, fmtlen, STR_CLASS_EXTRA, i + STR_CLASS_EXTRA);
573 // resize buffer
574 allocated = len + i + STR_CLASS_EXTRA;
575 allocated = (allocated / 0x10 + 1) * 0x10; // use complete cache line
576 buf = (char*)realloc(buf, sizeof(char) * allocated);
577 *(buf + len) = '\0';
578 return -1;
579 }
580#endif
581
582 len += i;
583 return 0;
584 }
585
586 DLLLOCAL int sprintf(const char *fmt, ...) {
587 va_list args;
588 while (true) {
589 va_start(args, fmt);
590 int rc = vsprintf(fmt, args);
591 va_end(args);
592 if (!rc)
593 break;
594 }
595 return 0;
596 }
597
598 DLLLOCAL void concatUTF8FromUnicode(unsigned code);
599
600 DLLLOCAL int concatUnicode(unsigned code, ExceptionSink *xsink) {
601 assert(xsink);
602 if (getEncoding() == QCS_UTF8) {
603 concatUTF8FromUnicode(code);
604 return 0;
605 }
606
607 QoreString tmp(QCS_UTF8);
608 tmp.concatUTF8FromUnicode(code);
609 TempString ns(tmp.convertEncoding(getEncoding(), xsink));
610 if (*xsink)
611 return -1;
612 concat(ns->priv);
613 return 0;
614 }
615
616 DLLLOCAL void setRegexBaseOpts(QoreRegexBase& re, int opts);
617
618 DLLLOCAL void setRegexOpts(QoreRegexSubst& re, int opts);
619
620 DLLLOCAL void splice_simple(size_t offset, size_t length, QoreString* extract = nullptr);
621 DLLLOCAL void splice_simple(size_t offset, size_t length, const char* str, size_t str_len,
622 QoreString* extract = nullptr);
623 DLLLOCAL void splice_complex(qore_offset_t offset, ExceptionSink* xsink, QoreString* extract = nullptr);
624 DLLLOCAL void splice_complex(qore_offset_t offset, qore_offset_t length, ExceptionSink* xsink,
625 QoreString* extract = nullptr);
626 DLLLOCAL void splice_complex(qore_offset_t offset, qore_offset_t length, const QoreString* str,
627 ExceptionSink* xsink, QoreString* extract = nullptr);
628 DLLLOCAL int substr_simple(QoreString* str, qore_offset_t offset) const;
629 DLLLOCAL int substr_simple(QoreString* str, qore_offset_t offset, qore_offset_t length) const;
630 DLLLOCAL int substr_complex(QoreString* str, qore_offset_t offset, ExceptionSink* xsink) const;
631 DLLLOCAL int substr_complex(QoreString* str, qore_offset_t offset, qore_offset_t length,
632 ExceptionSink* xsink) const;
633
634 DLLLOCAL int trimLeading(ExceptionSink* xsink, const intvec_t& vec);
635 DLLLOCAL int trimLeading(ExceptionSink* xsink, const qore_string_private* chars);
636 DLLLOCAL int trimTrailing(ExceptionSink* xsink, const intvec_t& vec);
637 DLLLOCAL int trimTrailing(ExceptionSink* xsink, const qore_string_private* chars);
638
639 DLLLOCAL void terminate(size_t size);
640
641 DLLLOCAL int concatUnicode(unsigned code);
642
643 DLLLOCAL int concatDecodeUriIntern(ExceptionSink* xsink, const qore_string_private& str,
644 bool detect_query = false);
645
646 DLLLOCAL int concatEncodeUriRequest(ExceptionSink* xsink, const qore_string_private& str);
647
648 DLLLOCAL unsigned int getUnicodePointFromBytePos(size_t offset, unsigned& len, ExceptionSink* xsink) const;
649
650 DLLLOCAL int concatEncode(ExceptionSink* xsink, const QoreString& str, unsigned code = CE_XHTML);
651 DLLLOCAL int concatDecode(ExceptionSink* xsink, const QoreString& str, unsigned code = CD_ALL);
652
653 DLLLOCAL int getUnicodeCharArray(intvec_t& vec, ExceptionSink* xsink) const {
654 size_t j = 0;
655 while (j < len) {
656 unsigned clen;
657 int c = getUnicodePointFromBytePos((qore_offset_t)j, clen, xsink);
658 if (*xsink)
659 return -1;
660 vec.push_back(c);
661 j += clen;
662 }
663 return 0;
664 }
665
666 DLLLOCAL int allocate(unsigned requested_size) {
667 if ((unsigned)allocated >= requested_size)
668 return 0;
669 requested_size = (requested_size / 0x10 + 1) * 0x10; // fill complete cache line
670 char* aux = (char*)realloc(buf, requested_size * sizeof(char));
671 if (!aux) {
672 assert(false);
673 // FIXME: std::bad_alloc() should be thrown here;
674 return -1;
675 }
676 buf = aux;
677 allocated = requested_size;
678 return 0;
679 }
680
681 DLLLOCAL const QoreEncoding* getEncoding() const {
682 return encoding ? encoding : QCS_USASCII;
683 }
684
685 DLLLOCAL size_t getCharWidth(ExceptionSink* xsink) const;
686
687 DLLLOCAL void concatBase64(const char* bbuf, size_t size, size_t maxlinelen, bool url_encode = false);
688
689 DLLLOCAL static bool inVector(int c, const intvec_t& vec) {
690 for (unsigned j = 0; j < vec.size(); ++j) {
691 if ((int)vec[j] == c)
692 return true;
693 }
694 return false;
695 }
696
697 DLLLOCAL static qore_string_private* get(QoreString& str) {
698 return str.priv;
699 }
700
701 DLLLOCAL static int getHex(const char*& p) {
702 if (*p == '%' && isxdigit(*(p + 1)) && isxdigit(*(p + 2))) {
703 char x[3] = { *(p + 1), *(p + 2), '\0' };
704 p += 3;
705 return strtol(x, 0, 16);
706 }
707 return -1;
708 }
709
710 DLLLOCAL static int convert_encoding_intern(const char* src, size_t src_len, const QoreEncoding* from,
711 QoreString& targ, const QoreEncoding* nccs, ExceptionSink* xsink);
712};
713
714#endif
DLLEXPORT const QoreEncoding * QCS_UTF8
UTF-8 multi-byte encoding (only UTF-8 and UTF-16 are multi-byte encodings)
Definition: QoreEncoding.h:247
DLLEXPORT const QoreEncoding * QCS_USASCII
ascii encoding
Definition: QoreEncoding.h:246
DLLEXPORT void * q_memrmem(const void *big, size_t big_len, const void *little, size_t little_len)
finds a memory sequence in a larger memory sequence searching from the end of the sequence
DLLEXPORT void * q_memmem(const void *big, size_t big_len, const void *little, size_t little_len)
finds a memory sequence in a larger memory sequence
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:50
defines string encoding functions in Qore
Definition: QoreEncoding.h:83
Qore's string type supported by the QoreEncoding class.
Definition: QoreString.h:93
DLLEXPORT const char * c_str() const
returns the string's buffer; this data should not be changed
DLLEXPORT size_t strlen() const
returns number of bytes in the string (not including the null pointer)
DLLEXPORT const char * getBuffer() const
returns the string's buffer; this data should not be changed
DLLEXPORT size_t size() const
returns number of bytes in the string (not including the null pointer)
hashdecl qore_string_private * priv
the private implementation of QoreString
Definition: QoreString.h:1027
use this class to manage strings where the character encoding must be specified and may be different ...
Definition: QoreString.h:1125
class used to hold a possibly temporary QoreString pointer, stack only, cannot be dynamically allocat...
Definition: QoreString.h:1066
intptr_t qore_offset_t
used for offsets that could be negative
Definition: common.h:76
#define CD_ALL
code for decoding everything
Definition: QoreString.h:73
#define CE_XHTML
code for encoding XHTML entities
Definition: QoreString.h:55