~ubuntu-branches/ubuntu/quantal/kyotocabinet/quantal

« back to all changes in this revision

Viewing changes to kcutil.h

  • Committer: Package Import Robot
  • Author(s): Shawn Landden
  • Date: 2012-06-07 16:12:07 UTC
  • Revision ID: package-import@ubuntu.com-20120607161207-prbj5blqgzzfl8of
Tags: upstream-1.2.76
ImportĀ upstreamĀ versionĀ 1.2.76

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*************************************************************************************************
 
2
 * Utility functions
 
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
 *************************************************************************************************/
 
14
 
 
15
 
 
16
#ifndef _KCUTIL_H                        // duplication check
 
17
#define _KCUTIL_H
 
18
 
 
19
#include <kccommon.h>
 
20
 
 
21
namespace kyotocabinet {                 // common namespace
 
22
 
 
23
 
 
24
/** The maximum value of int8_t. */
 
25
const int8_t INT8MAX = (std::numeric_limits<int8_t>::max)();
 
26
 
 
27
 
 
28
/** The maximum value of int16_t. */
 
29
const int16_t INT16MAX = (std::numeric_limits<int16_t>::max)();
 
30
 
 
31
 
 
32
/** The maximum value of int32_t. */
 
33
const int32_t INT32MAX = (std::numeric_limits<int32_t>::max)();
 
34
 
 
35
 
 
36
/** The maximum value of int64_t. */
 
37
const int64_t INT64MAX = (std::numeric_limits<int64_t>::max)();
 
38
 
 
39
 
 
40
/** The minimum value of int8_t. */
 
41
const int8_t INT8MIN = (std::numeric_limits<int8_t>::min)();
 
42
 
 
43
 
 
44
/** The minimum value of int16_t. */
 
45
const int16_t INT16MIN = (std::numeric_limits<int16_t>::min)();
 
46
 
 
47
 
 
48
/** The minimum value of int32_t. */
 
49
const int32_t INT32MIN = (std::numeric_limits<int32_t>::min)();
 
50
 
 
51
 
 
52
/** The minimum value of int64_t. */
 
53
const int64_t INT64MIN = (std::numeric_limits<int64_t>::min)();
 
54
 
 
55
 
 
56
/** The maximum value of uint8_t. */
 
57
const uint8_t UINT8MAX = (std::numeric_limits<uint8_t>::max)();
 
58
 
 
59
 
 
60
/** The maximum value of uint16_t. */
 
61
const uint16_t UINT16MAX = (std::numeric_limits<uint16_t>::max)();
 
62
 
 
63
 
 
64
/** The maximum value of uint32_t. */
 
65
const uint32_t UINT32MAX = (std::numeric_limits<uint32_t>::max)();
 
66
 
 
67
 
 
68
/** The maximum value of uint64_t. */
 
69
const uint64_t UINT64MAX = (std::numeric_limits<uint64_t>::max)();
 
70
 
 
71
 
 
72
/** The maximum value of size_t. */
 
73
const size_t SIZEMAX = (std::numeric_limits<size_t>::max)();
 
74
 
 
75
 
 
76
/** The maximum value of float. */
 
77
const float FLTMAX = (std::numeric_limits<float>::max)();
 
78
 
 
79
 
 
80
/** The maximum value of double. */
 
81
const double DBLMAX = (std::numeric_limits<double>::max)();
 
82
 
 
83
 
 
84
/** An alias of hash map of strings. */
 
85
typedef std::unordered_map<std::string, std::string> StringHashMap;
 
86
 
 
87
 
 
88
/** An alias of tree map of strings. */
 
89
typedef std::map<std::string, std::string> StringTreeMap;
 
90
 
 
91
 
 
92
/** The package version. */
 
93
extern const char* const VERSION;
 
94
 
 
95
 
 
96
/** The library version. */
 
97
extern const int32_t LIBVER;
 
98
 
 
99
 
 
100
/** The library revision. */
 
101
extern const int32_t LIBREV;
 
102
 
 
103
 
 
104
/** The database format version. */
 
105
extern const int32_t FMTVER;
 
106
 
 
107
 
 
108
/** The system name. */
 
109
extern const char* const OSNAME;
 
110
 
 
111
 
 
112
/** The flag for big endian environments. */
 
113
extern const bool BIGEND;
 
114
 
 
115
 
 
116
/** The clock tick of interruption. */
 
117
extern const int32_t CLOCKTICK;
 
118
 
 
119
 
 
120
/** The size of a page. */
 
121
extern const int32_t PAGESIZ;
 
122
 
 
123
 
 
124
/** The extra feature list. */
 
125
extern const char* const FEATURES;
 
126
 
 
127
 
 
128
/** The buffer size for numeric data. */
 
129
const size_t NUMBUFSIZ = 32;
 
130
 
 
131
 
 
132
/** The maximum memory size for debugging. */
 
133
const size_t MEMMAXSIZ = INT32MAX / 2;
 
134
 
 
135
 
 
136
/**
 
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.
 
140
 */
 
141
int64_t atoi(const char* str);
 
142
 
 
143
 
 
144
/**
 
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.
 
151
 */
 
152
int64_t atoix(const char* str);
 
153
 
 
154
 
 
155
/**
 
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.
 
159
 */
 
160
int64_t atoih(const char* str);
 
161
 
 
162
 
 
163
/**
 
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.
 
168
 */
 
169
int64_t atoin(const char* ptr, size_t size);
 
170
 
 
171
 
 
172
/**
 
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.
 
176
 */
 
177
double atof(const char* str);
 
178
 
 
179
 
 
180
/**
 
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.
 
185
 */
 
186
double atofn(const char* ptr, size_t size);
 
187
 
 
188
 
 
189
/**
 
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.
 
193
 */
 
194
uint16_t hton16(uint16_t num);
 
195
 
 
196
 
 
197
/**
 
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.
 
201
 */
 
202
uint32_t hton32(uint32_t num);
 
203
 
 
204
 
 
205
/**
 
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.
 
209
 */
 
210
uint64_t hton64(uint64_t num);
 
211
 
 
212
 
 
213
/**
 
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.
 
217
 */
 
218
uint16_t ntoh16(uint16_t num);
 
219
 
 
220
 
 
221
/**
 
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.
 
225
 */
 
226
uint32_t ntoh32(uint32_t num);
 
227
 
 
228
 
 
229
/**
 
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.
 
233
 */
 
234
uint64_t ntoh64(uint64_t num);
 
235
 
 
236
 
 
237
/**
 
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.
 
242
 */
 
243
void writefixnum(void* buf, uint64_t num, size_t width);
 
244
 
 
245
 
 
246
/**
 
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.
 
251
 */
 
252
uint64_t readfixnum(const void* buf, size_t width);
 
253
 
 
254
 
 
255
/**
 
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.
 
260
 */
 
261
size_t writevarnum(void* buf, uint64_t num);
 
262
 
 
263
 
 
264
/**
 
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.
 
270
 */
 
271
size_t readvarnum(const void* buf, size_t size, uint64_t* np);
 
272
 
 
273
 
 
274
/**
 
275
 * Check the size of variable length format of a number.
 
276
 * @return the size of variable length format.
 
277
 */
 
278
size_t sizevarnum(uint64_t num);
 
279
 
 
280
 
 
281
/**
 
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.
 
286
 */
 
287
uint64_t hashmurmur(const void* buf, size_t size);
 
288
 
 
289
 
 
290
/**
 
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.
 
295
 */
 
296
uint64_t hashfnv(const void* buf, size_t size);
 
297
 
 
298
 
 
299
/**
 
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
 
304
 * NUMBUFSIZ.
 
305
 * @return the auxiliary hash value.
 
306
 */
 
307
uint32_t hashpath(const void* buf, size_t size, char* obuf);
 
308
 
 
309
 
 
310
/**
 
311
 * Get a prime number nearby a number.
 
312
 * @param num a natural number.
 
313
 * @return the result number.
 
314
 */
 
315
uint64_t nearbyprime(uint64_t num);
 
316
 
 
317
 
 
318
/**
 
319
 * Get the quiet Not-a-Number value.
 
320
 * @return the quiet Not-a-Number value.
 
321
 */
 
322
double nan();
 
323
 
 
324
 
 
325
/**
 
326
 * Get the positive infinity value.
 
327
 * @return the positive infinity value.
 
328
 */
 
329
double inf();
 
330
 
 
331
 
 
332
/**
 
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.
 
335
 */
 
336
bool chknan(double num);
 
337
 
 
338
 
 
339
/**
 
340
 * Check a number is an infinity value.
 
341
 * @return true for the number is an infinity value, or false if not.
 
342
 */
 
343
bool chkinf(double num);
 
344
 
 
345
 
 
346
/**
 
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.
 
352
 */
 
353
void vstrprintf(std::string* dest, const char* format, va_list ap);
 
354
 
 
355
 
 
356
/**
 
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.
 
362
 */
 
363
void strprintf(std::string* dest, const char* format, ...);
 
364
 
 
365
 
 
366
/**
 
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.
 
372
 */
 
373
std::string strprintf(const char* format, ...);
 
374
 
 
375
 
 
376
/**
 
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.
 
382
 */
 
383
size_t strsplit(const std::string& str, char delim, std::vector<std::string>* elems);
 
384
 
 
385
 
 
386
/**
 
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.
 
392
 */
 
393
size_t strsplit(const std::string& str, const std::string& delims,
 
394
                std::vector<std::string>* elems);
 
395
 
 
396
 
 
397
/**
 
398
 * Convert the letters of a string into upper case.
 
399
 * @param str the string to convert.
 
400
 * @return the string itself.
 
401
 */
 
402
std::string* strtoupper(std::string* str);
 
403
 
 
404
 
 
405
/**
 
406
 * Convert the letters of a string into lower case.
 
407
 * @param str the string to convert.
 
408
 * @return the string itself.
 
409
 */
 
410
std::string* strtolower(std::string* str);
 
411
 
 
412
 
 
413
/**
 
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.
 
418
 */
 
419
bool strfwm(const std::string& str, const std::string& key);
 
420
 
 
421
 
 
422
/**
 
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.
 
427
 */
 
428
bool strbwm(const std::string& str, const std::string& key);
 
429
 
 
430
 
 
431
/**
 
432
 * Cut space characters at head or tail of a string.
 
433
 * @param str the string to convert.
 
434
 * @return the string itself.
 
435
 */
 
436
std::string* strtrim(std::string* str);
 
437
 
 
438
 
 
439
/**
 
440
 * Convert a UTF-8 string into a UCS-4 array.
 
441
 * @param src the source object.
 
442
 * @param dest the destination object.
 
443
 */
 
444
void strutftoucs(const std::string& src, std::vector<uint32_t>* dest);
 
445
 
 
446
 
 
447
/**
 
448
 * Convert a UCS-4 array into a UTF-8 string.
 
449
 * @param src the source object.
 
450
 * @param dest the destination object.
 
451
 */
 
452
void strucstoutf(const std::vector<uint32_t>& src, std::string* dest);
 
453
 
 
454
 
 
455
/**
 
456
 * Serialize a string vector object into a string object.
 
457
 * @param src the source object.
 
458
 * @param dest the destination object.
 
459
 */
 
460
void strvecdump(const std::vector<std::string>& src, std::string* dest);
 
461
 
 
462
 
 
463
/**
 
464
 * Deserialize a string object into a string vector object.
 
465
 * @param src the source object.
 
466
 * @param dest the destination object.
 
467
 */
 
468
void strvecload(const std::string& src, std::vector<std::string>* dest);
 
469
 
 
470
 
 
471
/**
 
472
 * Serialize a string vector object into a string object.
 
473
 * @param src the source object.
 
474
 * @param dest the destination object.
 
475
 */
 
476
void strmapdump(const std::map<std::string, std::string>& src, std::string* dest);
 
477
 
 
478
 
 
479
/**
 
480
 * Deserialize a string object into a string map object.
 
481
 * @param src the source object.
 
482
 * @param dest the destination object.
 
483
 */
 
484
void strmapload(const std::string& src, std::map<std::string, std::string>* dest);
 
485
 
 
486
 
 
487
/**
 
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.
 
494
 */
 
495
char* hexencode(const void* buf, size_t size);
 
496
 
 
497
 
 
498
/**
 
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
 
502
 * is assigned.
 
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.
 
508
 */
 
509
char* hexdecode(const char* str, size_t* sp);
 
510
 
 
511
 
 
512
/**
 
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.
 
519
 */
 
520
char* urlencode(const void* buf, size_t size);
 
521
 
 
522
 
 
523
/**
 
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
 
527
 * is assigned.
 
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.
 
533
 */
 
534
char* urldecode(const char* str, size_t* sp);
 
535
 
 
536
 
 
537
/**
 
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.
 
544
 */
 
545
char* quoteencode(const void* buf, size_t size);
 
546
 
 
547
 
 
548
/**
 
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
 
552
 * is assigned.
 
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.
 
558
 */
 
559
char* quotedecode(const char* str, size_t* sp);
 
560
 
 
561
 
 
562
/**
 
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.
 
569
 */
 
570
char* baseencode(const void* buf, size_t size);
 
571
 
 
572
 
 
573
/**
 
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
 
577
 * is assigned.
 
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.
 
583
 */
 
584
char* basedecode(const char* str, size_t* sp);
 
585
 
 
586
 
 
587
/**
 
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
 
595
 * source region.
 
596
 */
 
597
void arccipher(const void* ptr, size_t size, const void* kbuf, size_t ksiz, void* obuf);
 
598
 
 
599
 
 
600
/**
 
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.
 
606
 */
 
607
char* memdup(const char* ptr, size_t size);
 
608
 
 
609
 
 
610
/**
 
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
 
616
 * equivalent.
 
617
 */
 
618
int32_t memicmp(const void* abuf, const void* bbuf, size_t size);
 
619
 
 
620
 
 
621
/**
 
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.
 
629
 */
 
630
void* memmem(const void* hbuf, size_t hsiz, const void* nbuf, size_t nsiz);
 
631
 
 
632
 
 
633
/**
 
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.
 
641
 */
 
642
void* memimem(const void* hbuf, size_t hsiz, const void* nbuf, size_t nsiz);
 
643
 
 
644
 
 
645
/**
 
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.
 
652
 */
 
653
size_t memdist(const void* abuf, size_t asiz, const void* bbuf, size_t bsiz);
 
654
 
 
655
 
 
656
/**
 
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.
 
661
 */
 
662
char* strdup(const char* str);
 
663
 
 
664
 
 
665
/**
 
666
 * Convert the letters of a string into upper case.
 
667
 * @param str the string to convert.
 
668
 * @return the string itself.
 
669
 */
 
670
char* strtoupper(char* str);
 
671
 
 
672
 
 
673
/**
 
674
 * Convert the letters of a string into lower case.
 
675
 * @param str the string to convert.
 
676
 * @return the string itself.
 
677
 */
 
678
char* strtolower(char* str);
 
679
 
 
680
 
 
681
/**
 
682
 * Cut space characters at head or tail of a string.
 
683
 * @param str the string to convert.
 
684
 * @return the string itself.
 
685
 */
 
686
char* strtrim(char* str);
 
687
 
 
688
 
 
689
/**
 
690
 * Squeeze space characters in a string and trim it.
 
691
 * @param str the string to convert.
 
692
 * @return the string itself.
 
693
 */
 
694
char* strsqzspc(char* str);
 
695
 
 
696
 
 
697
/**
 
698
 * Normalize space characters in a string and trim it.
 
699
 * @param str the string to convert.
 
700
 * @return the string itself.
 
701
 */
 
702
char* strnrmspc(char* str);
 
703
 
 
704
 
 
705
/**
 
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
 
710
 * equivalent.
 
711
 */
 
712
int32_t stricmp(const char* astr, const char* bstr);
 
713
 
 
714
 
 
715
/**
 
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.
 
721
 */
 
722
char* stristr(const char* hstr, const char* nstr);
 
723
 
 
724
 
 
725
/**
 
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.
 
730
 */
 
731
bool strfwm(const char* str, const char* key);
 
732
 
 
733
 
 
734
/**
 
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.
 
739
 */
 
740
bool strifwm(const char* str, const char* key);
 
741
 
 
742
 
 
743
/**
 
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.
 
748
 */
 
749
bool strbwm(const char* str, const char* key);
 
750
 
 
751
 
 
752
/**
 
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.
 
757
 */
 
758
bool stribwm(const char* str, const char* key);
 
759
 
 
760
 
 
761
/**
 
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.
 
765
 */
 
766
size_t strutflen(const char* str);
 
767
 
 
768
 
 
769
/**
 
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.
 
775
 */
 
776
void strutftoucs(const char* src, uint32_t* dest, size_t* np);
 
777
 
 
778
 
 
779
/**
 
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.
 
786
 */
 
787
void strutftoucs(const char* src, size_t slen, uint32_t* dest, size_t* np);
 
788
 
 
789
 
 
790
/**
 
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.
 
796
 */
 
797
size_t strucstoutf(const uint32_t* src, size_t snum, char* dest);
 
798
 
 
799
 
 
800
/**
 
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.
 
805
 */
 
806
size_t strutfdist(const char* astr, const char* bstr);
 
807
 
 
808
 
 
809
/**
 
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.
 
816
 */
 
817
size_t strucsdist(const uint32_t* aary, size_t anum, const uint32_t* bary, size_t bnum);
 
818
 
 
819
 
 
820
/**
 
821
 * Allocate a region on memory.
 
822
 * @param size the size of the region.
 
823
 * @return the pointer to the allocated region.
 
824
 */
 
825
void* xmalloc(size_t size);
 
826
 
 
827
 
 
828
/**
 
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.
 
833
 */
 
834
void* xcalloc(size_t nmemb, size_t size);
 
835
 
 
836
 
 
837
/**
 
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.
 
842
 */
 
843
void* xrealloc(void* ptr, size_t size);
 
844
 
 
845
 
 
846
/**
 
847
 * Free a region on memory.
 
848
 * @param ptr the pointer to the region.
 
849
 */
 
850
void xfree(void* ptr);
 
851
 
 
852
 
 
853
/**
 
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.
 
857
 */
 
858
void* mapalloc(size_t size);
 
859
 
 
860
 
 
861
/**
 
862
 * Free a region on mapped memory.
 
863
 * @param ptr the pointer to the allocated region.
 
864
 */
 
865
void mapfree(void* ptr);
 
866
 
 
867
 
 
868
/**
 
869
 * Get the time of day in seconds.
 
870
 * @return the time of day in seconds.  The accuracy is in microseconds.
 
871
 */
 
872
double time();
 
873
 
 
874
 
 
875
/**
 
876
 * Get the process ID.
 
877
 * @return the process ID.
 
878
 */
 
879
int64_t getpid();
 
880
 
 
881
 
 
882
/**
 
883
 * Get the value of an environment variable.
 
884
 * @return the value of the environment variable, or NULL on failure.
 
885
 */
 
886
const char* getenv(const char* name);
 
887
 
 
888
 
 
889
/**
 
890
 * Get system information of the environment.
 
891
 * @param strmap a string map to contain the result.
 
892
 */
 
893
void getsysinfo(std::map<std::string, std::string>* strmap);
 
894
 
 
895
 
 
896
/**
 
897
 * Set the standard streams into the binary mode.
 
898
 */
 
899
void setstdiobin();
 
900
 
 
901
 
 
902
/**
 
903
 * Dummy test driver.
 
904
 * @return always true.
 
905
 */
 
906
bool _dummytest();
 
907
 
 
908
 
 
909
/**
 
910
 * Convert a decimal string to an integer.
 
911
 */
 
912
inline int64_t atoi(const char* str) {
 
913
  _assert_(str);
 
914
  while (*str > '\0' && *str <= ' ') {
 
915
    str++;
 
916
  }
 
917
  int32_t sign = 1;
 
918
  int64_t num = 0;
 
919
  if (*str == '-') {
 
920
    str++;
 
921
    sign = -1;
 
922
  } else if (*str == '+') {
 
923
    str++;
 
924
  }
 
925
  while (*str != '\0') {
 
926
    if (*str < '0' || *str > '9') break;
 
927
    num = num * 10 + *str - '0';
 
928
    str++;
 
929
  }
 
930
  return num * sign;
 
931
}
 
932
 
 
933
 
 
934
/**
 
935
 * Convert a decimal string with a metric prefix to an integer.
 
936
 */
 
937
inline int64_t atoix(const char* str) {
 
938
  _assert_(str);
 
939
  while (*str > '\0' && *str <= ' ') {
 
940
    str++;
 
941
  }
 
942
  int32_t sign = 1;
 
943
  if (*str == '-') {
 
944
    str++;
 
945
    sign = -1;
 
946
  } else if (*str == '+') {
 
947
    str++;
 
948
  }
 
949
  long double num = 0;
 
950
  while (*str != '\0') {
 
951
    if (*str < '0' || *str > '9') break;
 
952
    num = num * 10 + *str - '0';
 
953
    str++;
 
954
  }
 
955
  if (*str == '.') {
 
956
    str++;
 
957
    long double base = 10;
 
958
    while (*str != '\0') {
 
959
      if (*str < '0' || *str > '9') break;
 
960
      num += (*str - '0') / base;
 
961
      str++;
 
962
      base *= 10;
 
963
    }
 
964
  }
 
965
  num *= sign;
 
966
  while (*str > '\0' && *str <= ' ') {
 
967
    str++;
 
968
  }
 
969
  if (*str == 'k' || *str == 'K') {
 
970
    num *= 1LL << 10;
 
971
  } else if (*str == 'm' || *str == 'M') {
 
972
    num *= 1LL << 20;
 
973
  } else if (*str == 'g' || *str == 'G') {
 
974
    num *= 1LL << 30;
 
975
  } else if (*str == 't' || *str == 'T') {
 
976
    num *= 1LL << 40;
 
977
  } else if (*str == 'p' || *str == 'P') {
 
978
    num *= 1LL << 50;
 
979
  } else if (*str == 'e' || *str == 'E') {
 
980
    num *= 1LL << 60;
 
981
  }
 
982
  if (num > INT64MAX) return INT64MAX;
 
983
  if (num < INT64MIN) return INT64MIN;
 
984
  return (int64_t)num;
 
985
}
 
986
 
 
987
 
 
988
/**
 
989
 * Convert a hexadecimal string to an integer.
 
990
 */
 
991
inline int64_t atoih(const char* str) {
 
992
  _assert_(str);
 
993
  while (*str > '\0' && *str <= ' ') {
 
994
    str++;
 
995
  }
 
996
  if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
 
997
    str += 2;
 
998
  }
 
999
  int64_t num = 0;
 
1000
  while (true) {
 
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;
 
1007
    } else {
 
1008
      break;
 
1009
    }
 
1010
    str++;
 
1011
  }
 
