ooxml_crypt 0.1.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 (264) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +58 -0
  5. data/Rakefile +12 -0
  6. data/bin/console +15 -0
  7. data/bin/setup +8 -0
  8. data/ext/ooxml_crypt/extconf.rb +18 -0
  9. data/ext/ooxml_crypt/ooxml_crypt.c +27 -0
  10. data/ext/ooxml_crypt/ooxml_crypt.h +7 -0
  11. data/lib/ooxml_crypt/version.rb +5 -0
  12. data/lib/ooxml_crypt.rb +75 -0
  13. data/vendor/cybozulib/.github/workflows/main.yml +12 -0
  14. data/vendor/cybozulib/.gitignore +5 -0
  15. data/vendor/cybozulib/CMakeLists.txt +6 -0
  16. data/vendor/cybozulib/COPYRIGHT +27 -0
  17. data/vendor/cybozulib/Makefile +26 -0
  18. data/vendor/cybozulib/bin/libeay32.dll +0 -0
  19. data/vendor/cybozulib/bin/libmecab.dll +0 -0
  20. data/vendor/cybozulib/bin/ssleay32.dll +0 -0
  21. data/vendor/cybozulib/common.mk +116 -0
  22. data/vendor/cybozulib/common.props +25 -0
  23. data/vendor/cybozulib/cybozulib.sln +286 -0
  24. data/vendor/cybozulib/debug.props +14 -0
  25. data/vendor/cybozulib/include/cybozu/array.hpp +197 -0
  26. data/vendor/cybozulib/include/cybozu/atoi.hpp +238 -0
  27. data/vendor/cybozulib/include/cybozu/atomic.hpp +146 -0
  28. data/vendor/cybozulib/include/cybozu/base64.hpp +210 -0
  29. data/vendor/cybozulib/include/cybozu/benchmark.hpp +212 -0
  30. data/vendor/cybozulib/include/cybozu/bfd.hpp +105 -0
  31. data/vendor/cybozulib/include/cybozu/bit_operation.hpp +139 -0
  32. data/vendor/cybozulib/include/cybozu/bitvector.hpp +358 -0
  33. data/vendor/cybozulib/include/cybozu/condition_variable.hpp +113 -0
  34. data/vendor/cybozulib/include/cybozu/condition_variable_cs.hpp +74 -0
  35. data/vendor/cybozulib/include/cybozu/config.hpp +392 -0
  36. data/vendor/cybozulib/include/cybozu/critical_section.hpp +60 -0
  37. data/vendor/cybozulib/include/cybozu/crypto.hpp +321 -0
  38. data/vendor/cybozulib/include/cybozu/csucvector.hpp +624 -0
  39. data/vendor/cybozulib/include/cybozu/csv.hpp +294 -0
  40. data/vendor/cybozulib/include/cybozu/data_type.hpp +27 -0
  41. data/vendor/cybozulib/include/cybozu/endian.hpp +224 -0
  42. data/vendor/cybozulib/include/cybozu/env.hpp +63 -0
  43. data/vendor/cybozulib/include/cybozu/event.hpp +122 -0
  44. data/vendor/cybozulib/include/cybozu/exception.hpp +253 -0
  45. data/vendor/cybozulib/include/cybozu/file.hpp +626 -0
  46. data/vendor/cybozulib/include/cybozu/fmindex.hpp +291 -0
  47. data/vendor/cybozulib/include/cybozu/format.hpp +93 -0
  48. data/vendor/cybozulib/include/cybozu/frequency.hpp +264 -0
  49. data/vendor/cybozulib/include/cybozu/hash.hpp +67 -0
  50. data/vendor/cybozulib/include/cybozu/inttype.hpp +174 -0
  51. data/vendor/cybozulib/include/cybozu/itoa.hpp +336 -0
  52. data/vendor/cybozulib/include/cybozu/json.hpp +120 -0
  53. data/vendor/cybozulib/include/cybozu/line_stream.hpp +149 -0
  54. data/vendor/cybozulib/include/cybozu/link_libeay32.hpp +21 -0
  55. data/vendor/cybozulib/include/cybozu/link_mpir.hpp +18 -0
  56. data/vendor/cybozulib/include/cybozu/link_ssleay32.hpp +19 -0
  57. data/vendor/cybozulib/include/cybozu/log.hpp +237 -0
  58. data/vendor/cybozulib/include/cybozu/minixml.hpp +452 -0
  59. data/vendor/cybozulib/include/cybozu/mmap.hpp +143 -0
  60. data/vendor/cybozulib/include/cybozu/mutex.hpp +144 -0
  61. data/vendor/cybozulib/include/cybozu/nlp/mecab.hpp +96 -0
  62. data/vendor/cybozulib/include/cybozu/nlp/plsi.hpp +315 -0
  63. data/vendor/cybozulib/include/cybozu/nlp/random.hpp +74 -0
  64. data/vendor/cybozulib/include/cybozu/nlp/sparse.hpp +529 -0
  65. data/vendor/cybozulib/include/cybozu/nlp/svd.hpp +486 -0
  66. data/vendor/cybozulib/include/cybozu/nlp/tfidf.hpp +226 -0
  67. data/vendor/cybozulib/include/cybozu/nlp/top_score.hpp +75 -0
  68. data/vendor/cybozulib/include/cybozu/option.hpp +743 -0
  69. data/vendor/cybozulib/include/cybozu/parallel.hpp +88 -0
  70. data/vendor/cybozulib/include/cybozu/pcg.hpp +72 -0
  71. data/vendor/cybozulib/include/cybozu/process.hpp +324 -0
  72. data/vendor/cybozulib/include/cybozu/quit_signal_handler.hpp +66 -0
  73. data/vendor/cybozulib/include/cybozu/random_generator.hpp +144 -0
  74. data/vendor/cybozulib/include/cybozu/regex.hpp +463 -0
  75. data/vendor/cybozulib/include/cybozu/select8.hpp +279 -0
  76. data/vendor/cybozulib/include/cybozu/serializer.hpp +363 -0
  77. data/vendor/cybozulib/include/cybozu/sha1.hpp +209 -0
  78. data/vendor/cybozulib/include/cybozu/sha2.hpp +506 -0
  79. data/vendor/cybozulib/include/cybozu/siphash.hpp +105 -0
  80. data/vendor/cybozulib/include/cybozu/socket.hpp +785 -0
  81. data/vendor/cybozulib/include/cybozu/ssl.hpp +203 -0
  82. data/vendor/cybozulib/include/cybozu/stacktrace.hpp +291 -0
  83. data/vendor/cybozulib/include/cybozu/stream.hpp +269 -0
  84. data/vendor/cybozulib/include/cybozu/string.hpp +1746 -0
  85. data/vendor/cybozulib/include/cybozu/string_operation.hpp +365 -0
  86. data/vendor/cybozulib/include/cybozu/sucvector.hpp +378 -0
  87. data/vendor/cybozulib/include/cybozu/test.hpp +373 -0
  88. data/vendor/cybozulib/include/cybozu/thread.hpp +229 -0
  89. data/vendor/cybozulib/include/cybozu/time.hpp +281 -0
  90. data/vendor/cybozulib/include/cybozu/tls.hpp +115 -0
  91. data/vendor/cybozulib/include/cybozu/unordered_map.hpp +13 -0
  92. data/vendor/cybozulib/include/cybozu/unordered_set.hpp +13 -0
  93. data/vendor/cybozulib/include/cybozu/v128.hpp +376 -0
  94. data/vendor/cybozulib/include/cybozu/wavelet_matrix.hpp +345 -0
  95. data/vendor/cybozulib/include/cybozu/xorshift.hpp +189 -0
  96. data/vendor/cybozulib/include/cybozu/zlib.hpp +325 -0
  97. data/vendor/cybozulib/include/sais.hxx +364 -0
  98. data/vendor/cybozulib/misc/make_select8tbl.cpp +26 -0
  99. data/vendor/cybozulib/mk.bat +37 -0
  100. data/vendor/cybozulib/readme.md +29 -0
  101. data/vendor/cybozulib/release.props +12 -0
  102. data/vendor/cybozulib/sample/Makefile +30 -0
  103. data/vendor/cybozulib/sample/csucvector_smpl.cpp +42 -0
  104. data/vendor/cybozulib/sample/data/svd/org/test1.S +4 -0
  105. data/vendor/cybozulib/sample/data/svd/org/test1.U +4 -0
  106. data/vendor/cybozulib/sample/data/svd/org/test1.V +6 -0
  107. data/vendor/cybozulib/sample/data/svd/test1 +4 -0
  108. data/vendor/cybozulib/sample/data/svd/test2 +4 -0
  109. data/vendor/cybozulib/sample/desymbol.cpp +127 -0
  110. data/vendor/cybozulib/sample/exception_smpl.cpp +46 -0
  111. data/vendor/cybozulib/sample/fmindex_smpl.cpp +231 -0
  112. data/vendor/cybozulib/sample/log_smpl.cpp +19 -0
  113. data/vendor/cybozulib/sample/mecab_smpl.cpp +37 -0
  114. data/vendor/cybozulib/sample/option2_smpl.cpp +68 -0
  115. data/vendor/cybozulib/sample/option_smpl.cpp +42 -0
  116. data/vendor/cybozulib/sample/plsi_smpl.cpp +207 -0
  117. data/vendor/cybozulib/sample/proj/exception_smpl.vcproj +184 -0
  118. data/vendor/cybozulib/sample/proj/mecab_smpl.vcproj +184 -0
  119. data/vendor/cybozulib/sample/proj/ssl_smpl/ssl_smpl.vcxproj +85 -0
  120. data/vendor/cybozulib/sample/proj/ssl_smpl.vcproj +347 -0
  121. data/vendor/cybozulib/sample/proj/stacktrace_smpl/stacktrace_smpl.vcxproj +85 -0
  122. data/vendor/cybozulib/sample/proj/svd_smpl.vcproj +184 -0
  123. data/vendor/cybozulib/sample/quit_signal_handler.cpp +30 -0
  124. data/vendor/cybozulib/sample/serializer_smpl.cpp +196 -0
  125. data/vendor/cybozulib/sample/socket_smpl.cpp +82 -0
  126. data/vendor/cybozulib/sample/ssl_smpl.cpp +39 -0
  127. data/vendor/cybozulib/sample/stacktrace_smpl.cpp +52 -0
  128. data/vendor/cybozulib/sample/svd_bench_smpl.cpp +143 -0
  129. data/vendor/cybozulib/sample/svd_smpl.cpp +94 -0
  130. data/vendor/cybozulib/sample/wm_bench_smpl.cpp +182 -0
  131. data/vendor/cybozulib/sample/zlib_smpl.cpp +41 -0
  132. data/vendor/cybozulib/src/Makefile +8 -0
  133. data/vendor/cybozulib/src/base/Makefile +19 -0
  134. data/vendor/cybozulib/test/Makefile +12 -0
  135. data/vendor/cybozulib/test/base/Makefile +37 -0
  136. data/vendor/cybozulib/test/base/array_test.cpp +173 -0
  137. data/vendor/cybozulib/test/base/atoi_test.cpp +774 -0
  138. data/vendor/cybozulib/test/base/atomic_test.cpp +49 -0
  139. data/vendor/cybozulib/test/base/base64_test.cpp +113 -0
  140. data/vendor/cybozulib/test/base/bit_operation_test.cpp +134 -0
  141. data/vendor/cybozulib/test/base/bitvector_test.cpp +204 -0
  142. data/vendor/cybozulib/test/base/condition_variable_cs_test.cpp +92 -0
  143. data/vendor/cybozulib/test/base/condition_variable_test.cpp +88 -0
  144. data/vendor/cybozulib/test/base/config_test.cpp +236 -0
  145. data/vendor/cybozulib/test/base/crypto_test.cpp +122 -0
  146. data/vendor/cybozulib/test/base/csucvector_test.cpp +63 -0
  147. data/vendor/cybozulib/test/base/csv_test.cpp +182 -0
  148. data/vendor/cybozulib/test/base/data/a.xml +26 -0
  149. data/vendor/cybozulib/test/base/endian_test.cpp +56 -0
  150. data/vendor/cybozulib/test/base/env_test.cpp +22 -0
  151. data/vendor/cybozulib/test/base/event_test.cpp +41 -0
  152. data/vendor/cybozulib/test/base/file_test.cpp +233 -0
  153. data/vendor/cybozulib/test/base/fmindex_test.cpp +118 -0
  154. data/vendor/cybozulib/test/base/format_test.cpp +12 -0
  155. data/vendor/cybozulib/test/base/frequency_test.cpp +104 -0
  156. data/vendor/cybozulib/test/base/itoa_test.cpp +522 -0
  157. data/vendor/cybozulib/test/base/line_stream_test.cpp +208 -0
  158. data/vendor/cybozulib/test/base/mecab_test.cpp +41 -0
  159. data/vendor/cybozulib/test/base/minixml_test.cpp +103 -0
  160. data/vendor/cybozulib/test/base/mmap_test.cpp +15 -0
  161. data/vendor/cybozulib/test/base/option_test.cpp +487 -0
  162. data/vendor/cybozulib/test/base/parallel_test.cpp +48 -0
  163. data/vendor/cybozulib/test/base/proj/array_test/array_test.vcxproj +86 -0
  164. data/vendor/cybozulib/test/base/proj/atoi_test/atoi_test.vcxproj +86 -0
  165. data/vendor/cybozulib/test/base/proj/atomic_test/atomic_test.vcxproj +86 -0
  166. data/vendor/cybozulib/test/base/proj/base64_test/base64_test.vcxproj +86 -0
  167. data/vendor/cybozulib/test/base/proj/condition_variable_cs_test/condition_variable_cs_test.vcxproj +86 -0
  168. data/vendor/cybozulib/test/base/proj/condition_variable_test/condition_variable_test.vcxproj +86 -0
  169. data/vendor/cybozulib/test/base/proj/config_test/config_test.vcxproj +86 -0
  170. data/vendor/cybozulib/test/base/proj/csv_test/csv_test.vcxproj +86 -0
  171. data/vendor/cybozulib/test/base/proj/endian_test/endian_test.vcxproj +86 -0
  172. data/vendor/cybozulib/test/base/proj/env_test/env_test.vcxproj +86 -0
  173. data/vendor/cybozulib/test/base/proj/event_test/event_test.vcxproj +86 -0
  174. data/vendor/cybozulib/test/base/proj/file_test/file_test.vcxproj +86 -0
  175. data/vendor/cybozulib/test/base/proj/itoa_test/itoa_test.vcxproj +86 -0
  176. data/vendor/cybozulib/test/base/proj/mecab_test/mecab_test.vcxproj +88 -0
  177. data/vendor/cybozulib/test/base/proj/minixml_test/minixml_test.vcxproj +86 -0
  178. data/vendor/cybozulib/test/base/proj/mmap_test/mmap_test.vcxproj +86 -0
  179. data/vendor/cybozulib/test/base/proj/serializer_test/serializer_test.vcxproj +86 -0
  180. data/vendor/cybozulib/test/base/proj/sha1_test/sha1_test.vcxproj +86 -0
  181. data/vendor/cybozulib/test/base/proj/stream_test/stream_test.vcxproj +86 -0
  182. data/vendor/cybozulib/test/base/proj/string_operation_test/string_operation_test.vcxproj +86 -0
  183. data/vendor/cybozulib/test/base/proj/string_test/string_test.vcxproj +86 -0
  184. data/vendor/cybozulib/test/base/proj/thread_test/thread_test.vcxproj +86 -0
  185. data/vendor/cybozulib/test/base/proj/time_test/time_test.vcxproj +86 -0
  186. data/vendor/cybozulib/test/base/proj/tls_test/tls_test.vcxproj +86 -0
  187. data/vendor/cybozulib/test/base/proj/zlib_test/zlib_test.vcxproj +86 -0
  188. data/vendor/cybozulib/test/base/random_generator_test.cpp +28 -0
  189. data/vendor/cybozulib/test/base/regex_test.cpp +74 -0
  190. data/vendor/cybozulib/test/base/serializer_test.cpp +483 -0
  191. data/vendor/cybozulib/test/base/sha1_test.cpp +61 -0
  192. data/vendor/cybozulib/test/base/sha2_test.cpp +191 -0
  193. data/vendor/cybozulib/test/base/siphash_test.cpp +33 -0
  194. data/vendor/cybozulib/test/base/socket_test.cpp +76 -0
  195. data/vendor/cybozulib/test/base/stream_test.cpp +101 -0
  196. data/vendor/cybozulib/test/base/string_operation_test.cpp +340 -0
  197. data/vendor/cybozulib/test/base/string_test.cpp +1705 -0
  198. data/vendor/cybozulib/test/base/sucvector_test.cpp +312 -0
  199. data/vendor/cybozulib/test/base/thread_test.cpp +62 -0
  200. data/vendor/cybozulib/test/base/time_test.cpp +164 -0
  201. data/vendor/cybozulib/test/base/tls_test.cpp +50 -0
  202. data/vendor/cybozulib/test/base/wavelet_matrix_test.cpp +145 -0
  203. data/vendor/cybozulib/test/base/zlib_test.cpp +371 -0
  204. data/vendor/cybozulib/test/nlp/Makefile +27 -0
  205. data/vendor/cybozulib/test/nlp/proj/random_test.vcproj +184 -0
  206. data/vendor/cybozulib/test/nlp/proj/sparse_test.vcproj +184 -0
  207. data/vendor/cybozulib/test/nlp/proj/svd_test.vcproj +184 -0
  208. data/vendor/cybozulib/test/nlp/random_test.cpp +62 -0
  209. data/vendor/cybozulib/test/nlp/sparse_test.cpp +347 -0
  210. data/vendor/cybozulib/test/nlp/svd_test.cpp +234 -0
  211. data/vendor/cybozulib/test/nlp/top_score_test.cpp +40 -0
  212. data/vendor/cybozulib/tool/create_vcproj.py +186 -0
  213. data/vendor/cybozulib/tool/vcproj_tmpl.py +185 -0
  214. data/vendor/msoffice/COPYRIGHT +27 -0
  215. data/vendor/msoffice/Makefile +29 -0
  216. data/vendor/msoffice/bin/64/msoc.dll +0 -0
  217. data/vendor/msoffice/bin/64/msocsample.exe +0 -0
  218. data/vendor/msoffice/bin/64/msoffice-crypt.exe +0 -0
  219. data/vendor/msoffice/bin/msoc.dll +0 -0
  220. data/vendor/msoffice/bin/msocsample.exe +0 -0
  221. data/vendor/msoffice/bin/msoffice-crypt.exe +0 -0
  222. data/vendor/msoffice/common.mk +71 -0
  223. data/vendor/msoffice/common.props +26 -0
  224. data/vendor/msoffice/debug.props +14 -0
  225. data/vendor/msoffice/include/attack.hpp +211 -0
  226. data/vendor/msoffice/include/cfb.hpp +777 -0
  227. data/vendor/msoffice/include/crypto_util.hpp +450 -0
  228. data/vendor/msoffice/include/custom_sha1.hpp +342 -0
  229. data/vendor/msoffice/include/decode.hpp +240 -0
  230. data/vendor/msoffice/include/encode.hpp +221 -0
  231. data/vendor/msoffice/include/make_dataspace.hpp +316 -0
  232. data/vendor/msoffice/include/msoc.h +129 -0
  233. data/vendor/msoffice/include/resource.hpp +7 -0
  234. data/vendor/msoffice/include/standard_encryption.hpp +145 -0
  235. data/vendor/msoffice/include/uint32vec.hpp +179 -0
  236. data/vendor/msoffice/include/util.hpp +212 -0
  237. data/vendor/msoffice/lib/.emptydir +0 -0
  238. data/vendor/msoffice/misc/decrypt-xls.vbs +46 -0
  239. data/vendor/msoffice/mk.bat +1 -0
  240. data/vendor/msoffice/mkdll.bat +3 -0
  241. data/vendor/msoffice/msoc.def +13 -0
  242. data/vendor/msoffice/msocsample.py +178 -0
  243. data/vendor/msoffice/msoffice12.sln +31 -0
  244. data/vendor/msoffice/readme.md +110 -0
  245. data/vendor/msoffice/release.props +28 -0
  246. data/vendor/msoffice/src/Makefile +19 -0
  247. data/vendor/msoffice/src/attack.cpp +124 -0
  248. data/vendor/msoffice/src/cfb_test.cpp +77 -0
  249. data/vendor/msoffice/src/minisample.c +54 -0
  250. data/vendor/msoffice/src/msocdll.cpp +276 -0
  251. data/vendor/msoffice/src/msocsample.c +136 -0
  252. data/vendor/msoffice/src/msoffice-crypt.cpp +219 -0
  253. data/vendor/msoffice/src/proj/attack/attack.vcxproj +88 -0
  254. data/vendor/msoffice/src/proj/main/msoffice-crypt.vcxproj +88 -0
  255. data/vendor/msoffice/src/sha1.cpp +234 -0
  256. data/vendor/msoffice/test/Makefile +20 -0
  257. data/vendor/msoffice/test/cfb_test.cpp +74 -0
  258. data/vendor/msoffice/test/hash_test.cpp +59 -0
  259. data/vendor/msoffice/test/proj/cfb/cfb_test.vcxproj +90 -0
  260. data/vendor/msoffice/test/proj/hash/hash_test.vcxproj +90 -0
  261. data/vendor/msoffice/test/sampl.bat +8 -0
  262. data/vendor/msoffice/test_all.py +46 -0
  263. data/vendor/update +4 -0
  264. metadata +351 -0
