1
/*************************************************************************************************
3
* Copyright (C) 2009-2012 FAL Labs
4
* This file is part of Kyoto Cabinet.
5
* This program is free software: you can redistribute it and/or modify it under the terms of
6
* the GNU General Public License as published by the Free Software Foundation, either version
7
* 3 of the License, or any later version.
8
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
* See the GNU General Public License for more details.
11
* You should have received a copy of the GNU General Public License along with this program.
12
* If not, see <http://www.gnu.org/licenses/>.
13
*************************************************************************************************/
16
#ifndef _KCUTIL_H // duplication check
21
namespace kyotocabinet { // common namespace
24
/** The maximum value of int8_t. */
25
const int8_t INT8MAX = (std::numeric_limits<int8_t>::max)();
28
/** The maximum value of int16_t. */
29
const int16_t INT16MAX = (std::numeric_limits<int16_t>::max)();
32
/** The maximum value of int32_t. */
33
const int32_t INT32MAX = (std::numeric_limits<int32_t>::max)();
36
/** The maximum value of int64_t. */
37
const int64_t INT64MAX = (std::numeric_limits<int64_t>::max)();
40
/** The minimum value of int8_t. */
41
const int8_t INT8MIN = (std::numeric_limits<int8_t>::min)();
44
/** The minimum value of int16_t. */
45
const int16_t INT16MIN = (std::numeric_limits<int16_t>::min)();
48
/** The minimum value of int32_t. */
49
const int32_t INT32MIN = (std::numeric_limits<int32_t>::min)();
52
/** The minimum value of int64_t. */
53
const int64_t INT64MIN = (std::numeric_limits<int64_t>::min)();
56
/** The maximum value of uint8_t. */
57
const uint8_t UINT8MAX = (std::numeric_limits<uint8_t>::max)();
60
/** The maximum value of uint16_t. */
61
const uint16_t UINT16MAX = (std::numeric_limits<uint16_t>::max)();
64
/** The maximum value of uint32_t. */
65
const uint32_t UINT32MAX = (std::numeric_limits<uint32_t>::max)();
68
/** The maximum value of uint64_t. */
69
const uint64_t UINT64MAX = (std::numeric_limits<uint64_t>::max)();
72
/** The maximum value of size_t. */
73
const size_t SIZEMAX = (std::numeric_limits<size_t>::max)();
76
/** The maximum value of float. */
77
const float FLTMAX = (std::numeric_limits<float>::max)();
80
/** The maximum value of double. */
81
const double DBLMAX = (std::numeric_limits<double>::max)();
84
/** An alias of hash map of strings. */
85
typedef std::unordered_map<std::string, std::string> StringHashMap;
88
/** An alias of tree map of strings. */
89
typedef std::map<std::string, std::string> StringTreeMap;
92
/** The package version. */
93
extern const char* const VERSION;
96
/** The library version. */
97
extern const int32_t LIBVER;
100
/** The library revision. */
101
extern const int32_t LIBREV;
104
/** The database format version. */
105
extern const int32_t FMTVER;
108
/** The system name. */
109
extern const char* const OSNAME;
112
/** The flag for big endian environments. */
113
extern const bool BIGEND;
116
/** The clock tick of interruption. */
117
extern const int32_t CLOCKTICK;
120
/** The size of a page. */
121
extern const int32_t PAGESIZ;
124
/** The extra feature list. */
125
extern const char* const FEATURES;
128
/** The buffer size for numeric data. */
129
const size_t NUMBUFSIZ = 32;
132
/** The maximum memory size for debugging. */
133
const size_t MEMMAXSIZ = INT32MAX / 2;
137
* Convert a decimal string to an integer.
138
* @param str the decimal string.
139
* @return the integer. If the string does not contain numeric expression, 0 is returned.
141
int64_t atoi(const char* str);
145
* Convert a decimal string with a metric prefix to an integer.
146
* @param str the decimal string, which can be trailed by a binary metric prefix. "K", "M", "G",
147
* "T", "P", and "E" are supported. They are case-insensitive.
148
* @return the integer. If the string does not contain numeric expression, 0 is returned. If
149
* the integer overflows the domain, kyotocabinet::INT64MAX or kyotocabinet::INT64_MIN is
150
* returned according to the sign.
152
int64_t atoix(const char* str);
156
* Convert a hexadecimal string to an integer.
157
* @param str the hexadecimal string.
158
* @return the integer. If the string does not contain numeric expression, 0 is returned.
160
int64_t atoih(const char* str);
164
* Convert a decimal byte array to an integer.
165
* @param ptr the decimal byte array.
166
* @param size the size of the decimal byte array.
167
* @return the integer. If the string does not contain numeric expression, 0 is returned.
169
int64_t atoin(const char* ptr, size_t size);
173
* Convert a decimal string to a real number.
174
* @param str the decimal string.
175
* @return the real number. If the string does not contain numeric expression, 0.0 is returned.
177
double atof(const char* str);
181
* Convert a decimal byte array to a real number.
182
* @param ptr the decimal byte array.
183
* @param size the size of the decimal byte array.
184
* @return the real number. If the string does not contain numeric expression, 0.0 is returned.
186
double atofn(const char* ptr, size_t size);
190
* Normalize a 16-bit number in the native order into the network byte order.
191
* @param num the 16-bit number in the native order.
192
* @return the number in the network byte order.
194
uint16_t hton16(uint16_t num);
198
* Normalize a 32-bit number in the native order into the network byte order.
199
* @param num the 32-bit number in the native order.
200
* @return the number in the network byte order.
202
uint32_t hton32(uint32_t num);
206
* Normalize a 64-bit number in the native order into the network byte order.
207
* @param num the 64-bit number in the native order.
208
* @return the number in the network byte order.
210
uint64_t hton64(uint64_t num);
214
* Denormalize a 16-bit number in the network byte order into the native order.
215
* @param num the 16-bit number in the network byte order.
216
* @return the converted number in the native order.
218
uint16_t ntoh16(uint16_t num);
222
* Denormalize a 32-bit number in the network byte order into the native order.
223
* @param num the 32-bit number in the network byte order.
224
* @return the converted number in the native order.
226
uint32_t ntoh32(uint32_t num);
230
* Denormalize a 64-bit number in the network byte order into the native order.
231
* @param num the 64-bit number in the network byte order.
232
* @return the converted number in the native order.
234
uint64_t ntoh64(uint64_t num);
238
* Write a number in fixed length format into a buffer.
239
* @param buf the desitination buffer.
240
* @param num the number.
241
* @param width the width.
243
void writefixnum(void* buf, uint64_t num, size_t width);
247
* Read a number in fixed length format from a buffer.
248
* @param buf the source buffer.
249
* @param width the width.
250
* @return the read number.
252
uint64_t readfixnum(const void* buf, size_t width);
256
* Write a number in variable length format into a buffer.
257
* @param buf the desitination buffer.
258
* @param num the number.
259
* @return the length of the written region.
261
size_t writevarnum(void* buf, uint64_t num);
265
* Read a number in variable length format from a buffer.
266
* @param buf the source buffer.
267
* @param size the size of the source buffer.
268
* @param np the pointer to the variable into which the read number is assigned.
269
* @return the length of the read region, or 0 on failure.
271
size_t readvarnum(const void* buf, size_t size, uint64_t* np);
275
* Check the size of variable length format of a number.
276
* @return the size of variable length format.
278
size_t sizevarnum(uint64_t num);
282
* Get the hash value by MurMur hashing.
283
* @param buf the source buffer.
284
* @param size the size of the source buffer.
285
* @return the hash value.
287
uint64_t hashmurmur(const void* buf, size_t size);
291
* Get the hash value by FNV hashing.
292
* @param buf the source buffer.
293
* @param size the size of the source buffer.
294
* @return the hash value.
296
uint64_t hashfnv(const void* buf, size_t size);
300
* Get the hash value suitable for a file name.
301
* @param buf the source buffer.
302
* @param size the size of the source buffer.
303
* @param obuf the buffer into which the result hash string is written. It must be more than
305
* @return the auxiliary hash value.
307
uint32_t hashpath(const void* buf, size_t size, char* obuf);
311
* Get a prime number nearby a number.
312
* @param num a natural number.
313
* @return the result number.
315
uint64_t nearbyprime(uint64_t num);
319
* Get the quiet Not-a-Number value.
320
* @return the quiet Not-a-Number value.
326
* Get the positive infinity value.
327
* @return the positive infinity value.
333
* Check a number is a Not-a-Number value.
334
* @return true for the number is a Not-a-Number value, or false if not.
336
bool chknan(double num);
340
* Check a number is an infinity value.
341
* @return true for the number is an infinity value, or false if not.
343
bool chkinf(double num);
347
* Append a formatted string at the end of a string.
348
* @param dest the destination string.
349
* @param format the printf-like format string. The conversion character `%' can be used with
350
* such flag characters as `s', `d', `o', `u', `x', `X', `c', `e', `E', `f', `g', `G', and `%'.
351
* @param ap used according to the format string.
353
void vstrprintf(std::string* dest, const char* format, va_list ap);
357
* Append a formatted string at the end of a string.
358
* @param dest the destination string.
359
* @param format the printf-like format string. The conversion character `%' can be used with
360
* such flag characters as `s', `d', `o', `u', `x', `X', `c', `e', `E', `f', `g', `G', and `%'.
361
* @param ... used according to the format string.
363
void strprintf(std::string* dest, const char* format, ...);
367
* Generate a formatted string.
368
* @param format the printf-like format string. The conversion character `%' can be used with
369
* such flag characters as `s', `d', `o', `u', `x', `X', `c', `e', `E', `f', `g', `G', and `%'.
370
* @param ... used according to the format string.
371
* @return the result string.
373
std::string strprintf(const char* format, ...);
377
* Split a string with a delimiter.
378
* @param str the string.
379
* @param delim the delimiter.
380
* @param elems a vector object into which the result elements are pushed.
381
* @return the number of result elements.
383
size_t strsplit(const std::string& str, char delim, std::vector<std::string>* elems);
387
* Split a string with delimiters.
388
* @param str the string.
389
* @param delims the delimiters.
390
* @param elems a vector object into which the result elements are pushed.
391
* @return the number of result elements.
393
size_t strsplit(const std::string& str, const std::string& delims,
394
std::vector<std::string>* elems);
398
* Convert the letters of a string into upper case.
399
* @param str the string to convert.
400
* @return the string itself.
402
std::string* strtoupper(std::string* str);
406
* Convert the letters of a string into lower case.
407
* @param str the string to convert.
408
* @return the string itself.
410
std::string* strtolower(std::string* str);
414
* Check whether a string begins with a key.
415
* @param str the string.
416
* @param key the forward matching key string.
417
* @return true if the target string begins with the key, else, it is false.
419
bool strfwm(const std::string& str, const std::string& key);
423
* Check whether a string ends with a key.
424
* @param str the string.
425
* @param key the backward matching key string.
426
* @return true if the target string ends with the key, else, it is false.
428
bool strbwm(const std::string& str, const std::string& key);
432
* Cut space characters at head or tail of a string.
433
* @param str the string to convert.
434
* @return the string itself.
436
std::string* strtrim(std::string* str);
440
* Convert a UTF-8 string into a UCS-4 array.
441
* @param src the source object.
442
* @param dest the destination object.
444
void strutftoucs(const std::string& src, std::vector<uint32_t>* dest);
448
* Convert a UCS-4 array into a UTF-8 string.
449
* @param src the source object.
450
* @param dest the destination object.
452
void strucstoutf(const std::vector<uint32_t>& src, std::string* dest);
456
* Serialize a string vector object into a string object.
457
* @param src the source object.
458
* @param dest the destination object.
460
void strvecdump(const std::vector<std::string>& src, std::string* dest);
464
* Deserialize a string object into a string vector object.
465
* @param src the source object.
466
* @param dest the destination object.
468
void strvecload(const std::string& src, std::vector<std::string>* dest);
472
* Serialize a string vector object into a string object.
473
* @param src the source object.
474
* @param dest the destination object.
476
void strmapdump(const std::map<std::string, std::string>& src, std::string* dest);
480
* Deserialize a string object into a string map object.
481
* @param src the source object.
482
* @param dest the destination object.
484
void strmapload(const std::string& src, std::map<std::string, std::string>* dest);
488
* Encode a serial object by hexadecimal encoding.
489
* @param buf the pointer to the region.
490
* @param size the size of the region.
491
* @return the result string.
492
* @note Because the region of the return value is allocated with the the new[] operator, it
493
* should be released with the delete[] operator when it is no longer in use.
495
char* hexencode(const void* buf, size_t size);
499
* Decode a string encoded by hexadecimal encoding.
500
* @param str specifies the encoded string.
501
* @param sp the pointer to the variable into which the size of the region of the return value
503
* @return the pointer to the region of the result.
504
* @note Because an additional zero code is appended at the end of the region of the return
505
* value, the return value can be treated as a character string. Because the region of the
506
* return value is allocated with the the new[] operator, it should be released with the delete[]
507
* operator when it is no longer in use.
509
char* hexdecode(const char* str, size_t* sp);
513
* Encode a serial object by URL encoding.
514
* @param buf the pointer to the region.
515
* @param size the size of the region.
516
* @return the result string.
517
* @note Because the region of the return value is allocated with the the new[] operator, it
518
* should be released with the delete[] operator when it is no longer in use.
520
char* urlencode(const void* buf, size_t size);
524
* Decode a string encoded by URL encoding.
525
* @param str specifies the encoded string.
526
* @param sp the pointer to the variable into which the size of the region of the return value
528
* @return the pointer to the region of the result.
529
* @note Because an additional zero code is appended at the end of the region of the return
530
* value, the return value can be treated as a character string. Because the region of the
531
* return value is allocated with the the new[] operator, it should be released with the delete[]
532
* operator when it is no longer in use.
534
char* urldecode(const char* str, size_t* sp);
538
* Encode a serial object by Quoted-printable encoding.
539
* @param buf the pointer to the region.
540
* @param size the size of the region.
541
* @return the result string.
542
* @note Because the region of the return value is allocated with the the new[] operator, it
543
* should be released with the delete[] operator when it is no longer in use.
545
char* quoteencode(const void* buf, size_t size);
549
* Decode a string encoded by Quoted-printable encoding.
550
* @param str specifies the encoded string.
551
* @param sp the pointer to the variable into which the size of the region of the return value
553
* @return the pointer to the region of the result.
554
* @note Because an additional zero code is appended at the end of the region of the return
555
* value, the return value can be treated as a character string. Because the region of the
556
* return value is allocated with the the new[] operator, it should be released with the delete[]
557
* operator when it is no longer in use.
559
char* quotedecode(const char* str, size_t* sp);
563
* Encode a serial object by Base64 encoding.
564
* @param buf the pointer to the region.
565
* @param size the size of the region.
566
* @return the result string.
567
* @note Because the region of the return value is allocated with the the new[] operator, it
568
* should be released with the delete[] operator when it is no longer in use.
570
char* baseencode(const void* buf, size_t size);
574
* Decode a string encoded by Base64 encoding.
575
* @param str specifies the encoded string.
576
* @param sp the pointer to the variable into which the size of the region of the return value
578
* @return the pointer to the region of the result.
579
* @note Because an additional zero code is appended at the end of the region of the return
580
* value, the return value can be treated as a character string. Because the region of the
581
* return value is allocated with the the new[] operator, it should be released with the delete[]
582
* operator when it is no longer in use.
584
char* basedecode(const char* str, size_t* sp);
588
* Cipher or decipher a serial object with the Arcfour stream cipher.
589
* @param ptr the pointer to the region.
590
* @param size the size of the region.
591
* @param kbuf the pointer to the region of the cipher key.
592
* @param ksiz the size of the region of the cipher key.
593
* @param obuf the pointer to the region into which the result data is written. The size of the
594
* buffer should be equal to or more than the input region. The region can be the same as the
597
void arccipher(const void* ptr, size_t size, const void* kbuf, size_t ksiz, void* obuf);
601
* Duplicate a region on memory.
602
* @param ptr the source buffer.
603
* @param size the size of the source buffer.
604
* @note Because the region of the return value is allocated with the the new[] operator, it
605
* should be released with the delete[] operator when it is no longer in use.
607
char* memdup(const char* ptr, size_t size);
611
* Compare two regions by case insensitive evaluation.
612
* @param abuf a buffer.
613
* @param bbuf the other buffer.
614
* @param size the size of each buffer.
615
* @return positive if the former is big, negative if the latter is big, 0 if both are
618
int32_t memicmp(const void* abuf, const void* bbuf, size_t size);
622
* Find the first occurrence of a sub pattern.
623
* @param hbuf the target pattern buffer.
624
* @param hsiz the size of the target pattern buffer.
625
* @param nbuf the sub pattern buffer.
626
* @param nsiz the size of the sub pattern buffer.
627
* @return the pointer to the beginning of the sub pattern in the target pattern buffer, or NULL
628
* if the sub pattern is not found.
630
void* memmem(const void* hbuf, size_t hsiz, const void* nbuf, size_t nsiz);
634
* Find the first occurrence of a sub pattern by case insensitive evaluation.
635
* @param hbuf the target pattern buffer.
636
* @param hsiz the size of the target pattern buffer.
637
* @param nbuf the sub pattern buffer.
638
* @param nsiz the size of the sub pattern buffer.
639
* @return the pointer to the beginning of the sub pattern in the target pattern buffer, or NULL
640
* if the sub pattern is not found.
642
void* memimem(const void* hbuf, size_t hsiz, const void* nbuf, size_t nsiz);
646
* Calculate the levenshtein distance of two regions in bytes.
647
* @param abuf the pointer to the region of one buffer.
648
* @param asiz the size of the region of one buffer.
649
* @param bbuf the pointer to the region of the other buffer.
650
* @param bsiz the size of the region of the other buffer.
651
* @return the levenshtein distance of two regions.
653
size_t memdist(const void* abuf, size_t asiz, const void* bbuf, size_t bsiz);
657
* Duplicate a string on memory.
658
* @param str the source string.
659
* @note Because the region of the return value is allocated with the the new[] operator, it
660
* should be released with the delete[] operator when it is no longer in use.
662
char* strdup(const char* str);
666
* Convert the letters of a string into upper case.
667
* @param str the string to convert.
668
* @return the string itself.
670
char* strtoupper(char* str);
674
* Convert the letters of a string into lower case.
675
* @param str the string to convert.
676
* @return the string itself.
678
char* strtolower(char* str);
682
* Cut space characters at head or tail of a string.
683
* @param str the string to convert.
684
* @return the string itself.
686
char* strtrim(char* str);
690
* Squeeze space characters in a string and trim it.
691
* @param str the string to convert.
692
* @return the string itself.
694
char* strsqzspc(char* str);
698
* Normalize space characters in a string and trim it.
699
* @param str the string to convert.
700
* @return the string itself.
702
char* strnrmspc(char* str);
706
* Compare two strings by case insensitive evaluation.
707
* @param astr a string.
708
* @param bstr the other string.
709
* @return positive if the former is big, negative if the latter is big, 0 if both are
712
int32_t stricmp(const char* astr, const char* bstr);
716
* Find the first occurrence of a substring by case insensitive evaluation.
717
* @param hstr the target string.
718
* @param nstr the substring.
719
* @return the pointer to the beginning of the substring in the target string, or NULL if the
720
* substring is not found.
722
char* stristr(const char* hstr, const char* nstr);
726
* Check whether a string begins with a key.
727
* @param str the string.
728
* @param key the forward matching key string.
729
* @return true if the target string begins with the key, else, it is false.
731
bool strfwm(const char* str, const char* key);
735
* Check whether a string begins with a key by case insensitive evaluation.
736
* @param str the string.
737
* @param key the forward matching key string.
738
* @return true if the target string begins with the key, else, it is false.
740
bool strifwm(const char* str, const char* key);
744
* Check whether a string ends with a key.
745
* @param str the string.
746
* @param key the backward matching key string.
747
* @return true if the target string ends with the key, else, it is false.
749
bool strbwm(const char* str, const char* key);
753
* Check whether a string ends with a key by case insensitive evaluation.
754
* @param str the string.
755
* @param key the backward matching key string.
756
* @return true if the target string ends with the key, else, it is false.
758
bool stribwm(const char* str, const char* key);
762
* Get the number of characters in a UTF-8 string.
763
* @param str the UTF-8 string.
764
* @return the number of characters in the string.
766
size_t strutflen(const char* str);
770
* Convert a UTF-8 string into a UCS-4 array.
771
* @param src the source object.
772
* @param dest the destination object. It must have enough size.
773
* @param np the pointer to the variable into which the number of elements in the destination
774
* object is assgined.
776
void strutftoucs(const char* src, uint32_t* dest, size_t* np);
780
* Convert a UTF-8 string into a UCS-4 array.
781
* @param src the source object which does not have to be trailed by zero code.
782
* @param slen the length of the source object.
783
* @param dest the destination object. It must have enough size.
784
* @param np the pointer to the variable into which the number of elements in the destination
785
* object is assgined.
787
void strutftoucs(const char* src, size_t slen, uint32_t* dest, size_t* np);
791
* Convert a UCS-4 array into a UTF-8 string.
792
* @param src the source object.
793
* @param snum the number of elements in the source object.
794
* @param dest the destination object. It must have enough size.
795
* @return the size of the result string.
797
size_t strucstoutf(const uint32_t* src, size_t snum, char* dest);
801
* Calculate the levenshtein distance of two UTF-8 strings.
802
* @param astr one UTF-8 string.
803
* @param bstr the other UTF-8 string.
804
* @return the levenshtein distance of two arrays.
806
size_t strutfdist(const char* astr, const char* bstr);
810
* Calculate the levenshtein distance of two UCS-4 arrays.
811
* @param aary one UCS-4 array.
812
* @param anum the number of elements of one array.
813
* @param bary the other UCS-4 array.
814
* @param bnum the number of elements of the other array.
815
* @return the levenshtein distance of two arrays.
817
size_t strucsdist(const uint32_t* aary, size_t anum, const uint32_t* bary, size_t bnum);
821
* Allocate a region on memory.
822
* @param size the size of the region.
823
* @return the pointer to the allocated region.
825
void* xmalloc(size_t size);
829
* Allocate a nullified region on memory.
830
* @param nmemb the number of elements.
831
* @param size the size of each element.
832
* @return the pointer to the allocated region.
834
void* xcalloc(size_t nmemb, size_t size);
838
* Re-allocate a region on memory.
839
* @param ptr the pointer to the region.
840
* @param size the size of the region.
841
* @return the pointer to the re-allocated region.
843
void* xrealloc(void* ptr, size_t size);
847
* Free a region on memory.
848
* @param ptr the pointer to the region.
850
void xfree(void* ptr);
854
* Allocate a nullified region on mapped memory.
855
* @param size the size of the region.
856
* @return the pointer to the allocated region. It should be released with the memfree call.
858
void* mapalloc(size_t size);
862
* Free a region on mapped memory.
863
* @param ptr the pointer to the allocated region.
865
void mapfree(void* ptr);
869
* Get the time of day in seconds.
870
* @return the time of day in seconds. The accuracy is in microseconds.
876
* Get the process ID.
877
* @return the process ID.
883
* Get the value of an environment variable.
884
* @return the value of the environment variable, or NULL on failure.
886
const char* getenv(const char* name);
890
* Get system information of the environment.
891
* @param strmap a string map to contain the result.
893
void getsysinfo(std::map<std::string, std::string>* strmap);
897
* Set the standard streams into the binary mode.
904
* @return always true.
910
* Convert a decimal string to an integer.
912
inline int64_t atoi(const char* str) {
914
while (*str > '\0' && *str <= ' ') {
922
} else if (*str == '+') {
925
while (*str != '\0') {
926
if (*str < '0' || *str > '9') break;
927
num = num * 10 + *str - '0';
935
* Convert a decimal string with a metric prefix to an integer.
937
inline int64_t atoix(const char* str) {
939
while (*str > '\0' && *str <= ' ') {
946
} else if (*str == '+') {
950
while (*str != '\0') {
951
if (*str < '0' || *str > '9') break;
952
num = num * 10 + *str - '0';
957
long double base = 10;
958
while (*str != '\0') {
959
if (*str < '0' || *str > '9') break;
960
num += (*str - '0') / base;
966
while (*str > '\0' && *str <= ' ') {
969
if (*str == 'k' || *str == 'K') {
971
} else if (*str == 'm' || *str == 'M') {
973
} else if (*str == 'g' || *str == 'G') {
975
} else if (*str == 't' || *str == 'T') {
977
} else if (*str == 'p' || *str == 'P') {
979
} else if (*str == 'e' || *str == 'E') {
982
if (num > INT64MAX) return INT64MAX;
983
if (num < INT64MIN) return INT64MIN;
989
* Convert a hexadecimal string to an integer.
991
inline int64_t atoih(const char* str) {
993
while (*str > '\0' && *str <= ' ') {
996
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
1001
if (*str >= '0' && *str <= '9') {
1002
num = num * 0x10 + *str - '0';
1003
} else if (*str >= 'a' && *str <= 'f') {
1004
num = num * 0x10 + *str - 'a' + 10;
1005
} else if (*str >= 'A' && *str <= 'F') {
1006
num = num * 0x10 + *str - 'A' + 10;
1017
* Convert a decimal byte array to an integer.
1019
inline int64_t atoin(const char* ptr, size_t size) {
1020
_assert_(ptr && size <= MEMMAXSIZ);
1021
while (size > 0 && *ptr >= '\0' && *ptr <= ' ') {
1032
} else if (*ptr == '+') {
1038
if (*ptr < '0' || *ptr > '9') break;
1039
num = num * 10 + *ptr - '0';
1048
* Convert a decimal string to a real number.
1050
inline double atof(const char* str) {
1052
while (*str > '\0' && *str <= ' ') {
1059
} else if (*str == '+') {
1062
if ((str[0] == 'i' || str[0] == 'I') && (str[1] == 'n' || str[1] == 'N') &&
1063
(str[2] == 'f' || str[2] == 'F')) return HUGE_VAL * sign;
1064
if ((str[0] == 'n' || str[0] == 'N') && (str[1] == 'a' || str[1] == 'A') &&
1065
(str[2] == 'n' || str[2] == 'N')) return nan();
1066
long double num = 0;
1068
while (*str != '\0') {
1069
if (*str < '0' || *str > '9') break;
1070
num = num * 10 + *str - '0';
1076
long double fract = 0.0;
1077
long double base = 10;
1078
while (col < 16 && *str != '\0') {
1079
if (*str < '0' || *str > '9') break;
1080
fract += (*str - '0') / base;
1087
if (*str == 'e' || *str == 'E') {
1089
num *= std::pow((long double)10, (long double)atoi(str));
1096
* Convert a decimal byte array to a real number.
1098
inline double atofn(const char* ptr, size_t size) {
1099
_assert_(ptr && size <= MEMMAXSIZ);
1100
while (size > 0 && *ptr >= '\0' && *ptr <= ' ') {
1110
} else if (*ptr == '+') {
1116
if ((ptr[0] == 'i' || ptr[0] == 'I') && (ptr[1] == 'n' || ptr[1] == 'N') &&
1117
(ptr[2] == 'f' || ptr[2] == 'F')) return HUGE_VAL * sign;
1118
if ((ptr[0] == 'n' || ptr[0] == 'N') && (ptr[1] == 'a' || ptr[1] == 'A') &&
1119
(ptr[2] == 'n' || ptr[2] == 'N')) return nan();
1121
long double num = 0;
1124
if (*ptr < '0' || *ptr > '9') break;
1125
num = num * 10 + *ptr - '0';
1130
if (size > 0 && *ptr == '.') {
1133
long double fract = 0.0;
1134
long double base = 10;
1135
while (col < 16 && size > 0) {
1136
if (*ptr < '0' || *ptr > '9') break;
1137
fract += (*ptr - '0') / base;
1145
if (size > 0 && (*ptr == 'e' || *ptr == 'E')) {
1148
num *= std::pow((long double)10, (long double)atoin(ptr, size));
1156
* Normalize a 16-bit number in the native order into the network byte order.
1158
inline uint16_t hton16(uint16_t num) {
1160
if (BIGEND) return num;
1161
return ((num & 0x00ffU) << 8) | ((num & 0xff00U) >> 8);
1166
* Normalize a 32-bit number in the native order into the network byte order.
1168
inline uint32_t hton32(uint32_t num) {
1170
if (BIGEND) return num;
1171
return ((num & 0x000000ffUL) << 24) | ((num & 0x0000ff00UL) << 8) | \
1172
((num & 0x00ff0000UL) >> 8) | ((num & 0xff000000UL) >> 24);
1177
* Normalize a 64-bit number in the native order into the network byte order.
1179
inline uint64_t hton64(uint64_t num) {
1181
if (BIGEND) return num;
1182
return ((num & 0x00000000000000ffULL) << 56) | ((num & 0x000000000000ff00ULL) << 40) |
1183
((num & 0x0000000000ff0000ULL) << 24) | ((num & 0x00000000ff000000ULL) << 8) |
1184
((num & 0x000000ff00000000ULL) >> 8) | ((num & 0x0000ff0000000000ULL) >> 24) |
1185
((num & 0x00ff000000000000ULL) >> 40) | ((num & 0xff00000000000000ULL) >> 56);
1190
* Denormalize a 16-bit number in the network byte order into the native order.
1192
inline uint16_t ntoh16(uint16_t num) {
1199
* Denormalize a 32-bit number in the network byte order into the native order.
1201
inline uint32_t ntoh32(uint32_t num) {
1208
* Denormalize a 64-bit number in the network byte order into the native order.
1210
inline uint64_t ntoh64(uint64_t num) {
1217
* Write a number in fixed length format into a buffer.
1219
inline void writefixnum(void* buf, uint64_t num, size_t width) {
1220
_assert_(buf && width <= sizeof(int64_t));
1222
std::memcpy(buf, (const char*)&num + sizeof(num) - width, width);
1227
* Read a number in fixed length format from a buffer.
1229
inline uint64_t readfixnum(const void* buf, size_t width) {
1230
_assert_(buf && width <= sizeof(int64_t));
1232
std::memcpy(&num, buf, width);
1233
return ntoh64(num) >> ((sizeof(num) - width) * 8);
1238
* Write a number in variable length format into a buffer.
1240
inline size_t writevarnum(void* buf, uint64_t num) {
1242
unsigned char* wp = (unsigned char*)buf;
1243
if (num < (1ULL << 7)) {
1245
} else if (num < (1ULL << 14)) {
1246
*(wp++) = (num >> 7) | 0x80;
1247
*(wp++) = num & 0x7f;
1248
} else if (num < (1ULL << 21)) {
1249
*(wp++) = (num >> 14) | 0x80;
1250
*(wp++) = ((num >> 7) & 0x7f) | 0x80;
1251
*(wp++) = num & 0x7f;
1252
} else if (num < (1ULL << 28)) {
1253
*(wp++) = (num >> 21) | 0x80;
1254
*(wp++) = ((num >> 14) & 0x7f) | 0x80;
1255
*(wp++) = ((num >> 7) & 0x7f) | 0x80;
1256
*(wp++) = num & 0x7f;
1257
} else if (num < (1ULL << 35)) {
1258
*(wp++) = (num >> 28) | 0x80;
1259
*(wp++) = ((num >> 21) & 0x7f) | 0x80;
1260
*(wp++) = ((num >> 14) & 0x7f) | 0x80;
1261
*(wp++) = ((num >> 7) & 0x7f) | 0x80;
1262
*(wp++) = num & 0x7f;
1263
} else if (num < (1ULL << 42)) {
1264
*(wp++) = (num >> 35) | 0x80;
1265
*(wp++) = ((num >> 28) & 0x7f) | 0x80;
1266
*(wp++) = ((num >> 21) & 0x7f) | 0x80;
1267
*(wp++) = ((num >> 14) & 0x7f) | 0x80;
1268
*(wp++) = ((num >> 7) & 0x7f) | 0x80;
1269
*(wp++) = num & 0x7f;
1270
} else if (num < (1ULL << 49)) {
1271
*(wp++) = (num >> 42) | 0x80;
1272
*(wp++) = ((num >> 35) & 0x7f) | 0x80;
1273
*(wp++) = ((num >> 28) & 0x7f) | 0x80;
1274
*(wp++) = ((num >> 21) & 0x7f) | 0x80;
1275
*(wp++) = ((num >> 14) & 0x7f) | 0x80;
1276
*(wp++) = ((num >> 7) & 0x7f) | 0x80;
1277
*(wp++) = num & 0x7f;
1278
} else if (num < (1ULL << 56)) {
1279
*(wp++) = (num >> 49) | 0x80;
1280
*(wp++) = ((num >> 42) & 0x7f) | 0x80;
1281
*(wp++) = ((num >> 35) & 0x7f) | 0x80;
1282
*(wp++) = ((num >> 28) & 0x7f) | 0x80;
1283
*(wp++) = ((num >> 21) & 0x7f) | 0x80;
1284
*(wp++) = ((num >> 14) & 0x7f) | 0x80;
1285
*(wp++) = ((num >> 7) & 0x7f) | 0x80;
1286
*(wp++) = num & 0x7f;
1287
} else if (num < (1ULL << 63)) {
1288
*(wp++) = (num >> 56) | 0x80;
1289
*(wp++) = ((num >> 49) & 0x7f) | 0x80;
1290
*(wp++) = ((num >> 42) & 0x7f) | 0x80;
1291
*(wp++) = ((num >> 35) & 0x7f) | 0x80;
1292
*(wp++) = ((num >> 28) & 0x7f) | 0x80;
1293
*(wp++) = ((num >> 21) & 0x7f) | 0x80;
1294
*(wp++) = ((num >> 14) & 0x7f) | 0x80;
1295
*(wp++) = ((num >> 7) & 0x7f) | 0x80;
1296
*(wp++) = num & 0x7f;
1298
*(wp++) = (num >> 63) | 0x80;
1299
*(wp++) = ((num >> 56) & 0x7f) | 0x80;
1300
*(wp++) = ((num >> 49) & 0x7f) | 0x80;
1301
*(wp++) = ((num >> 42) & 0x7f) | 0x80;
1302
*(wp++) = ((num >> 35) & 0x7f) | 0x80;
1303
*(wp++) = ((num >> 28) & 0x7f) | 0x80;
1304
*(wp++) = ((num >> 21) & 0x7f) | 0x80;
1305
*(wp++) = ((num >> 14) & 0x7f) | 0x80;
1306
*(wp++) = ((num >> 7) & 0x7f) | 0x80;
1307
*(wp++) = num & 0x7f;
1309
return wp - (unsigned char*)buf;
1314
* Read a number in variable length format from a buffer.
1316
inline size_t readvarnum(const void* buf, size_t size, uint64_t* np) {
1317
_assert_(buf && size <= MEMMAXSIZ && np);
1318
const unsigned char* rp = (const unsigned char*)buf;
1319
const unsigned char* ep = rp + size;
1328
num = (num << 7) + (c & 0x7f);
1330
} while (c >= 0x80);
1332
return rp - (const unsigned char*)buf;
1337
* Check the size of variable length format of a number.
1339
inline size_t sizevarnum(uint64_t num) {
1341
if (num < (1ULL << 7)) return 1;
1342
if (num < (1ULL << 14)) return 2;
1343
if (num < (1ULL << 21)) return 3;
1344
if (num < (1ULL << 28)) return 4;
1345
if (num < (1ULL << 35)) return 5;
1346
if (num < (1ULL << 42)) return 6;
1347
if (num < (1ULL << 49)) return 7;
1348
if (num < (1ULL << 56)) return 8;
1349
if (num < (1ULL << 63)) return 9;
1355
* Get the hash value by MurMur hashing.
1357
inline uint64_t hashmurmur(const void* buf, size_t size) {
1358
_assert_(buf && size <= MEMMAXSIZ);
1359
const uint64_t mul = 0xc6a4a7935bd1e995ULL;
1360
const int32_t rtt = 47;
1361
uint64_t hash = 19780211ULL ^ (size * mul);
1362
const unsigned char* rp = (const unsigned char*)buf;
1363
while (size >= sizeof(uint64_t)) {
1364
uint64_t num = ((uint64_t)rp[0] << 0) | ((uint64_t)rp[1] << 8) |
1365
((uint64_t)rp[2] << 16) | ((uint64_t)rp[3] << 24) |
1366
((uint64_t)rp[4] << 32) | ((uint64_t)rp[5] << 40) |
1367
((uint64_t)rp[6] << 48) | ((uint64_t)rp[7] << 56);
1373
rp += sizeof(uint64_t);
1374
size -= sizeof(uint64_t);
1377
case 7: hash ^= (uint64_t)rp[6] << 48;
1378
case 6: hash ^= (uint64_t)rp[5] << 40;
1379
case 5: hash ^= (uint64_t)rp[4] << 32;
1380
case 4: hash ^= (uint64_t)rp[3] << 24;
1381
case 3: hash ^= (uint64_t)rp[2] << 16;
1382
case 2: hash ^= (uint64_t)rp[1] << 8;
1383
case 1: hash ^= (uint64_t)rp[0];
1386
hash ^= hash >> rtt;
1388
hash ^= hash >> rtt;
1394
* Get the hash value by FNV hashing.
1396
inline uint64_t hashfnv(const void* buf, size_t size) {
1397
_assert_(buf && size <= MEMMAXSIZ);
1398
uint64_t hash = 14695981039346656037ULL;
1399
const unsigned char* rp = (unsigned char*)buf;
1400
const unsigned char* ep = rp + size;
1402
hash = (hash ^ *(rp++)) * 109951162811ULL;
1409
* Get the hash value suitable for a file name.
1411
inline uint32_t hashpath(const void* buf, size_t size, char* obuf) {
1412
_assert_(buf && size <= MEMMAXSIZ && obuf);
1413
const unsigned char* rp = (const unsigned char*)buf;
1418
const unsigned char* ep = rp + size;
1420
int32_t num = *rp >> 4;
1422
*(wp++) = '0' + num;
1424
*(wp++) = 'a' + num - 10;
1428
*(wp++) = '0' + num;
1430
*(wp++) = 'a' + num - 10;
1437
uint64_t hash = hashmurmur(buf, size);
1438
rv = (((hash & 0xffff000000000000ULL) >> 48) | ((hash & 0x0000ffff00000000ULL) >> 16)) ^
1439
(((hash & 0x000000000000ffffULL) << 16) | ((hash & 0x00000000ffff0000ULL) >> 16));
1441
*(wp++) = 'f' + 1 + (size & 0x0f);
1442
for (int32_t i = 0; i <= 6; i += 3) {
1443
uint32_t num = (rp[i] ^ rp[i+1] ^ rp[i+2] ^
1444
rp[size-i-1] ^ rp[size-i-2] ^ rp[size-i-3]) % 36;
1446
*(wp++) = '0' + num;
1448
*(wp++) = 'a' + num - 10;
1451
uint64_t hash = hashmurmur(buf, size);
1452
rv = (((hash & 0xffff000000000000ULL) >> 48) | ((hash & 0x0000ffff00000000ULL) >> 16)) ^
1453
(((hash & 0x000000000000ffffULL) << 16) | ((hash & 0x00000000ffff0000ULL) >> 16));
1454
uint64_t inc = hashfnv(buf, size);
1455
inc = (((inc & 0xffff000000000000ULL) >> 48) | ((inc & 0x0000ffff00000000ULL) >> 16)) ^
1456
(((inc & 0x000000000000ffffULL) << 16) | ((inc & 0x00000000ffff0000ULL) >> 16));
1457
for (size_t i = 0; i < sizeof(hash); i++) {
1458
uint32_t least = hash >> ((sizeof(hash) - 1) * 8);
1459
uint64_t num = least >> 4;
1460
if (inc & 0x01) num += 0x10;
1463
*(wp++) = '0' + num;
1465
*(wp++) = 'a' + num - 10;
1468
if (inc & 0x01) num += 0x10;
1471
*(wp++) = '0' + num;
1473
*(wp++) = 'a' + num - 10;
1484
* Get a prime number nearby a number.
1486
inline uint64_t nearbyprime(uint64_t num) {
1488
static uint64_t table[] = {
1489
2ULL, 3ULL, 5ULL, 7ULL, 11ULL, 13ULL, 17ULL, 19ULL, 23ULL, 29ULL, 31ULL, 37ULL, 41ULL,
1490
43ULL, 47ULL, 53ULL, 59ULL, 61ULL, 67ULL, 71ULL, 79ULL, 97ULL, 107ULL, 131ULL, 157ULL,
1491
181ULL, 223ULL, 257ULL, 307ULL, 367ULL, 431ULL, 521ULL, 613ULL, 727ULL, 863ULL, 1031ULL,
1492
1217ULL, 1451ULL, 1723ULL, 2053ULL, 2437ULL, 2897ULL, 3449ULL, 4099ULL, 4871ULL, 5801ULL,
1493
6899ULL, 8209ULL, 9743ULL, 11587ULL, 13781ULL, 16411ULL, 19483ULL, 23173ULL, 27581ULL,
1494
32771ULL, 38971ULL, 46349ULL, 55109ULL, 65537ULL, 77951ULL, 92681ULL, 110221ULL, 131101ULL,
1495
155887ULL, 185363ULL, 220447ULL, 262147ULL, 311743ULL, 370759ULL, 440893ULL, 524309ULL,
1496
623521ULL, 741457ULL, 881743ULL, 1048583ULL, 1246997ULL, 1482919ULL, 1763491ULL,
1497
2097169ULL, 2493949ULL, 2965847ULL, 3526987ULL, 4194319ULL, 4987901ULL, 5931641ULL,
1498
7053971ULL, 8388617ULL, 9975803ULL, 11863289ULL, 14107921ULL, 16777259ULL, 19951597ULL,
1499
23726569ULL, 28215809ULL, 33554467ULL, 39903197ULL, 47453149ULL, 56431657ULL,
1500
67108879ULL, 79806341ULL, 94906297ULL, 112863217ULL, 134217757ULL, 159612679ULL,
1501
189812533ULL, 225726419ULL, 268435459ULL, 319225391ULL, 379625083ULL, 451452839ULL,
1502
536870923ULL, 638450719ULL, 759250133ULL, 902905657ULL, 1073741827ULL, 1276901429ULL,
1503
1518500279ULL, 1805811341ULL, 2147483659ULL, 2553802871ULL, 3037000507ULL, 3611622607ULL,
1504
4294967311ULL, 5107605691ULL, 6074001001ULL, 7223245229ULL, 8589934609ULL, 10215211387ULL,
1505
12148002047ULL, 14446490449ULL, 17179869209ULL, 20430422699ULL, 24296004011ULL,
1506
28892980877ULL, 34359738421ULL, 40860845437ULL, 48592008053ULL, 57785961671ULL,
1507
68719476767ULL, 81721690807ULL, 97184016049ULL, 115571923303ULL, 137438953481ULL,
1508
163443381347ULL, 194368032011ULL, 231143846587ULL, 274877906951ULL, 326886762733ULL,
1509
388736063999ULL, 462287693167ULL, 549755813911ULL, 653773525393ULL, 777472128049ULL,
1510
924575386373ULL, 1099511627791ULL, 1307547050819ULL, 1554944255989ULL, 1849150772699ULL,
1511
2199023255579ULL, 2615094101561ULL, 3109888512037ULL, 3698301545321ULL,
1512
4398046511119ULL, 5230188203153ULL, 6219777023959ULL, 7396603090651ULL,
1513
8796093022237ULL, 10460376406273ULL, 12439554047911ULL, 14793206181251ULL,
1514
17592186044423ULL, 20920752812471ULL, 24879108095833ULL, 29586412362491ULL,
1515
35184372088891ULL, 41841505624973ULL, 49758216191633ULL, 59172824724919ULL,
1516
70368744177679ULL, 83683011249917ULL, 99516432383281ULL, 118345649449813ULL,
1517
140737488355333ULL, 167366022499847ULL, 199032864766447ULL, 236691298899683ULL,
1518
281474976710677ULL, 334732044999557ULL, 398065729532981ULL, 473382597799229ULL,
1519
562949953421381ULL, 669464089999087ULL, 796131459065743ULL, 946765195598473ULL,
1520
1125899906842679ULL, 1338928179998197ULL, 1592262918131449ULL, 1893530391196921ULL,
1521
2251799813685269ULL, 2677856359996339ULL, 3184525836262943ULL, 3787060782393821ULL,
1522
4503599627370517ULL, 5355712719992603ULL, 6369051672525833ULL, 7574121564787633ULL
1524
static const size_t tnum = sizeof(table) / sizeof(table[0]);
1525
uint64_t* ub = std::lower_bound(table, table + tnum, num);
1526
return ub == (uint64_t*)table + tnum ? num : *ub;
1531
* Get the quiet Not-a-Number value.
1533
inline double nan() {
1535
return std::numeric_limits<double>::quiet_NaN();
1540
* Get the positive infinity value.
1542
inline double inf() {
1544
return std::numeric_limits<double>::infinity();
1549
* Check a number is a Not-a-Number value.
1551
inline bool chknan(double num) {
1558
* Check a number is an infinity value.
1560
inline bool chkinf(double num) {
1562
return num == inf() || num == -inf();
1567
* Append a formatted string at the end of a string.
1569
inline void vstrprintf(std::string* dest, const char* format, va_list ap) {
1570
_assert_(dest && format);
1571
while (*format != '\0') {
1572
if (*format == '%') {
1573
char cbuf[NUMBUFSIZ];
1578
while (std::strchr("0123456789 .+-hlLz", *format) && *format != '\0' &&
1579
cbsiz < NUMBUFSIZ - 1) {
1580
if (*format == 'l' || *format == 'L') lnum++;
1581
cbuf[cbsiz++] = *(format++);
1583
cbuf[cbsiz++] = *format;
1587
const char* tmp = va_arg(ap, const char*);
1591
dest->append("(null)");
1596
char tbuf[NUMBUFSIZ*4];
1599
tsiz = std::sprintf(tbuf, cbuf, va_arg(ap, long long));
1600
} else if (lnum >= 1) {
1601
tsiz = std::sprintf(tbuf, cbuf, va_arg(ap, long));
1603
tsiz = std::sprintf(tbuf, cbuf, va_arg(ap, int));
1605
dest->append(tbuf, tsiz);
1608
case 'o': case 'u': case 'x': case 'X': case 'c': {
1609
char tbuf[NUMBUFSIZ*4];
1612
tsiz = std::sprintf(tbuf, cbuf, va_arg(ap, unsigned long long));
1613
} else if (lnum >= 1) {
1614
tsiz = std::sprintf(tbuf, cbuf, va_arg(ap, unsigned long));
1616
tsiz = std::sprintf(tbuf, cbuf, va_arg(ap, unsigned int));
1618
dest->append(tbuf, tsiz);
1621
case 'e': case 'E': case 'f': case 'g': case 'G': {
1622
char tbuf[NUMBUFSIZ*4];
1625
tsiz = std::snprintf(tbuf, sizeof(tbuf), cbuf, va_arg(ap, long double));
1627
tsiz = std::snprintf(tbuf, sizeof(tbuf), cbuf, va_arg(ap, double));
1629
if (tsiz > sizeof(tbuf)) {
1630
tbuf[sizeof(tbuf)-1] = '*';
1631
tsiz = sizeof(tbuf);
1633
dest->append(tbuf, tsiz);
1637
char tbuf[NUMBUFSIZ*4];
1638
size_t tsiz = std::sprintf(tbuf, "%p", va_arg(ap, void*));
1639
dest->append(tbuf, tsiz);
1643
dest->append("%", 1);
1648
dest->append(format, 1);
1656
* Append a formatted string at the end of a string.
1658
inline void strprintf(std::string* dest, const char* format, ...) {
1659
_assert_(dest && format);
1661
va_start(ap, format);
1662
vstrprintf(dest, format, ap);
1668
* Generate a formatted string on memory.
1670
inline std::string strprintf(const char* format, ...) {
1674
va_start(ap, format);
1675
vstrprintf(&str, format, ap);
1682
* Split a string with a delimiter
1684
inline size_t strsplit(const std::string& str, char delim, std::vector<std::string>* elems) {
1687
std::string::const_iterator it = str.begin();
1688
std::string::const_iterator pv = it;
1689
while (it != str.end()) {
1691
std::string col(pv, it);
1692
elems->push_back(col);
1697
std::string col(pv, it);
1698
elems->push_back(col);
1699
return elems->size();
1704
* Split a string with delimiters.
1706
inline size_t strsplit(const std::string& str, const std::string& delims,
1707
std::vector<std::string>* elems) {
1710
std::string::const_iterator it = str.begin();
1711
std::string::const_iterator pv = it;
1712
while (it != str.end()) {
1713
while (delims.find(*it, 0) != std::string::npos) {
1714
std::string col(pv, it);
1715
elems->push_back(col);
1721
std::string col(pv, it);
1722
elems->push_back(col);
1723
return elems->size();
1728
* Convert the letters of a string into upper case.
1730
inline std::string* strtoupper(std::string* str) {
1732
size_t size = str->size();
1733
for (size_t i = 0; i < size; i++) {
1734
int32_t c = (unsigned char)(*str)[i];
1735
if (c >= 'a' && c <= 'z') (*str)[i] = c - ('a' - 'A');
1742
* Convert the letters of a string into lower case.
1744
inline std::string* strtolower(std::string* str) {
1746
size_t size = str->size();
1747
for (size_t i = 0; i < size; i++) {
1748
int32_t c = (unsigned char)(*str)[i];
1749
if (c >= 'A' && c <= 'Z') (*str)[i] = c + ('a' - 'A');
1756
* Check whether a string begins with a key.
1758
inline bool strfwm(const std::string& str, const std::string& key) {
1760
size_t ksiz = key.size();
1761
if (ksiz > str.size()) return false;
1762
return !std::memcmp(str.data(), key.data(), ksiz);
1767
* Check whether a string ends with a key.
1769
inline bool strbwm(const std::string& str, const std::string& key) {
1771
size_t ksiz = key.size();
1772
if (ksiz > str.size()) return false;
1773
return !std::memcmp(str.data() + str.size() - ksiz, key.data(), ksiz);
1778
* Cut space characters at head or tail of a string.
1780
inline std::string* strtrim(std::string* str) {
1782
size_t size = str->size();
1785
for (size_t i = 0; i < size; i++) {
1786
int32_t c = (unsigned char)(*str)[i];
1787
if (c >= '\0' && c <= ' ') {
1788
if (wi > 0) (*str)[wi++] = c;
1800
* Convert a UTF-8 string into a UCS-4 array.
1802
inline void strutftoucs(const std::string& src, std::vector<uint32_t>* dest) {
1804
dest->reserve(dest->size() + src.size());
1805
size_t size = src.size();
1808
uint32_t c = (unsigned char)src[ri];
1811
} else if (c < 0xe0) {
1812
if (c >= 0xc0 && ri + 1 < size) {
1813
c = ((c & 0x1f) << 6) | (src[ri+1] & 0x3f);
1814
if (c >= 0x80) dest->push_back(c);
1817
} else if (c < 0xf0) {
1818
if (ri + 2 < size) {
1819
c = ((c & 0x0f) << 12) | ((src[ri+1] & 0x3f) << 6) | (src[ri+2] & 0x3f);
1820
if (c >= 0x800) dest->push_back(c);
1823
} else if (c < 0xf8) {
1824
if (ri + 3 < size) {
1825
c = ((c & 0x07) << 18) | ((src[ri+1] & 0x3f) << 12) | ((src[ri+2] & 0x3f) << 6) |
1827
if (c >= 0x10000) dest->push_back(c);
1830
} else if (c < 0xfc) {
1831
if (ri + 4 < size) {
1832
c = ((c & 0x03) << 24) | ((src[ri+1] & 0x3f) << 18) | ((src[ri+2] & 0x3f) << 12) |
1833
((src[ri+3] & 0x3f) << 6) | (src[ri+4] & 0x3f);
1834
if (c >= 0x200000) dest->push_back(c);
1837
} else if (c < 0xfe) {
1838
if (ri + 5 < size) {
1839
c = ((c & 0x01) << 30) | ((src[ri+1] & 0x3f) << 24) | ((src[ri+2] & 0x3f) << 18) |
1840
((src[ri+3] & 0x3f) << 12) | ((src[ri+4] & 0x3f) << 6) | (src[ri+5] & 0x3f);
1841
if (c >= 0x4000000) dest->push_back(c);
1851
* Convert a UCS-4 array into a UTF-8 string.
1853
inline void strucstoutf(const std::vector<uint32_t>& src, std::string* dest) {
1855
dest->reserve(dest->size() + src.size() * 3);
1856
std::vector<uint32_t>::const_iterator it = src.begin();
1857
std::vector<uint32_t>::const_iterator itend = src.end();
1858
while (it != itend) {
1862
} else if (c < 0x800) {
1863
dest->append(1, 0xc0 | (c >> 6));
1864
dest->append(1, 0x80 | (c & 0x3f));
1865
} else if (c < 0x10000) {
1866
dest->append(1, 0xe0 | (c >> 12));
1867
dest->append(1, 0x80 | ((c & 0xfff) >> 6));
1868
dest->append(1, 0x80 | (c & 0x3f));
1869
} else if (c < 0x200000) {
1870
dest->append(1, 0xf0 | (c >> 18));
1871
dest->append(1, 0x80 | ((c & 0x3ffff) >> 12));
1872
dest->append(1, 0x80 | ((c & 0xfff) >> 6));
1873
dest->append(1, 0x80 | (c & 0x3f));
1874
} else if (c < 0x4000000) {
1875
dest->append(1, 0xf8 | (c >> 24));
1876
dest->append(1, 0x80 | ((c & 0xffffff) >> 18));
1877
dest->append(1, 0x80 | ((c & 0x3ffff) >> 12));
1878
dest->append(1, 0x80 | ((c & 0xfff) >> 6));
1879
dest->append(1, 0x80 | (c & 0x3f));
1880
} else if (c < 0x80000000) {
1881
dest->append(1, 0xfc | (c >> 30));
1882
dest->append(1, 0x80 | ((c & 0x3fffffff) >> 24));
1883
dest->append(1, 0x80 | ((c & 0xffffff) >> 18));
1884
dest->append(1, 0x80 | ((c & 0x3ffff) >> 12));
1885
dest->append(1, 0x80 | ((c & 0xfff) >> 6));
1886
dest->append(1, 0x80 | (c & 0x3f));
1894
* Serialize a string vector object into a string object.
1896
inline void strvecdump(const std::vector<std::string>& src, std::string* dest) {
1898
std::vector<std::string>::const_iterator it = src.begin();
1899
std::vector<std::string>::const_iterator itend = src.end();
1901
while (it != itend) {
1902
dsiz += 2 + it->size();
1905
dest->reserve(dest->size() + dsiz);
1907
while (it != itend) {
1908
char nbuf[NUMBUFSIZ];
1909
size_t nsiz = writevarnum(nbuf, it->size());
1910
dest->append(nbuf, nsiz);
1911
dest->append(it->data(), it->size());
1918
* Deserialize a string object into a string vector object.
1920
inline void strvecload(const std::string& src, std::vector<std::string>* dest) {
1922
const char* rp = src.data();
1923
size_t size = src.size();
1926
size_t step = readvarnum(rp, size, &vsiz);
1929
if (vsiz > size) break;
1930
dest->push_back(std::string(rp, vsiz));
1938
* Serialize a string vector object into a string object.
1940
inline void strmapdump(const std::map<std::string, std::string>& src, std::string* dest) {
1942
std::map<std::string, std::string>::const_iterator it = src.begin();
1943
std::map<std::string, std::string>::const_iterator itend = src.end();
1945
while (it != itend) {
1946
dsiz += 4 + it->first.size() + it->second.size();
1949
dest->reserve(dest->size() + dsiz);
1951
while (it != itend) {
1952
char nbuf[NUMBUFSIZ*2];
1953
size_t nsiz = writevarnum(nbuf, it->first.size());
1954
nsiz += writevarnum(nbuf + nsiz, it->second.size());
1955
dest->append(nbuf, nsiz);
1956
dest->append(it->first.data(), it->first.size());
1957
dest->append(it->second.data(), it->second.size());
1964
* Deserialize a string object into a string map object.
1966
inline void strmapload(const std::string& src, std::map<std::string, std::string>* dest) {
1968
const char* rp = src.data();
1969
int64_t size = src.size();
1972
size_t step = readvarnum(rp, size, &ksiz);
1975
if (size < 1) break;
1977
step = readvarnum(rp, size, &vsiz);
1980
int64_t rsiz = ksiz + vsiz;
1981
if (rsiz > size) break;
1982
(*dest)[std::string(rp, ksiz)] = std::string(rp + ksiz, vsiz);
1990
* Encode a serial object by hexadecimal encoding.
1992
inline char* hexencode(const void* buf, size_t size) {
1993
_assert_(buf && size <= MEMMAXSIZ);
1994
const unsigned char* rp = (const unsigned char*)buf;
1995
char* zbuf = new char[size*2+1];
1997
for (const unsigned char* ep = rp + size; rp < ep; rp++) {
1998
int32_t num = *rp >> 4;
2000
*(wp++) = '0' + num;
2002
*(wp++) = 'a' + num - 10;
2006
*(wp++) = '0' + num;
2008
*(wp++) = 'a' + num - 10;
2017
* Decode a string encoded by hexadecimal encoding.
2019
inline char* hexdecode(const char* str, size_t* sp) {
2020
_assert_(str && sp);
2021
char* zbuf = new char[std::strlen(str)+1];
2024
while (*str > '\0' && *str <= ' ') {
2028
int32_t c = *(str++);
2029
if (c >= '0' && c <= '9') {
2031
} else if (c >= 'a' && c <= 'f') {
2033
} else if (c >= 'A' && c <= 'F') {
2035
} else if (c == '\0') {
2039
if (c >= '0' && c <= '9') {
2040
num = num * 0x10 + c - '0';
2041
} else if (c >= 'a' && c <= 'f') {
2042
num = num * 0x10 + c - 'a' + 10;
2043
} else if (c >= 'A' && c <= 'F') {
2044
num = num * 0x10 + c - 'A' + 10;
2045
} else if (c == '\0') {
2058
* Encode a serial object by URL encoding.
2060
inline char* urlencode(const void* buf, size_t size) {
2061
_assert_(buf && size <= MEMMAXSIZ);
2062
const unsigned char* rp = (const unsigned char*)buf;
2063
char* zbuf = new char[size*3+1];
2065
for (const unsigned char* ep = rp + size; rp < ep; rp++) {
2067
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
2068
(c >= '0' && c <= '9') || (c != '\0' && std::strchr("_-.~", c))) {
2072
int32_t num = c >> 4;
2074
*(wp++) = '0' + num;
2076
*(wp++) = 'a' + num - 10;
2080
*(wp++) = '0' + num;
2082
*(wp++) = 'a' + num - 10;
2092
* Decode a string encoded by URL encoding.
2094
inline char* urldecode(const char* str, size_t* sp) {
2095
_assert_(str && sp);
2096
size_t zsiz = std::strlen(str);
2097
char* zbuf = new char[zsiz+1];
2099
const char* ep = str + zsiz;
2104
if (++str >= ep) break;
2106
if (c >= '0' && c <= '9') {
2108
} else if (c >= 'a' && c <= 'f') {
2110
} else if (c >= 'A' && c <= 'F') {
2113
if (++str >= ep) break;
2115
if (c >= '0' && c <= '9') {
2116
num = num * 0x10 + c - '0';
2117
} else if (c >= 'a' && c <= 'f') {
2118
num = num * 0x10 + c - 'a' + 10;
2119
} else if (c >= 'A' && c <= 'F') {
2120
num = num * 0x10 + c - 'A' + 10;
2124
} else if (c == '+') {
2127
} else if (c <= ' ' || c == 0x7f) {
2141
* Encode a serial object by Quoted-printable encoding.
2143
inline char* quoteencode(const void* buf, size_t size) {
2144
_assert_(buf && size <= MEMMAXSIZ);
2145
const unsigned char* rp = (const unsigned char*)buf;
2146
char* zbuf = new char[size*3+1];
2148
for (const unsigned char* ep = rp + size; rp < ep; rp++) {
2150
if (c == '=' || c < ' ' || c > 0x7e) {
2152
int32_t num = c >> 4;
2154
*(wp++) = '0' + num;
2156
*(wp++) = 'A' + num - 10;
2160
*(wp++) = '0' + num;
2162
*(wp++) = 'A' + num - 10;
2174
* Decode a string encoded by Quoted-printable encoding.
2176
inline char* quotedecode(const char* str, size_t* sp) {
2177
_assert_(str && sp);
2178
size_t zsiz = std::strlen(str);
2179
char* zbuf = new char[zsiz+1];
2181
const char* ep = str + zsiz;
2186
if (++str >= ep) break;
2189
if (++str >= ep) break;
2190
if (*str == '\n') str++;
2191
} else if (c == '\n') {
2194
if (c >= '0' && c <= '9') {
2196
} else if (c >= 'a' && c <= 'f') {
2198
} else if (c >= 'A' && c <= 'F') {
2201
if (++str >= ep) break;
2203
if (c >= '0' && c <= '9') {
2204
num = num * 0x10 + c - '0';
2205
} else if (c >= 'a' && c <= 'f') {
2206
num = num * 0x10 + c - 'a' + 10;
2207
} else if (c >= 'A' && c <= 'F') {
2208
num = num * 0x10 + c - 'A' + 10;
2213
} else if (c < ' ' || c == 0x7f) {
2227
* Encode a serial object by Base64 encoding.
2229
inline char* baseencode(const void* buf, size_t size) {
2230
_assert_(buf && size <= MEMMAXSIZ);
2231
const char* tbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2232
const unsigned char* rp = (const unsigned char*)buf;
2233
char* zbuf = new char[size*4/3+5];
2235
for (size_t i = 0; i < size; i += 3) {
2238
*(wp++) = tbl[rp[0] >> 2];
2239
*(wp++) = tbl[(rp[0] & 3) << 4];
2245
*(wp++) = tbl[rp[0] >> 2];
2246
*(wp++) = tbl[((rp[0] & 3) << 4) + (rp[1] >> 4)];
2247
*(wp++) = tbl[(rp[1] & 0xf) << 2];
2252
*(wp++) = tbl[rp[0] >> 2];
2253
*(wp++) = tbl[((rp[0] & 3) << 4) + (rp[1] >> 4)];
2254
*(wp++) = tbl[((rp[1] & 0xf) << 2) + (rp[2] >> 6)];
2255
*(wp++) = tbl[rp[2] & 0x3f];
2267
* Decode a string encoded by Base64 encoding.
2269
inline char* basedecode(const char* str, size_t* sp) {
2270
_assert_(str && sp);
2273
size_t len = std::strlen(str);
2274
unsigned char* zbuf = new unsigned char[len+4];
2275
unsigned char* wp = zbuf;
2277
while (bpos < len && eqcnt == 0) {
2280
for (i = 0; bpos < len && i < 4; bpos++) {
2281
if (str[bpos] >= 'A' && str[bpos] <= 'Z') {
2282
bits = (bits << 6) | (str[bpos] - 'A');
2284
} else if (str[bpos] >= 'a' && str[bpos] <= 'z') {
2285
bits = (bits << 6) | (str[bpos] - 'a' + 26);
2287
} else if (str[bpos] >= '0' && str[bpos] <= '9') {
2288
bits = (bits << 6) | (str[bpos] - '0' + 52);
2290
} else if (str[bpos] == '+') {
2291
bits = (bits << 6) | 62;
2293
} else if (str[bpos] == '/') {
2294
bits = (bits << 6) | 63;
2296
} else if (str[bpos] == '=') {
2302
if (i == 0 && bpos >= len) continue;
2305
*wp++ = (bits >> 16) & 0xff;
2306
*wp++ = (bits >> 8) & 0xff;
2307
*wp++ = bits & 0xff;
2312
*wp++ = (bits >> 16) & 0xff;
2313
*wp++ = (bits >> 8) & 0xff;
2318
*wp++ = (bits >> 16) & 0xff;
2331
* Cipher or decipher a serial object with the Arcfour stream cipher.
2333
inline void arccipher(const void* ptr, size_t size, const void* kbuf, size_t ksiz, void* obuf) {
2334
_assert_(ptr && size <= MEMMAXSIZ && kbuf && ksiz <= MEMMAXSIZ && obuf);
2339
uint32_t sbox[0x100], kbox[0x100];
2340
for (int32_t i = 0; i < 0x100; i++) {
2342
kbox[i] = ((uint8_t*)kbuf)[i%ksiz];
2345
for (int32_t i = 0; i < 0x100; i++) {
2346
sidx = (sidx + sbox[i] + kbox[i]) & 0xff;
2347
uint32_t swap = sbox[i];
2348
sbox[i] = sbox[sidx];
2353
for (size_t i = 0; i < size; i++) {
2355
y = (y + sbox[x]) & 0xff;
2356
uint32_t swap = sbox[x];
2359
((uint8_t*)obuf)[i] = ((uint8_t*)ptr)[i] ^ sbox[(sbox[x]+sbox[y])&0xff];
2365
* Duplicate a region on memory.
2367
inline char* memdup(const char* ptr, size_t size) {
2368
_assert_(ptr && size <= MEMMAXSIZ);
2369
char* obuf = new char[size+1];
2370
std::memcpy(obuf, ptr, size);
2376
* Compare two regions by case insensitive evaluation.
2378
inline int32_t memicmp(const void* abuf, const void* bbuf, size_t size) {
2379
_assert_(abuf && bbuf && size <= MEMMAXSIZ);
2380
const unsigned char* ap = (unsigned char*)abuf;
2381
const unsigned char* bp = (unsigned char*)bbuf;
2382
const unsigned char* ep = ap + size;
2385
if (ac >= 'A' && ac <= 'Z') ac += 'a' - 'A';
2387
if (bc >= 'A' && bc <= 'Z') bc += 'a' - 'A';
2388
if (ac != bc) return ac - bc;
2397
* Find the first occurrence of a sub pattern.
2399
inline void* memmem(const void* hbuf, size_t hsiz, const void* nbuf, size_t nsiz) {
2400
_assert_(hbuf && hsiz <= MEMMAXSIZ && nbuf && nsiz <= MEMMAXSIZ);
2401
if (nsiz < 1) return (void*)hbuf;
2402
if (hsiz < nsiz) return NULL;
2403
int32_t tc = *(unsigned char*)nbuf;
2404
const unsigned char* rp = (unsigned char*)hbuf;
2405
const unsigned char* ep = (unsigned char*)hbuf + hsiz - nsiz;
2409
for (size_t i = 1; i < nsiz; i++) {
2410
if (rp[i] != ((unsigned char*)nbuf)[i]) {
2415
if (hit) return (void*)rp;
2424
* Find the first occurrence of a sub pattern by case insensitive evaluation.
2426
inline void* memimem(const void* hbuf, size_t hsiz, const void* nbuf, size_t nsiz) {
2427
_assert_(hbuf && hsiz <= MEMMAXSIZ && nbuf && nsiz <= MEMMAXSIZ);
2428
if (nsiz < 1) return (void*)hbuf;
2429
if (hsiz < nsiz) return NULL;
2430
int32_t tc = *(unsigned char*)nbuf;
2431
if (tc >= 'A' && tc <= 'Z') tc += 'a' - 'A';
2432
const unsigned char* rp = (unsigned char*)hbuf;
2433
const unsigned char* ep = (unsigned char*)hbuf + hsiz - nsiz;
2436
if (cc >= 'A' && cc <= 'Z') cc += 'a' - 'A';
2439
for (size_t i = 1; i < nsiz; i++) {
2441
if (hc >= 'A' && hc <= 'Z') hc += 'a' - 'A';
2442
int32_t nc = ((unsigned char*)nbuf)[i];
2443
if (nc >= 'A' && nc <= 'Z') nc += 'a' - 'A';
2449
if (hit) return (void*)rp;
2458
* Duplicate a string on memory.
2460
inline char* strdup(const char* str) {
2462
size_t size = std::strlen(str);
2463
char* obuf = memdup(str, size);
2470
* Convert the letters of a string into upper case.
2472
inline char* strtoupper(char* str) {
2475
while (*wp != '\0') {
2476
if (*wp >= 'a' && *wp <= 'z') *wp -= 'a' - 'A';
2484
* Convert the letters of a string into lower case.
2486
inline char* strtolower(char* str) {
2489
while (*wp != '\0') {
2490
if (*wp >= 'A' && *wp <= 'Z') *wp += 'a' - 'A';
2498
* Cut space characters at head or tail of a string.
2500
inline char* strtrim(char* str) {
2502
const char* rp = str;
2505
while (*rp != '\0') {
2506
if (*rp > '\0' && *rp <= ' ') {
2507
if (!head) *(wp++) = *rp;
2515
while (wp > str && wp[-1] > '\0' && wp[-1] <= ' ') {
2523
* Squeeze space characters in a string and trim it.
2525
inline char* strsqzspc(char* str) {
2527
const char* rp = str;
2530
while (*rp != '\0') {
2531
if (*rp > '\0' && *rp <= ' ') {
2532
if (!spc) *(wp++) = *rp;
2541
for (wp--; wp >= str; wp--) {
2542
if (*wp > '\0' && *wp <= ' ') {
2553
* Normalize space characters in a string and trim it.
2555
inline char* strnrmspc(char* str) {
2557
const char* rp = str;
2560
while (*rp != '\0') {
2561
if ((*rp > '\0' && *rp <= ' ') || *rp == 0x7f) {
2562
if (!spc) *(wp++) = ' ';
2571
for (wp--; wp >= str; wp--) {
2584
* Compare two strings by case insensitive evaluation.
2586
inline int32_t stricmp(const char* astr, const char* bstr) {
2587
_assert_(astr && bstr);
2588
while (*astr != '\0') {
2589
if (*bstr == '\0') return 1;
2590
int32_t ac = *(unsigned char*)astr;
2591
if (ac >= 'A' && ac <= 'Z') ac += 'a' - 'A';
2592
int32_t bc = *(unsigned char*)bstr;
2593
if (bc >= 'A' && bc <= 'Z') bc += 'a' - 'A';
2594
if (ac != bc) return ac - bc;
2598
return (*bstr == '\0') ? 0 : -1;
2603
* Find the first occurrence of a substring by case insensitive evaluation.
2605
inline char* stristr(const char* hstr, const char* nstr) {
2606
_assert_(hstr && nstr);
2607
if (*nstr == '\0') return (char*)hstr;
2609
if (tc >= 'A' && tc <= 'Z') tc += 'a' - 'A';
2610
const char* rp = hstr;
2611
while (*rp != '\0') {
2613
if (cc >= 'A' && cc <= 'Z') cc += 'a' - 'A';
2616
for (size_t i = 1; nstr[i] != '\0'; i++) {
2618
if (hc >= 'A' && hc <= 'Z') hc += 'a' - 'A';
2619
int32_t nc = nstr[i];
2620
if (nc >= 'A' && nc <= 'Z') nc += 'a' - 'A';
2626
if (hit) return (char*)rp;
2635
* Check whether a string begins with a key.
2637
inline bool strfwm(const char* str, const char* key) {
2638
_assert_(str && key);
2639
while (*key != '\0') {
2640
if (*str != *key || *str == '\0') return false;
2649
* Check whether a string begins with a key by case insensitive evaluation.
2651
inline bool strifwm(const char* str, const char* key) {
2652
_assert_(str && key);
2653
while (*key != '\0') {
2654
if (*str == '\0') return false;
2656
if (sc >= 'A' && sc <= 'Z') sc += 'a' - 'A';
2658
if (kc >= 'A' && kc <= 'Z') kc += 'a' - 'A';
2659
if (sc != kc) return false;
2668
* Check whether a string ends with a key.
2670
inline bool strbwm(const char* str, const char* key) {
2671
_assert_(str && key);
2672
size_t slen = std::strlen(str);
2673
size_t klen = std::strlen(key);
2674
for (size_t i = 1; i <= klen; i++) {
2675
if (i > slen || str[slen-i] != key[klen-i]) return false;
2682
* Check whether a string ends with a key by case insensitive evaluation.
2684
inline bool stribwm(const char* str, const char* key) {
2685
_assert_(str && key);
2686
size_t slen = std::strlen(str);
2687
size_t klen = std::strlen(key);
2688
for (size_t i = 1; i <= klen; i++) {
2689
if (i > slen) return false;
2690
int32_t sc = str[slen-i];
2691
if (sc >= 'A' && sc <= 'Z') sc += 'a' - 'A';
2692
int32_t kc = key[klen-i];
2693
if (kc >= 'A' && kc <= 'Z') kc += 'a' - 'A';
2694
if (sc != kc) return false;
2701
* Get the number of characters in a UTF-8 string.
2703
inline size_t strutflen(const char* str) {
2706
while (*str != '\0') {
2707
len += (*(unsigned char*)str & 0xc0) != 0x80;
2715
* Convert a UTF-8 string into a UCS-4 array.
2717
inline void strutftoucs(const char* src, uint32_t* dest, size_t* np) {
2718
_assert_(src && dest && np);
2719
const unsigned char* rp = (unsigned char*)src;
2721
while (*rp != '\0') {
2725
} else if (c < 0xe0) {
2726
if (rp[1] != '\0') {
2727
c = ((c & 0x1f) << 6) | (rp[1] & 0x3f);
2728
if (c >= 0x80) dest[dnum++] = c;
2731
} else if (c < 0xf0) {
2732
if (rp[1] != '\0' && rp[2] != '\0') {
2733
c = ((c & 0x0f) << 12) | ((rp[1] & 0x3f) << 6) | (rp[2] & 0x3f);
2734
if (c >= 0x800) dest[dnum++] = c;
2737
} else if (c < 0xf8) {
2738
if (rp[1] != '\0' && rp[2] != '\0' && rp[3] != '\0') {
2739
c = ((c & 0x07) << 18) | ((rp[1] & 0x3f) << 12) | ((rp[2] & 0x3f) << 6) |
2741
if (c >= 0x10000) dest[dnum++] = c;
2744
} else if (c < 0xfc) {
2745
if (rp[1] != '\0' && rp[2] != '\0' && rp[3] != '\0' && rp[4] != '\0') {
2746
c = ((c & 0x03) << 24) | ((rp[1] & 0x3f) << 18) | ((rp[2] & 0x3f) << 12) |
2747
((rp[3] & 0x3f) << 6) | (rp[4] & 0x3f);
2748
if (c >= 0x200000) dest[dnum++] = c;
2751
} else if (c < 0xfe) {
2752
if (rp[1] != '\0' && rp[2] != '\0' && rp[3] != '\0' && rp[4] != '\0' && rp[5] != '\0') {
2753
c = ((c & 0x01) << 30) | ((rp[1] & 0x3f) << 24) | ((rp[2] & 0x3f) << 18) |
2754
((rp[3] & 0x3f) << 12) | ((rp[4] & 0x3f) << 6) | (rp[5] & 0x3f);
2755
if (c >= 0x4000000) dest[dnum++] = c;
2766
* Convert a UTF-8 string into a UCS-4 array.
2768
inline void strutftoucs(const char* src, size_t slen, uint32_t* dest, size_t* np) {
2769
_assert_(src && slen <= MEMMAXSIZ && dest && np);
2770
const unsigned char* rp = (unsigned char*)src;
2771
const unsigned char* ep = rp + slen;
2777
} else if (c < 0xe0) {
2778
if (rp[1] != '\0') {
2779
c = ((c & 0x1f) << 6) | (rp[1] & 0x3f);
2780
if (c >= 0x80) dest[dnum++] = c;
2783
} else if (c < 0xf0) {
2784
if (rp[1] != '\0' && rp[2] != '\0') {
2785
c = ((c & 0x0f) << 12) | ((rp[1] & 0x3f) << 6) | (rp[2] & 0x3f);
2786
if (c >= 0x800) dest[dnum++] = c;
2789
} else if (c < 0xf8) {
2790
if (rp[1] != '\0' && rp[2] != '\0' && rp[3] != '\0') {
2791
c = ((c & 0x07) << 18) | ((rp[1] & 0x3f) << 12) | ((rp[2] & 0x3f) << 6) |
2793
if (c >= 0x10000) dest[dnum++] = c;
2796
} else if (c < 0xfc) {
2797
if (rp[1] != '\0' && rp[2] != '\0' && rp[3] != '\0' && rp[4] != '\0') {
2798
c = ((c & 0x03) << 24) | ((rp[1] & 0x3f) << 18) | ((rp[2] & 0x3f) << 12) |
2799
((rp[3] & 0x3f) << 6) | (rp[4] & 0x3f);
2800
if (c >= 0x200000) dest[dnum++] = c;
2803
} else if (c < 0xfe) {
2804
if (rp[1] != '\0' && rp[2] != '\0' && rp[3] != '\0' && rp[4] != '\0' && rp[5] != '\0') {
2805
c = ((c & 0x01) << 30) | ((rp[1] & 0x3f) << 24) | ((rp[2] & 0x3f) << 18) |
2806
((rp[3] & 0x3f) << 12) | ((rp[4] & 0x3f) << 6) | (rp[5] & 0x3f);
2807
if (c >= 0x4000000) dest[dnum++] = c;
2818
* Convert a UCS-4 array into a UTF-8 string.
2820
inline size_t strucstoutf(const uint32_t* src, size_t snum, char* dest) {
2821
_assert_(src && snum <= MEMMAXSIZ && dest);
2822
const uint32_t* ep = src + snum;
2823
unsigned char* wp = (unsigned char*)dest;
2828
} else if (c < 0x800) {
2829
*(wp++) = 0xc0 | (c >> 6);
2830
*(wp++) = 0x80 | (c & 0x3f);
2831
} else if (c < 0x10000) {
2832
*(wp++) = 0xe0 | (c >> 12);
2833
*(wp++) = 0x80 | ((c & 0xfff) >> 6);
2834
*(wp++) = 0x80 | (c & 0x3f);
2835
} else if (c < 0x200000) {
2836
*(wp++) = 0xf0 | (c >> 18);
2837
*(wp++) = 0x80 | ((c & 0x3ffff) >> 12);
2838
*(wp++) = 0x80 | ((c & 0xfff) >> 6);
2839
*(wp++) = 0x80 | (c & 0x3f);
2840
} else if (c < 0x4000000) {
2841
*(wp++) = 0xf8 | (c >> 24);
2842
*(wp++) = 0x80 | ((c & 0xffffff) >> 18);
2843
*(wp++) = 0x80 | ((c & 0x3ffff) >> 12);
2844
*(wp++) = 0x80 | ((c & 0xfff) >> 6);
2845
*(wp++) = 0x80 | (c & 0x3f);
2846
} else if (c < 0x80000000) {
2847
*(wp++) = 0xfc | (c >> 30);
2848
*(wp++) = 0x80 | ((c & 0x3fffffff) >> 24);
2849
*(wp++) = 0x80 | ((c & 0xffffff) >> 18);
2850
*(wp++) = 0x80 | ((c & 0x3ffff) >> 12);
2851
*(wp++) = 0x80 | ((c & 0xfff) >> 6);
2852
*(wp++) = 0x80 | (c & 0x3f);
2857
return wp - (unsigned char*)dest;
2862
* Allocate a region on memory.
2864
inline void* xmalloc(size_t size) {
2865
_assert_(size <= MEMMAXSIZ);
2866
void* ptr = std::malloc(size);
2867
if (!ptr) throw std::bad_alloc();
2873
* Allocate a nullified region on memory.
2875
inline void* xcalloc(size_t nmemb, size_t size) {
2876
_assert_(nmemb <= MEMMAXSIZ && size <= MEMMAXSIZ);
2877
void* ptr = std::calloc(nmemb, size);
2878
if (!ptr) throw std::bad_alloc();
2884
* Re-allocate a region on memory.
2886
inline void* xrealloc(void* ptr, size_t size) {
2887
_assert_(size <= MEMMAXSIZ);
2888
ptr = std::realloc(ptr, size);
2889
if (!ptr) throw std::bad_alloc();
2895
* Free a region on memory.
2897
inline void xfree(void* ptr) {
2904
* Dummy test driver.
2906
inline bool _dummytest() {
2908
std::ostringstream oss;
2909
oss << INT8MAX << INT16MAX << INT32MAX << INT64MAX;
2910
oss << INT8MIN << INT16MIN << INT32MIN << INT64MIN;
2911
oss << UINT8MAX << UINT16MAX << UINT32MAX << UINT64MAX;
2912
oss << SIZEMAX << FLTMAX << DBLMAX;
2913
oss << VERSION << LIBVER << LIBREV << FMTVER << OSNAME;
2914
oss << BIGEND << CLOCKTICK << PAGESIZ << FEATURES;
2915
oss << NUMBUFSIZ << MEMMAXSIZ;
2916
return oss.tellp() > 0;
2920
} // common namespace
2922
#endif // duplication check