1012
  return num;
 
1013
}
 
1014
 
 
1015
 
 
1016
/**
 
1017
 * Convert a decimal byte array to an integer.
 
1018
 */
 
1019
inline int64_t atoin(const char* ptr, size_t size) {
 
1020
  _assert_(ptr && size <= MEMMAXSIZ);
 
1021
  while (size > 0 && *ptr >= '\0' && *ptr <= ' ') {
 
1022
    ptr++;
 
1023
    size--;
 
1024
  }
 
1025
  int32_t sign = 1;
 
1026
  int64_t num = 0;
 
1027
  if (size > 0) {
 
1028
    if (*ptr == '-') {
 
1029
      ptr++;
 
1030
      size--;
 
1031
      sign = -1;
 
1032
    } else if (*ptr == '+') {
 
1033
      ptr++;
 
1034
      size--;
 
1035
    }
 
1036
  }
 
1037
  while (size > 0) {
 
1038
    if (*ptr < '0' || *ptr > '9') break;
 
1039
    num = num * 10 + *ptr - '0';
 
1040
    ptr++;
 
1041
    size--;
 
1042
  }
 
1043
  return num * sign;
 
1044
}
 
1045
 
 
1046
 
 
1047
/**
 
1048
 * Convert a decimal string to a real number.
 
1049
 */
 
