ooxml_crypt 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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