Qore Programming Language  1.7.0
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 - 2022 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 
51 typedef std::vector<int> intvec_t;
52 
53 hashdecl qore_string_private {
54 private:
55 
56 public:
57  size_t len = 0;
58  size_t allocated = 0;
59  char* buf = nullptr;
60  const QoreEncoding* encoding = nullptr;
61 
62  DLLLOCAL qore_string_private() {
63  }
64 
65  DLLLOCAL qore_string_private(const qore_string_private &p) {
66  allocated = p.len + STR_CLASS_EXTRA;
67  allocated = (allocated / 0x10 + 1) * 0x10; // use complete cache line
68  buf = (char*)malloc(sizeof(char) * allocated);
69  len = p.len;
70  if (len)
71  memcpy(buf, p.buf, len);
72  buf[len] = '\0';
73  encoding = p.getEncoding();
74  }
75 
76  DLLLOCAL ~qore_string_private() {
77  if (buf)
78  free(buf);
79  }
80 
81  DLLLOCAL void check_char(size_t i) {
82  if (i >= allocated) {
83  size_t d = i >> 2;
84  allocated = i + (d < STR_CLASS_BLOCK ? STR_CLASS_BLOCK : d);
85  allocated = (allocated / 0x10 + 1) * 0x10; // use complete cache line
86  buf = (char*)realloc(buf, allocated * sizeof(char));
87  }
88  }
89 
90  DLLLOCAL size_t check_offset(qore_offset_t offset) {
91  if (offset < 0) {
92  offset = len + offset;
93  return offset < 0 ? 0 : offset;
94  }
95 
96  return ((size_t)offset > len) ? len : offset;
97  }
98 
99  DLLLOCAL void check_offset(qore_offset_t offset, qore_offset_t num, size_t &n_offset, size_t &n_num) {
100  n_offset = check_offset(offset);
101 
102  if (num < 0) {
103  num = len + num - n_offset;
104  if (num < 0)
105  n_num = 0;
106  else
107  n_num = num;
108  return;
109  }
110  n_num = num;
111  }
112 
113  // NOTE: this is purely byte oriented - no character semantics here
114  DLLLOCAL qore_offset_t find(char c, qore_offset_t pos = 0) {
115  if (pos < 0) {
116  pos = len + pos;
117  if (pos < 0)
118  pos = 0;
119  } else if (pos > 0 && pos > (qore_offset_t)len)
120  return -1;
121  const char* p;
122  if (!(p = strchr(buf + pos, c)))
123  return -1;
124  return (qore_offset_t)(p - buf);
125  }
126 
127  // NOTE: this is purely byte oriented - no character semantics here
128  DLLLOCAL qore_offset_t rfind(char c, qore_offset_t pos = -1) {
129  if (pos < 0) {
130  pos = len + pos;
131  if (pos < 0)
132  return -1;
133  } else if (pos > 0 && pos > (qore_offset_t)len)
134  pos = len - 1;
135 
136  const char* p = buf + pos;
137  while (p >= buf) {
138  if (*p == c)
139  return (qore_offset_t)(p - buf);
140  --p;
141  }
142  return -1;
143  }
144 
145  // NOTE: this is purely byte oriented - no character semantics here
146  DLLLOCAL qore_offset_t findAny(const char* str, qore_offset_t pos = 0) {
147  if (pos < 0) {
148  pos = len + pos;
149  if (pos < 0)
150  pos = 0;
151  } else if (pos > 0 && pos > (qore_offset_t)len)
152  return -1;
153  const char* p;
154  if (!(p = strstr(buf + pos, str)))
155  return -1;
156  return (qore_offset_t)(p - buf);
157  }
158 
159  // NOTE: this is purely byte oriented - no character semantics here
160  DLLLOCAL qore_offset_t rfindAny(const char* str, qore_offset_t pos = -1) {
161  if (pos < 0) {
162  pos = len + pos;
163  if (pos < 0)
164  return -1;
165  } else if (pos > 0 && pos > (qore_offset_t)len)
166  pos = len - 1;
167 
168  const char* p = buf + pos;
169  while (p >= buf) {
170  for (const char* t = str; *t; ++t) {
171  if (*p == *t)
172  return (qore_offset_t)(p - buf);
173  }
174  --p;
175  }
176  return -1;
177  }
178 
179  DLLLOCAL static qore_offset_t index_simple(const char* haystack, size_t hlen, const char* needle, size_t nlen,
180  qore_offset_t pos = 0) {
181  const char* start = haystack + pos;
182  void* ptr = q_memmem(start, hlen - pos, needle, nlen);
183  if (!ptr) {
184  return -1;
185  }
186  return reinterpret_cast<const char*>(ptr) - start + pos;
187  }
188 
189  DLLLOCAL qore_offset_t index(const QoreString &orig_needle, qore_offset_t pos, ExceptionSink *xsink) const {
190  assert(xsink);
191  TempEncodingHelper needle(orig_needle, getEncoding(), xsink);
192  if (!needle)
193  return -1;
194 
195  // do simple index
196  if (!getEncoding()->isMultiByte()) {
197  if (pos < 0) {
198  pos = len + pos;
199  if (pos < 0) {
200  pos = 0;
201  }
202  } else if (pos >= (qore_offset_t)len) {
203  return -1;
204  }
205 
206  return index_simple(buf, len, needle->c_str(), needle->size(), pos);
207  }
208 
209  // do multibyte index()
210  if (findByteOffset(pos, xsink))
211  return -1;
212  if (pos < 0)
213  pos = 0;
214  else if (pos >= (qore_offset_t)len)
215  return -1;
216 
217  qore_offset_t ind = index_simple(buf + pos, len - pos, needle->c_str(), needle->size());
218  if (ind != -1) {
219  ind = getEncoding()->getCharPos(buf, buf + pos + ind, xsink);
220  if (*xsink)
221  return -1;
222  }
223 
224  return ind;
225  }
226 
227  DLLLOCAL qore_offset_t bindex(const QoreString &needle, qore_offset_t pos) const {
228  if (needle.strlen() + pos > len)
229  return -1;
230 
231  return bindex(needle.c_str(), pos, needle.size());
232  }
233 
234  DLLLOCAL qore_offset_t bindex(const std::string &needle, qore_offset_t pos) const {
235  if (needle.size() + pos > len)
236  return -1;
237 
238  return bindex(needle.c_str(), pos, needle.size());
239  }
240 
241  DLLLOCAL qore_offset_t bindex(const char *needle, qore_offset_t pos, size_t nsize = 0) const {
242  if (pos < 0) {
243  pos = len + pos;
244  if (pos < 0) {
245  pos = 0;
246  }
247  } else if (pos >= (qore_offset_t)len) {
248  return -1;
249  }
250 
251  if (!nsize) {
252  nsize = strlen(needle);
253  }
254  return index_simple(buf, len, needle, nsize, pos);
255  }
256 
257  // finds the last occurrence of needle in haystack at or before position pos
258  // pos must be a non-negative valid byte offset in haystack
259  DLLLOCAL static qore_offset_t rindex_simple(const char* haystack, size_t hlen, const char* needle,
260  size_t nlen, qore_offset_t pos = -1) {
261  if (pos < 0) {
262  pos = hlen + pos;
263  if (pos < 0) {
264  return -1;
265  }
266  } else if (pos >= (qore_offset_t)hlen) {
267  pos = hlen - 1;
268  }
269 
270  assert(pos < (qore_offset_t)hlen);
271  void* ptr = q_memrmem(haystack, pos + 1, needle, nlen);
272  if (!ptr) {
273  return -1;
274  }
275  return static_cast<qore_offset_t>(reinterpret_cast<const char*>(ptr) - 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 static bool inVector(int c, const intvec_t& vec) {
688  for (unsigned j = 0; j < vec.size(); ++j) {
689  if ((int)vec[j] == c)
690  return true;
691  }
692  return false;
693  }
694 
695  DLLLOCAL static qore_string_private* get(QoreString& str) {
696  return str.priv;
697  }
698 
699  DLLLOCAL static int getHex(const char*& p) {
700  if (*p == '%' && isxdigit(*(p + 1)) && isxdigit(*(p + 2))) {
701  char x[3] = { *(p + 1), *(p + 2), '\0' };
702  p += 3;
703  return strtol(x, 0, 16);
704  }
705  return -1;
706  }
707 
708  DLLLOCAL static int convert_encoding_intern(const char* src, size_t src_len, const QoreEncoding* from,
709  QoreString& targ, const QoreEncoding* nccs, ExceptionSink* xsink);
710 };
711 
712 #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_memmem(const void *big, size_t big_len, const void *little, size_t little_len)
finds a memory sequence in a larger memory sequence
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
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:48
defines string encoding functions in Qore
Definition: QoreEncoding.h:83
Qore's string type supported by the QoreEncoding class.
Definition: QoreString.h:93
DLLEXPORT size_t strlen() const
returns number of bytes in the string (not including the null pointer)
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:1006
DLLEXPORT const char * c_str() const
returns the string's buffer; this data should not be changed
DLLEXPORT const char * getBuffer() const
returns the string's buffer; this data should not be changed
use this class to manage strings where the character encoding must be specified and may be different ...
Definition: QoreString.h:1104
class used to hold a possibly temporary QoreString pointer, stack only, cannot be dynamically allocat...
Definition: QoreString.h:1045
intptr_t qore_offset_t
used for offsets that could be negative
Definition: common.h:76