1050
inline double atof(const char* str) {
 
1051
  _assert_(str);
 
1052
  while (*str > '\0' && *str <= ' ') {
 
1053
    str++;
 
1054
  }
 
1055
  int32_t sign = 1;
 
1056
  if (*str == '-') {
 
1057
    str++;
 
1058
    sign = -1;
 
1059
  } else if (*str == '+') {
 
1060
    str++;
 
1061
  }
 
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;
 
1067
  int32_t col = 0;
 
1068
  while (*str != '\0') {
 
1069
    if (*str < '0' || *str > '9') break;
 
1070
    num = num * 10 + *str - '0';
 
1071
    str++;
 
1072
    if (num > 0) col++;
 
1073
  }
 
1074
  if (*str == '.') {
 
1075
    str++;
 
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;
 
1081
      str++;
 
1082
      col++;
 
1083
      base *= 10;
 
1084
    }
 
1085
    num += fract;
 
1086
  }
 
1087
  if (*str == 'e' || *str == 'E') {
 
1088
    str++;
 
1089
    num *= std::pow((long double)10, (long double)atoi(str));
 
1090
  }
 
1091
  return num * sign;
 
1092
}
 
1093
 
 
1094
 
 
1095
/**
 
1096
 * Convert a decimal byte array to a real number.
 
1097
 */
 
1098
inline double atofn(const char* ptr, size_t size) {
 
1099
  _assert_(ptr && size <= MEMMAXSIZ);
 
1100
  while (size > 0 && *ptr >= '\0' && *ptr <= ' ') {
 
1101
    ptr++;
 
1102
    size--;
 
1103
  }
 
1104
  int32_t sign = 1;
 
1105
  if (size > 0) {
 
1106
    if (*ptr == '-') {
 
1107
      ptr++;
 
1108
      size--;
 
1109
      sign = -1;
 
1110
    } else if (*ptr == '+') {
 
1111
      ptr++;
 
1112
      size--;
 
1113
    }
 
1114
  }
 
1115
  if (size > 2) {
 
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();
 
1120
  }
 
1121
  long double num = 0;
 
1122
  int32_t col = 0;
 
1123
  while (size > 0) {
 
1124
    if (*ptr < '0' || *ptr > '9') break;
 
1125
    num = num * 10 + *ptr - '0';
 
1126
    ptr++;
 
1127
    size--;
 
1128
    if (num > 0) col++;
 
1129
  }
 
1130
  if (size > 0 && *ptr == '.') {
 
1131
    ptr++;
 
1132
    size--;
 
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;
 
1138
      ptr++;
 
1139
      size--;
 
1140
      col++;
 
1141
      base *= 10;
 
1142
    }
 
1143
    num += fract;
 
1144
  }
 
1145
  if (size > 0 && (*ptr == 'e' || *ptr == 'E')) {
 
1146
    ptr++;
 
1147
    size--;
 
1148
    num *= std::pow((long double)10, (long double)atoin(ptr, size));
 
1149
  }
 
1150
  return num * sign;
 
1151
}
 
1152
 
 
1153
 
 
1154
 
 
1155
/**
 
1156
 * Normalize a 16-bit number in the native order into the network byte order.
 
1157
 */
 
1158
inline uint16_t hton16(uint16_t num) {
 
1159
  _assert_(true);
 
1160
  if (BIGEND) return num;
 
1161
  return ((num & 0x00ffU) << 8) | ((num & 0xff00U) >> 8);
 
1162
}
 
1163
 
 
1164
 
 
1165
/**
 
1166
 * Normalize a 32-bit number in the native order into the network byte order.
 
1167
 */
 
1168
inline uint32_t hton32(uint32_t num) {
 
1169
  _assert_(true);
 
1170
  if (BIGEND) return num;
 
1171
  return ((num & 0x000000ffUL) << 24) | ((num & 0x0000ff00UL) << 8) | \
 
1172
      ((num & 0x00ff0000UL) >> 8) | ((num & 0xff000000UL) >> 24);
 
1173
}
 
