@ohos-ports/bare-buffer 3.7.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +26 -0
  3. package/binding.c +1077 -0
  4. package/binding.gyp +32 -0
  5. package/binding.js +1 -0
  6. package/build/Release/bare_buffer.node +0 -0
  7. package/deps/libbase64/.clang-format +10 -0
  8. package/deps/libbase64/.gitattributes +1 -0
  9. package/deps/libbase64/.github/workflows/integrate.yml +45 -0
  10. package/deps/libbase64/.github/workflows/nightly.yml +28 -0
  11. package/deps/libbase64/.prettierrc +1 -0
  12. package/deps/libbase64/CMakeLists.txt +71 -0
  13. package/deps/libbase64/LICENSE +201 -0
  14. package/deps/libbase64/NOTICE +13 -0
  15. package/deps/libbase64/README.md +11 -0
  16. package/deps/libbase64/include/base64.h +323 -0
  17. package/deps/libbase64/package.json +25 -0
  18. package/deps/libbase64/src/base64.c +22 -0
  19. package/deps/libbase64/test/CMakeLists.txt +31 -0
  20. package/deps/libbase64/test/decode-invalid.c +35 -0
  21. package/deps/libbase64/test/decode-length.c +23 -0
  22. package/deps/libbase64/test/decode.c +36 -0
  23. package/deps/libbase64/test/encode-length.c +22 -0
  24. package/deps/libbase64/test/encode.c +42 -0
  25. package/deps/libbase64/test/fuzz/CMakeLists.txt +18 -0
  26. package/deps/libbase64/test/fuzz/decode/utf16le.c +53 -0
  27. package/deps/libbase64/test/fuzz/decode/utf8.c +47 -0
  28. package/deps/libbase64/test/fuzz/encode/utf16le.c +56 -0
  29. package/deps/libbase64/test/fuzz/encode/utf8.c +56 -0
  30. package/deps/libhex/.clang-format +10 -0
  31. package/deps/libhex/.gitattributes +1 -0
  32. package/deps/libhex/.github/workflows/integrate.yml +45 -0
  33. package/deps/libhex/.github/workflows/nightly.yml +28 -0
  34. package/deps/libhex/.prettierrc +1 -0
  35. package/deps/libhex/CMakeLists.txt +72 -0
  36. package/deps/libhex/LICENSE +201 -0
  37. package/deps/libhex/NOTICE +13 -0
  38. package/deps/libhex/README.md +11 -0
  39. package/deps/libhex/include/hex.h +163 -0
  40. package/deps/libhex/package.json +25 -0
  41. package/deps/libhex/src/hex.c +16 -0
  42. package/deps/libhex/test/CMakeLists.txt +31 -0
  43. package/deps/libhex/test/decode-invalid.c +37 -0
  44. package/deps/libhex/test/decode-length.c +23 -0
  45. package/deps/libhex/test/decode.c +25 -0
  46. package/deps/libhex/test/encode-length.c +22 -0
  47. package/deps/libhex/test/encode.c +25 -0
  48. package/deps/libhex/test/fuzz/CMakeLists.txt +18 -0
  49. package/deps/libhex/test/fuzz/decode/utf16le.c +53 -0
  50. package/deps/libhex/test/fuzz/decode/utf8.c +47 -0
  51. package/deps/libhex/test/fuzz/encode/utf16le.c +36 -0
  52. package/deps/libhex/test/fuzz/encode/utf8.c +36 -0
  53. package/deps/libutf/.clang-format +10 -0
  54. package/deps/libutf/.gitattributes +1 -0
  55. package/deps/libutf/.github/workflows/integrate.yml +45 -0
  56. package/deps/libutf/.github/workflows/nightly.yml +28 -0
  57. package/deps/libutf/.prettierrc +1 -0
  58. package/deps/libutf/CMakeLists.txt +105 -0
  59. package/deps/libutf/LICENSE +201 -0
  60. package/deps/libutf/NOTICE +13 -0
  61. package/deps/libutf/README.md +11 -0
  62. package/deps/libutf/include/utf/string.h +1655 -0
  63. package/deps/libutf/include/utf.h +132 -0
  64. package/deps/libutf/package.json +24 -0
  65. package/deps/libutf/src/ascii/validate.c +47 -0
  66. package/deps/libutf/src/endianness.c +19 -0
  67. package/deps/libutf/src/endianness.h +54 -0
  68. package/deps/libutf/src/latin1/convert-to-utf16.c +37 -0
  69. package/deps/libutf/src/latin1/convert-to-utf32.c +34 -0
  70. package/deps/libutf/src/latin1/convert-to-utf8.c +58 -0
  71. package/deps/libutf/src/latin1/length-from-utf16.c +26 -0
  72. package/deps/libutf/src/latin1/length-from-utf32.c +26 -0
  73. package/deps/libutf/src/latin1/length-from-utf8.c +34 -0
  74. package/deps/libutf/src/utf16/convert-to-latin1.c +41 -0
  75. package/deps/libutf/src/utf16/convert-to-utf32.c +56 -0
  76. package/deps/libutf/src/utf16/convert-to-utf8.c +80 -0
  77. package/deps/libutf/src/utf16/length-from-latin1.c +26 -0
  78. package/deps/libutf/src/utf16/length-from-utf32.c +33 -0
  79. package/deps/libutf/src/utf16/length-from-utf8.c +38 -0
  80. package/deps/libutf/src/utf16/validate.c +53 -0
  81. package/deps/libutf/src/utf32/convert-to-latin1.c +40 -0
  82. package/deps/libutf/src/utf32/convert-to-utf16.c +56 -0
  83. package/deps/libutf/src/utf32/convert-to-utf8.c +71 -0
  84. package/deps/libutf/src/utf32/length-from-latin1.c +26 -0
  85. package/deps/libutf/src/utf32/length-from-utf16.c +35 -0
  86. package/deps/libutf/src/utf32/length-from-utf8.c +35 -0
  87. package/deps/libutf/src/utf32/string.c +149 -0
  88. package/deps/libutf/src/utf32/validate.c +39 -0
  89. package/deps/libutf/src/utf8/convert-to-latin1.c +70 -0
  90. package/deps/libutf/src/utf8/convert-to-utf16.c +95 -0
  91. package/deps/libutf/src/utf8/convert-to-utf32.c +110 -0
  92. package/deps/libutf/src/utf8/length-from-latin1.c +32 -0
  93. package/deps/libutf/src/utf8/length-from-utf16.c +48 -0
  94. package/deps/libutf/src/utf8/length-from-utf32.c +35 -0
  95. package/deps/libutf/src/utf8/string.c +149 -0
  96. package/deps/libutf/src/utf8/validate.c +107 -0
  97. package/deps/libutf/test/CMakeLists.txt +56 -0
  98. package/deps/libutf/test/fuzz/CMakeLists.txt +26 -0
  99. package/deps/libutf/test/fuzz/corpus/.gitignore +2 -0
  100. package/deps/libutf/test/fuzz/crashes/.gitignore +2 -0
  101. package/deps/libutf/test/fuzz/latin1/convert-to-utf16.c +32 -0
  102. package/deps/libutf/test/fuzz/latin1/convert-to-utf32.c +32 -0
  103. package/deps/libutf/test/fuzz/latin1/convert-to-utf8.c +33 -0
  104. package/deps/libutf/test/fuzz/utf16/convert-to-latin1.c +36 -0
  105. package/deps/libutf/test/fuzz/utf16/convert-to-utf32.c +38 -0
  106. package/deps/libutf/test/fuzz/utf16/convert-to-utf8.c +38 -0
  107. package/deps/libutf/test/fuzz/utf32/convert-to-latin1.c +36 -0
  108. package/deps/libutf/test/fuzz/utf32/convert-to-utf16.c +38 -0
  109. package/deps/libutf/test/fuzz/utf32/convert-to-utf8.c +38 -0
  110. package/deps/libutf/test/fuzz/utf8/convert-to-latin1.c +33 -0
  111. package/deps/libutf/test/fuzz/utf8/convert-to-utf16.c +35 -0
  112. package/deps/libutf/test/fuzz/utf8/convert-to-utf32.c +35 -0
  113. package/deps/libutf/test/utf16/utf8-convert.c +45 -0
  114. package/deps/libutf/test/utf16/utf8-length.c +41 -0
  115. package/deps/libutf/test/utf16/validate-invalid.c +50 -0
  116. package/deps/libutf/test/utf16/validate.c +32 -0
  117. package/deps/libutf/test/utf32/string-append.c +74 -0
  118. package/deps/libutf/test/utf32/string-compare.c +108 -0
  119. package/deps/libutf/test/utf32/string-erase.c +79 -0
  120. package/deps/libutf/test/utf32/string-index.c +102 -0
  121. package/deps/libutf/test/utf32/string-insert.c +92 -0
  122. package/deps/libutf/test/utf32/string-last-index.c +71 -0
  123. package/deps/libutf/test/utf32/string-prepend.c +51 -0
  124. package/deps/libutf/test/utf32/string-replace.c +88 -0
  125. package/deps/libutf/test/utf32/string-reserve.c +99 -0
  126. package/deps/libutf/test/utf32/string-substring.c +93 -0
  127. package/deps/libutf/test/utf8/latin1-convert.c +23 -0
  128. package/deps/libutf/test/utf8/string-append.c +23 -0
  129. package/deps/libutf/test/utf8/string-compare.c +67 -0
  130. package/deps/libutf/test/utf8/string-erase.c +75 -0
  131. package/deps/libutf/test/utf8/string-index.c +99 -0
  132. package/deps/libutf/test/utf8/string-last-index.c +68 -0
  133. package/deps/libutf/test/utf8/string-prepend.c +23 -0
  134. package/deps/libutf/test/utf8/string-replace.c +74 -0
  135. package/deps/libutf/test/utf8/string-reserve.c +51 -0
  136. package/deps/libutf/test/utf8/string-substring.c +68 -0
  137. package/deps/libutf/test/utf8/utf16-convert.c +32 -0
  138. package/deps/libutf/test/utf8/utf16-length.c +29 -0
  139. package/deps/libutf/test/utf8/validate-invalid.c +26 -0
  140. package/deps/libutf/test/utf8/validate.c +21 -0
  141. package/global.d.ts +21 -0
  142. package/global.js +6 -0
  143. package/index.d.ts +769 -0
  144. package/index.js +1339 -0
  145. package/lib/ascii.js +36 -0
  146. package/lib/base64.js +25 -0
  147. package/lib/base64url.js +25 -0
  148. package/lib/checked.js +23 -0
  149. package/lib/constants.d.ts +7 -0
  150. package/lib/constants.js +3 -0
  151. package/lib/hex.js +20 -0
  152. package/lib/latin1.js +14 -0
  153. package/lib/utf16le.js +20 -0
  154. package/lib/utf8.js +18 -0
  155. package/package.json +64 -0
