Qore Programming Language  1.12.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 public:
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) - reinterpret_cast<const char*>(haystack));
275  }
276 
277  // start is a byte offset that has to point to the start of a valid character
278  DLLLOCAL int findByteOffset(qore_offset_t& pos, ExceptionSink* xsink, size_t start = 0) const {
279  assert(xsink);
280  assert(getEncoding()->isMultiByte());
281  if (!pos)
282  return 0;
283  // get positive character offset if negative
284  if (pos < 0) {
285  // get the length of the string in characters
286  size_t clen = getEncoding()->getLength(buf + start, buf + len, xsink);
287  if (*xsink)
288  return -1;
289  pos = clen + pos;
290  }
291  // now get the byte position from this character offset
292  pos = getEncoding()->getByteLen(buf + start, buf + len, pos, xsink);
293  return *xsink ? -1 : 0;
294  }
295 
296  DLLLOCAL qore_offset_t rindex(const QoreString &orig_needle, qore_offset_t pos, ExceptionSink *xsink) const {
297  assert(xsink);
298  TempEncodingHelper needle(orig_needle, getEncoding(), xsink);
299  if (!needle)
300  return -1;
301 
302  if (!getEncoding()->isMultiByte()) {
303  if (pos < 0) {
304  pos = len + pos;
305  if (pos < 0)
306  return -1;
307  }
308 
309  return rindex_simple(buf, len, needle->c_str(), needle->size(), pos);
310  }
311 
312  // do multi-byte rindex
313  if (findByteOffset(pos, xsink))
314  return -1;
315  if (pos < 0)
316  return -1;
317 
318  // get byte rindex position
319  qore_offset_t ind = rindex_simple(buf, len, needle->c_str(), needle->size(), pos);
320 
321  // calculate character position from byte position
322  if (ind && ind != -1) {
323  ind = getEncoding()->getCharPos(buf, buf + ind, xsink);
324  if (*xsink)
325  return 0;
326  }
327 
328  return ind;
329  }
330 
331  DLLLOCAL qore_offset_t brindex(const QoreString &needle, qore_offset_t pos) const {
332  return brindex(needle.getBuffer(), needle.strlen(), pos);
333  }
334 
335  DLLLOCAL qore_offset_t brindex(const std::string &needle, qore_offset_t pos) const {
336  return brindex(needle.c_str(), needle.size(), pos);
337  }
338 
339  DLLLOCAL qore_offset_t brindex(const char *needle, size_t needle_len, qore_offset_t pos) const {
340  if (pos < 0)
341  pos = len + pos;
342 
343  if (pos >= (qore_offset_t)len) {
344  pos = len - 1;
345  }
346 
347  if (pos < 0) {
348  if (pos == -1 && !len && !needle_len) {
349  return 0;
350  }
351  return -1;
352  }
353 
354  if (needle_len + (len - pos) > len)
355  return -1;
356 
357  return rindex_simple(buf, len, needle, needle_len, pos);
358  }
359 
360  DLLLOCAL bool startsWith(const char* str, size_t ssize) const {
361  return !strncmp(str, buf, ssize);
362  }
363 
364  DLLLOCAL bool endsWith(const char* str, size_t ssize) const {
365  if (ssize > len) {
366  return false;
367  }
368  return strncmp(str, buf + len - ssize, ssize);
369  }
370 
371  DLLLOCAL bool isDataPrintableAscii() const {
372  for (size_t i = 0; i < len; ++i) {
373  if (buf[i] < 32 || buf[i] > 126)
374  return false;
375  }
376  return true;
377  }
378 
379  DLLLOCAL bool isDataAscii() const {
380  for (size_t i = 0; i < len; ++i) {
381  if ((unsigned char)(buf[i]) > 127)
382  return false;
383  }
384  return true;
385  }
386 
387  DLLLOCAL void concat_intern(const char* p, size_t plen) {
388  assert(p);
389  assert(plen);
390  check_char(len + plen);
391  memcpy(buf + len, p, plen);
392  len += plen;
393  buf[len] = '\0';
394  }
395 
396  DLLLOCAL void concat_simple(const qore_string_private& str, qore_offset_t pos) {
397  if (pos < 0) {
398  pos = str.len + pos;
399  if (pos < 0)
400  pos = 0;
401  }
402  else if (pos >= (qore_offset_t)str.len)
403  return;
404 
405  concat_intern(str.buf + pos, str.len - pos);
406  }
407 
408  DLLLOCAL int concat(const qore_string_private& str, qore_offset_t pos, ExceptionSink* xsink) {
409  assert(str.getEncoding() == getEncoding());
410 
411  if (!getEncoding()->isMultiByte()) {
412  concat_simple(str, pos);
413  return 0;
414  }
415 
416  // find byte positions from character positions
417  if (pos) {
418  if (str.findByteOffset(pos, xsink))
419  return -1;
420  if (pos < 0)
421  pos = 0;
422  else if (pos > (qore_offset_t)str.len)
423  return 0;
424  }
425 
426  concat_intern(str.buf + pos, str.len - pos);
427  return 0;
428  }
429 
430  DLLLOCAL void concat_simple(const qore_string_private& str, qore_offset_t pos, qore_offset_t plen) {
431  if (pos < 0) {
432  pos = str.len + pos;
433  if (pos < 0)
434  pos = 0;
435  } else if (pos >= (qore_offset_t)str.len)
436  return;
437 
438  if (plen < 0) {
439  plen = str.len + plen;
440  if (plen <= 0)
441  return;
442  } else if (plen > (qore_offset_t)str.len)
443  plen = str.len;
444 
445  concat_intern(str.buf + pos, plen);
446  }
447 
448  DLLLOCAL int concat(const qore_string_private& str, qore_offset_t pos, qore_offset_t plen, ExceptionSink* xsink) {
449  assert(str.getEncoding() == getEncoding());
450  assert(plen);
451 
452  if (!getEncoding()->isMultiByte()) {
453  concat_simple(str, pos);
454  return 0;
455  }
456 
457  // find byte positions from character positions
458  if (pos) {
459  if (str.findByteOffset(pos, xsink))
460  return -1;
461  if (pos < 0)
462  pos = 0;
463  else if (pos > (qore_offset_t)str.len)
464  return 0;
465  }
466 
467  // find the byte position from the starting byte
468  if (str.findByteOffset(plen, xsink, pos))
469  return -1;
470  if (plen <= 0)
471  return 0;
472  if (plen > (qore_offset_t)str.len)
473  plen = str.len;
474 
475  concat_intern(str.buf + pos, plen);
476  return 0;
477  }
478 
479  DLLLOCAL qore_offset_t getByteOffset(size_t i, ExceptionSink* xsink) const {
480  assert(xsink);
481  size_t rc;
482  if (i) {
483  rc = getEncoding()->getByteLen(buf, buf + len, i, xsink);
484  if (*xsink)
485  return -1;
486  } else
487  rc = 0;
488  return rc > len ? -1 : (qore_offset_t)rc;
489  }
490 
491  DLLLOCAL void concat(char c) {
492  if (allocated) {
493  buf[len] = c;
494  check_char(++len);
495  buf[len] = '\0';
496  return;
497  }
498  // allocate new string buffer
499  allocated = STR_CLASS_BLOCK;
500  len = 1;
501  buf = (char*)malloc(sizeof(char) * allocated);
502  buf[0] = c;
503  buf[1] = '\0';
504  }
505 
506  DLLLOCAL void concat(const qore_string_private* str) {
507  assert(!str || (str->encoding == encoding) || !str->encoding);
508 
509  // if it's not a null string
510  if (str && str->len) {
511  // if priv->buffer needs to be resized
512  check_char(str->len + len + STR_CLASS_EXTRA);
513  // concatenate new string
514  memcpy(buf + len, str->buf, str->len);
515  len += str->len;
516  buf[len] = '\0';
517  }
518  }
519 
520  DLLLOCAL void concat(const char *str) {
521  // if it's not a null string
522  if (str) {
523  size_t i = 0;
524  // iterate through new string
525  while (str[i]) {
526  // if priv->buffer needs to be resized
527  check_char(len);
528  // concatenate one character at a time
529  buf[len++] = str[i++];
530  }
531  // see if priv->buffer needs to be resized for '\0'
532  check_char(len);
533  // terminate string
534  buf[len] = '\0';
535  }
536  }
537 
538  DLLLOCAL int concat(const QoreString* str, ExceptionSink* xsink);
539 
540  // return 0 for success
541  DLLLOCAL int vsprintf(const char *fmt, va_list args) {
542  size_t fmtlen = ::strlen(fmt);
543  // ensure minimum space is free
544  if ((allocated - len - fmtlen) < MIN_SPRINTF_BUFSIZE) {
545  allocated += fmtlen + MIN_SPRINTF_BUFSIZE;
546  allocated = (allocated / 0x10 + 1) * 0x10; // use complete cache line
547  // resize buffer
548  buf = (char*)realloc(buf, allocated * sizeof(char));
549  }
550  // set free buffer size
551  qore_offset_t free = allocated - len;
552 
553  // copy formatted string to buffer
554  int i = ::vsnprintf(buf + len, free, fmt, args);
555 
556 #ifdef HPUX
557  // vsnprintf failed but didn't tell us how big the buffer should be
558  if (i < 0) {
559  //printf("DEBUG: vsnprintf() failed: i=%d allocated=" QSD " len=" QSD " buf=%p fmtlen=" QSD
560  // " (new=i+%d = %d)\n", i, allocated, len, buf, fmtlen, STR_CLASS_EXTRA, i + STR_CLASS_EXTRA);
561  // resize buffer
562  allocated += STR_CLASS_EXTRA;
563  allocated = (allocated / 0x10 + 1) * 0x10; // use complete cache line
564  buf = (char*)realloc(buf, sizeof(char) * allocated);
565  *(buf + len) = '\0';
566  return -1;
567  }
568 #else
569  if (i >= free) {
570  //printf("DEBUG: vsnprintf() failed: i=%d allocated=" QSD " len=" QSD " buf=%p fmtlen=" QSD
571  // " (new=i+%d = %d)\n", i, allocated, len, buf, fmtlen, STR_CLASS_EXTRA, i + STR_CLASS_EXTRA);
572  // resize buffer
573  allocated = len + i + STR_CLASS_EXTRA;
574  allocated = (allocated / 0x10 + 1) * 0x10; // use complete cache line
575  buf = (char*)realloc(buf, sizeof(char) * allocated);
576  *(buf + len) = '\0';
577  return -1;
578  }
579 #endif
580 
581  len += i;
582  return 0;
583  }
584 
585  DLLLOCAL int sprintf(const char *fmt, ...) {
586  va_list args;
587  while (true) {
588  va_start(args, fmt);
589  int rc = vsprintf(fmt, args);
590  va_end(args);
591  if (!rc)
592  break;
593  }
594  return 0;
595  }
596 
597  DLLLOCAL void concatUTF8FromUnicode(unsigned code);
598 
599  DLLLOCAL int concatUnicode(unsigned code, ExceptionSink *xsink) {
600  assert(xsink);
601  if (getEncoding() == QCS_UTF8) {
602  concatUTF8FromUnicode(code);
603  return 0;
604  }
605 
606  QoreString tmp(QCS_UTF8);
607  tmp.concatUTF8FromUnicode(code);
608  TempString ns(tmp.convertEncoding(getEncoding(), xsink));
609  if (*xsink)
610  return -1;
611  concat(ns->priv);
612  return 0;
613  }
614 
615  DLLLOCAL void setRegexBaseOpts(QoreRegexBase& re, int opts);
616 
617  DLLLOCAL void setRegexOpts(QoreRegexSubst& re, int opts);
618 
619  DLLLOCAL void splice_simple(size_t offset, size_t length, QoreString* extract = nullptr);
620  DLLLOCAL void splice_simple(size_t offset, size_t length, const char* str, size_t str_len,
621  QoreString* extract = nullptr);
622  DLLLOCAL void splice_complex(qore_offset_t offset, ExceptionSink* xsink, QoreString* extract = nullptr);
623  DLLLOCAL void splice_complex(qore_offset_t offset, qore_offset_t length, ExceptionSink* xsink,
624  QoreString* extract = nullptr);
625  DLLLOCAL void splice_complex(qore_offset_t offset, qore_offset_t length, const QoreString* str,
626  ExceptionSink* xsink, QoreString* extract = nullptr);
627  DLLLOCAL int substr_simple(QoreString* str, qore_offset_t offset) const;
628  DLLLOCAL int substr_simple(QoreString* str, qore_offset_t offset, qore_offset_t length) const;
629  DLLLOCAL int substr_complex(QoreString* str, qore_offset_t offset, ExceptionSink* xsink) const;
630  DLLLOCAL int substr_complex(QoreString* str, qore_offset_t offset, qore_offset_t length,
631  ExceptionSink* xsink) const;
632 
633  DLLLOCAL int trimLeading(ExceptionSink* xsink, const intvec_t& vec);
634  DLLLOCAL int trimLeading(ExceptionSink* xsink, const qore_string_private* chars);
635  DLLLOCAL int trimTrailing(ExceptionSink* xsink, const intvec_t& vec);
636  DLLLOCAL int trimTrailing(ExceptionSink* xsink, const qore_string_private* chars);
637 
638  DLLLOCAL void terminate(size_t size);
639 
640  DLLLOCAL int concatUnicode(unsigned code);
641 
642  DLLLOCAL int concatDecodeUriIntern(ExceptionSink* xsink, const qore_string_private& str,
643  bool detect_query = false);
644 
645  DLLLOCAL int concatEncodeUriRequest(ExceptionSink* xsink, const qore_string_private& str);
646 
647  DLLLOCAL unsigned int getUnicodePointFromBytePos(size_t offset, unsigned& len, ExceptionSink* xsink) const;
648 
649  DLLLOCAL int concatEncode(ExceptionSink* xsink, const QoreString& str, unsigned code = CE_XHTML);
650  DLLLOCAL int concatDecode(ExceptionSink* xsink, const QoreString& str, unsigned code = CD_ALL);
651 
652  DLLLOCAL int getUnicodeCharArray(intvec_t& vec, ExceptionSink* xsink) const {
653  size_t j = 0;
654  while (j < len) {
655  unsigned clen;
656  int c = getUnicodePointFromBytePos((qore_offset_t)j, clen, xsink);
657  if (*xsink)
658  return -1;
659  vec.push_back(c);
660  j += clen;
661  }
662  return 0;
663  }
664 
665  DLLLOCAL int allocate(unsigned requested_size) {
666  if ((unsigned)allocated >= requested_size)
667  return 0;
668  requested_size = (requested_size / 0x10 + 1) * 0x10; // fill complete cache line
669  char* aux = (char*)realloc(buf, requested_size * sizeof(char));
670  if (!aux) {
671  assert(false);
672  // FIXME: std::bad_alloc() should be thrown here;
673  return -1;
674  }
675  buf = aux;
676  allocated = requested_size;
677  return 0;
678  }
679 
680  DLLLOCAL const QoreEncoding* getEncoding() const {
681  return encoding ? encoding : QCS_USASCII;
682  }
683 
684  DLLLOCAL size_t getCharWidth(ExceptionSink* xsink) const;
685 
686  DLLLOCAL static bool inVector(int c, const intvec_t& vec) {
687  for (unsigned j = 0; j < vec.size(); ++j) {
688  if ((int)vec[j] == c)
689  return true;
690  }
691  return false;
692  }
693 
694  DLLLOCAL static qore_string_private* get(QoreString& str) {
695  return str.priv;
696  }
697 
698  DLLLOCAL static int getHex(const char*& p) {
699  if (*p == '%' && isxdigit(*(p + 1)) && isxdigit(*(p + 2))) {
700  char x[3] = { *(p + 1), *(p + 2), '\0' };
701  p += 3;
702  return strtol(x, 0, 16);
703  }
704  return -1;
705  }
706 
707  DLLLOCAL static int convert_encoding_intern(const char* src, size_t src_len, const QoreEncoding* from,
708  QoreString& targ, const QoreEncoding* nccs, ExceptionSink* xsink);
709 };
710 
711 #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