1174
 
 
1175
 
 
1176
/**
 
1177
 * Normalize a 64-bit number in the native order into the network byte order.
 
1178
 */
 
1179
inline uint64_t hton64(uint64_t num) {
 
1180
  _assert_(true);
 
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);
 
1186
}
 
1187
 
 
1188
 
 
1189
/**
 
1190
 * Denormalize a 16-bit number in the network byte order into the native order.
 
1191
 */
 
1192
inline uint16_t ntoh16(uint16_t num) {
 
1193
  _assert_(true);
 
1194
  return hton16(num);
 
1195
}
 
1196
 
 
1197
 
 
1198
/**
 
1199
 * Denormalize a 32-bit number in the network byte order into the native order.
 
1200
 */
 
1201
inline uint32_t ntoh32(uint32_t num) {
 
1202
  _assert_(true);
 
1203
  return hton32(num);
 
1204
}
 
1205
 
 
1206
 
 
1207
/**
 
1208
 * Denormalize a 64-bit number in the network byte order into the native order.
 
1209
 */
 
1210
inline uint64_t ntoh64(uint64_t num) {
 
1211
  _assert_(true);
 
1212
  return hton64(num);
 
1213
}
 
1214
 
 
1215
 
 
1216
/**
 
1217
 * Write a number in fixed length format into a buffer.
 
1218
 */
 
1219
inline void writefixnum(void* buf, uint64_t num, size_t width) {
 
1220
  _assert_(buf && width <= sizeof(int64_t));
 
1221
  num = hton64(num);
 
1222
  std::memcpy(buf, (const char*)&num + sizeof(num) - width, width);
 
1223
}
 
1224
 
 
1225
 
 
1226
/**
 
1227
 * Read a number in fixed length format from a buffer.
 
1228
 */
 
1229
inline uint64_t readfixnum(const void* buf, size_t width) {
 
1230
  _assert_(buf && width <= sizeof(int64_t));
 
1231
  uint64_t num = 0;
 
1232
  std::memcpy(&num, buf, width);
 
1233
  return ntoh64(num) >> ((sizeof(num) - width) * 8);
 
1234
}
 
1235
 
 
1236
 
 
1237
/**
 
1238
 * Write a number in variable length format into a buffer.
 
1239
 */
 
1240
inline size_t writevarnum(void* buf, uint64_t num) {
 
1241
  _assert_(buf);
 
1242
  unsigned char* wp = (unsigned char*)buf;
 
1243
  if (num < (1ULL << 7)) {
 
1244
    *(wp++) = num;
 
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;
 
1297
  } else {
 
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;
 
1308
  }
 
1309
  return wp - (unsigned char*)buf;
 
1310
}
 
1311
 
 
1312
 
 
1313
/**
 
1314
 * Read a number in variable length format from a buffer.
 
1315
 */
 
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;
 
1320
  uint64_t num = 0;
 
1321
  uint32_t c;
 
1322
  do {
 
1323
    if (rp >= ep) {
 
1324
      *np = 0;
 
1325
      return 0;
 
1326
    }
 
1327
    c = *rp;
 
1328
    num = (num << 7) + (c & 0x7f);
 
1329
    rp++;
 
1330
  } while (c >= 0x80);
 
1331
  *np = num;
 
1332
  return rp - (const unsigned char*)buf;
 
1333
}
 
1334
 
 
1335
 
 
1336
/**
 
1337
 * Check the size of variable length format of a number.
 
1338
 */
 
1339
inline size_t sizevarnum(uint64_t num) {
 
1340
  _assert_(true);
 
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;
 
1350
  return 10;
 
1351
}
 
1352
 
 
1353
 
 
1354
/**
 
1355
 * Get the hash value by MurMur hashing.
 
1356
 */
 
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);
 
1368
    num *= mul;
 
1369
    num ^= num >> rtt;
 
1370
    num *= mul;
 
1371
    hash *= mul;
 
1372
    hash ^= num;
 
1373
    rp += sizeof(uint64_t);
 
1374
    size -= sizeof(uint64_t);
 
1375
  }
 
1376
  switch (size) {
 
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];
 
1384
      hash *= mul;
 
1385
  };
 
1386
  hash ^= hash >> rtt;
 
1387
  hash *= mul;
 
1388
  hash ^= hash >> rtt;
 
1389
  return hash;
 
1390
}
 
1391
 
 
1392
 
 
1393
/**
 
1394
 * Get the hash value by FNV hashing.
 
1395
 */
 
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;
 
1401
  while (rp < ep) {
 
1402
    hash = (hash ^ *(rp++)) * 109951162811ULL;
 
1403
  }
 
1404
  return hash;
 
1405
}
 
1406
 
 
1407
 
 
1408
/**
 
1409
 * Get the hash value suitable for a file name.
 
1410
 */
 
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;
 
1414
  uint32_t rv;
 
1415
  char* wp = obuf;
 
1416
  if (size <= 10) {
 
1417
    if (size > 0) {
 
1418
      const unsigned char* ep = rp + size;
 
1419
      while (rp < ep) {
 
1420
        int32_t num = *rp >> 4;
 
1421
        if (num < 10) {
 
1422
          *(wp++) = '0' + num;
 
1423
        } else {
 
1424
          *(wp++) = 'a' + num - 10;
 
1425
        }
 
1426
        num = *rp & 0x0f;
 
1427
        if (num < 10) {
 
1428
          *(wp++) = '0' + num;
 
1429
        } else {
 
1430
          *(wp++) = 'a' + num - 10;
 
1431
        }
 
1432
        rp++;
 
1433
      }
 
1434
    } else {
 
1435
      *(wp++) = '0';
 
1436
    }
 
1437
    uint64_t hash = hashmurmur(buf, size);
 
1438
    rv = (((hash & 0xffff000000000000ULL) >> 48) | ((hash & 0x0000ffff00000000ULL) >> 16)) ^
 
1439
        (((hash & 0x000000000000ffffULL) << 16) | ((hash & 0x00000000ffff0000ULL) >> 16));
 
1440
  } else {
 
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;
 
1445
      if (num < 10) {
 
1446
        *(wp++) = '0' + num;
 
1447
      } else {
 
1448
        *(wp++) = 'a' + num - 10;
 
1449
      }
 
1450
    }
 
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;
 
1461
      inc = inc >> 1;
 
1462
      if (num < 10) {
 
1463
        *(wp++) = '0' + num;
 
1464
      } else {
 
1465
        *(wp++) = 'a' + num - 10;
 
1466
      }
 
1467
      num = least & 0x0f;
 
1468
      if (inc & 0x01) num += 0x10;
 
1469
      inc = inc >> 1;
 
1470
      if (num < 10) {
 
1471
        *(wp++) = '0' + num;
 
1472
      } else {
 
1473
        *(wp++) = 'a' + num - 10;
 
1474
      }
 
1475
      hash = hash << 8;
 
1476
    }
 
1477
  }
 
1478
  *wp = '\0';
 
1479
  return rv;
 
1480
}
 
1481
 
 
1482
 
 
1483
/**
 
1484
 * Get a prime number nearby a number.
 
1485
 */
 
1486
inline uint64_t nearbyprime(uint64_t num) {
 
1487
  _assert_(true);
 
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
 
1523
  };
 
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;
 
1527
}
 
1528
 
 
1529
 
 
1530
/**
 
1531
 * Get the quiet Not-a-Number value.
 
1532
 */
 
1533
inline double nan() {
 
1534
  _assert_(true);
 
1535
  return std::numeric_limits<double>::quiet_NaN();
 
1536
}
 
1537
 
 
1538
 
 
1539
/**
 
1540
 * Get the positive infinity value.
 
1541
 */
 
1542
inline double inf() {
 
1543
  _assert_(true);
 
1544
  return std::numeric_limits<double>::infinity();
 
1545
}
 
1546
 
 
1547
 
 
1548
/**
 
1549
 * Check a number is a Not-a-Number value.
 
1550
 */
 
1551
inline bool chknan(double num) {
 
1552
  _assert_(true);
 
1553
  return num != num;
 
1554
}
 
1555
 
 
1556
 
 
1557
/**
 
1558
 * Check a number is an infinity value.
 
1559
 */
 
1560
inline bool chkinf(double num) {
 
1561
  _assert_(true);
 
1562
  return num == inf() || num == -inf();
 
1563
}
 
1564
 
 
1565
 
 
1566
/**
 
1567
 * Append a formatted string at the end of a string.
 
1568
 */
 
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];
 
1574
      cbuf[0] = '%';
 
1575
      size_t cbsiz = 1;
 
1576
      int32_t lnum = 0;
 
1577
      format++;
 
1578
      while (std::strchr("0123456789 .+-hlLz", *format) && *format != '\0' &&
 
1579
             cbsiz < NUMBUFSIZ - 1) {
 
1580
        if (*format == 'l' || *format == 'L') lnum++;
 
1581
        cbuf[cbsiz++] = *(format++);
 
1582
      }
 
1583
      cbuf[cbsiz++] = *format;
 
1584
      cbuf[cbsiz] = '\0';
 
1585
      switch (*format) {
 
1586
        case 's': {
 
1587
          const char* tmp = va_arg(ap, const char*);
 
1588
          if (tmp) {
 
1589
            dest->append(tmp);
 
1590
          } else {
 
1591
            dest->append("(null)");
 
1592
          }
 
1593
          break;
 
1594
        }
 
1595
        case 'd': {
 
1596
          char tbuf[NUMBUFSIZ*4];
 
1597
          size_t tsiz;
 
1598
          if (lnum >= 2) {
 
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));
 
1602
          } else {
 
1603
            tsiz = std::sprintf(tbuf, cbuf, va_arg(ap, int));
 
1604
          }
 