@@ -0,0 +1,93 @@
1
+ #include <assert.h>
2
+ #include <stddef.h>
3
+
4
+ #include "../../include/utf.h"
5
+ #include "../../include/utf/string.h"
6
+
7
+ int
8
+ main() {
9
+ int e;
10
+
11
+ static const utf32_t hello_world[] = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', 0};
12
+
13
+ {
14
+ static const utf32_t expected[] = {'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 0};
15
+
16
+ utf32_string_t string;
17
+ utf32_string_init(&string);
18
+
19
+ e = utf32_string_append_literal(&string, hello_world, (size_t) -1);
20
+ assert(e == 0);
21
+
22
+ utf32_string_view_t view = utf32_string_substring(&string, 2, 10);
23
+
24
+ assert(view.len == 8);
25
+ assert(utf32_string_view_compare_literal(view, expected, (size_t) -1) == 0);
26
+
27
+ utf32_string_destroy(&string);
28
+ }
29
+
30
+ // An end of (size_t) -1, or one past the length, runs to the end of the
31
+ // string, and a start past the end gives an empty view.
32
+ {
33
+ utf32_string_t string;
34
+ utf32_string_init(&string);
35
+
36
+ e = utf32_string_append_literal(&string, hello_world, (size_t) -1);
37
+ assert(e == 0);
38
+
39
+ assert(utf32_string_substring(&string, 6, (size_t) -1).len == 5);
40
+ assert(utf32_string_substring(&string, 6, 100).len == 5);
41
+ assert(utf32_string_substring(&string, 100, 100).len == 0);
42
+ assert(utf32_string_substring(&string, 8, 4).len == 0);
43
+
44
+ utf32_string_destroy(&string);
45
+ }
46
+
47
+ // Copying a substring out gives a string holding just those code points.
48
+ {
49
+ static const utf32_t expected[] = {'w', 'o', 'r', 'l', 'd', 0};
50
+
51
+ utf32_string_t string, copy;
52
+ utf32_string_init(&string);
53
+ utf32_string_init(&copy);
54
+
55
+ e = utf32_string_append_literal(&string, hello_world, (size_t) -1);
56
+ assert(e == 0);
57
+
58
+ e = utf32_string_substring_copy(&string, 6, (size_t) -1, &copy);
59
+ assert(e == 0);
60
+ assert(copy.len == 5);
61
+ assert(utf32_string_compare_literal(&copy, expected, (size_t) -1) == 0);
62
+
63
+ utf32_string_destroy(&copy);
64
+ utf32_string_destroy(&string);
65
+ }
66
+
67
+ // A copy into a string that has already outgrown its inline buffer reuses that
68
+ // allocation rather than leaking it.
69
+ {
70
+ utf32_string_t string, copy;
71
+ utf32_string_init(&string);
72
+ utf32_string_init(&copy);
73
+
74
+ e = utf32_string_append_literal(&string, hello_world, (size_t) -1);
75
+ assert(e == 0);
76
+
77
+ e = utf32_string_reserve(&copy, UTF32_STRING_INLINE_CAPACITY * 8);
78
+ assert(e == 0);
79
+ assert(copy.data != copy.buf);
80
+
81
+ e = utf32_string_view_substring_copy(utf32_string_view(&string), 0, 5, &copy);
82
+ assert(e == 0);
83
+ assert(copy.len == 5);
84
+
85
+ // Still on the allocation reserved above. Were the result initialized here
86
+ // instead, this would have been dropped back to the inline buffer and the
87
+ // allocation leaked.
88
+ assert(copy.data != copy.buf);
89
+
90
+ utf32_string_destroy(&copy);
91
+ utf32_string_destroy(&string);
92
+ }
93
+ }
@@ -0,0 +1,23 @@
1
+ #include <assert.h>
2
+ #include <string.h>
3
+
4
+ #include "../../include/utf.h"
5
+
6
+ #define test_convert(string, len, expected, written) \
7
+ { \
8
+ latin1_t result[len]; \
9
+ assert(utf8_convert_to_latin1((utf8_t *) string, len, result) == written); \
10
+ assert(memcmp(expected, result, written) == 0); \
11
+ }
12
+
13
+ int
14
+ main() {
15
+ // ASCII character 'A'
16
+ test_convert("\x41", 1, "\x41", 1);
17
+
18
+ // ø Character
19
+ test_convert("\xc3\xb8", 2, "\xf8", 1);
20
+
21
+ // Ending with an invalid character 'AAAД'
22
+ test_convert("\x41\x41\x41\xd0\x94", 4, "", 0);
23
+ }
@@ -0,0 +1,23 @@
1
+ #include <assert.h>
2
+ #include <string.h>
3
+
4
+ #include "../../include/utf.h"
5
+ #include "../../include/utf/string.h"
6
+
7
+ int
8
+ main() {
9
+ int e;
10
+
11
+ utf8_string_t string;
12
+ utf8_string_init(&string);
13
+
14
+ e = utf8_string_append_literal(&string, (utf8_t *) "hello", -1);
15
+ assert(e == 0);
16
+
17
+ e = utf8_string_append_literal(&string, (utf8_t *) " world", -1);
18
+ assert(e == 0);
19
+
20
+ assert(memcmp(string.data, "hello world", string.len) == 0);
21
+
22
+ utf8_string_destroy(&string);
23
+ }
@@ -0,0 +1,67 @@
1
+ #include <assert.h>
2
+ #include <stddef.h>
3
+
4
+ #include "../../include/utf.h"
5
+ #include "../../include/utf/string.h"
6
+
7
+ int
8
+ main() {
9
+ int e;
10
+
11
+ // Two empty strings are equal, and neither is compared over any bytes at all.
12
+ {
13
+ utf8_string_t a, b;
14
+ utf8_string_init(&a);
15
+ utf8_string_init(&b);
16
+
17
+ assert(utf8_string_compare(&a, &b) == 0);
18
+
19
+ utf8_string_view_t empty = utf8_string_view_init((const utf8_t *) "", 0);
20
+
21
+ assert(utf8_string_view_compare(empty, empty) == 0);
22
+ assert(utf8_string_compare_literal(&a, (utf8_t *) "", 0) == 0);
23
+ assert(utf8_string_view_compare_literal(empty, (utf8_t *) "", 0) == 0);
24
+
25
+ utf8_string_destroy(&a);
26
+ utf8_string_destroy(&b);
27
+ }
28
+
29
+ // Ordering follows the bytes, with the shorter of two strings that share a
30
+ // prefix coming first.
31
+ {
32
+ utf8_string_t a;
33
+ utf8_string_init(&a);
34
+
35
+ e = utf8_string_append_literal(&a, (utf8_t *) "banana", -1);
36
+ assert(e == 0);
37
+
38
+ assert(utf8_string_compare_literal(&a, (utf8_t *) "banana", -1) == 0);
39
+ assert(utf8_string_compare_literal(&a, (utf8_t *) "banan", -1) > 0);
40
+ assert(utf8_string_compare_literal(&a, (utf8_t *) "bananas", -1) < 0);
41
+ assert(utf8_string_compare_literal(&a, (utf8_t *) "apple", -1) > 0);
42
+ assert(utf8_string_compare_literal(&a, (utf8_t *) "cherry", -1) < 0);
43
+
44
+ utf8_string_destroy(&a);
45
+ }
46
+
47
+ // A null byte is compared like any other byte, rather than ending the
48
+ // comparison as it would were these C strings.
49
+ {
50
+ utf8_string_view_t a = utf8_string_view_init((const utf8_t *) "a\0b", 3);
51
+ utf8_string_view_t b = utf8_string_view_init((const utf8_t *) "a\0c", 3);
52
+ utf8_string_view_t c = utf8_string_view_init((const utf8_t *) "a\0b", 3);
53
+
54
+ assert(utf8_string_view_compare(a, b) < 0);
55
+ assert(utf8_string_view_compare(b, a) > 0);
56
+ assert(utf8_string_view_compare(a, c) == 0);
57
+
58
+ // The bytes past a null byte also tell apart strings of unequal length.
59
+ utf8_string_view_t d = utf8_string_view_init((const utf8_t *) "a\0", 2);
60
+
61
+ assert(utf8_string_view_compare(d, a) < 0);
62
+ assert(utf8_string_view_compare(a, d) > 0);
63
+
64
+ assert(utf8_string_view_compare_literal(a, (utf8_t *) "a\0b", 3) == 0);
65
+ assert(utf8_string_view_compare_literal(a, (utf8_t *) "a\0c", 3) < 0);
66
+ }
67
+ }
@@ -0,0 +1,75 @@
1
+ #include <assert.h>
2
+ #include <stddef.h>
3
+ #include <stdint.h>
4
+ #include <string.h>
5
+
6
+ #include "../../include/utf.h"
7
+ #include "../../include/utf/string.h"
8
+
9
+ int
10
+ main() {
11
+ int e;
12
+
13
+ // Plain erase in the middle.
14
+ {
15
+ utf8_string_t s;
16
+ utf8_string_init(&s);
17
+
18
+ e = utf8_string_append_literal(&s, (utf8_t *) "hello world", -1);
19
+ assert(e == 0);
20
+
21
+ e = utf8_string_erase(&s, 5, 6);
22
+ assert(e == 0);
23
+ assert(s.len == 5);
24
+ assert(memcmp(s.data, "hello", 5) == 0);
25
+
26
+ utf8_string_destroy(&s);
27
+ }
28
+
29
+ // Erase with len > string->len - pos must clamp.
30
+ {
31
+ utf8_string_t s;
32
+ utf8_string_init(&s);
33
+
34
+ e = utf8_string_append_literal(&s, (utf8_t *) "hello", -1);
35
+ assert(e == 0);
36
+
37
+ e = utf8_string_erase(&s, 2, 100);
38
+ assert(e == 0);
39
+ assert(s.len == 2);
40
+ assert(memcmp(s.data, "he", 2) == 0);
41
+
42
+ utf8_string_destroy(&s);
43
+ }
44
+
45
+ // Erase with pos + len overflowing size_t must also clamp.
46
+ {
47
+ utf8_string_t s;
48
+ utf8_string_init(&s);
49
+
50
+ e = utf8_string_append_literal(&s, (utf8_t *) "hello", -1);
51
+ assert(e == 0);
52
+
53
+ e = utf8_string_erase(&s, 1, SIZE_MAX);
54
+ assert(e == 0);
55
+ assert(s.len == 1);
56
+ assert(memcmp(s.data, "h", 1) == 0);
57
+
58
+ utf8_string_destroy(&s);
59
+ }
60
+
61
+ // Erase with pos > string->len is an error.
62
+ {
63
+ utf8_string_t s;
64
+ utf8_string_init(&s);
65
+
66
+ e = utf8_string_append_literal(&s, (utf8_t *) "hello", -1);
67
+ assert(e == 0);
68
+
69
+ e = utf8_string_erase(&s, 10, 1);
70
+ assert(e == -1);
71
+ assert(s.len == 5);
72
+
73
+ utf8_string_destroy(&s);
74
+ }
75
+ }
@@ -0,0 +1,99 @@
1
+ #include <assert.h>
2
+ #include <stddef.h>
3
+
4
+ #include "../../include/utf.h"
5
+ #include "../../include/utf/string.h"
6
+
7
+ int
8
+ main() {
9
+ int e;
10
+
11
+ // Empty string with pos = 0 or pos = (size_t) -1 must return not-found rather
12
+ // than search over a length of SIZE_MAX.
13
+ {
14
+ utf8_string_t s;
15
+ utf8_string_init(&s);
16
+
17
+ assert(utf8_string_index_of_character(&s, 0, 'a') == (size_t) -1);
18
+ assert(utf8_string_index_of_character(&s, (size_t) -1, 'a') == (size_t) -1);
19
+
20
+ utf8_string_view_t view = utf8_string_view_init((const utf8_t *) "", 0);
21
+ assert(utf8_string_view_index_of_character(view, 0, 'a') == (size_t) -1);
22
+ assert(utf8_string_view_index_of_character(view, (size_t) -1, 'a') == (size_t) -1);
23
+
24
+ utf8_string_destroy(&s);
25
+ }
26
+
27
+ // Search from the start and find the first match.
28
+ {
29
+ utf8_string_t s;
30
+ utf8_string_init(&s);
31
+
32
+ e = utf8_string_append_literal(&s, (utf8_t *) "banana", -1);
33
+ assert(e == 0);
34
+
35
+ assert(utf8_string_index_of_character(&s, 0, 'b') == 0);
36
+ assert(utf8_string_index_of_character(&s, 0, 'a') == 1);
37
+ assert(utf8_string_index_of_character(&s, 0, 'n') == 2);
38
+
39
+ // Searching from a later position skips the earlier matches.
40
+ assert(utf8_string_index_of_character(&s, 1, 'a') == 1);
41
+ assert(utf8_string_index_of_character(&s, 2, 'a') == 3);
42
+ assert(utf8_string_index_of_character(&s, 4, 'a') == 5);
43
+ assert(utf8_string_index_of_character(&s, 5, 'n') == (size_t) -1);
44
+
45
+ utf8_string_view_t view = utf8_string_view(&s);
46
+
47
+ assert(utf8_string_view_index_of_character(view, 0, 'b') == 0);
48
+ assert(utf8_string_view_index_of_character(view, 2, 'a') == 3);
49
+ assert(utf8_string_view_index_of_character(view, 5, 'n') == (size_t) -1);
50
+
51
+ utf8_string_destroy(&s);
52
+ }
53
+
54
+ // A search with no match returns not-found.
55
+ {
56
+ utf8_string_t s;
57
+ utf8_string_init(&s);
58
+
59
+ e = utf8_string_append_literal(&s, (utf8_t *) "abc", -1);
60
+ assert(e == 0);
61
+
62
+ assert(utf8_string_index_of_character(&s, 0, 'z') == (size_t) -1);
63
+
64
+ // pos at or past the end returns not-found.
65
+ assert(utf8_string_index_of_character(&s, 3, 'a') == (size_t) -1);
66
+ assert(utf8_string_index_of_character(&s, 100, 'a') == (size_t) -1);
67
+
68
+ utf8_string_destroy(&s);
69
+ }
70
+
71
+ // A null byte is a byte like any other, both to search for and to search past.
72
+ {
73
+ utf8_string_view_t view = utf8_string_view_init((const utf8_t *) "a\0b", 3);
74
+
75
+ assert(utf8_string_view_index_of_character(view, 0, '\0') == 1);
76
+ assert(utf8_string_view_index_of_character(view, 0, 'b') == 2);
77
+ }
78
+
79
+ // A search over a stretch long enough to be done more than a byte at a time
80
+ // finds a match at either end of it.
81
+ {
82
+ utf8_string_t s;
83
+ utf8_string_init(&s);
84
+
85
+ for (size_t i = 0; i < 100; i++) {
86
+ e = utf8_string_append_character(&s, 'a');
87
+ assert(e == 0);
88
+ }
89
+
90
+ e = utf8_string_append_character(&s, 'z');
91
+ assert(e == 0);
92
+
93
+ assert(utf8_string_index_of_character(&s, 0, 'z') == 100);
94
+ assert(utf8_string_index_of_character(&s, 1, 'a') == 1);
95
+ assert(utf8_string_index_of_character(&s, 0, 'y') == (size_t) -1);
96
+
97
+ utf8_string_destroy(&s);
98
+ }
99
+ }
@@ -0,0 +1,68 @@
1
+ #include <assert.h>
2
+ #include <stddef.h>
3
+
4
+ #include "../../include/utf.h"
5
+ #include "../../include/utf/string.h"
6
+
7
+ int
8
+ main() {
9
+ int e;
10
+
11
+ // Empty string with pos = (size_t) -1 must return not-found instead of
12
+ // reading data[SIZE_MAX].
13
+ {
14
+ utf8_string_t s;
15
+ utf8_string_init(&s);
16
+
17
+ assert(utf8_string_last_index_of_character(&s, (size_t) -1, 'a') == (size_t) -1);
18
+
19
+ utf8_string_view_t view = utf8_string_view_init((const utf8_t *) "", 0);
20
+ assert(utf8_string_view_last_index_of_character(view, (size_t) -1, 'a') == (size_t) -1);
21
+
22
+ utf8_string_destroy(&s);
23
+ }
24
+
25
+ // Search from the end and find a match.
26
+ {
27
+ utf8_string_t s;
28
+ utf8_string_init(&s);
29
+
30
+ e = utf8_string_append_literal(&s, (utf8_t *) "banana", -1);
31
+ assert(e == 0);
32
+
33
+ assert(utf8_string_last_index_of_character(&s, (size_t) -1, 'a') == 5);
34
+ assert(utf8_string_last_index_of_character(&s, (size_t) -1, 'n') == 4);
35
+ assert(utf8_string_last_index_of_character(&s, (size_t) -1, 'b') == 0);
36
+
37
+ utf8_string_destroy(&s);
38
+ }
39
+
40
+ // Search with no match must terminate (loop must not run forever or read
41
+ // before the buffer).
42
+ {
43
+ utf8_string_t s;
44
+ utf8_string_init(&s);
45
+
46
+ e = utf8_string_append_literal(&s, (utf8_t *) "abc", -1);
47
+ assert(e == 0);
48
+
49
+ assert(utf8_string_last_index_of_character(&s, (size_t) -1, 'z') == (size_t) -1);
50
+ assert(utf8_string_last_index_of_character(&s, 0, 'z') == (size_t) -1);
51
+
52
+ utf8_string_destroy(&s);
53
+ }
54
+
55
+ // pos >= string->len returns not-found.
56
+ {
57
+ utf8_string_t s;
58
+ utf8_string_init(&s);
59
+
60
+ e = utf8_string_append_literal(&s, (utf8_t *) "abc", -1);
61
+ assert(e == 0);
62
+
63
+ assert(utf8_string_last_index_of_character(&s, 3, 'a') == (size_t) -1);
64
+ assert(utf8_string_last_index_of_character(&s, 100, 'a') == (size_t) -1);
65
+
66
+ utf8_string_destroy(&s);
67
+ }
68
+ }
@@ -0,0 +1,23 @@
1
+ #include <assert.h>
2
+ #include <string.h>
3
+
4
+ #include "../../include/utf.h"
5
+ #include "../../include/utf/string.h"
6
+
7
+ int
8
+ main() {
9
+ int e;
10
+
11
+ utf8_string_t string;
12
+ utf8_string_init(&string);
13
+
14
+ e = utf8_string_prepend_literal(&string, (utf8_t *) " world", -1);
15
+ assert(e == 0);
16
+
17
+ e = utf8_string_prepend_literal(&string, (utf8_t *) "hello", -1);
18
+ assert(e == 0);
19
+
20
+ assert(memcmp(string.data, "hello world", string.len) == 0);
21
+
22
+ utf8_string_destroy(&string);
23
+ }
@@ -0,0 +1,74 @@
1
+ #include <assert.h>
2
+ #include <stddef.h>
3
+ #include <stdint.h>
4
+ #include <string.h>
5
+
6
+ #include "../../include/utf.h"
7
+ #include "../../include/utf/string.h"
8
+
9
+ int
10
+ main() {
11
+ int e;
12
+
13
+ utf8_string_t string;
14
+ utf8_string_init(&string);
15
+
16
+ e = utf8_string_append_literal(&string, (utf8_t *) "hello world", -1);
17
+ assert(e == 0);
18
+
19
+ e = utf8_string_replace_literal(&string, 5, 1, (utf8_t *) " there ", -1);
20
+ assert(e == 0);
21
+
22
+ assert(memcmp(string.data, "hello there world", string.len) == 0);
23
+
24
+ utf8_string_destroy(&string);
25
+
26
+ // replace_character must clamp len to (string->len - pos) so memmove doesn't
27
+ // underflow size_t.
28
+ {
29
+ utf8_string_t s;
30
+ utf8_string_init(&s);
31
+
32
+ e = utf8_string_append_literal(&s, (utf8_t *) "hello", -1);
33
+ assert(e == 0);
34
+
35
+ e = utf8_string_replace_character(&s, 2, 100, 'X');
36
+ assert(e == 0);
37
+ assert(s.len == 3);
38
+ assert(memcmp(s.data, "heX", 3) == 0);
39
+
40
+ utf8_string_destroy(&s);
41
+ }
42
+
43
+ // replace_character with pos + len overflowing size_t must also clamp.
44
+ {
45
+ utf8_string_t s;
46
+ utf8_string_init(&s);
47
+
48
+ e = utf8_string_append_literal(&s, (utf8_t *) "hello", -1);
49
+ assert(e == 0);
50
+
51
+ e = utf8_string_replace_character(&s, 1, SIZE_MAX, 'Y');
52
+ assert(e == 0);
53
+ assert(s.len == 2);
54
+ assert(memcmp(s.data, "hY", 2) == 0);
55
+
56
+ utf8_string_destroy(&s);
57
+ }
58
+
59
+ // replace_literal with pos + len overflowing size_t must also clamp.
60
+ {
61
+ utf8_string_t s;
62
+ utf8_string_init(&s);
63
+
64
+ e = utf8_string_append_literal(&s, (utf8_t *) "hello", -1);
65
+ assert(e == 0);
66
+
67
+ e = utf8_string_replace_literal(&s, 1, SIZE_MAX, (utf8_t *) "i!", 2);
68
+ assert(e == 0);
69
+ assert(s.len == 3);
70
+ assert(memcmp(s.data, "hi!", 3) == 0);
71
+
72
+ utf8_string_destroy(&s);
73
+ }
74
+ }
@@ -0,0 +1,51 @@
1
+ #include <assert.h>
2
+ #include <stddef.h>
3
+ #include <stdint.h>
4
+
5
+ #include "../../include/utf.h"
6
+ #include "../../include/utf/string.h"
7
+
8
+ int
9
+ main() {
10
+ int e;
11
+
12
+ // Normal reserve grows past the inline buffer.
13
+ {
14
+ utf8_string_t s;
15
+ utf8_string_init(&s);
16
+
17
+ e = utf8_string_reserve(&s, 64);
18
+ assert(e == 0);
19
+ assert(s.data != s.buf);
20
+ assert(s.cap >= 64);
21
+
22
+ utf8_string_destroy(&s);
23
+ }
24
+
25
+ // Reserve within the inline buffer is a no-op.
26
+ {
27
+ utf8_string_t s;
28
+ utf8_string_init(&s);
29
+
30
+ e = utf8_string_reserve(&s, sizeof(s.buf));
31
+ assert(e == 0);
32
+ assert(s.data == s.buf);
33
+
34
+ utf8_string_destroy(&s);
35
+ }
36
+
37
+ // Reserve must reject sizes that would overflow the power-of-two rounding,
38
+ // rather than wrapping to cap = 0 and returning success.
39
+ {
40
+ utf8_string_t s;
41
+ utf8_string_init(&s);
42
+
43
+ e = utf8_string_reserve(&s, SIZE_MAX);
44
+ assert(e == -1);
45
+
46
+ e = utf8_string_reserve(&s, (SIZE_MAX >> 1) + 2);
47
+ assert(e == -1);
48
+
49
+ utf8_string_destroy(&s);
50
+ }
51
+ }
@@ -0,0 +1,68 @@
1
+ #include <assert.h>
2
+ #include <string.h>
3
+
4
+ #include "../../include/utf.h"
5
+ #include "../../include/utf/string.h"
6
+
7
+ int
8
+ main() {
9
+ int e;
10
+
11
+ utf8_string_t string;
12
+ utf8_string_init(&string);
13
+
14
+ e = utf8_string_append_literal(&string, (utf8_t *) "hello world", -1);
15
+ assert(e == 0);
16
+
17
+ utf8_string_view_t view = utf8_string_substring(&string, 2, 8);
18
+
19
+ assert(memcmp(view.data, "llo worl", view.len) == 0);
20
+
21
+ utf8_string_destroy(&string);
22
+
23
+ // Copying a substring out gives a string holding just those bytes.
24
+ {
25
+ utf8_string_t s, copy;
26
+ utf8_string_init(&s);
27
+ utf8_string_init(&copy);
28
+
29
+ e = utf8_string_append_literal(&s, (utf8_t *) "hello world", -1);
30
+ assert(e == 0);
31
+
32
+ e = utf8_string_substring_copy(&s, 6, (size_t) -1, &copy);
33
+ assert(e == 0);
34
+ assert(copy.len == 5);
35
+ assert(memcmp(copy.data, "world", 5) == 0);
36
+
37
+ utf8_string_destroy(&copy);
38
+ utf8_string_destroy(&s);
39
+ }
40
+
41
+ // A copy into a string that has already outgrown its inline buffer reuses that
42
+ // allocation rather than leaking it.
43
+ {
44
+ utf8_string_t s, copy;
45
+ utf8_string_init(&s);
46
+ utf8_string_init(&copy);
47
+
48
+ e = utf8_string_append_literal(&s, (utf8_t *) "hello world", -1);
49
+ assert(e == 0);
50
+
51
+ e = utf8_string_reserve(&copy, sizeof(copy.buf) * 8);
52
+ assert(e == 0);
53
+ assert(copy.data != copy.buf);
54
+
55
+ e = utf8_string_view_substring_copy(utf8_string_view(&s), 0, 5, &copy);
56
+ assert(e == 0);
57
+ assert(copy.len == 5);
58
+ assert(memcmp(copy.data, "hello", 5) == 0);
59
+
60
+ // Still on the allocation reserved above. Were the result initialized here
61
+ // instead, this would have been dropped back to the inline buffer and the
62
+ // allocation leaked.
63
+ assert(copy.data != copy.buf);
64
+
65
+ utf8_string_destroy(&copy);
66
+ utf8_string_destroy(&s);
67
+ }
68
+ }