@@ -0,0 +1,1746 @@
1
+ #pragma once
2
+ /**
3
+ @file
4
+ @brief unicode string class like std::string
5
+ support char*, std::string with UTF-8
6
+
7
+ @author MITSUNARI Shigeo(@herumi)
8
+ */
9
+
10
+ #ifdef _MSC_VER
11
+ #pragma warning(push)
12
+ #pragma warning(disable : 4702)
13
+ #endif
14
+
15
+ #include <string>
16
+ #include <cstring>
17
+ #include <assert.h>
18
+ #include <stddef.h>
19
+ #include <stdio.h> // for printf
20
+ #include <iosfwd> // for istream, ostream
21
+ #include <functional> // for unary_function
22
+
23
+ #include <cybozu/exception.hpp>
24
+ #include <cybozu/hash.hpp>
25
+
26
+ // to deal with unicode literal(same macro defined in regex.hpp)
27
+ #ifdef _MSC_VER
28
+ #define CYBOZU_STR_WCHAR wchar_t
29
+ #define CYBOZU_STR_W(x) L##x // assume UTF-16 string
30
+ #else
31
+ #define CYBOZU_STR_WCHAR char
32
+ #define CYBOZU_STR_W(x) x // assume UTF-8 string
33
+ #endif
34
+
35
+ namespace cybozu {
36
+
37
+ #if defined(__GNUC__) && (__SIZEOF_WCHAR_T__ == 4)
38
+ /* avoid to use uint32_t because compiling boost::regex fails */
39
+ typedef wchar_t Char; //!< Char for Linux
40
+ typedef unsigned short Char16; /* unsigned is necessary for gcc */
41
+ #else
42
+ typedef int Char; //!< Char for Windows
43
+ typedef wchar_t Char16;
44
+ #endif
45
+
46
+ typedef std::basic_string<Char16> String16;
47
+
48
+ template<class CharT>
49
+ size_t strlen(const CharT *str)
50
+ {
51
+ size_t len = 0;
52
+ while (str[len]) len++;
53
+ return len;
54
+ }
55
+
56
+ template<class CharT>
57
+ CharT tolower(CharT c)
58
+ {
59
+ return ('A' <= c && c <= 'Z') ? c - 'A' + 'a' : c;
60
+ }
61
+
62
+ template<class CharT>
63
+ CharT toupper(CharT c)
64
+ {
65
+ return ('a' <= c && c <= 'z') ? c - 'a' + 'A' : c;
66
+ }
67
+
68
+ namespace string_local {
69
+
70
+ /* true if c in [min, max] */
71
+ inline bool in(unsigned char c, int min, int max)
72
+ {
73
+ // return min <= c && c <= max;
74
+ return static_cast<unsigned int>(c - min) <= static_cast<unsigned int>(max - min);
75
+ }
76
+
77
+ template<class T>
78
+ struct IsInt { enum { value = false }; };
79
+ template<>struct IsInt<int> { enum { value = true }; };
80
+ template<>struct IsInt<unsigned int> { enum { value = true }; };
81
+ template<>struct IsInt<long> { enum { value = true }; };
82
+ template<>struct IsInt<unsigned long> { enum { value = true }; };
83
+ template<>struct IsInt<long long> { enum { value = true }; };
84
+ template<>struct IsInt<unsigned long long> { enum { value = true }; };
85
+
86
+ template <bool b, class T = void>
87
+ struct disable_if { typedef T type; };
88
+
89
+ template <class T>
90
+ struct disable_if<true, T> {};
91
+
92
+ } // string_local
93
+
94
+ /**
95
+ utility function
96
+ */
97
+ namespace string {
98
+
99
+ /*
100
+ code point[a, b] 1byte 2ybte 3byte 4byte
101
+ U+0000 U+007f 00..7f ; 128
102
+ U+0080 U+07ff c2..df 80..bf ; 30 x 64 = 1920
103
+
104
+ U+0800 U+0fff e0 a0..bf 80..bf ; 1 x 32 x 64 = 2048
105
+ U+1000 U+cfff e1..ec 80..bf 80..bf ; 12 x 64 x 64 = 49152
106
+ U+d000 U+d7ff ed 80..9f 80..bf ; 1 x 32 x 64 = 2048
107
+
108
+ U+e000 U+ffff ee..ef 80..bf 80..bf ; 2 x 64 x 64 = 8192
109
+
110
+ U+10000 U+3ffff f0 90..bf 80..bf 80..bf ; 1 x 48 x 64 x 64 = 196608
111
+ U+40000 U+fffff f1..f3 80..bf 80..bf 80..bf ; 3 x 64 x 64 x 64 = 786432
112
+ U+100000 U+10ffff f4 80..8f 80..bf 80..bf ; 1 x 16 x 64 x 64 = 65536
113
+ */
114
+ inline int GetCharSize(Char c)
115
+ {
116
+ if (c <= 0x7f) return 1;
117
+ if (c <= 0x7ff) return 2;
118
+ if (c <= 0xd7ff) return 3;
119
+ if (c <= 0xdfff || c > 0x10ffff) return 0;
120
+ if (c <= 0xffff) return 3;
121
+ return 4;
122
+ }
123
+
124
+ // for Char/char
125
+ inline bool IsValidChar(Char c)
126
+ {
127
+ return GetCharSize(c) != 0;
128
+ }
129
+
130
+ /*
131
+ get one character from UTF-8 string and seek begin to next char
132
+ @note begin != end
133
+ @note begin is not determined if false
134
+ */
135
+ template<class Iterator>
136
+ bool GetCharFromUtf8(Char *c, Iterator& begin, const Iterator& end)
137
+ {
138
+ unsigned char c0 = *begin++;
139
+ if (c0 <= 0x7f) {
140
+ *c = c0;
141
+ return true;
142
+ }
143
+ if (string_local::in(c0, 0xc2, 0xdf)) {
144
+ if (begin != end) {
145
+ unsigned char c1 = *begin++;
146
+ if (string_local::in(c1, 0x80, 0xbf)) {
147
+ *c = ((c0 << 6) | (c1 & 0x3f)) - 0x3000;
148
+ return true;
149
+ }
150
+ }
151
+ } else if (c0 <= 0xef) {
152
+ if (begin != end) {
153
+ unsigned char c1 = *begin++;
154
+ if (begin != end) {
155
+ unsigned char c2 = *begin++;
156
+ if (string_local::in(c2, 0x80, 0xbf)) {
157
+ if ((c0 == 0xe0 && string_local::in(c1, 0xa0, 0xbf))
158
+ || (string_local::in(c0, 0xe1, 0xec) && string_local::in(c1, 0x80, 0xbf))
159
+ || (c0 == 0xed && string_local::in(c1, 0x80, 0x9f))
160
+ || (string_local::in(c0, 0xee, 0xef) && string_local::in(c1, 0x80, 0xbf))) {
161
+ *c = ((c0 << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f)) - 0xe0000;
162
+ return true;
163
+ }
164
+ }
165
+ }
166
+ }
167
+ } else if (string_local::in(c0, 0xf0, 0xf4)) {
168
+ if (begin != end) {
169
+ unsigned char c1 = *begin++;
170
+ if (begin != end) {
171
+ unsigned char c2 = *begin++;
172
+ if (begin != end) {
173
+ unsigned char c3 = *begin++;
174
+ if (string_local::in(c2, 0x80, 0xbf) && string_local::in(c3, 0x80, 0xbf)) {
175
+ if ((c0 == 0xf0 && string_local::in(c1, 0x90, 0xbf))
176
+ || (string_local::in(c0, 0xf1, 0xf3) && string_local::in(c1, 0x80, 0xbf))
177
+ || (c0 == 0xf4 && string_local::in(c1, 0x80, 0x8f))) {
178
+ *c = ((c0 << 18) | ((c1 & 0x3f) << 12) | ((c2 & 0x3f) << 6) | (c3 & 0x3f)) - 0x3c00000;
179
+ return true;
180
+ }
181
+ }
182
+ }
183
+ }
184
+ }
185
+ }
186
+ return false;
187
+ }
188
+
189
+ /*
190
+ get one character from UTF-16 string and seek begin to next char
191
+ @note begin != end
192
+ @note begin is not determined if false
193
+ */
194
+ template<class Iterator>
195
+ bool GetCharFromUtf16(Char& c, Iterator& begin, const Iterator& end)
196
+ {
197
+ struct string_local {
198
+ static inline bool isLead(Char c) { return (c & 0xfffffc00) == 0xd800; }
199
+ static inline bool isTrail(Char c) { return (c & 0xfffffc00) == 0xdc00; }
200
+ };
201
+ Char16 c0 = *begin++;
202
+ if (!string_local::isLead(c0)) {
203
+ c = c0;
204
+ return true;
205
+ }
206
+ if (begin != end) {
207
+ Char16 c1 = *begin++;
208
+ if (string_local::isTrail(c1)) {
209
+ const Char offset = (0xd800 << 10UL) + 0xdc00 - 0x10000;
210
+ c = (c0 << 10) + c1 - offset;
211
+ return true;
212
+ }
213
+ }
214
+ return false;
215
+ }
216
+
217
+ inline int toUtf8(char out[4], Char c)
218
+ {
219
+ if (c <= 0x7f) {
220
+ out[0] = static_cast<char>(c);
221
+ return 1;
222
+ } else if (c <= 0x7ff) {
223
+ out[0] = static_cast<char>((c >> 6) | 0xc0);
224
+ out[1] = static_cast<char>((c & 0x3f) | 0x80);
225
+ return 2;
226
+ } else if (c <= 0xffff) {
227
+ if (0xd7ff < c && c <= 0xdfff) {
228
+ return 0;
229
+ }
230
+ out[0] = static_cast<char>((c >> 12) | 0xe0);
231
+ out[1] = static_cast<char>(((c >> 6) & 0x3f) | 0x80);
232
+ out[2] = static_cast<char>((c & 0x3f) | 0x80);
233
+ return 3;
234
+ } else if (c <= 0x10ffff) {
235
+ out[0] = static_cast<char>((c >> 18) | 0xf0);
236
+ out[1] = static_cast<char>(((c >> 12) & 0x3f) | 0x80);
237
+ out[2] = static_cast<char>(((c >> 6) & 0x3f) | 0x80);
238
+ out[3] = static_cast<char>((c & 0x3f) | 0x80);
239
+ return 4;
240
+ }
241
+ return 0;
242
+ }
243
+
244
+ inline int toUtf16(Char16 out[2], Char c)
245
+ {
246
+ if (c <= 0xffff) {
247
+ out[0] = static_cast<Char16>(c);
248
+ return 1;
249
+ } else if (c <= 0x0010ffff) {
250
+ out[0] = static_cast<Char16>((c >> 10) + 0xd7c0);
251
+ out[1] = static_cast<Char16>((c & 0x3ff) | 0xdc00);
252
+ return 2;
253
+ }
254
+ return 0;
255
+ }
256
+
257
+ inline bool AppendUtf8(std::string& out, Char c)
258
+ {
259
+ char buf[4];
260
+ int len = toUtf8(buf, c);
261
+ if (len > 0) {
262
+ out.append(buf, len);
263
+ return true;
264
+ }
265
+ return false;
266
+ }
267
+
268
+ inline bool AppendUtf16(String16& out, Char c)
269
+ {
270
+ Char16 buf[2];
271
+ int len = toUtf16(buf, c);
272
+ if (len > 0) {
273
+ out.append(buf, len);
274
+ return true;
275
+ }
276
+ return false;
277
+ }
278
+
279
+ } // string
280
+
281
+ template<class CharT, class Traits = std::char_traits<CharT>, class Alloc = std::allocator<CharT> >
282
+ class StringT {
283
+ public:
284
+ typedef std::basic_string<CharT, Traits, Alloc> BasicString;
285
+ typedef CharT value_type;
286
+ typedef size_t size_type;
287
+ typedef ptrdiff_t difference_type;
288
+ typedef CharT& reference;
289
+ typedef const CharT& const_reference;
290
+ typedef CharT* pointer;
291
+ typedef const CharT* const_pointer;
292
+ typedef typename BasicString::iterator iterator;
293
+ typedef typename BasicString::const_iterator const_iterator;
294
+ typedef std::reverse_iterator<iterator> reverse_iterator;
295
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
296
+ //@}
297
+ static const size_t npos = size_t(-1); //!< standard npos
298
+
299
+ /**
300
+ dump unicode of string for debug
301
+ @param msg [in] user message
302
+ */
303
+ void dump(const char *msg = 0) const
304
+ {
305
+ if (msg) printf("%s", msg);
306
+ for (size_t i = 0; i < size(); i++) {
307
+ printf("%08x ", str_[i]);
308
+ }
309
+ printf("\n");
310
+ }
311
+
312
+ /**
313
+ construct empty string
314
+ */
315
+ StringT() { }
316
+
317
+ /**
318
+ construct from str [off, off + count)
319
+ @param str [in] original string
320
+ @param off [in] offset
321
+ @param count [in] count of character(default npos)
322
+ */
323
+ StringT(const StringT& str, size_type off, size_type count = npos)
324
+ : str_(str.str_, off, count)
325
+ { }
326
+
327
+ /**
328
+ construct from [str, str + count)
329
+ @param str [in] original string
330
+ @param count [in] count of character
331
+ */
332
+ StringT(const CharT *str, size_type count)
333
+ : str_(str, count)
334
+ {
335
+ }
336
+
337
+ /**
338
+ construct from [str, NUL)
339
+ @param str [in] original string
340
+ */
341
+ StringT(const CharT *str)
342
+ : str_(str)
343
+ {
344
+ }
345
+
346
+ /**
347
+ construct from count * c
348
+ @param count [in] count of character
349
+ @param c [in] initial character
350
+ */
351
+ StringT(size_type count, CharT c)
352
+ : str_(count, c)
353
+ {
354
+ }
355
+
356
+ /**
357
+ construct from [begin, end)
358
+ @param begin [in] begin of iterator
359
+ @param end [in] end of iterator
360
+ */
361
+ template<class Iterator>
362
+ StringT(Iterator begin, Iterator end, typename string_local::disable_if<string_local::IsInt<Iterator>::value>::type* = 0)
363
+ {
364
+ append(begin, end);
365
+ }
366
+
367
+ // construct from [begin, end), const pointers
368
+ // StringT(const_pointer begin, const_pointer end);
369
+ // construct from [begin, end), const_iterators
370
+ // StringT(const_iterator begin, const_iterator end);
371
+
372
+ /**
373
+ construct by copying str
374
+ @param str [in] original string
375
+ */
376
+ StringT(const StringT& str)
377
+ : str_(str.str_)
378
+ {
379
+ }
380
+
381
+ /**
382
+ construct by [str, str + count)
383
+ @param str [in] original string
384
+ @param count [in] count of character
385
+ */
386
+ StringT(const char *str, size_type count) // A
387
+ {
388
+ append(str, count);
389
+ }
390
+
391
+ /**
392
+ construct from [str, NUL)
393
+ @param str [in] original string
394
+ */
395
+ StringT(const char *str) // A
396
+ {
397
+ append(str);
398
+ }
399
+ /**
400
+ construct by copying str
401
+ @param str [in] original string
402
+ */
403
+ StringT(const std::string& str) // A
404
+ {
405
+ append(str);
406
+ }
407
+
408
+ /**
409
+ construt by Char16(same ICU::UChar)
410
+ @param str [in] UTF-16 format string
411
+ */
412
+ StringT(const String16& str) // A
413
+ {
414
+ append(&str[0], &str[0] + str.size());
415
+ }
416
+ StringT(const Char16* str) // A
417
+ {
418
+ append(str, str + cybozu::strlen(str));
419
+ }
420
+ /**
421
+ construct by BasicString
422
+ @param str [in] UTF-32 string
423
+ */
424
+ StringT(const BasicString& str) // A
425
+ : str_(str)
426
+ {
427
+ }
428
+
429
+ /**
430
+ assign str
431
+ @param str [in] assign string
432
+ */
433
+ StringT& operator=(const StringT& str)
434
+ {
435
+ return assign(str);
436
+ }
437
+
438
+ /**
439
+ assign [str, NUL)
440
+ @param str [in] assign string
441
+ */
442
+ StringT& operator=(const CharT *str)
443
+ {
444
+ return assign(str);
445
+ }
446
+
447
+ /**
448
+ assign 1 * c
449
+ @param c [in] initial character
450
+ */
451
+ StringT& operator=(CharT c)
452
+ {
453
+ return assign(1, c);
454
+ }
455
+
456
+ /**
457
+ assign [str, NUL)
458
+ @param str [in] assign string
459
+ */
460
+ StringT& operator=(const char *str) // A
461
+ {
462
+ return assign(str);
463
+ }
464
+ /**
465
+ assign str
466
+ @param str [in] assign string
467
+ */
468
+ StringT& operator=(const std::string& str) // A
469
+ {
470
+ return assign(str);
471
+ }
472
+
473
+ /**
474
+ append str
475
+ @param str [in] append string
476
+ */
477
+ StringT& operator+=(const StringT& str)
478
+ {
479
+ return append(str);
480
+ }
481
+
482
+ /**
483
+ append [str, NUL)
484
+ @param str [in] append string
485
+ */
486
+ StringT& operator+=(const CharT *str)
487
+ {
488
+ return append(str);
489
+ }
490
+
491
+ /**
492
+ append 1 * c
493
+ @param c [in] append character
494
+ */
495
+ StringT& operator+=(CharT c)
496
+ {
497
+ return append(1, c);
498
+ }
499
+
500
+ /**
501
+ append str
502
+ @param str [in] append string
503
+ */
504
+ StringT& append(const StringT& str)
505
+ {
506
+ str_.append(str.str_); return *this;
507
+ }
508
+
509
+ /**
510
+ append str [off, off + count)
511
+ @param str [in] append string
512
+ @param off [in] string offset
513
+ @param count [in] count of character
514
+ */
515
+ StringT& append(const StringT& str, size_type off, size_type count)
516
+ {
517
+ str_.append(str.str_, off, count); return *this;
518
+ }
519
+
520
+ /**
521
+ append [str, str + count)
522
+ @param str [in] append string
523
+ @param count [in] count of character
524
+ */
525
+ StringT& append(const CharT *str, size_type count)
526
+ {
527
+ return append(str, str + count);
528
+ }
529
+
530
+ /**
531
+ append [str, NUL)
532
+ @param str [in] append string
533
+ */
534
+ StringT& append(const CharT *str)
535
+ {
536
+ str_.append(str); return *this;
537
+ }
538
+
539
+ /**
540
+ append count * c
541
+ @param count [in] count of character
542
+ @param c [in] initial character
543
+ */
544
+ StringT& append(size_type count, CharT c)
545
+ {
546
+ str_.append(count, c); return *this;
547
+ }
548
+
549
+ /**
550
+ append [begin, end)
551
+ @param begin [in] begin of iterator
552
+ @param end [in] end of iterator
553
+ */
554
+ template<class Iterator>
555
+ StringT& append(Iterator begin, Iterator end, typename string_local::disable_if<string_local::IsInt<Iterator>::value>::type* = 0)
556
+ {
557
+ while (begin != end) {
558
+ CharT c;
559
+ c = getOneChar(begin, end);
560
+ str_.push_back(c);
561
+ }
562
+ return *this;
563
+ }
564
+
565
+ // append [begin, end), const pointers
566
+ // StringT& append(const_pointer begin, const_pointer end);
567
+ // append [begin, end), const_iterators
568
+ // StringT& append(const_iterator begin, const_iterator end);
569
+
570
+ /**
571
+ append [str, str + count)
572
+ @param str [in] append string
573
+ @param count [in] count of character
574
+ */
575
+ StringT& append(const char *str, size_type count) // A
576
+ {
577
+ return append(str, str + count);
578
+ }
579
+
580
+ /**
581
+ append [str, NUL)
582
+ @param str [in] append string
583
+ */
584
+ StringT& append(const char *str) // A
585
+ {
586
+ return append(str, std::strlen(str));
587
+ }
588
+ StringT& append(const Char16 *begin, const Char16 *end)
589
+ {
590
+ while (begin != end) {
591
+ Char c;
592
+ if (!string::GetCharFromUtf16(c, begin, end)) {
593
+ throw cybozu::Exception("StringT:GetCharFromUtf16");
594
+ }
595
+ str_ += c;
596
+ }
597
+ return *this;
598
+ }
599
+ StringT& append(const Char16 *str)
600
+ {
601
+ return append(str, str + cybozu::strlen(str));
602
+ }
603
+ /**
604
+ append str
605
+ @param str [in] append string
606
+ */
607
+ StringT& append(const std::string& str) // A
608
+ {
609
+ return append(str.begin(), str.end());
610
+ }
611
+
612
+ /**
613
+ assign str
614
+ @param str [in] assign str
615
+ */
616
+ StringT& assign(const StringT& str)
617
+ {
618
+ clear(); return append(str);
619
+ }
620
+
621
+ /**
622
+ assign str [off, off + count)
623
+ @param str [in] assign string
624
+ @param off [in] offset
625
+ @param count [in] count of character
626
+ */
627
+ StringT& assign(const StringT& str, size_type off, size_type count)
628
+ {
629
+ clear(); return append(str, off, count);
630
+ }
631
+
632
+ /**
633
+ assign [str, str + count)
634
+ @param str [in] assign string
635
+ @param count [in] count of character
636
+ */
637
+ StringT& assign(const CharT *str, size_type count)
638
+ {
639
+ return assign(str, str + count);
640
+ }
641
+
642
+ /**
643
+ assign [str, NUL)
644
+ @param str [in] assign string
645
+ */
646
+ StringT& assign(const CharT *str)
647
+ {
648
+ clear(); return append(str);
649
+ }
650
+ StringT& assign(const Char16 *str)
651
+ {
652
+ clear(); return append(str);
653
+ }
654
+
655
+ /**
656
+ assign count * c
657
+ @param count [in] count of character
658
+ @param c [in] initial character
659
+ */
660
+ StringT& assign(size_type count, CharT c)
661
+ {
662
+ clear(); return append(count, c);
663
+ }
664
+
665
+ /**
666
+ assign [First, end)
667
+ @param begin [in] begin of iterator
668
+ @param end [in] end of iterator
669
+ */
670
+ template<class Iterator>
671
+ StringT& assign(Iterator begin, Iterator end, typename string_local::disable_if<string_local::IsInt<Iterator>::value>::type* = 0)
672
+ {
673
+ clear(); return append(begin, end);
674
+ }
675
+
676
+ // assign [First, end), const pointers
677
+ // StringT& assign(const_pointer begin, const_pointer end);
678
+
679
+ // assign [First, end), const_iterators
680
+ // StringT& assign(const_iterator begin, const_iterator end);
681
+
682
+ /**
683
+ assign [str, str + count)
684
+ @param str [in] original string
685
+ @param count [in] count of character
686
+ */
687
+ StringT& assign(const char *str, size_type count) // A
688
+ {
689
+ return assign(str, str + count);
690
+ }
691
+
692
+ /**
693
+ assign [str, NUL)
694
+ @param str [in] original string
695
+ */
696
+ StringT& assign(const char *str) // A
697
+ {
698
+ clear(); return append(str);
699
+ }
700
+ /**
701
+ assign str
702
+ @param str [in] original string
703
+ */
704
+ StringT& assign(const std::string& str) // A
705
+ {
706
+ clear(); return append(str);
707
+ }
708
+
709
+ /**
710
+ insert str at off
711
+ @param off [in] offset
712
+ @param str [in] insert str
713
+ */
714
+ StringT& insert(size_type off, const StringT& str)
715
+ {
716
+ str_.insert(off, str.str_); return *this;
717
+ }
718
+
719
+ /**
720
+ insert str [off, off + count) at off
721
+ @param off [in] offset of destination
722
+ @param rhs [in] source str
723
+ @param rhsOff [in] offset of source str
724
+ @param count [in] count of source str
725
+ */
726
+ StringT& insert(size_type off, const StringT& rhs, size_type rhsOff, size_type count)
727
+ {
728
+ str_.insert(off, rhs.str_, rhsOff, count); return *this;
729
+ }
730
+
731
+ /**
732
+ insert [str, str + count) at off
733
+ @param off [in] offset of destination
734
+ @param str [in] source str
735
+ @param count [in] count of source str
736
+ */
737
+ StringT& insert(size_type off, const CharT *str, size_type count)
738
+ {
739
+ str_.insert(off, str, count); return *this;
740
+ }
741
+
742
+ /**
743
+ insert [str, NUL) at off
744
+ @param off [in] offset of destination
745
+ @param str [in] source str
746
+ */
747
+ StringT& insert(size_type off, const CharT *str)
748
+ {
749
+ str_.insert(off, str); return *this;
750
+ }
751
+
752
+ /**
753
+ insert count * c at off
754
+ @param off [in] offset of destination
755
+ @param count [in] count of source str
756
+ @param c [in] initial character
757
+ */
758
+ StringT& insert(size_type off, size_type count, CharT c)
759
+ {
760
+ str_.insert(off, count, c); return *this;
761
+ }
762
+ /**
763
+ insert c at here
764
+ @param here [in] offset of destination
765
+ @param c [in] initial character(default 0)
766
+ */
767
+ iterator insert(iterator here, CharT c = 0)
768
+ {
769
+ return str_.insert(here, c);
770
+ }
771
+
772
+ /**
773
+ insert count * CharT at here
774
+ @param here [in] offset of destination
775
+ @param count [in] count of str
776
+ @param c [in] initial character
777
+ */
778
+ void insert(iterator here, size_type count, CharT c)
779
+ {
780
+ str_.insert(here, count, c);
781
+ }
782
+
783
+ /**
784
+ insert [begin, end) at here
785
+ @param here [in] offset of destination
786
+ @param begin [in] begin of iterator
787
+ @param end [in] end of iterator
788
+ */
789
+ template<class Iterator>
790
+ void insert(iterator here, Iterator begin, Iterator end)
791
+ {
792
+ StringT str(begin, end);
793
+ str_.insert(here, str.begin(), str.end());
794
+ }
795
+
796
+ // insert [begin, end) at here, const pointers
797
+ // void insert(iterator here, const_pointer begin, const_pointer end);
798
+ // insert [begin, end) at here, const_iterators
799
+ // void insert(iterator here, const_iterator begin, const_iterator end);
800
+
801
+ /**
802
+ erase elements [off, off + count)
803
+ @param off [in] offset
804
+ @param count [in] count of character(default npos)
805
+ */
806
+ StringT& erase(size_type off = 0, size_type count = npos)
807
+ {
808
+ str_.erase(off, count); return *this;
809
+ }
810
+
811
+ /**
812
+ erase element at here
813
+ @param here [in] erase from here
814
+ */
815
+ iterator erase(iterator here)
816
+ {
817
+ return str_.erase(here);
818
+ }
819
+
820
+ /**
821
+ erase substring [begin, end)
822
+ @param begin [in] begin of iterator
823
+ @param end [in] end of iterator
824
+ */
825
+ iterator erase(iterator begin, iterator end)
826
+ {
827
+ return str_.erase(begin, end);
828
+ }
829
+
830
+ /**
831
+ erase all
832
+ */
833
+ void clear() { str_.clear(); }
834
+
835
+ /**
836
+ replace [off, off + n) with rhs
837
+ @param off [in] start offset
838
+ @param n [in] count of remove character
839
+ @param rhs [in] append string
840
+ */
841
+ StringT& replace(size_type off, size_type n, const StringT& rhs)
842
+ {
843
+ str_.replace(off, n, rhs.str_); return *this;
844
+ }
845
+
846
+ /**
847
+ replace [off, off + n) with rhs [rhsOff, rhsOff + count)
848
+ @param off [in] start offset
849
+ @param n [in] count of remove character
850
+ @param rhs [in] append string
851
+ @param rhsOff [in] append from
852
+ @param count [in] count of append
853
+ */
854
+ StringT& replace(size_type off, size_type n, const StringT& rhs, size_type rhsOff, size_type count)
855
+ {
856
+ str_.replace(off, n, rhs.str_, rhsOff, count); return *this;
857
+ }
858
+
859
+ /**
860
+ replace [off, off + n) with [str, str + count)
861
+ @param off [in] start offset
862
+ @param n [in] count of remove character
863
+ @param str [in] append string
864
+ @param count [in] count of append
865
+ */
866
+ StringT& replace(size_type off, size_type n, const CharT *str, size_type count)
867
+ {
868
+ str_.replace(off, n, str, count); return *this;
869
+ }
870
+
871
+ /**
872
+ replace [off, off + n) with [str, NUL)
873
+ @param off [in] start offset
874
+ @param n [in] count of remove character
875
+ @param str [in] append string
876
+ */
877
+ StringT& replace(size_type off, size_type n, const CharT *str)
878
+ {
879
+ str_.replace(off, n, str); return *this;
880
+ }
881
+
882
+ /**
883
+ replace [off, off + n) with count * c
884
+ @param off [in] start offset
885
+ @param n [in] count of remove character
886
+ @param count [in] count of append
887
+ @param c [in] initial character
888
+ */
889
+ StringT& replace(size_type off, size_type n, size_type count, CharT c)
890
+ {
891
+ str_.replace(off, n, count, c); return *this;
892
+ }
893
+
894
+ /**
895
+ replace [begin, end) with rhs
896
+ @param begin [in] begin to remove
897
+ @param end [in] end to remove
898
+ @param rhs [in] append str
899
+ */
900
+ StringT& replace(iterator begin, iterator end, const StringT& rhs)
901
+ {
902
+ str_.replace(begin, end, rhs.str_); return *this;
903
+ }
904
+
905
+ /**
906
+ replace [begin, end) with [str, str + count)
907
+ @param begin [in] begin to remove
908
+ @param end [in] end to remove
909
+ @param str in] append str
910
+ @param count [in] count of append
911
+ */
912
+ StringT& replace(iterator begin, iterator end, const CharT *str, size_type count)
913
+ {
914
+ str_.replace(begin, end, str, count); return *this;
915
+ }
916
+
917
+ /**
918
+ replace [begin, end) with [str, NUL)
919
+ @param begin [in] begin to remove
920
+ @param end [in] end to remove
921
+ @param str in] append str
922
+ */
923
+ StringT& replace(iterator begin, iterator end, const CharT *str)
924
+ {
925
+ str_.replace(begin, end, str); return *this;
926
+ }
927
+
928
+ /**
929
+ replace [begin, end) with count * c
930
+ @param begin [in] begin to remove
931
+ @param end [in] end to remove
932
+ @param count [in] count of append
933
+ @param c [in] initial character
934
+ */
935
+ StringT& replace(iterator begin, iterator end, size_type count, CharT c)
936
+ {
937
+ str_.replace(begin, end, count, c); return *this;
938
+ }
939
+
940
+ /**
941
+ replace [begin, end) with [begin2, end2)
942
+ @param begin [in] begin to remove
943
+ @param end [in] end to remove
944
+ @param begin2 [in] begin to append
945
+ @param end2 [in] end to append
946
+ */
947
+ template<class Iterator>
948
+ StringT& replace(iterator begin, iterator end, Iterator begin2, Iterator end2)
949
+ {
950
+ StringT str(begin2, end2);
951
+ str_.replace(begin, end, str.begin(), str.end());
952
+ return *this;
953
+ }
954
+
955
+ // replace [begin, end) with [begin2, end2), const pointers
956
+ // StringT& replace(iterator begin, iterator end, const_pointer begin2, const_pointer end2);
957
+
958
+ // replace [begin, end) with [begin2, end2), const_iterators
959
+ // StringT& replace(iterator begin, iterator end, const_iterator begin2, const_iterator end2);
960
+
961
+ /**
962
+ return iterator for beginning of mutable sequence
963
+ */
964
+ iterator begin() CYBOZU_NOEXCEPT { return str_.begin(); }
965
+
966
+ /**
967
+ return iterator for beginning of nonmutable sequence
968
+ */
969
+ const_iterator begin() const CYBOZU_NOEXCEPT { return str_.begin(); }
970
+
971
+ /**
972
+ return iterator for end of mutable sequence
973
+ */
974
+ iterator end() CYBOZU_NOEXCEPT { return str_.end(); }
975
+
976
+ /**
977
+ return iterator for end of nonmutable sequence
978
+ */
979
+ const_iterator end() const CYBOZU_NOEXCEPT { return str_.end(); }
980
+
981
+ /**
982
+ return iterator for beginning of reversed mutable sequence
983
+ */
984
+ reverse_iterator rbegin() CYBOZU_NOEXCEPT { return str_.rbegin(); }
985
+
986
+ /**
987
+ return iterator for beginning of reversed nonmutable sequence
988
+ */
989
+ const_reverse_iterator rbegin() const CYBOZU_NOEXCEPT { return str_.rbegin(); }
990
+
991
+ /**
992
+ return iterator for end of reversed mutable sequence
993
+ */
994
+ reverse_iterator rend() CYBOZU_NOEXCEPT { return str_.rend(); }
995
+
996
+ /**
997
+ return iterator for end of reversed nonmutable sequence
998
+ */
999
+ const_reverse_iterator rend() const CYBOZU_NOEXCEPT { return str_.rend(); }
1000
+
1001
+ /**
1002
+ subscript mutable sequence with checking
1003
+ @param off [in] offset
1004
+ */
1005
+ reference at(size_type off) { return str_.at(off); }
1006
+
1007
+ /**
1008
+ get element at off
1009
+ @param off [in] offset
1010
+ */
1011
+ const_reference at(size_type off) const { return str_.at(off); }
1012
+
1013
+ /**
1014
+ subscript mutable sequence
1015
+ @param off [in] offset
1016
+ */
1017
+ reference operator[](size_type off) { return str_[off]; }
1018
+
1019
+ /**
1020
+ subscript nonmutable sequence
1021
+ @param off [in] offset
1022
+ */
1023
+ const_reference operator[](size_type off) const { return str_[off]; }
1024
+
1025
+ /**
1026
+ insert element at end
1027
+ @param c [in] append character
1028
+ */
1029
+ void push_back(CharT c)
1030
+ {
1031
+ str_.push_back(c);
1032
+ }
1033
+
1034
+ /**
1035
+ return pointer to null-terminated nonmutable array
1036
+ */
1037
+ const CharT *c_str() const { return str_.c_str(); }
1038
+
1039
+ /**
1040
+ return pointer to nonmutable array
1041
+ */
1042
+ const CharT *data() const { return str_.data(); }
1043
+
1044
+ /**
1045
+ return length of sequence
1046
+ */
1047
+ size_type length() const CYBOZU_NOEXCEPT { return str_.length(); }
1048
+
1049
+ /**
1050
+ return length of sequence
1051
+ */
1052
+ size_type size() const CYBOZU_NOEXCEPT { return str_.size(); }
1053
+
1054
+ /**
1055
+ return maximum possible length of sequence
1056
+ */
1057
+ size_type max_size() const CYBOZU_NOEXCEPT { return str_.max_size(); }
1058
+
1059
+ /**
1060
+ determine new length, padding with null elements as needed
1061
+ */
1062
+ void resize(size_type newSize) { str_.resize(newSize); }
1063
+
1064
+ /**
1065
+ determine new length, padding with c elements as needed
1066
+ @param newSize [in] new length
1067
+ @param c [in] initial character
1068
+ */
1069
+ void resize(size_type newSize, CharT c)
1070
+ {
1071
+ str_.resize(newSize, c);
1072
+ }
1073
+
1074
+ /**
1075
+ return current length of allocated storage
1076
+ */
1077
+ size_type capacity() const CYBOZU_NOEXCEPT { return str_.capacity(); }
1078
+
1079
+ /**
1080
+ determine new minimum length of allocated storage
1081
+ @param newSize [in] reserve size
1082
+ */
1083
+ void reserve(size_type newSize = 0) { str_.reserve(newSize); }
1084
+
1085
+ /**
1086
+ test if sequence is empty
1087
+ @return true if empty
1088
+ */
1089
+ bool empty() const CYBOZU_NOEXCEPT { return str_.empty(); }
1090
+
1091
+ /**
1092
+ copy [off, off + count) to [dest, dest + count)
1093
+ @param dest [in] destination
1094
+ @param count [in] count of copy
1095
+ @param off [in] copy from here
1096
+ */
1097
+ size_type copy(CharT *dest, size_type count, size_type off = 0) const
1098
+ {
1099
+ #ifdef _MSC_VER
1100
+ return str_._Copy_s(dest, count, count, off);
1101
+ #else
1102
+ return str_.copy(dest, count, off);
1103
+ #endif
1104
+ }
1105
+
1106
+ /**
1107
+ exchange contents with rhs
1108
+ @param rhs [in] swap string
1109
+ */
1110
+ void swap(StringT& rhs) { str_.swap(rhs.str_); }
1111
+
1112
+ /**
1113
+ look for rhs beginnng at or after off
1114
+ @param rhs [in] target
1115
+ @param off [in] search from here
1116
+ @return position
1117
+ */
1118
+ size_type find(const StringT& rhs, size_type off = 0) const
1119
+ {
1120
+ return str_.find(rhs.str_, off);
1121
+ }
1122
+
1123
+ /**
1124
+ look for [str, str + count) beginnng at or after off
1125
+ @param str [in] target
1126
+ @param off [in] search from here
1127
+ @param count [in] count of str
1128
+ */
1129
+ size_type find(const CharT *str, size_type off, size_type count) const
1130
+ {
1131
+ return str_.find(str, off, count);
1132
+ }
1133
+
1134
+ /**
1135
+ look for [str, NUL) beginnng at or after off
1136
+ @param str [in] target
1137
+ @param off [in] search from here
1138
+ */
1139
+ size_type find(const CharT *str, size_type off = 0) const
1140
+ {
1141
+ return str_.find(str, off);
1142
+ }
1143
+
1144
+ /**
1145
+ look for c at or after off
1146
+ @param c [in] target
1147
+ @param off [in] search from here
1148
+ */
1149
+ size_type find(CharT c, size_type off = 0) const
1150
+ {
1151
+ return str_.find(c, off);
1152
+ }
1153
+
1154
+ /**
1155
+ look for rhs beginning before off
1156
+ @param rhs [in] target
1157
+ @param off [in] search from here
1158
+ */
1159
+ size_type rfind(const StringT& rhs, size_type off = npos) const
1160
+ {
1161
+ return str_.rfind(rhs.str_, off);
1162
+ }
1163
+
1164
+ /**
1165
+ look for [str, str + count) beginning before off
1166
+ @param str [in] target
1167
+ @param off [in] search from here
1168
+ @param count [in] count of character
1169
+ */
1170
+ size_type rfind(const CharT *str, size_type off, size_type count) const
1171
+ {
1172
+ return str_.rfind(str, off, count);
1173
+ }
1174
+
1175
+ /**
1176
+ look for [str, NUL) beginning before off
1177
+ @param str [in] target
1178
+ @param off [in] search from here
1179
+ */
1180
+ size_type rfind(const CharT *str, size_type off = npos) const
1181
+ {
1182
+ return str_.rfind(str, off);
1183
+ }
1184
+
1185
+ /**
1186
+ look for c before off
1187
+ @param c [in] target
1188
+ @param off [in] search from here
1189
+ */
1190
+ size_type rfind(CharT c, size_type off = npos) const
1191
+ {
1192
+ return str_.rfind(c, off);
1193
+ }
1194
+
1195
+ /**
1196
+ look for one of rhs at or after off
1197
+ @param rhs [in] target
1198
+ @param off [in] search from here
1199
+ */
1200
+ size_type find_first_of(const StringT& rhs, size_type off = 0) const
1201
+ {
1202
+ return str_.find_first_of(rhs.str_, off);
1203
+ }
1204
+
1205
+ /**
1206
+ look for one of [str, str + count) at or after off
1207
+ @param str [in] target
1208
+ @param off [in] search from here
1209
+ @param count [in] count of character
1210
+ */
1211
+ size_type find_first_of(const CharT *str, size_type off, size_type count) const
1212
+ {
1213
+ return str_.find_first_of(str, off, count);
1214
+ }
1215
+
1216
+ /**
1217
+ look for one of [str, NUL) at or after off
1218
+ @param str [in] target
1219
+ @param off [in] search from here
1220
+ */
1221
+ size_type find_first_of(const CharT *str, size_type off = 0) const
1222
+ {
1223
+ return str_.find_first_of(str, off);
1224
+ }
1225
+
1226
+ /**
1227
+ look for c at or after off
1228
+ @param c [in] target
1229
+ @param off [in] search from here
1230
+ */
1231
+ size_type find_first_of(CharT c, size_type off = 0) const
1232
+ {
1233
+ return str_.find_first_of(c, off);
1234
+ }
1235
+
1236
+ /**
1237
+ look for one of rhs before off
1238
+ @param rhs [in] target
1239
+ @param off [in] search from here
1240
+ */
1241
+ size_type find_last_of(const StringT& rhs, size_type off = npos) const
1242
+ {
1243
+ return str_.find_last_of(rhs.str_, off);
1244
+ }
1245
+
1246
+ /**
1247
+ look for one of [str, str + count) before off
1248
+ @param str [in] target
1249
+ @param off [in] search from here
1250
+ @param count [in] count of character
1251
+ */
1252
+ size_type find_last_of(const CharT *str, size_type off, size_type count) const
1253
+ {
1254
+ return str_.find_last_of(str, off, count);
1255
+ }
1256
+
1257
+ /**
1258
+ look for one of [str, NUL) before off
1259
+ @param str [in] target
1260
+ @param off [in] search from here
1261
+ */
1262
+ size_type find_last_of(const CharT *str, size_type off = npos) const
1263
+ {
1264
+ return str_.find_last_of(str, off);
1265
+ }
1266
+
1267
+ /**
1268
+ look for c before off
1269
+ @param c [in] target
1270
+ @param off [in] search from here
1271
+ */
1272
+ size_type find_last_of(CharT c, size_type off = npos) const
1273
+ {
1274
+ return str_.find_last_of(c, off);
1275
+ }
1276
+
1277
+ /**
1278
+ look for none of rhs at or after off
1279
+ @param rhs [in] target
1280
+ @param off [in] search from here
1281
+ */
1282
+ size_type find_first_not_of(const StringT& rhs, size_type off = 0) const
1283
+ {
1284
+ return str_.find_first_not_of(rhs.str_, off);
1285
+ }
1286
+
1287
+ /**
1288
+ look for none of [str, str + count) at or after off
1289
+ @param str [in] target
1290
+ @param off [in] search from here
1291
+ @param count [in] count of character
1292
+ */
1293
+ size_type find_first_not_of(const CharT *str, size_type off, size_type count) const
1294
+ {
1295
+ return str_.find_first_not_of(str, off, count);
1296
+ }
1297
+
1298
+ /**
1299
+ look for one of [str, NUL) at or after off
1300
+ @param str [in] target
1301
+ @param off [in] search from here
1302
+ */
1303
+ size_type find_first_not_of(const CharT *str, size_type off = 0) const
1304
+ {
1305
+ return str_.find_first_not_of(str, off);
1306
+ }
1307
+
1308
+ /**
1309
+ look for non c at or after off
1310
+ @param c [in] target
1311
+ @param off [in] search from here
1312
+ */
1313
+ size_type find_first_not_of(CharT c, size_type off = 0) const
1314
+ {
1315
+ return str_.find_first_not_of(c, off);
1316
+ }
1317
+
1318
+ /**
1319
+ look for none of rhs before off
1320
+ @param rhs [in] target
1321
+ @param off [in] search from here
1322
+ */
1323
+ size_type find_last_not_of(const StringT& rhs, size_type off = npos) const
1324
+ {
1325
+ return str_.find_last_not_of(rhs.str_, off);
1326
+ }
1327
+
1328
+ /**
1329
+ look for none of [str, str + count) before off
1330
+ @param str [in] target
1331
+ @param off [in] search from here
1332
+ @param count [in] count of character
1333
+ */
1334
+ size_type find_last_not_of(const CharT *str, size_type off, size_type count) const
1335
+ {
1336
+ return str_.find_last_not_of(str, off, count);
1337
+ }
1338
+
1339
+ /**
1340
+ look for none of [str, NUL) before off
1341
+ @param str [in] target
1342
+ @param off [in] search from here
1343
+ */
1344
+ size_type find_last_not_of(const CharT *str, size_type off = npos) const
1345
+ {
1346
+ return str_.find_last_not_of(str, off);
1347
+ }
1348
+
1349
+ /**
1350
+ look for non c before off
1351
+ @param c [in] target
1352
+ @param off [in] search from here
1353
+ */
1354
+ size_type find_last_not_of(CharT c, size_type off = npos) const
1355
+ {
1356
+ return str_.find_last_not_of(c, off);
1357
+ }
1358
+ /**
1359
+ return [off, off + count) as new string
1360
+ @param off [in] from here
1361
+ @param count [in] count of substring
1362
+ */
1363
+ StringT substr(size_type off = 0, size_type count = npos) const
1364
+ {
1365
+ return str_.substr(off, count);
1366
+ }
1367
+ /**
1368
+ compare *this with rhs
1369
+ @param rhs [in] target
1370
+ */
1371
+ int compare(const StringT& rhs) const
1372
+ {
1373
+ return str_.compare(rhs.str_);
1374
+ }
1375
+
1376
+ /**
1377
+ compare [off, off + n) with rhs
1378
+ @param off [in] from here
1379
+ @param n [in] count of lhs
1380
+ @param rhs [in] target
1381
+ */
1382
+ int compare(size_type off, size_type n, const StringT& rhs) const
1383
+ {
1384
+ return str_.compare(off, n, rhs.str_);
1385
+ }
1386
+
1387
+ /**
1388
+ compare [off, off + n) with rhs [rhsOff, rhsOff + count)
1389
+ @param off [in] from here
1390
+ @param n [in] count of lhs
1391
+ @param rhs [in] target
1392
+ @param rhsOff [in] target from here
1393
+ @param count [in] count of rhs
1394
+ */
1395
+ int compare(size_type off, size_type n, const StringT& rhs, size_type rhsOff, size_type count) const
1396
+ {
1397
+ return str_.compare(off, n, rhs.str_, rhsOff, count);
1398
+ }
1399
+
1400
+ /**
1401
+ compare [0, _Mysize) with [str, NUL)
1402
+ @param str [in] target
1403
+ */
1404
+ int compare(const CharT *str) const
1405
+ {
1406
+ return str_.compare(str);
1407
+ }
1408
+ int compare(const Char16 *str) const
1409
+ {
1410
+ const StringT rhs(str);
1411
+ return str_.compare(rhs.str_);
1412
+ }
1413
+
1414
+ /**
1415
+ compare [off, off + n) with [str, NUL)
1416
+ @param off [in] from here
1417
+ @param n [in] count of lhs
1418
+ @param str [in] target
1419
+ */
1420
+ int compare(size_type off, size_type n, const CharT *str) const
1421
+ {
1422
+ return str_.compare(off, n, str);
1423
+ }
1424
+
1425
+ /**
1426
+ compare [off, off + n) with [str, str + count)
1427
+ @param off [in] from here
1428
+ @param n [in] count of lhs
1429
+ @param str [in] target
1430
+ @param count [in] count of rhs
1431
+ */
1432
+ int compare(size_type off,size_type n, const CharT *str, size_type count) const
1433
+ {
1434
+ return str_.compare(off, n, str, count);
1435
+ }
1436
+ /**
1437
+ convert to std::string with UTF-8
1438
+ */
1439
+ void toUtf8(std::string& str) const
1440
+ {
1441
+ for (size_t i = 0, n = str_.size(); i < n; i++) {
1442
+ if (!cybozu::string::AppendUtf8(str, str_[i])) {
1443
+ throw cybozu::Exception("string:toUtf8") << i;
1444
+ }
1445
+ }
1446
+ }
1447
+ std::string toUtf8() const
1448
+ {
1449
+ std::string str;
1450
+ toUtf8(str);
1451
+ return str;
1452
+ }
1453
+ /**
1454
+ convert to std::string with UTF-16LE
1455
+ */
1456
+ void toUtf16(cybozu::String16& str) const
1457
+ {
1458
+ for (size_t i = 0, n = str_.size(); i < n; i++) {
1459
+ if (!cybozu::string::AppendUtf16(str, str_[i])) {
1460
+ throw cybozu::Exception("string:toUtf16") << i;
1461
+ }
1462
+ }
1463
+ }
1464
+ cybozu::String16 toUtf16() const
1465
+ {
1466
+ cybozu::String16 str;
1467
+ toUtf16(str);
1468
+ return str;
1469
+ }
1470
+ /**
1471
+ is this valid unicode string?
1472
+ @return true correct string
1473
+ @return false bad string
1474
+ */
1475
+ bool isValid() const
1476
+ {
1477
+ for (size_t i = 0, n = str_.size(); i < n; i++) {
1478
+ if (!cybozu::string::IsValidChar(str_[i])) return false;
1479
+ }
1480
+ return true;
1481
+ }
1482
+ #if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11
1483
+ StringT(StringT&& rhs) CYBOZU_NOEXCEPT
1484
+ {
1485
+ assign(std::forward<StringT>(rhs));
1486
+ }
1487
+ StringT& operator=(StringT&& rhs) CYBOZU_NOEXCEPT
1488
+ {
1489
+ assign(std::forward<StringT>(rhs));
1490
+ return *this;
1491
+ }
1492
+ StringT& assign(StringT&& rhs) CYBOZU_NOEXCEPT
1493
+ {
1494
+ str_.assign(std::forward<BasicString>(rhs.str_));
1495
+ return *this;
1496
+ }
1497
+ const_iterator cbegin() const CYBOZU_NOEXCEPT { return begin(); }
1498
+ const_iterator cend() const CYBOZU_NOEXCEPT { return end(); }
1499
+ const_reverse_iterator crbegin() const CYBOZU_NOEXCEPT { return rbegin(); }
1500
+ const_reverse_iterator crend() const CYBOZU_NOEXCEPT { return rend(); }
1501
+ void shrink_to_fit() { str_.shrink_to_fit(); }
1502
+ void pop_back() { str_.erase(str_.size() - 1, 1); }
1503
+ reference front() { return operator[](0); }
1504
+ const_reference front() const { return str_.front(); }
1505
+ reference back() { return str_.back(); }
1506
+ const_reference back() const { return str_.back(); }
1507
+ #endif
1508
+ /**
1509
+ get internal const str(don't use this function)
1510
+ */
1511
+ const BasicString& get() const { return str_; }
1512
+ /**
1513
+ get internal str(don't use this function)
1514
+ */
1515
+ BasicString& get() { return str_; }
1516
+ template<class T>bool operator==(const T& rhs) const { return compare(rhs) == 0; }
1517
+ template<class T>bool operator!=(const T& rhs) const { return compare(rhs) != 0; }
1518
+ template<class T>bool operator<=(const T& rhs) const { return compare(rhs) <= 0; }
1519
+ template<class T>bool operator>=(const T& rhs) const { return compare(rhs) >= 0; }
1520
+ template<class T>bool operator<(const T& rhs) const { return compare(rhs) < 0; }
1521
+ template<class T>bool operator>(const T& rhs) const { return compare(rhs) > 0; }
1522
+ private:
1523
+ template<class Iterator>
1524
+ cybozu::Char getOneChar(Iterator& begin, const Iterator& end)
1525
+ {
1526
+ return getOneCharSub(begin, end, *begin);
1527
+ }
1528
+ // dispatch
1529
+ template<class Iterator>
1530
+ cybozu::Char getOneCharSub(Iterator& begin, const Iterator&, cybozu::Char)
1531
+ {
1532
+ return *begin++;
1533
+ }
1534
+ template<class Iterator>
1535
+ cybozu::Char getOneCharSub(Iterator& begin, const Iterator& end, char)
1536
+ {
1537
+ cybozu::Char c;
1538
+ if (!cybozu::string::GetCharFromUtf8(&c, begin, end)) {
1539
+ throw cybozu::Exception("string:getOneCharSub");
1540
+ }
1541
+ return c;
1542
+ }
1543
+ BasicString str_;
1544
+ };
1545
+
1546
+ typedef StringT<cybozu::Char> String;
1547
+
1548
+ inline std::istream& getline(std::istream& is, String& str, const char delim = '\n')
1549
+ {
1550
+ std::string tmp;
1551
+ std::getline(is, tmp, delim);
1552
+ str.assign(tmp);
1553
+ return is;
1554
+ }
1555
+
1556
+ inline std::istream& operator>>(std::istream& is, String& str)
1557
+ {
1558
+ std::string tmp;
1559
+ is >> tmp;
1560
+ str.assign(tmp);
1561
+ return is;
1562
+ }
1563
+
1564
+ inline std::ostream& operator<<(std::ostream& os, const String& str)
1565
+ {
1566
+ return os << str.toUtf8();
1567
+ }
1568
+
1569
+ inline bool operator==(const cybozu::Char* lhs, const String& rhs) { return rhs == lhs; }
1570
+ inline bool operator!=(const cybozu::Char* lhs, const String& rhs) { return rhs != lhs; }
1571
+ inline bool operator<=(const cybozu::Char* lhs, const String& rhs) { return rhs >= lhs; }
1572
+ inline bool operator>=(const cybozu::Char* lhs, const String& rhs) { return rhs <= lhs; }
1573
+ inline bool operator<(const cybozu::Char* lhs, const String& rhs) { return rhs > lhs; }
1574
+ inline bool operator>(const cybozu::Char* lhs, const String& rhs) { return rhs < lhs; }
1575
+
1576
+ inline bool operator==(const cybozu::Char16* lhs, const String& rhs) { return rhs == lhs; }
1577
+ inline bool operator!=(const cybozu::Char16* lhs, const String& rhs) { return rhs != lhs; }
1578
+ inline bool operator<=(const cybozu::Char16* lhs, const String& rhs) { return rhs >= lhs; }
1579
+ inline bool operator>=(const cybozu::Char16* lhs, const String& rhs) { return rhs <= lhs; }
1580
+ inline bool operator<(const cybozu::Char16* lhs, const String& rhs) { return rhs > lhs; }
1581
+ inline bool operator>(const cybozu::Char16* lhs, const String& rhs) { return rhs < lhs; }
1582
+
1583
+ inline bool operator==(const std::string& lhs, const String& rhs) { return rhs == lhs; }
1584
+ inline bool operator!=(const std::string& lhs, const String& rhs) { return rhs != lhs; }
1585
+ inline bool operator<=(const std::string& lhs, const String& rhs) { return rhs >= lhs; }
1586
+ inline bool operator>=(const std::string& lhs, const String& rhs) { return rhs <= lhs; }
1587
+ inline bool operator<(const std::string& lhs, const String& rhs) { return rhs > lhs; }
1588
+ inline bool operator>(const std::string& lhs, const String& rhs) { return rhs < lhs; }
1589
+
1590
+ inline bool operator==(const cybozu::String::BasicString& lhs, const String& rhs) { return rhs == lhs; }
1591
+ inline bool operator!=(const cybozu::String::BasicString& lhs, const String& rhs) { return rhs != lhs; }
1592
+ inline bool operator<=(const cybozu::String::BasicString& lhs, const String& rhs) { return rhs >= lhs; }
1593
+ inline bool operator>=(const cybozu::String::BasicString& lhs, const String& rhs) { return rhs <= lhs; }
1594
+ inline bool operator<(const cybozu::String::BasicString& lhs, const String& rhs) { return rhs > lhs; }
1595
+ inline bool operator>(const cybozu::String::BasicString& lhs, const String& rhs) { return rhs < lhs; }
1596
+ #ifdef _MSC_VER
1597
+ inline bool operator==(const std::wstring& lhs, const String& rhs) { return rhs == lhs; }
1598
+ inline bool operator!=(const std::wstring& lhs, const String& rhs) { return rhs != lhs; }
1599
+ inline bool operator<=(const std::wstring& lhs, const String& rhs) { return rhs >= lhs; }
1600
+ inline bool operator>=(const std::wstring& lhs, const String& rhs) { return rhs <= lhs; }
1601
+ inline bool operator<(const std::wstring& lhs, const String& rhs) { return rhs > lhs; }
1602
+ inline bool operator>(const std::wstring& lhs, const String& rhs) { return rhs < lhs; }
1603
+ #endif
1604
+
1605
+ inline void swap(String& lhs, String& rhs) { lhs.swap(rhs); }
1606
+
1607
+ inline String operator+(const String& lhs, const String& rhs) { return String(lhs) += rhs; }
1608
+ #if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11
1609
+ inline String operator+(String&& lhs, const String& rhs) { return std::move(lhs.append(rhs)); }
1610
+ #endif
1611
+
1612
+ template<class Iter16>
1613
+ bool ConvertUtf16ToUtf8(std::string *out, Iter16 begin, Iter16 end)
1614
+ {
1615
+ out->clear();
1616
+ out->reserve((end - begin) * 3);
1617
+ while (begin != end) {
1618
+ cybozu::Char c;
1619
+ if (!string::GetCharFromUtf16(c, begin, end)) return false;
1620
+ if (!string::AppendUtf8(*out, c)) return false;
1621
+ }
1622
+ return true;
1623
+ }
1624
+ inline bool ConvertUtf16ToUtf8(std::string *out, const cybozu::String16& in)
1625
+ {
1626
+ return ConvertUtf16ToUtf8(out, &in[0], &in[0] + in.size());
1627
+ }
1628
+
1629
+ template<class Iter8>
1630
+ bool ConvertUtf8ToUtf16(cybozu::String16 *out, Iter8 begin, Iter8 end)
1631
+ {
1632
+ out->clear();
1633
+ out->reserve((end - begin) / 2);
1634
+ while (begin != end) {
1635
+ cybozu::Char c;
1636
+ if (!string::GetCharFromUtf8(&c, begin, end)) return false;
1637
+ if (!string::AppendUtf16(*out, c)) return false;
1638
+ }
1639
+ return true;
1640
+ }
1641
+
1642
+ inline bool ConvertUtf8ToUtf16(cybozu::String16 *out, const std::string& in)
1643
+ {
1644
+ return ConvertUtf8ToUtf16(out, &in[0], &in[0] + in.size());
1645
+ }
1646
+
1647
+ inline cybozu::String16 ToUtf16(const std::string& in)
1648
+ {
1649
+ cybozu::String16 out;
1650
+ if (ConvertUtf8ToUtf16(&out, in)) return out;
1651
+ throw cybozu::Exception("string:ToUtf16:bad utf8") << in;
1652
+ }
1653
+
1654
+ inline std::string ToUtf8(const cybozu::String16& in)
1655
+ {
1656
+ std::string out;
1657
+ if (ConvertUtf16ToUtf8(&out, in)) return out;
1658
+ throw cybozu::Exception("string:ToUtf8:bad utf16");
1659
+ }
1660
+
1661
+ template<class Iterator>
1662
+ class Utf8refT {
1663
+ Iterator begin_;
1664
+ Iterator end_;
1665
+ bool ignoreBadChar_;
1666
+ public:
1667
+ Utf8refT(Iterator begin, Iterator end, bool ignoreBadChar = false)
1668
+ : begin_(begin)
1669
+ , end_(end)
1670
+ , ignoreBadChar_(ignoreBadChar)
1671
+ {
1672
+ }
1673
+ /*
1674
+ get character and seek next pointer
1675
+ */
1676
+ bool next(Char *c)
1677
+ {
1678
+ RETRY:
1679
+ if (begin_ == end_) return false;
1680
+ bool b = string::GetCharFromUtf8(c, begin_, end_);
1681
+ if (b) return true;
1682
+ if (ignoreBadChar_) goto RETRY;
1683
+ throw cybozu::Exception("string:Utf8ref:getAndNext");
1684
+ }
1685
+ };
1686
+
1687
+ struct Utf8ref : Utf8refT<const char*> {
1688
+ Utf8ref(const char *begin, const char *end, bool ignoreBadChar = false) : Utf8refT<const char*>(begin, end, ignoreBadChar) {}
1689
+ Utf8ref(const char *str, size_t size, bool ignoreBadChar = false) : Utf8refT<const char*>(str, str + size, ignoreBadChar) {}
1690
+ explicit Utf8ref(const std::string& str, bool ignoreBadChar = false) : Utf8refT<const char*>(str.c_str(), str.c_str() + str.size(), ignoreBadChar) {}
1691
+ };
1692
+
1693
+ template<class InputStream>
1694
+ void load(cybozu::String& str, InputStream& is)
1695
+ {
1696
+ loadPodVec(str, is);
1697
+ }
1698
+
1699
+ template<class OutputStream>
1700
+ void save(OutputStream& os, const cybozu::String& str)
1701
+ {
1702
+ savePodVec(os, str);
1703
+ }
1704
+
1705
+ } // cybozu
1706
+
1707
+ // specialization for boost::hash
1708
+ namespace boost {
1709
+
1710
+ template<>
1711
+ struct hash<cybozu::String> : public std::unary_function<cybozu::String, size_t> {
1712
+ size_t operator()(const cybozu::String& str) const
1713
+ {
1714
+ return static_cast<size_t>(cybozu::hash64(str.c_str(), str.size()));
1715
+ }
1716
+ };
1717
+
1718
+ } // boost
1719
+
1720
+ namespace std {
1721
+
1722
+ #if defined(_MSC_VER) && (_MSC_VER == 1600)
1723
+ // defined in std ?
1724
+ #else
1725
+ CYBOZU_NAMESPACE_TR1_BEGIN
1726
+ #endif
1727
+
1728
+ template<>
1729
+ struct hash<cybozu::String> : public std::unary_function<cybozu::String, size_t> {
1730
+ size_t operator()(const cybozu::String& str) const
1731
+ {
1732
+ return static_cast<size_t>(cybozu::hash64(str.c_str(), str.size()));
1733
+ }
1734
+ };
1735
+
1736
+ #if defined(_MSC_VER) && (_MSC_VER == 1600)
1737
+ // defined in std ?
1738
+ #else
1739
+ CYBOZU_NAMESPACE_TR1_END
1740
+ #endif
1741
+
1742
+ } // std
1743
+
1744
+ #ifdef _MSC_VER
1745
+ #pragma warning(pop)
1746
+ #endif