1605
          dest->append(tbuf, tsiz);
 
1606
          break;
 
1607
        }
 
1608
        case 'o': case 'u': case 'x': case 'X': case 'c': {
 
1609
          char tbuf[NUMBUFSIZ*4];
 
1610
          size_t tsiz;
 
1611
          if (lnum >= 2) {
 
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));
 
1615
          } else {
 
1616
            tsiz = std::sprintf(tbuf, cbuf, va_arg(ap, unsigned int));
 
1617
          }
 
1618
          dest->append(tbuf, tsiz);
 
1619
          break;
 
1620
        }
 
1621
        case 'e': case 'E': case 'f': case 'g': case 'G': {
 
1622
          char tbuf[NUMBUFSIZ*4];
 
1623
          size_t tsiz;
 
1624
          if (lnum >= 1) {
 
1625
            tsiz = std::snprintf(tbuf, sizeof(tbuf), cbuf, va_arg(ap, long double));
 
1626
          } else {
 
1627
            tsiz = std::snprintf(tbuf, sizeof(tbuf), cbuf, va_arg(ap, double));
 
1628
          }
 
1629
          if (tsiz > sizeof(tbuf)) {
 
1630
            tbuf[sizeof(tbuf)-1] = '*';
 
1631
            tsiz = sizeof(tbuf);
 
1632
          }
 
1633
          dest->append(tbuf, tsiz);
 
1634
          break;
 
1635
        }
 
1636
        case 'p': {
 
1637
          char tbuf[NUMBUFSIZ*4];
 
1638
          size_t tsiz = std::sprintf(tbuf, "%p", va_arg(ap, void*));
 
1639
          dest->append(tbuf, tsiz);
 
1640
          break;
 
1641
        }
 
1642
        case '%': {
 
1643
          dest->append("%", 1);
 
1644
          break;
 
1645
        }
 
1646
      }
 
1647
    } else {
 
1648
      dest->append(format, 1);
 
1649
    }
 
1650
    format++;
 
1651
  }
 
1652
}
 
1653
 
 
1654
 
 
1655
/**
 
1656
 * Append a formatted string at the end of a string.
 
1657
 */
 
1658
inline void strprintf(std::string* dest, const char* format, ...) {
 
1659
  _assert_(dest && format);
 
1660
  va_list ap;
 
1661
  va_start(ap, format);
 
1662
  vstrprintf(dest, format, ap);
 
1663
  va_end(ap);
 
1664
}
 
1665
 
 
1666
 
 
1667
/**
 
1668
 * Generate a formatted string on memory.
 
1669
 */
 
1670
inline std::string strprintf(const char* format, ...) {
 
1671
  _assert_(format);
 
1672
  std::string str;
 
1673
  va_list ap;
 
1674
  va_start(ap, format);
 
1675
  vstrprintf(&str, format, ap);
 
1676
  va_end(ap);
 
1677
  return str;
 
1678
}
 
1679
 
 
1680
 
 
1681
/**
 
1682
 * Split a string with a delimiter
 
1683
 */
 
1684
inline size_t strsplit(const std::string& str, char delim, std::vector<std::string>* elems) {
 
1685
  _assert_(elems);
 
1686
  elems->clear();
 
1687
  std::string::const_iterator it = str.begin();
 
1688
  std::string::const_iterator pv = it;
 
1689
  while (it != str.end()) {
 
1690
    if (*it == delim) {
 
1691
      std::string col(pv, it);
 
1692
      elems->push_back(col);
 
1693
      pv = it + 1;
 
1694
    }
 
1695
    ++it;
 
1696
  }
 
1697
  std::string col(pv, it);
 
1698
  elems->push_back(col);
 
1699
  return elems->size();
 
1700
}
 
1701
 
 
1702
 
 
1703
/**
 
1704
 * Split a string with delimiters.
 
1705
 */
 
1706
inline size_t strsplit(const std::string& str, const std::string& delims,
 
1707
                       std::vector<std::string>* elems) {
 
1708
  _assert_(elems);
 
1709
  elems->clear();
 
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);
 
1716
      pv = it + 1;
 
1717
      break;
 
1718
    }
 
1719
    ++it;
 
1720
  }
 
1721
  std::string col(pv, it);
 
1722
  elems->push_back(col);
 
1723
  return elems->size();
 
1724
}
 
1725
 
 
1726
 
 
1727
/**
 
1728
 * Convert the letters of a string into upper case.
 
1729
 */
 
1730
inline std::string* strtoupper(std::string* str) {
 
1731
  _assert_(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');
 
1736
  }
 
1737
  return str;
 
1738
}
 
1739
 
 
1740
 
 
1741
/**
 
1742
 * Convert the letters of a string into lower case.
 
1743
 */
 
1744
inline std::string* strtolower(std::string* str) {
 
1745
  _assert_(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');
 
1750
  }
 
1751
  return str;
 
1752
}
 
1753
 
 
1754
 
 
1755
/**
 
1756
 * Check whether a string begins with a key.
 
1757
 */
 
1758
inline bool strfwm(const std::string& str, const std::string& key) {
 
1759
  _assert_(true);
 
1760
  size_t ksiz = key.size();
 
1761
  if (ksiz > str.size()) return false;
 
1762
  return !std::memcmp(str.data(), key.data(), ksiz);
 
1763
}
 
1764
 
 
1765
 
 
1766
/**
 
1767
 * Check whether a string ends with a key.
 
1768
 */
 
1769
inline bool strbwm(const std::string& str, const std::string& key) {
 
1770
  _assert_(true);
 
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);
 
1774
}
 
1775
 
 
1776
 
 
1777
/**
 
1778
 * Cut space characters at head or tail of a string.
 
1779
 */
 
1780
inline std::string* strtrim(std::string* str) {
 
1781
  _assert_(str);
 
1782
  size_t size = str->size();
 
1783
  size_t wi = 0;
 
1784
  size_t li = 0;
 
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;
 
1789
    } else {
 
1790
      (*str)[wi++] = c;
 
1791
      li = wi;
 
1792
    }
 
1793
  }
 
1794
  str->resize(li);
 
1795
  return str;
 
1796
}
 
1797
 
 
1798
 
 
1799
/**
 
1800
 * Convert a UTF-8 string into a UCS-4 array.
 
1801
 */
 
1802
inline void strutftoucs(const std::string& src, std::vector<uint32_t>* dest) {
 
1803
  _assert_(dest);
 
1804
  dest->reserve(dest->size() + src.size());
 
1805
  size_t size = src.size();
 
1806
  size_t ri = 0;
 
1807
  while (ri < size) {
 
1808
    uint32_t c = (unsigned char)src[ri];
 
1809
    if (c < 0x80) {
 
1810
      dest->push_back(c);
 
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);
 
1815
        ri++;
 
1816
      }
 
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);
 
1821
        ri += 2;
 
1822
      }
 
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) |
 
1826
            (src[ri+3] & 0x3f);
 
1827
        if (c >= 0x10000) dest->push_back(c);
 
1828
        ri += 3;
 
1829
      }
 
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);
 
1835
        ri += 4;
 
1836
      }
 
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);
 
1842
        ri += 5;
 
1843
      }
 
1844
    }
 
1845
    ri++;
 
1846
  }
 
1847
}
 
1848
 
 
1849
 
 
1850
/**
 
1851
 * Convert a UCS-4 array into a UTF-8 string.
 
1852
 */
 
1853
inline void strucstoutf(const std::vector<uint32_t>& src, std::string* dest) {
 
1854
  _assert_(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) {
 
1859
    uint32_t c = *it;
 
1860
    if (c < 0x80) {
 
1861
      dest->append(1, c);
 
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));
 
1887
    }
 
1888
    ++it;
 
1889
  }
 
1890
}
 
1891
 
 
1892
 
 
1893
/**
 
1894
 * Serialize a string vector object into a string object.
 
1895
 */
 
1896
inline void strvecdump(const std::vector<std::string>& src, std::string* dest) {
 
1897
  _assert_(dest);
 
1898
  std::vector<std::string>::const_iterator it = src.begin();
 
1899
  std::vector<std::string>::const_iterator itend = src.end();
 
1900
  size_t dsiz = 1;
 
1901
  while (it != itend) {
 
1902
    dsiz += 2 + it->size();
 
1903
    ++it;
 
1904
  }
 
1905
  dest->reserve(dest->size() + dsiz);
 
1906
  it = src.begin();
 
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());
 
1912
    ++it;
 
1913
  }
 
1914
}
 
1915
 
 
1916
 
 
1917
/**
 
1918
 * Deserialize a string object into a string vector object.
 
1919
 */
 
1920
inline void strvecload(const std::string& src, std::vector<std::string>* dest) {
 
1921
  _assert_(dest);
 
1922
  const char* rp = src.data();
 
1923
  size_t size = src.size();
 
1924
  while (size > 0) {
 
1925
    uint64_t vsiz;
 
1926
    size_t step = readvarnum(rp, size, &vsiz);
 
1927
    rp += step;
 
1928
    size -= step;
 
1929
    if (vsiz > size) break;
 
1930
    dest->push_back(std::string(rp, vsiz));
 
1931
    rp += vsiz;
 
1932
    size -= vsiz;
 
1933
  }
 
1934
}
 
1935
 
 
1936
 
 
1937
/**
 
1938
 * Serialize a string vector object into a string object.
 
1939
 */
 
1940
inline void strmapdump(const std::map<std::string, std::string>& src, std::string* dest) {
 
1941
  _assert_(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();
 
1944
  size_t dsiz = 1;
 
1945
  while (it != itend) {
 
1946
    dsiz += 4 + it->first.size() + it->second.size();
 
1947
    ++it;
 
1948
  }
 
1949
  dest->reserve(dest->size() + dsiz);
 
1950
  it = src.begin();
 
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());
 
1958
    ++it;
 
1959
  }
 
1960
}
 
1961
 
 
1962
 
 
1963
/**
 
1964
 * Deserialize a string object into a string map object.
 
1965
 */
 
1966
inline void strmapload(const std::string& src, std::map<std::string, std::string>* dest) {
 
1967
  _assert_(dest);
 
1968
  const char* rp = src.data();
 
1969
  int64_t size = src.size();
 
1970
  while (size > 1) {
 
1971
    uint64_t ksiz;
 
1972
    size_t step = readvarnum(rp, size, &ksiz);
 
1973
    rp += step;
 
1974
    size -= step;
 
1975
    if (size < 1) break;
 
1976
    uint64_t vsiz;
 
1977
    step = readvarnum(rp, size, &vsiz);
 
1978
    rp += step;
 
1979
    size -= step;
 
1980
    int64_t rsiz = ksiz + vsiz;
 
1981
    if (rsiz > size) break;
 
1982
    (*dest)[std::string(rp, ksiz)] = std::string(rp + ksiz, vsiz);
 
1983
    rp += rsiz;
 
1984
    size -= rsiz;
 
1985
  }
 
1986
}
 
1987
 
 
1988
 
 
1989
/**
 
1990
 * Encode a serial object by hexadecimal encoding.
 
1991
 */
 
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];
 
1996
  char* wp = zbuf;
 
1997
  for (const unsigned char* ep = rp + size; rp < ep; rp++) {
 
1998
    int32_t num = *rp >> 4;
 
1999
    if (num < 10) {
 
2000
      *(wp++) = '0' + num;
 
2001
    } else {
 
2002
      *(wp++) = 'a' + num - 10;
 
2003
    }
 
2004
    num = *rp & 0x0f;
 
2005
    if (num < 10) {
 
2006
      *(wp++) = '0' + num;
 
2007
    } else {
 
2008
      *(wp++) = 'a' + num - 10;
 
2009
    }
 
2010
  }
 
2011
  *wp = '\0';
 
2012
  return zbuf;
 
2013
}
 
2014
 
 
2015
 
 
2016
/**
 
2017
 * Decode a string encoded by hexadecimal encoding.
 
2018
 */
 
2019
inline char* hexdecode(const char* str, size_t* sp) {
 
2020
  _assert_(str && sp);
 
2021
  char* zbuf = new char[std::strlen(str)+1];
 
2022
  char* wp = zbuf;
 
2023
  while (true) {
 
2024
    while (*str > '\0' && *str <= ' ') {
 
2025
      str++;
 
2026
    }
 
2027
    int32_t num = 0;
 
2028
    int32_t c = *(str++);
 
2029
    if (c >= '0' && c <= '9') {
 
2030
      num = c - '0';
 
2031
    } else if (c >= 'a' && c <= 'f') {
 
2032
      num = c - 'a' + 10;
 
2033
    } else if (c >= 'A' && c <= 'F') {
 
2034
      num = c - 'A' + 10;
 
2035
    } else if (c == '\0') {
 
2036
      break;
 
2037
    }
 
2038
    c = *(str++);
 
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') {
 
2046
      *(wp++) = num;
 
2047
      break;
 
2048
    }
 
2049
    *(wp++) = num;
 
2050
  }
 
2051
  *wp = '\0';
 
2052
  *sp = wp - zbuf;
 
2053
  return zbuf;
 
2054
}
 
2055
 
 
2056
 
 
2057
/**
 
2058
 * Encode a serial object by URL encoding.
 
2059
 */
 
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];
 
2064
  char* wp = zbuf;
 
2065
  for (const unsigned char* ep = rp + size; rp < ep; rp++) {
 
2066
    int32_t c = *rp;
 
2067
    if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
 
2068
        (c >= '0' && c <= '9') || (c != '\0' && std::strchr("_-.~", c))) {
 
2069
      *(wp++) = c;
 
2070
    } else {
 
2071
      *(wp++) = '%';
 
2072
      int32_t num = c >> 4;
 
2073
      if (num < 10) {
 
2074
        *(wp++) = '0' + num;
 
2075
      } else {
 
2076
        *(wp++) = 'a' + num - 10;
 
2077
      }
 
2078
      num = c & 0x0f;
 
2079
      if (num < 10) {
 
2080
        *(wp++) = '0' + num;
 
2081
      } else {
 
2082
        *(wp++) = 'a' + num - 10;
 
2083
      }
 
2084
    }
 
2085
  }
 
2086
  *wp = '\0';
 
2087
  return zbuf;
 
2088
}
 
2089
 
 
2090
 
 
2091
/**
 
2092
 * Decode a string encoded by URL encoding.
 
2093
 */
 
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];
 
2098
  char* wp = zbuf;
 
2099
  const char* ep = str + zsiz;
 
2100
  while (str < ep) {
 
2101
    int32_t c = *str;
 
2102
    if (c == '%') {
 
2103
      int32_t num = 0;
 
2104
      if (++str >= ep) break;
 
2105
      c = *str;
 
2106
      if (c >= '0' && c <= '9') {
 
2107
        num = c - '0';
 
2108
      } else if (c >= 'a' && c <= 'f') {
 
2109
        num = c - 'a' + 10;
 
2110
      } else if (c >= 'A' && c <= 'F') {
 
2111
        num = c - 'A' + 10;
 
2112
      }
 
2113
      if (++str >= ep) break;
 
2114
      c = *str;
 
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;
 
2121
      }
 
2122
      *(wp++) = num;
 
2123
      str++;
 
2124
    } else if (c == '+') {
 
2125
      *(wp++) = ' ';
 
2126
      str++;
 
2127
    } else if (c <= ' ' || c == 0x7f) {
 
2128
      str++;
 
2129
    } else {
 
2130
      *(wp++) = c;
 
2131
      str++;
 
2132
    }
 
2133
  }
 
2134
  *wp = '\0';
 
2135
  *sp = wp - zbuf;
 
2136
  return zbuf;
 
2137
}
 
2138
 
 
2139
 
 
2140
/**
 
2141
 * Encode a serial object by Quoted-printable encoding.
 
2142
 */
 
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];
 
2147
  char* wp = zbuf;
 
2148
  for (const unsigned char* ep = rp + size; rp < ep; rp++) {
 
2149
    int32_t c = *rp;
 
2150
    if (c == '=' || c < ' ' || c > 0x7e) {
 
2151
      *(wp++) = '=';
 
2152
      int32_t num = c >> 4;
 
2153
      if (num < 10) {
 
2154
        *(wp++) = '0' + num;
 
2155
      } else {
 
2156
        *(wp++) = 'A' + num - 10;
 
2157
      }
 
2158
      num = c & 0x0f;
 
2159
      if (num < 10) {
 
2160
        *(wp++) = '0' + num;
 
2161
      } else {
 
2162
        *(wp++) = 'A' + num - 10;
 
2163
      }
 
2164
    } else {
 
2165
      *(wp++) = c;
 
2166
    }
 
2167
  }
 
2168
  *wp = '\0';
 
2169
  return zbuf;
 
2170
}
 
2171
 
 
2172
 
 
2173
/**
 
2174
 * Decode a string encoded by Quoted-printable encoding.
 
2175
 */
 
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];
 
2180
  char* wp = zbuf;
 
2181
  const char* ep = str + zsiz;
 
2182
  while (str < ep) {
 
2183
    int32_t c = *str;
 
2184
    if (c == '=') {
 
2185
      int32_t num = 0;
 
2186
      if (++str >= ep) break;
 
2187
      c = *str;
 
2188
      if (c == '\r') {
 
2189
        if (++str >= ep) break;
 
2190
        if (*str == '\n') str++;
 
2191
      } else if (c == '\n') {
 
2192
        str++;
 
2193
      } else {
 
2194
        if (c >= '0' && c <= '9') {
 
2195
          num = c - '0';
 
2196
        } else if (c >= 'a' && c <= 'f') {
 
2197
          num = c - 'a' + 10;
 
2198
        } else if (c >= 'A' && c <= 'F') {
 
2199
          num = c - 'A' + 10;
 
2200
        }
 
2201
        if (++str >= ep) break;
 
2202
        c = *str;
 
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;
 
2209
        }
 
2210
        *(wp++) = num;
 
2211
        str++;
 
2212
      }
 
2213
    } else if (c < ' ' || c == 0x7f) {
 
2214
      str++;
 
2215
    } else {
 
2216
      *(wp++) = c;
 
2217
      str++;
 
2218
    }
 
2219
  }
 
2220
  *wp = '\0';
 
2221
  *sp = wp - zbuf;
 
2222
  return zbuf;
 
2223
}
 
2224
 
 
2225
 
 
2226
/**
 
2227
 * Encode a serial object by Base64 encoding.
 
2228
 */
 
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];
 
2234
  char* wp = zbuf;
 
2235
  for (size_t i = 0; i < size; i += 3) {
 
2236
    switch (size - i) {
 
2237
      case 1: {
 
2238
        *(wp++) = tbl[rp[0] >> 2];
 
2239
        *(wp++) = tbl[(rp[0] & 3) << 4];
 
2240
        *(wp++) = '=';
 
2241
        *(wp++) = '=';
 
2242
        break;
 
2243
      }
 
2244
      case 2: {
 
2245
        *(wp++) = tbl[rp[0] >> 2];
 
2246
        *(wp++) = tbl[((rp[0] & 3) << 4) + (rp[1] >> 4)];
 
2247
        *(wp++) = tbl[(rp[1] & 0xf) << 2];
 
2248
        *(wp++) = '=';
 
2249
        break;
 
2250
      }
 
2251
      default: {
 
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];
 
2256
        break;
 
2257
      }
 
2258
    }
 
2259
    rp += 3;
 
2260
  }
 
2261
  *wp = '\0';
 
2262
  return zbuf;
 
2263
}
 
2264
 
 
2265
 
 
2266
/**
 
2267
 * Decode a string encoded by Base64 encoding.
 
2268
 */
 
2269
inline char* basedecode(const char* str, size_t* sp) {
 
2270
  _assert_(str && sp);
 
2271
  size_t bpos = 0;
 
2272
  size_t eqcnt = 0;
 
2273
  size_t len = std::strlen(str);
 
2274
  unsigned char* zbuf = new unsigned char[len+4];
 
2275
  unsigned char* wp = zbuf;
 
2276
  size_t zsiz = 0;
 
2277
  while (bpos < len && eqcnt == 0) {
 
2278
    size_t bits = 0;
 
2279
    size_t i;
 
2280
    for (i = 0; bpos < len && i < 4; bpos++) {
 
2281
      if (str[bpos] >= 'A' && str[bpos] <= 'Z') {
 
2282
        bits = (bits << 6) | (str[bpos] - 'A');
 
2283
        i++;
 
2284
      } else if (str[bpos] >= 'a' && str[bpos] <= 'z') {
 
2285
        bits = (bits << 6) | (str[bpos] - 'a' + 26);
 
2286
        i++;
 
2287
      } else if (str[bpos] >= '0' && str[bpos] <= '9') {
 
2288
        bits = (bits << 6) | (str[bpos] - '0' + 52);
 
2289
        i++;
 
2290
      } else if (str[bpos] == '+') {
 
2291
        bits = (bits << 6) | 62;
 
2292
        i++;
 
2293
      } else if (str[bpos] == '/') {
 
2294
        bits = (bits << 6) | 63;
 
2295
        i++;
 
2296
      } else if (str[bpos] == '=') {
 
2297
        bits <<= 6;
 
2298
        i++;
 
2299
        eqcnt++;
 
2300
      }
 
2301
    }
 
2302
    if (i == 0 && bpos >= len) continue;
 
2303
    switch (eqcnt) {
 
2304
      case 0: {
 
2305
        *wp++ = (bits >> 16) & 0xff;
 
2306
        *wp++ = (bits >> 8) & 0xff;
 
2307
        *wp++ = bits & 0xff;
 
2308
        zsiz += 3;
 
2309
        break;
 
2310
      }
 
2311
      case 1: {
 
2312
        *wp++ = (bits >> 16) & 0xff;
 
2313
        *wp++ = (bits >> 8) & 0xff;
 
2314
        zsiz += 2;
 
2315
        break;
 
2316
      }
 
2317
      case 2: {
 
2318
        *wp++ = (bits >> 16) & 0xff;
 
2319
        zsiz += 1;
 
2320
        break;
 
2321
      }
 
2322
    }
 
2323
  }
 
2324
  zbuf[zsiz] = '\0';
 
2325
  *sp = zsiz;
 
2326
  return (char*)zbuf;
 
2327
}
 
2328
 
 
2329
 
 
2330
/**
 
2331
 * Cipher or decipher a serial object with the Arcfour stream cipher.
 
2332
 */
 
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);
 
2335
  if (ksiz < 1) {
 
2336
    kbuf = "";
 
2337
    ksiz = 1;
 
2338
  }
 
2339
  uint32_t sbox[0x100], kbox[0x100];
 
2340
  for (int32_t i = 0; i < 0x100; i++) {
 
2341
    sbox[i] = i;
 
2342
    kbox[i] = ((uint8_t*)kbuf)[i%ksiz];
 
2343
  }
 
2344
  uint32_t sidx = 0;
 
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];
 
2349
    sbox[sidx] = swap;
 
2350
  }
 
2351
  uint32_t x = 0;
 
2352
  uint32_t y = 0;
 
2353
  for (size_t i = 0; i < size; i++) {
 
2354
    x = (x + 1) & 0xff;
 
2355
    y = (y + sbox[x]) & 0xff;
 
2356
    uint32_t swap = sbox[x];
 
2357
    sbox[x] = sbox[y];
 
2358
    sbox[y] = swap;
 
2359
    ((uint8_t*)obuf)[i] = ((uint8_t*)ptr)[i] ^ sbox[(sbox[x]+sbox[y])&0xff];
 
2360
  }
 
2361
}
 
2362
 
 
2363
 
 
2364
/**
 
2365
 * Duplicate a region on memory.
 
2366
 */
 
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);
 
2371
  return obuf;
 
2372
}
 
2373
 
 
2374
 
 
2375
/**
 
2376
 * Compare two regions by case insensitive evaluation.
 
2377
 */
 
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;
 
2383
  while (ap < ep) {
 
2384
    int32_t ac = *ap;
 
2385
    if (ac >= 'A' && ac <= 'Z') ac += 'a' - 'A';
 
2386
    int32_t bc = *bp;
 
2387
    if (bc >= 'A' && bc <= 'Z') bc += 'a' - 'A';
 
2388
    if (ac != bc) return ac - bc;
 
2389
    ap++;
 
2390
    bp++;
 
2391
  }
 
2392
  return 0;
 
2393
}
 
2394
 
 
2395
 
 
2396
/**
 
2397
 * Find the first occurrence of a sub pattern.
 
2398
 */
 
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;
 
2406
  while (rp <= ep) {
 
2407
    if (*rp == tc) {
 
2408
      bool hit = true;
 
2409
      for (size_t i = 1; i < nsiz; i++) {
 
2410
        if (rp[i] != ((unsigned char*)nbuf)[i]) {
 
2411
          hit = false;
 
2412
          break;
 
2413
        }
 
2414
      }
 
2415
      if (hit) return (void*)rp;
 
2416
    }
 
2417
    rp++;
 
2418
  }
 
2419
  return NULL;
 
2420
}
 
2421
 
 
2422
 
 
2423
/**
 
2424
 * Find the first occurrence of a sub pattern by case insensitive evaluation.
 
2425
 */
 
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;
 
2434
  while (rp <= ep) {
 
2435
    int32_t cc = *rp;
 
2436
    if (cc >= 'A' && cc <= 'Z') cc += 'a' - 'A';
 
2437
    if (cc == tc) {
 
2438
      bool hit = true;
 
2439
      for (size_t i = 1; i < nsiz; i++) {
 
2440
        int32_t hc = rp[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';
 
2444
        if (hc != nc) {
 
2445
          hit = false;
 
2446
          break;
 
2447
        }
 
2448
      }
 
2449
      if (hit) return (void*)rp;
 
2450
    }
 
2451
    rp++;
 
2452
  }
 
2453
  return NULL;
 
2454
}
 
2455
 
 
2456
 
 
2457
/**
 
2458
 * Duplicate a string on memory.
 
2459
 */
 
2460
inline char* strdup(const char* str) {
 
2461
  _assert_(str);
 
2462
  size_t size = std::strlen(str);
 
2463
  char* obuf = memdup(str, size);
 
2464
  obuf[size] = '\0';
 
2465
  return obuf;
 
2466
}
 
2467
 
 
2468
 
 
2469
/**
 
2470
 * Convert the letters of a string into upper case.
 
2471
 */
 
2472
inline char* strtoupper(char* str) {
 
2473
  _assert_(str);
 
2474
  char* wp = str;
 
2475
  while (*wp != '\0') {
 
2476
    if (*wp >= 'a' && *wp <= 'z') *wp -= 'a' - 'A';
 
2477
    wp++;
 
2478
  }
 
2479
  return str;
 
2480
}
 
2481
 
 
2482
 
 
2483
/**
 
2484
 * Convert the letters of a string into lower case.
 
2485
 */
 
2486
inline char* strtolower(char* str) {
 
2487
  _assert_(str);
 
2488
  char* wp = str;
 
2489
  while (*wp != '\0') {
 
2490
    if (*wp >= 'A' && *wp <= 'Z') *wp += 'a' - 'A';
 
2491
    wp++;
 
2492
  }
 
2493
  return str;
 
2494
}
 
2495
 
 
2496
 
 
2497
/**
 
2498
 * Cut space characters at head or tail of a string.
 
2499
 */
 
2500
inline char* strtrim(char* str) {
 
2501
  _assert_(str);
 
2502
  const char* rp = str;
 
2503
  char* wp = str;
 
2504
  bool head = true;
 
2505
  while (*rp != '\0') {
 
2506
    if (*rp > '\0' && *rp <= ' ') {
 
2507
      if (!head) *(wp++) = *rp;
 
2508
    } else {
 
2509
      *(wp++) = *rp;
 
2510
      head = false;
 
2511
    }
 
2512
    rp++;
 
2513
  }
 
2514
  *wp = '\0';
 
2515
  while (wp > str && wp[-1] > '\0' && wp[-1] <= ' ') {
 
2516
    *(--wp) = '\0';
 
2517
  }
 
2518
  return str;
 
2519
}
 
2520
 
 
2521
 
 
2522
/**
 
2523
 * Squeeze space characters in a string and trim it.
 
2524
 */
 
2525
inline char* strsqzspc(char* str) {
 
2526
  _assert_(str);
 
2527
  const char* rp = str;
 
2528
  char* wp = str;
 
2529
  bool spc = true;
 
2530
  while (*rp != '\0') {
 
2531
    if (*rp > '\0' && *rp <= ' ') {
 
2532
      if (!spc) *(wp++) = *rp;
 
2533
      spc = true;
 
2534
    } else {
 
2535
      *(wp++) = *rp;
 
2536
      spc = false;
 
2537
    }
 
2538
    rp++;
 
2539
  }
 
2540
  *wp = '\0';
 
2541
  for (wp--; wp >= str; wp--) {
 
2542
    if (*wp > '\0' && *wp <= ' ') {
 
2543
      *wp = '\0';
 
2544
    } else {
 
2545
      break;
 
2546
    }
 
2547
  }
 
2548
  return str;
 
2549
}
 
2550
 
 
2551
 
 
2552
/**
 
2553
 * Normalize space characters in a string and trim it.
 
2554
 */
 
2555
inline char* strnrmspc(char* str) {
 
2556
  _assert_(str);
 
2557
  const char* rp = str;
 
2558
  char* wp = str;
 
2559
  bool spc = true;
 
2560
  while (*rp != '\0') {
 
2561
    if ((*rp > '\0' && *rp <= ' ') || *rp == 0x7f) {
 
2562
      if (!spc) *(wp++) = ' ';
 
2563
      spc = true;
 
2564
    } else {
 
2565
      *(wp++) = *rp;
 
2566
      spc = false;
 
2567
    }
 
2568
    rp++;
 
2569
  }
 
2570
  *wp = '\0';
 
2571
  for (wp--; wp >= str; wp--) {
 
2572
    if (*wp == ' ') {
 
2573
      *wp = '\0';
 
2574
    } else {
 
2575
      break;
 
2576
    }
 
2577
  }
 
2578
  return str;
 
2579
}
 
2580
 
 
2581
 
 
2582
 
 
2583
/**
 
2584
 * Compare two strings by case insensitive evaluation.
 
2585
 */
 
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;
 
2595
    astr++;
 
2596
    bstr++;
 
2597
  }
 
2598
  return (*bstr == '\0') ? 0 : -1;
 
2599
}
 
2600
 
 
2601
 
 
2602
/**
 
2603
 * Find the first occurrence of a substring by case insensitive evaluation.
 
2604
 */
 
2605
inline char* stristr(const char* hstr, const char* nstr) {
 
2606
  _assert_(hstr && nstr);
 
2607
  if (*nstr == '\0') return (char*)hstr;
 
2608
  int32_t tc = *nstr;
 
2609
  if (tc >= 'A' && tc <= 'Z') tc += 'a' - 'A';
 
2610
  const char* rp = hstr;
 
2611
  while (*rp != '\0') {
 
2612
    int32_t cc = *rp;
 
2613
    if (cc >= 'A' && cc <= 'Z') cc += 'a' - 'A';
 
2614
    if (cc == tc) {
 
2615
      bool hit = true;
 
2616
      for (size_t i = 1; nstr[i] != '\0'; i++) {
 
2617
        int32_t hc = rp[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';
 
2621
        if (hc != nc) {
 
2622
          hit = false;
 
2623
          break;
 
2624
        }
 
2625
      }
 
2626
      if (hit) return (char*)rp;
 
2627
    }
 
2628
    rp++;
 
2629
  }
 
2630
  return NULL;
 
2631
}
 
2632
 
 
2633
 
 
2634
/**
 
2635
 * Check whether a string begins with a key.
 
2636
 */
 
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;
 
2641
    key++;
 
2642
    str++;
 
2643
  }
 
2644
  return true;
 
2645
}
 
2646
 
 
2647
 
 
2648
/**
 
2649
 * Check whether a string begins with a key by case insensitive evaluation.
 
2650
 */
 
2651
inline bool strifwm(const char* str, const char* key) {
 
2652
  _assert_(str && key);
 
2653
  while (*key != '\0') {
 
2654
    if (*str == '\0') return false;
 
2655
    int32_t sc = *str;
 
2656
    if (sc >= 'A' && sc <= 'Z') sc += 'a' - 'A';
 
2657
    int32_t kc = *key;
 
2658
    if (kc >= 'A' && kc <= 'Z') kc += 'a' - 'A';
 
2659
    if (sc != kc) return false;
 
2660
    key++;
 
2661
    str++;
 
2662
  }
 
2663
  return true;
 
2664
}
 
2665
 
 
2666
 
 
2667
/**
 
2668
 * Check whether a string ends with a key.
 
2669
 */
 
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;
 
2676
  }
 
2677
  return true;
 
2678
}
 
2679
 
 
2680
 
 
2681
/**
 
2682
 * Check whether a string ends with a key by case insensitive evaluation.
 
2683
 */
 
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;
 
2695
  }
 
2696
  return true;
 
2697
}
 
2698
 
 
2699
 
 
2700
/**
 
2701
 * Get the number of characters in a UTF-8 string.
 
2702
 */
 
2703
inline size_t strutflen(const char* str) {
 
2704
  _assert_(str);
 
2705
  size_t len = 0;
 
2706
  while (*str != '\0') {
 
2707
    len += (*(unsigned char*)str & 0xc0) != 0x80;
 
2708
    str++;
 
2709
  }
 
2710
  return len;
 
2711
}
 
2712
 
 
2713
 
 
2714
/**
 
2715
 * Convert a UTF-8 string into a UCS-4 array.
 
2716
 */
 
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;
 
2720
  size_t dnum = 0;
 
2721
  while (*rp != '\0') {
 
2722
    uint32_t c = *rp;
 
2723
    if (c < 0x80) {
 
2724
      dest[dnum++] = c;
 
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;
 
2729
        rp++;
 
2730
      }
 
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;
 
2735
        rp += 2;
 
2736
      }
 
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) |
 
2740
            (rp[3] & 0x3f);
 
2741
        if (c >= 0x10000) dest[dnum++] = c;
 
2742
        rp += 3;
 
2743
      }
 
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;
 
2749
        rp += 4;
 
2750
      }
 
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;
 
2756
        rp += 5;
 
2757
      }
 
2758
    }
 
2759
    rp++;
 
2760
  }
 
2761
  *np = dnum;
 
2762
}
 
2763
 
 
2764
 
 
2765
/**
 
2766
 * Convert a UTF-8 string into a UCS-4 array.
 
2767
 */
 
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;
 
2772
  size_t dnum = 0;
 
2773
  while (rp < ep) {
 
2774
    uint32_t c = *rp;
 
2775
    if (c < 0x80) {
 
2776
      dest[dnum++] = c;
 
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;
 
2781
        rp++;
 
2782
      }
 
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;
 
2787
        rp += 2;
 
2788
      }
 
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) |
 
2792
            (rp[3] & 0x3f);
 
2793
        if (c >= 0x10000) dest[dnum++] = c;
 
2794
        rp += 3;
 
2795
      }
 
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;
 
2801
        rp += 4;
 
2802
      }
 
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;
 
2808
        rp += 5;
 
2809
      }
 
2810
    }
 
2811
    rp++;
 
2812
  }
 
2813
  *np = dnum;
 
2814
}
 
2815
 
 
2816
 
 
2817
/**
 
2818
 * Convert a UCS-4 array into a UTF-8 string.
 
2819
 */
 
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;
 
2824
  while (src < ep) {
 
2825
    uint32_t c = *src;
 
2826
    if (c < 0x80) {
 
2827
      *(wp++) = c;
 
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);
 
2853
    }
 
2854
    src++;
 
2855
  }
 
2856
  *wp = '\0';
 
2857
  return wp - (unsigned char*)dest;
 
2858
}
 
2859
 
 
2860
 
 
2861
/**
 
2862
 * Allocate a region on memory.
 
2863
 */
 
2864
inline void* xmalloc(size_t size) {
 
2865
  _assert_(size <= MEMMAXSIZ);
 
2866
  void* ptr = std::malloc(size);
 
2867
  if (!ptr) throw std::bad_alloc();
 
2868
  return ptr;
 
2869
}
 
2870
 
 
2871
 
 
2872
/**
 
2873
 * Allocate a nullified region on memory.
 
2874
 */
 
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();
 
2879
  return ptr;
 
2880
}
 
2881
 
 
2882
 
 
2883
/**
 
2884
 * Re-allocate a region on memory.
 
2885
 */
 
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();
 
2890
  return ptr;
 
2891
}
 
2892
 
 
2893
 
 
2894
/**
 
2895
 * Free a region on memory.
 
2896
 */
 
2897
inline void xfree(void* ptr) {
 
2898
  _assert_(true);
 
2899
  std::free(ptr);
 
2900
}
 
2901
 
 
2902
 
 
2903
/**
 
2904
 * Dummy test driver.
 
2905
 */
 
2906
inline bool _dummytest() {
 
2907
  _assert_(true);
 
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;
 
2917
}
 
2918
 
 
2919
 
 
2920
}                                        // common namespace
 
2921
 
 
2922
#endif                                   // duplication check
 
2923
 
 
2924
// END OF FILE