@eosrio/node-abieos 2.1.0-beta.0 → 2.2.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 (740) hide show
  1. package/README.md +4 -1
  2. package/dist/abieos.node +0 -0
  3. package/lib/abieos.d.ts +19 -0
  4. package/lib/abieos.d.ts.map +1 -0
  5. package/lib/abieos.js +100 -0
  6. package/lib/abieos.ts +107 -0
  7. package/package.json +13 -8
  8. package/.gitmodules +0 -6
  9. package/.idea/misc.xml +0 -6
  10. package/.idea/modules.xml +0 -8
  11. package/.idea/node-abieos.iml +0 -12
  12. package/.idea/vcs.xml +0 -9
  13. package/.idea/workspace.xml +0 -266
  14. package/CMakeLists.txt +0 -35
  15. package/abieos.d.ts +0 -21
  16. package/abieos.js +0 -59
  17. package/eosio.json +0 -1596
  18. package/external/date/CMakeLists.txt +0 -175
  19. package/external/date/LICENSE.txt +0 -31
  20. package/external/date/README.md +0 -61
  21. package/external/date/compile_fail.sh +0 -16
  22. package/external/date/include/date/chrono_io.h +0 -34
  23. package/external/date/include/date/date.h +0 -8335
  24. package/external/date/include/date/ios.h +0 -50
  25. package/external/date/include/date/islamic.h +0 -3031
  26. package/external/date/include/date/iso_week.h +0 -1745
  27. package/external/date/include/date/julian.h +0 -3046
  28. package/external/date/include/date/ptz.h +0 -592
  29. package/external/date/include/date/tz.h +0 -2760
  30. package/external/date/include/date/tz_private.h +0 -318
  31. package/external/date/src/ios.mm +0 -337
  32. package/external/date/src/tz.cpp +0 -3801
  33. package/external/date/test/clock_cast_test/custom_clock.pass.cpp +0 -213
  34. package/external/date/test/clock_cast_test/deprecated.pass.cpp +0 -90
  35. package/external/date/test/clock_cast_test/local_t.pass.cpp +0 -132
  36. package/external/date/test/clock_cast_test/noncastable.pass.cpp +0 -251
  37. package/external/date/test/clock_cast_test/normal_clocks.pass.cpp +0 -102
  38. package/external/date/test/clock_cast_test/to_sys_return_int.fail.cpp +0 -49
  39. package/external/date/test/clock_cast_test/to_sys_return_reference.fail.cpp +0 -51
  40. package/external/date/test/clock_cast_test/to_sys_return_utc_time.fail.cpp +0 -49
  41. package/external/date/test/date_test/day.pass.cpp +0 -143
  42. package/external/date/test/date_test/daypday.fail.cpp +0 -32
  43. package/external/date/test/date_test/daysmday.fail.cpp +0 -32
  44. package/external/date/test/date_test/daysmweekday.fail.cpp +0 -32
  45. package/external/date/test/date_test/detail/decimal_format_seconds.pass.cpp +0 -145
  46. package/external/date/test/date_test/detail/make_precision.pass.cpp +0 -63
  47. package/external/date/test/date_test/detail/static_pow10.pass.cpp +0 -50
  48. package/external/date/test/date_test/detail/width.pass.cpp +0 -64
  49. package/external/date/test/date_test/durations.pass.cpp +0 -62
  50. package/external/date/test/date_test/durations_output.pass.cpp +0 -328
  51. package/external/date/test/date_test/format/century.pass.cpp +0 -117
  52. package/external/date/test/date_test/format/misc.pass.cpp +0 -52
  53. package/external/date/test/date_test/format/range.pass.cpp +0 -78
  54. package/external/date/test/date_test/format/two_dight_year.pass.cpp +0 -121
  55. package/external/date/test/date_test/last.pass.cpp +0 -34
  56. package/external/date/test/date_test/make_time.pass.cpp +0 -164
  57. package/external/date/test/date_test/month.pass.cpp +0 -181
  58. package/external/date/test/date_test/month_day.pass.cpp +0 -82
  59. package/external/date/test/date_test/month_day_last.pass.cpp +0 -75
  60. package/external/date/test/date_test/month_weekday.pass.cpp +0 -77
  61. package/external/date/test/date_test/month_weekday_last.pass.cpp +0 -77
  62. package/external/date/test/date_test/month_weekday_last_less.fail.cpp +0 -34
  63. package/external/date/test/date_test/month_weekday_less.fail.cpp +0 -34
  64. package/external/date/test/date_test/monthpmonth.fail.cpp +0 -32
  65. package/external/date/test/date_test/months_m_year_month.fail.cpp +0 -33
  66. package/external/date/test/date_test/months_m_year_month_day.fail.cpp +0 -33
  67. package/external/date/test/date_test/monthsmmonth.fail.cpp +0 -32
  68. package/external/date/test/date_test/multi_year_duration_addition.pass.cpp +0 -297
  69. package/external/date/test/date_test/op_div_day_day.fail.cpp +0 -33
  70. package/external/date/test/date_test/op_div_int_month.fail.cpp +0 -33
  71. package/external/date/test/date_test/op_div_int_year.fail.cpp +0 -33
  72. package/external/date/test/date_test/op_div_last_last.fail.cpp +0 -33
  73. package/external/date/test/date_test/op_div_month_day.pass.cpp +0 -41
  74. package/external/date/test/date_test/op_div_month_day_last.pass.cpp +0 -39
  75. package/external/date/test/date_test/op_div_month_day_month_day.fail.cpp +0 -33
  76. package/external/date/test/date_test/op_div_month_month.fail.cpp +0 -33
  77. package/external/date/test/date_test/op_div_month_weekday.pass.cpp +0 -39
  78. package/external/date/test/date_test/op_div_month_weekday_last.pass.cpp +0 -39
  79. package/external/date/test/date_test/op_div_month_year.fail.cpp +0 -33
  80. package/external/date/test/date_test/op_div_survey.pass.cpp +0 -437
  81. package/external/date/test/date_test/op_div_weekday_indexed_weekday_indexed.fail.cpp +0 -33
  82. package/external/date/test/date_test/op_div_weekday_last_weekday_last.fail.cpp +0 -33
  83. package/external/date/test/date_test/op_div_year_month.pass.cpp +0 -35
  84. package/external/date/test/date_test/op_div_year_month_day.pass.cpp +0 -43
  85. package/external/date/test/date_test/op_div_year_month_day_last.pass.cpp +0 -41
  86. package/external/date/test/date_test/op_div_year_month_weekday.pass.cpp +0 -41
  87. package/external/date/test/date_test/op_div_year_month_weekday_last.pass.cpp +0 -41
  88. package/external/date/test/date_test/op_div_year_month_year_month.fail.cpp +0 -33
  89. package/external/date/test/date_test/op_div_year_year.fail.cpp +0 -33
  90. package/external/date/test/date_test/parse.pass.cpp +0 -904
  91. package/external/date/test/date_test/sizeof.pass.cpp +0 -62
  92. package/external/date/test/date_test/time_of_day_hours.pass.cpp +0 -104
  93. package/external/date/test/date_test/time_of_day_microfortnights.pass.cpp +0 -119
  94. package/external/date/test/date_test/time_of_day_milliseconds.pass.cpp +0 -126
  95. package/external/date/test/date_test/time_of_day_minutes.pass.cpp +0 -110
  96. package/external/date/test/date_test/time_of_day_nanoseconds.pass.cpp +0 -126
  97. package/external/date/test/date_test/time_of_day_seconds.pass.cpp +0 -116
  98. package/external/date/test/date_test/weekday.pass.cpp +0 -201
  99. package/external/date/test/date_test/weekday_indexed.pass.cpp +0 -70
  100. package/external/date/test/date_test/weekday_last.pass.cpp +0 -66
  101. package/external/date/test/date_test/weekday_lessthan.fail.cpp +0 -32
  102. package/external/date/test/date_test/weekday_sum.fail.cpp +0 -32
  103. package/external/date/test/date_test/year.pass.cpp +0 -146
  104. package/external/date/test/date_test/year_month.pass.cpp +0 -142
  105. package/external/date/test/date_test/year_month_day.pass.cpp +0 -244
  106. package/external/date/test/date_test/year_month_day_last.pass.cpp +0 -177
  107. package/external/date/test/date_test/year_month_day_m_year_month_day.fail.cpp +0 -33
  108. package/external/date/test/date_test/year_month_day_p_year_month_day.fail.cpp +0 -33
  109. package/external/date/test/date_test/year_month_p_year_month.fail.cpp +0 -33
  110. package/external/date/test/date_test/year_month_weekday.pass.cpp +0 -178
  111. package/external/date/test/date_test/year_month_weekday_last.pass.cpp +0 -169
  112. package/external/date/test/date_test/year_p_year.fail.cpp +0 -32
  113. package/external/date/test/date_test/years_m_year.fail.cpp +0 -32
  114. package/external/date/test/date_test/years_m_year_month.fail.cpp +0 -33
  115. package/external/date/test/date_test/years_m_year_month_day.fail.cpp +0 -33
  116. package/external/date/test/iso_week/last.pass.cpp +0 -34
  117. package/external/date/test/iso_week/lastweek_weekday.pass.cpp +0 -82
  118. package/external/date/test/iso_week/op_div_survey.pass.cpp +0 -196
  119. package/external/date/test/iso_week/weekday.pass.cpp +0 -227
  120. package/external/date/test/iso_week/weekday_lessthan.fail.cpp +0 -32
  121. package/external/date/test/iso_week/weekday_sum.fail.cpp +0 -32
  122. package/external/date/test/iso_week/weeknum.pass.cpp +0 -121
  123. package/external/date/test/iso_week/weeknum_p_weeknum.fail.cpp +0 -32
  124. package/external/date/test/iso_week/weeknum_weekday.pass.cpp +0 -86
  125. package/external/date/test/iso_week/year.pass.cpp +0 -120
  126. package/external/date/test/iso_week/year_lastweek.pass.cpp +0 -97
  127. package/external/date/test/iso_week/year_lastweek_weekday.pass.cpp +0 -129
  128. package/external/date/test/iso_week/year_p_year.fail.cpp +0 -32
  129. package/external/date/test/iso_week/year_weeknum.pass.cpp +0 -97
  130. package/external/date/test/iso_week/year_weeknum_weekday.pass.cpp +0 -139
  131. package/external/date/test/iso_week/years_m_year.fail.cpp +0 -32
  132. package/external/date/test/just.pass.cpp +0 -26
  133. package/external/date/test/testit +0 -177
  134. package/external/date/test/tz_test/OffsetZone.pass.cpp +0 -81
  135. package/external/date/test/tz_test/README.md +0 -22
  136. package/external/date/test/tz_test/tzdata2015e.txt.zip +0 -0
  137. package/external/date/test/tz_test/tzdata2015f.txt.zip +0 -0
  138. package/external/date/test/tz_test/tzdata2016c.txt.zip +0 -0
  139. package/external/date/test/tz_test/tzdata2016d.txt.zip +0 -0
  140. package/external/date/test/tz_test/tzdata2016e.txt.zip +0 -0
  141. package/external/date/test/tz_test/tzdata2016f.txt.zip +0 -0
  142. package/external/date/test/tz_test/validate.cpp +0 -165
  143. package/external/date/test/tz_test/zone.pass.cpp +0 -37
  144. package/external/date/test/tz_test/zoned_time.pass.cpp +0 -464
  145. package/external/date/test_fail.sh +0 -10
  146. package/external/rapidjson/.gitattributes +0 -22
  147. package/external/rapidjson/.gitmodules +0 -3
  148. package/external/rapidjson/.travis.yml +0 -99
  149. package/external/rapidjson/CHANGELOG.md +0 -158
  150. package/external/rapidjson/CMakeLists.txt +0 -221
  151. package/external/rapidjson/CMakeModules/FindGTestSrc.cmake +0 -30
  152. package/external/rapidjson/RapidJSON.pc.in +0 -7
  153. package/external/rapidjson/RapidJSONConfig.cmake.in +0 -15
  154. package/external/rapidjson/RapidJSONConfigVersion.cmake.in +0 -10
  155. package/external/rapidjson/appveyor.yml +0 -54
  156. package/external/rapidjson/bin/data/glossary.json +0 -22
  157. package/external/rapidjson/bin/data/menu.json +0 -27
  158. package/external/rapidjson/bin/data/readme.txt +0 -1
  159. package/external/rapidjson/bin/data/sample.json +0 -3315
  160. package/external/rapidjson/bin/data/webapp.json +0 -88
  161. package/external/rapidjson/bin/data/widget.json +0 -26
  162. package/external/rapidjson/bin/encodings/utf16be.json +0 -0
  163. package/external/rapidjson/bin/encodings/utf16bebom.json +0 -0
  164. package/external/rapidjson/bin/encodings/utf16le.json +0 -0
  165. package/external/rapidjson/bin/encodings/utf16lebom.json +0 -0
  166. package/external/rapidjson/bin/encodings/utf32be.json +0 -0
  167. package/external/rapidjson/bin/encodings/utf32bebom.json +0 -0
  168. package/external/rapidjson/bin/encodings/utf32le.json +0 -0
  169. package/external/rapidjson/bin/encodings/utf32lebom.json +0 -0
  170. package/external/rapidjson/bin/encodings/utf8.json +0 -7
  171. package/external/rapidjson/bin/encodings/utf8bom.json +0 -7
  172. package/external/rapidjson/bin/jsonchecker/fail1.json +0 -1
  173. package/external/rapidjson/bin/jsonchecker/fail10.json +0 -1
  174. package/external/rapidjson/bin/jsonchecker/fail11.json +0 -1
  175. package/external/rapidjson/bin/jsonchecker/fail12.json +0 -1
  176. package/external/rapidjson/bin/jsonchecker/fail13.json +0 -1
  177. package/external/rapidjson/bin/jsonchecker/fail14.json +0 -1
  178. package/external/rapidjson/bin/jsonchecker/fail15.json +0 -1
  179. package/external/rapidjson/bin/jsonchecker/fail16.json +0 -1
  180. package/external/rapidjson/bin/jsonchecker/fail17.json +0 -1
  181. package/external/rapidjson/bin/jsonchecker/fail18.json +0 -1
  182. package/external/rapidjson/bin/jsonchecker/fail19.json +0 -1
  183. package/external/rapidjson/bin/jsonchecker/fail2.json +0 -1
  184. package/external/rapidjson/bin/jsonchecker/fail20.json +0 -1
  185. package/external/rapidjson/bin/jsonchecker/fail21.json +0 -1
  186. package/external/rapidjson/bin/jsonchecker/fail22.json +0 -1
  187. package/external/rapidjson/bin/jsonchecker/fail23.json +0 -1
  188. package/external/rapidjson/bin/jsonchecker/fail24.json +0 -1
  189. package/external/rapidjson/bin/jsonchecker/fail25.json +0 -1
  190. package/external/rapidjson/bin/jsonchecker/fail26.json +0 -1
  191. package/external/rapidjson/bin/jsonchecker/fail27.json +0 -2
  192. package/external/rapidjson/bin/jsonchecker/fail28.json +0 -2
  193. package/external/rapidjson/bin/jsonchecker/fail29.json +0 -1
  194. package/external/rapidjson/bin/jsonchecker/fail3.json +0 -1
  195. package/external/rapidjson/bin/jsonchecker/fail30.json +0 -1
  196. package/external/rapidjson/bin/jsonchecker/fail31.json +0 -1
  197. package/external/rapidjson/bin/jsonchecker/fail32.json +0 -1
  198. package/external/rapidjson/bin/jsonchecker/fail33.json +0 -1
  199. package/external/rapidjson/bin/jsonchecker/fail4.json +0 -1
  200. package/external/rapidjson/bin/jsonchecker/fail5.json +0 -1
  201. package/external/rapidjson/bin/jsonchecker/fail6.json +0 -1
  202. package/external/rapidjson/bin/jsonchecker/fail7.json +0 -1
  203. package/external/rapidjson/bin/jsonchecker/fail8.json +0 -1
  204. package/external/rapidjson/bin/jsonchecker/fail9.json +0 -1
  205. package/external/rapidjson/bin/jsonchecker/pass1.json +0 -58
  206. package/external/rapidjson/bin/jsonchecker/pass2.json +0 -1
  207. package/external/rapidjson/bin/jsonchecker/pass3.json +0 -6
  208. package/external/rapidjson/bin/jsonchecker/readme.txt +0 -3
  209. package/external/rapidjson/bin/types/booleans.json +0 -102
  210. package/external/rapidjson/bin/types/floats.json +0 -102
  211. package/external/rapidjson/bin/types/guids.json +0 -102
  212. package/external/rapidjson/bin/types/integers.json +0 -102
  213. package/external/rapidjson/bin/types/mixed.json +0 -592
  214. package/external/rapidjson/bin/types/nulls.json +0 -102
  215. package/external/rapidjson/bin/types/paragraphs.json +0 -102
  216. package/external/rapidjson/bin/types/readme.txt +0 -1
  217. package/external/rapidjson/contrib/natvis/LICENSE +0 -45
  218. package/external/rapidjson/contrib/natvis/README.md +0 -7
  219. package/external/rapidjson/contrib/natvis/rapidjson.natvis +0 -38
  220. package/external/rapidjson/doc/CMakeLists.txt +0 -27
  221. package/external/rapidjson/doc/Doxyfile.in +0 -2369
  222. package/external/rapidjson/doc/Doxyfile.zh-cn.in +0 -2369
  223. package/external/rapidjson/doc/diagram/architecture.dot +0 -50
  224. package/external/rapidjson/doc/diagram/architecture.png +0 -0
  225. package/external/rapidjson/doc/diagram/insituparsing.dot +0 -65
  226. package/external/rapidjson/doc/diagram/insituparsing.png +0 -0
  227. package/external/rapidjson/doc/diagram/iterative-parser-states-diagram.dot +0 -62
  228. package/external/rapidjson/doc/diagram/iterative-parser-states-diagram.png +0 -0
  229. package/external/rapidjson/doc/diagram/move1.dot +0 -47
  230. package/external/rapidjson/doc/diagram/move1.png +0 -0
  231. package/external/rapidjson/doc/diagram/move2.dot +0 -62
  232. package/external/rapidjson/doc/diagram/move2.png +0 -0
  233. package/external/rapidjson/doc/diagram/move3.dot +0 -60
  234. package/external/rapidjson/doc/diagram/move3.png +0 -0
  235. package/external/rapidjson/doc/diagram/normalparsing.dot +0 -56
  236. package/external/rapidjson/doc/diagram/normalparsing.png +0 -0
  237. package/external/rapidjson/doc/diagram/simpledom.dot +0 -54
  238. package/external/rapidjson/doc/diagram/simpledom.png +0 -0
  239. package/external/rapidjson/doc/diagram/tutorial.dot +0 -58
  240. package/external/rapidjson/doc/diagram/tutorial.png +0 -0
  241. package/external/rapidjson/doc/diagram/utilityclass.dot +0 -73
  242. package/external/rapidjson/doc/diagram/utilityclass.png +0 -0
  243. package/external/rapidjson/doc/dom.md +0 -280
  244. package/external/rapidjson/doc/dom.zh-cn.md +0 -284
  245. package/external/rapidjson/doc/encoding.md +0 -146
  246. package/external/rapidjson/doc/encoding.zh-cn.md +0 -152
  247. package/external/rapidjson/doc/faq.md +0 -289
  248. package/external/rapidjson/doc/faq.zh-cn.md +0 -290
  249. package/external/rapidjson/doc/features.md +0 -104
  250. package/external/rapidjson/doc/features.zh-cn.md +0 -103
  251. package/external/rapidjson/doc/internals.md +0 -368
  252. package/external/rapidjson/doc/internals.zh-cn.md +0 -363
  253. package/external/rapidjson/doc/logo/rapidjson.png +0 -0
  254. package/external/rapidjson/doc/logo/rapidjson.svg +0 -119
  255. package/external/rapidjson/doc/misc/DoxygenLayout.xml +0 -194
  256. package/external/rapidjson/doc/misc/doxygenextra.css +0 -274
  257. package/external/rapidjson/doc/misc/footer.html +0 -11
  258. package/external/rapidjson/doc/misc/header.html +0 -24
  259. package/external/rapidjson/doc/npm.md +0 -31
  260. package/external/rapidjson/doc/performance.md +0 -26
  261. package/external/rapidjson/doc/performance.zh-cn.md +0 -26
  262. package/external/rapidjson/doc/pointer.md +0 -234
  263. package/external/rapidjson/doc/pointer.zh-cn.md +0 -234
  264. package/external/rapidjson/doc/sax.md +0 -509
  265. package/external/rapidjson/doc/sax.zh-cn.md +0 -487
  266. package/external/rapidjson/doc/schema.md +0 -505
  267. package/external/rapidjson/doc/schema.zh-cn.md +0 -237
  268. package/external/rapidjson/doc/stream.md +0 -429
  269. package/external/rapidjson/doc/stream.zh-cn.md +0 -429
  270. package/external/rapidjson/doc/tutorial.md +0 -536
  271. package/external/rapidjson/doc/tutorial.zh-cn.md +0 -535
  272. package/external/rapidjson/docker/debian/Dockerfile +0 -8
  273. package/external/rapidjson/example/CMakeLists.txt +0 -45
  274. package/external/rapidjson/example/archiver/archiver.cpp +0 -292
  275. package/external/rapidjson/example/archiver/archiver.h +0 -145
  276. package/external/rapidjson/example/archiver/archivertest.cpp +0 -287
  277. package/external/rapidjson/example/capitalize/capitalize.cpp +0 -67
  278. package/external/rapidjson/example/condense/condense.cpp +0 -32
  279. package/external/rapidjson/example/filterkey/filterkey.cpp +0 -135
  280. package/external/rapidjson/example/filterkeydom/filterkeydom.cpp +0 -170
  281. package/external/rapidjson/example/jsonx/jsonx.cpp +0 -207
  282. package/external/rapidjson/example/lookaheadparser/lookaheadparser.cpp +0 -350
  283. package/external/rapidjson/example/messagereader/messagereader.cpp +0 -105
  284. package/external/rapidjson/example/parsebyparts/parsebyparts.cpp +0 -176
  285. package/external/rapidjson/example/pretty/pretty.cpp +0 -30
  286. package/external/rapidjson/example/prettyauto/prettyauto.cpp +0 -56
  287. package/external/rapidjson/example/schemavalidator/schemavalidator.cpp +0 -78
  288. package/external/rapidjson/example/serialize/serialize.cpp +0 -173
  289. package/external/rapidjson/example/simpledom/simpledom.cpp +0 -29
  290. package/external/rapidjson/example/simplepullreader/simplepullreader.cpp +0 -53
  291. package/external/rapidjson/example/simplereader/simplereader.cpp +0 -42
  292. package/external/rapidjson/example/simplewriter/simplewriter.cpp +0 -36
  293. package/external/rapidjson/example/tutorial/tutorial.cpp +0 -151
  294. package/external/rapidjson/include/rapidjson/allocators.h +0 -284
  295. package/external/rapidjson/include/rapidjson/cursorstreamwrapper.h +0 -78
  296. package/external/rapidjson/include/rapidjson/document.h +0 -2646
  297. package/external/rapidjson/include/rapidjson/encodedstream.h +0 -299
  298. package/external/rapidjson/include/rapidjson/encodings.h +0 -716
  299. package/external/rapidjson/include/rapidjson/error/en.h +0 -74
  300. package/external/rapidjson/include/rapidjson/error/error.h +0 -161
  301. package/external/rapidjson/include/rapidjson/filereadstream.h +0 -99
  302. package/external/rapidjson/include/rapidjson/filewritestream.h +0 -104
  303. package/external/rapidjson/include/rapidjson/fwd.h +0 -151
  304. package/external/rapidjson/include/rapidjson/internal/biginteger.h +0 -290
  305. package/external/rapidjson/include/rapidjson/internal/diyfp.h +0 -271
  306. package/external/rapidjson/include/rapidjson/internal/dtoa.h +0 -245
  307. package/external/rapidjson/include/rapidjson/internal/ieee754.h +0 -78
  308. package/external/rapidjson/include/rapidjson/internal/itoa.h +0 -308
  309. package/external/rapidjson/include/rapidjson/internal/meta.h +0 -186
  310. package/external/rapidjson/include/rapidjson/internal/pow10.h +0 -55
  311. package/external/rapidjson/include/rapidjson/internal/regex.h +0 -732
  312. package/external/rapidjson/include/rapidjson/internal/stack.h +0 -231
  313. package/external/rapidjson/include/rapidjson/internal/strfunc.h +0 -69
  314. package/external/rapidjson/include/rapidjson/internal/strtod.h +0 -290
  315. package/external/rapidjson/include/rapidjson/internal/swap.h +0 -46
  316. package/external/rapidjson/include/rapidjson/istreamwrapper.h +0 -113
  317. package/external/rapidjson/include/rapidjson/memorybuffer.h +0 -70
  318. package/external/rapidjson/include/rapidjson/memorystream.h +0 -71
  319. package/external/rapidjson/include/rapidjson/msinttypes/inttypes.h +0 -316
  320. package/external/rapidjson/include/rapidjson/msinttypes/stdint.h +0 -300
  321. package/external/rapidjson/include/rapidjson/ostreamwrapper.h +0 -81
  322. package/external/rapidjson/include/rapidjson/pointer.h +0 -1357
  323. package/external/rapidjson/include/rapidjson/prettywriter.h +0 -277
  324. package/external/rapidjson/include/rapidjson/rapidjson.h +0 -654
  325. package/external/rapidjson/include/rapidjson/reader.h +0 -2230
  326. package/external/rapidjson/include/rapidjson/schema.h +0 -2494
  327. package/external/rapidjson/include/rapidjson/stream.h +0 -223
  328. package/external/rapidjson/include/rapidjson/stringbuffer.h +0 -121
  329. package/external/rapidjson/include/rapidjson/writer.h +0 -710
  330. package/external/rapidjson/include_dirs.js +0 -2
  331. package/external/rapidjson/library.json +0 -15
  332. package/external/rapidjson/license.txt +0 -57
  333. package/external/rapidjson/package.json +0 -24
  334. package/external/rapidjson/rapidjson.autopkg +0 -77
  335. package/external/rapidjson/readme.md +0 -160
  336. package/external/rapidjson/readme.zh-cn.md +0 -152
  337. package/external/rapidjson/test/CMakeLists.txt +0 -20
  338. package/external/rapidjson/test/perftest/CMakeLists.txt +0 -28
  339. package/external/rapidjson/test/perftest/misctest.cpp +0 -974
  340. package/external/rapidjson/test/perftest/perftest.cpp +0 -24
  341. package/external/rapidjson/test/perftest/perftest.h +0 -185
  342. package/external/rapidjson/test/perftest/platformtest.cpp +0 -166
  343. package/external/rapidjson/test/perftest/rapidjsontest.cpp +0 -472
  344. package/external/rapidjson/test/perftest/schematest.cpp +0 -223
  345. package/external/rapidjson/test/unittest/CMakeLists.txt +0 -92
  346. package/external/rapidjson/test/unittest/allocatorstest.cpp +0 -100
  347. package/external/rapidjson/test/unittest/bigintegertest.cpp +0 -138
  348. package/external/rapidjson/test/unittest/cursorstreamwrappertest.cpp +0 -115
  349. package/external/rapidjson/test/unittest/documenttest.cpp +0 -672
  350. package/external/rapidjson/test/unittest/dtoatest.cpp +0 -98
  351. package/external/rapidjson/test/unittest/encodedstreamtest.cpp +0 -313
  352. package/external/rapidjson/test/unittest/encodingstest.cpp +0 -451
  353. package/external/rapidjson/test/unittest/filestreamtest.cpp +0 -112
  354. package/external/rapidjson/test/unittest/fwdtest.cpp +0 -230
  355. package/external/rapidjson/test/unittest/istreamwrappertest.cpp +0 -181
  356. package/external/rapidjson/test/unittest/itoatest.cpp +0 -160
  357. package/external/rapidjson/test/unittest/jsoncheckertest.cpp +0 -143
  358. package/external/rapidjson/test/unittest/namespacetest.cpp +0 -70
  359. package/external/rapidjson/test/unittest/ostreamwrappertest.cpp +0 -92
  360. package/external/rapidjson/test/unittest/pointertest.cpp +0 -1529
  361. package/external/rapidjson/test/unittest/prettywritertest.cpp +0 -373
  362. package/external/rapidjson/test/unittest/readertest.cpp +0 -2190
  363. package/external/rapidjson/test/unittest/regextest.cpp +0 -638
  364. package/external/rapidjson/test/unittest/schematest.cpp +0 -2072
  365. package/external/rapidjson/test/unittest/simdtest.cpp +0 -219
  366. package/external/rapidjson/test/unittest/strfunctest.cpp +0 -30
  367. package/external/rapidjson/test/unittest/stringbuffertest.cpp +0 -192
  368. package/external/rapidjson/test/unittest/strtodtest.cpp +0 -132
  369. package/external/rapidjson/test/unittest/unittest.cpp +0 -51
  370. package/external/rapidjson/test/unittest/unittest.h +0 -140
  371. package/external/rapidjson/test/unittest/valuetest.cpp +0 -1851
  372. package/external/rapidjson/test/unittest/writertest.cpp +0 -598
  373. package/external/rapidjson/test/valgrind.supp +0 -17
  374. package/external/rapidjson/thirdparty/gtest/.travis.yml +0 -81
  375. package/external/rapidjson/thirdparty/gtest/BUILD.bazel +0 -175
  376. package/external/rapidjson/thirdparty/gtest/CMakeLists.txt +0 -33
  377. package/external/rapidjson/thirdparty/gtest/CONTRIBUTING.md +0 -160
  378. package/external/rapidjson/thirdparty/gtest/LICENSE +0 -28
  379. package/external/rapidjson/thirdparty/gtest/Makefile.am +0 -14
  380. package/external/rapidjson/thirdparty/gtest/README.md +0 -122
  381. package/external/rapidjson/thirdparty/gtest/WORKSPACE +0 -8
  382. package/external/rapidjson/thirdparty/gtest/appveyor.yml +0 -104
  383. package/external/rapidjson/thirdparty/gtest/ci/build-linux-autotools.sh +0 -44
  384. package/external/rapidjson/thirdparty/gtest/ci/build-linux-bazel.sh +0 -36
  385. package/external/rapidjson/thirdparty/gtest/ci/env-linux.sh +0 -41
  386. package/external/rapidjson/thirdparty/gtest/ci/env-osx.sh +0 -40
  387. package/external/rapidjson/thirdparty/gtest/ci/get-nprocessors.sh +0 -48
  388. package/external/rapidjson/thirdparty/gtest/ci/install-linux.sh +0 -49
  389. package/external/rapidjson/thirdparty/gtest/ci/install-osx.sh +0 -39
  390. package/external/rapidjson/thirdparty/gtest/ci/log-config.sh +0 -51
  391. package/external/rapidjson/thirdparty/gtest/ci/travis.sh +0 -44
  392. package/external/rapidjson/thirdparty/gtest/configure.ac +0 -16
  393. package/external/rapidjson/thirdparty/gtest/googlemock/CHANGES +0 -126
  394. package/external/rapidjson/thirdparty/gtest/googlemock/CMakeLists.txt +0 -242
  395. package/external/rapidjson/thirdparty/gtest/googlemock/CONTRIBUTORS +0 -40
  396. package/external/rapidjson/thirdparty/gtest/googlemock/LICENSE +0 -28
  397. package/external/rapidjson/thirdparty/gtest/googlemock/Makefile.am +0 -224
  398. package/external/rapidjson/thirdparty/gtest/googlemock/README.md +0 -344
  399. package/external/rapidjson/thirdparty/gtest/googlemock/build-aux/.keep +0 -0
  400. package/external/rapidjson/thirdparty/gtest/googlemock/cmake/gmock.pc.in +0 -9
  401. package/external/rapidjson/thirdparty/gtest/googlemock/cmake/gmock_main.pc.in +0 -9
  402. package/external/rapidjson/thirdparty/gtest/googlemock/configure.ac +0 -146
  403. package/external/rapidjson/thirdparty/gtest/googlemock/docs/CheatSheet.md +0 -564
  404. package/external/rapidjson/thirdparty/gtest/googlemock/docs/CookBook.md +0 -3660
  405. package/external/rapidjson/thirdparty/gtest/googlemock/docs/DesignDoc.md +0 -280
  406. package/external/rapidjson/thirdparty/gtest/googlemock/docs/Documentation.md +0 -15
  407. package/external/rapidjson/thirdparty/gtest/googlemock/docs/ForDummies.md +0 -447
  408. package/external/rapidjson/thirdparty/gtest/googlemock/docs/FrequentlyAskedQuestions.md +0 -627
  409. package/external/rapidjson/thirdparty/gtest/googlemock/docs/KnownIssues.md +0 -19
  410. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/gmock-actions.h +0 -1262
  411. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/gmock-cardinalities.h +0 -147
  412. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/gmock-generated-actions.h +0 -2571
  413. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/gmock-generated-actions.h.pump +0 -833
  414. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/gmock-generated-function-mockers.h +0 -1379
  415. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/gmock-generated-function-mockers.h.pump +0 -347
  416. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/gmock-generated-matchers.h +0 -2258
  417. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/gmock-generated-matchers.h.pump +0 -675
  418. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/gmock-generated-nice-strict.h +0 -458
  419. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/gmock-generated-nice-strict.h.pump +0 -178
  420. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/gmock-matchers.h +0 -5255
  421. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/gmock-more-actions.h +0 -246
  422. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/gmock-more-matchers.h +0 -91
  423. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/gmock-spec-builders.h +0 -1918
  424. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/gmock.h +0 -95
  425. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h +0 -8
  426. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump +0 -10
  427. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/internal/custom/gmock-matchers.h +0 -38
  428. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/internal/custom/gmock-port.h +0 -46
  429. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h +0 -286
  430. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h.pump +0 -136
  431. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/internal/gmock-internal-utils.h +0 -574
  432. package/external/rapidjson/thirdparty/gtest/googlemock/include/gmock/internal/gmock-port.h +0 -87
  433. package/external/rapidjson/thirdparty/gtest/googlemock/msvc/2005/gmock.sln +0 -32
  434. package/external/rapidjson/thirdparty/gtest/googlemock/msvc/2005/gmock.vcproj +0 -191
  435. package/external/rapidjson/thirdparty/gtest/googlemock/msvc/2005/gmock_config.vsprops +0 -15
  436. package/external/rapidjson/thirdparty/gtest/googlemock/msvc/2005/gmock_main.vcproj +0 -187
  437. package/external/rapidjson/thirdparty/gtest/googlemock/msvc/2005/gmock_test.vcproj +0 -201
  438. package/external/rapidjson/thirdparty/gtest/googlemock/msvc/2010/gmock.sln +0 -46
  439. package/external/rapidjson/thirdparty/gtest/googlemock/msvc/2010/gmock.vcxproj +0 -145
  440. package/external/rapidjson/thirdparty/gtest/googlemock/msvc/2010/gmock_config.props +0 -19
  441. package/external/rapidjson/thirdparty/gtest/googlemock/msvc/2010/gmock_main.vcxproj +0 -151
  442. package/external/rapidjson/thirdparty/gtest/googlemock/msvc/2010/gmock_test.vcxproj +0 -176
  443. package/external/rapidjson/thirdparty/gtest/googlemock/msvc/2015/gmock.sln +0 -46
  444. package/external/rapidjson/thirdparty/gtest/googlemock/msvc/2015/gmock.vcxproj +0 -145
  445. package/external/rapidjson/thirdparty/gtest/googlemock/msvc/2015/gmock_config.props +0 -19
  446. package/external/rapidjson/thirdparty/gtest/googlemock/msvc/2015/gmock_main.vcxproj +0 -151
  447. package/external/rapidjson/thirdparty/gtest/googlemock/msvc/2015/gmock_test.vcxproj +0 -176
  448. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/fuse_gmock_files.py +0 -240
  449. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/generator/LICENSE +0 -203
  450. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/generator/README +0 -34
  451. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/generator/README.cppclean +0 -115
  452. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/generator/cpp/__init__.py +0 -0
  453. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/generator/cpp/ast.py +0 -1733
  454. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/generator/cpp/gmock_class.py +0 -227
  455. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/generator/cpp/gmock_class_test.py +0 -448
  456. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/generator/cpp/keywords.py +0 -59
  457. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/generator/cpp/tokenize.py +0 -287
  458. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/generator/cpp/utils.py +0 -41
  459. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/generator/gmock_gen.py +0 -31
  460. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/gmock-config.in +0 -303
  461. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/gmock_doctor.py +0 -640
  462. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/upload.py +0 -1387
  463. package/external/rapidjson/thirdparty/gtest/googlemock/scripts/upload_gmock.py +0 -78
  464. package/external/rapidjson/thirdparty/gtest/googlemock/src/gmock-all.cc +0 -47
  465. package/external/rapidjson/thirdparty/gtest/googlemock/src/gmock-cardinalities.cc +0 -156
  466. package/external/rapidjson/thirdparty/gtest/googlemock/src/gmock-internal-utils.cc +0 -204
  467. package/external/rapidjson/thirdparty/gtest/googlemock/src/gmock-matchers.cc +0 -573
  468. package/external/rapidjson/thirdparty/gtest/googlemock/src/gmock-spec-builders.cc +0 -883
  469. package/external/rapidjson/thirdparty/gtest/googlemock/src/gmock.cc +0 -205
  470. package/external/rapidjson/thirdparty/gtest/googlemock/src/gmock_main.cc +0 -54
  471. package/external/rapidjson/thirdparty/gtest/googlemock/test/BUILD.bazel +0 -123
  472. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock-actions_test.cc +0 -1575
  473. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock-cardinalities_test.cc +0 -428
  474. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock-generated-actions_test.cc +0 -1230
  475. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock-generated-function-mockers_test.cc +0 -647
  476. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock-generated-internal-utils_test.cc +0 -129
  477. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock-generated-matchers_test.cc +0 -1341
  478. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock-internal-utils_test.cc +0 -718
  479. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock-matchers_test.cc +0 -6767
  480. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock-more-actions_test.cc +0 -710
  481. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock-nice-strict_test.cc +0 -511
  482. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock-port_test.cc +0 -43
  483. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock-spec-builders_test.cc +0 -2771
  484. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock_all_test.cc +0 -51
  485. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock_ex_test.cc +0 -81
  486. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock_leak_test.py +0 -108
  487. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock_leak_test_.cc +0 -100
  488. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock_link2_test.cc +0 -40
  489. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock_link_test.cc +0 -40
  490. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock_link_test.h +0 -691
  491. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock_output_test.py +0 -183
  492. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock_output_test_.cc +0 -310
  493. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock_output_test_golden.txt +0 -317
  494. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock_stress_test.cc +0 -323
  495. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock_test.cc +0 -262
  496. package/external/rapidjson/thirdparty/gtest/googlemock/test/gmock_test_utils.py +0 -110
  497. package/external/rapidjson/thirdparty/gtest/googletest/CHANGES +0 -157
  498. package/external/rapidjson/thirdparty/gtest/googletest/CMakeLists.txt +0 -312
  499. package/external/rapidjson/thirdparty/gtest/googletest/CONTRIBUTORS +0 -37
  500. package/external/rapidjson/thirdparty/gtest/googletest/LICENSE +0 -28
  501. package/external/rapidjson/thirdparty/gtest/googletest/Makefile.am +0 -339
  502. package/external/rapidjson/thirdparty/gtest/googletest/README.md +0 -341
  503. package/external/rapidjson/thirdparty/gtest/googletest/cmake/gtest.pc.in +0 -9
  504. package/external/rapidjson/thirdparty/gtest/googletest/cmake/gtest_main.pc.in +0 -10
  505. package/external/rapidjson/thirdparty/gtest/googletest/cmake/internal_utils.cmake +0 -280
  506. package/external/rapidjson/thirdparty/gtest/googletest/codegear/gtest.cbproj +0 -138
  507. package/external/rapidjson/thirdparty/gtest/googletest/codegear/gtest.groupproj +0 -54
  508. package/external/rapidjson/thirdparty/gtest/googletest/codegear/gtest_all.cc +0 -38
  509. package/external/rapidjson/thirdparty/gtest/googletest/codegear/gtest_link.cc +0 -40
  510. package/external/rapidjson/thirdparty/gtest/googletest/codegear/gtest_main.cbproj +0 -82
  511. package/external/rapidjson/thirdparty/gtest/googletest/codegear/gtest_unittest.cbproj +0 -88
  512. package/external/rapidjson/thirdparty/gtest/googletest/configure.ac +0 -68
  513. package/external/rapidjson/thirdparty/gtest/googletest/docs/Pkgconfig.md +0 -146
  514. package/external/rapidjson/thirdparty/gtest/googletest/docs/PumpManual.md +0 -177
  515. package/external/rapidjson/thirdparty/gtest/googletest/docs/XcodeGuide.md +0 -93
  516. package/external/rapidjson/thirdparty/gtest/googletest/docs/advanced.md +0 -2416
  517. package/external/rapidjson/thirdparty/gtest/googletest/docs/faq.md +0 -1092
  518. package/external/rapidjson/thirdparty/gtest/googletest/docs/primer.md +0 -536
  519. package/external/rapidjson/thirdparty/gtest/googletest/docs/samples.md +0 -14
  520. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/gtest-death-test.h +0 -342
  521. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/gtest-message.h +0 -249
  522. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/gtest-param-test.h +0 -1438
  523. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/gtest-param-test.h.pump +0 -501
  524. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/gtest-printers.h +0 -1082
  525. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/gtest-spi.h +0 -231
  526. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/gtest-test-part.h +0 -179
  527. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/gtest-typed-test.h +0 -264
  528. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/gtest.h +0 -2332
  529. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/gtest_pred_impl.h +0 -357
  530. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/gtest_prod.h +0 -61
  531. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/custom/gtest-port.h +0 -70
  532. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/custom/gtest-printers.h +0 -42
  533. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/custom/gtest.h +0 -45
  534. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/gtest-death-test-internal.h +0 -275
  535. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/gtest-filepath.h +0 -205
  536. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/gtest-internal.h +0 -1277
  537. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/gtest-linked_ptr.h +0 -243
  538. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/gtest-param-util-generated.h +0 -5139
  539. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/gtest-param-util-generated.h.pump +0 -279
  540. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/gtest-param-util.h +0 -723
  541. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/gtest-port-arch.h +0 -100
  542. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/gtest-port.h +0 -2687
  543. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/gtest-string.h +0 -167
  544. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/gtest-tuple.h +0 -1020
  545. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/gtest-tuple.h.pump +0 -347
  546. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/gtest-type-util.h +0 -3347
  547. package/external/rapidjson/thirdparty/gtest/googletest/include/gtest/internal/gtest-type-util.h.pump +0 -313
  548. package/external/rapidjson/thirdparty/gtest/googletest/m4/acx_pthread.m4 +0 -363
  549. package/external/rapidjson/thirdparty/gtest/googletest/m4/gtest.m4 +0 -74
  550. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest-md.sln +0 -55
  551. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest-md.vcxproj +0 -149
  552. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest-md.vcxproj.filters +0 -18
  553. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest.sln +0 -55
  554. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest.vcxproj +0 -149
  555. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest.vcxproj.filters +0 -18
  556. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest_main-md.vcxproj +0 -154
  557. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest_main-md.vcxproj.filters +0 -18
  558. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest_main.vcxproj +0 -162
  559. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest_main.vcxproj.filters +0 -18
  560. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest_prod_test-md.vcxproj +0 -199
  561. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest_prod_test-md.vcxproj.filters +0 -26
  562. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest_prod_test.vcxproj +0 -191
  563. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest_prod_test.vcxproj.filters +0 -26
  564. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest_unittest-md.vcxproj +0 -188
  565. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest_unittest-md.vcxproj.filters +0 -18
  566. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest_unittest.vcxproj +0 -180
  567. package/external/rapidjson/thirdparty/gtest/googletest/msvc/2010/gtest_unittest.vcxproj.filters +0 -18
  568. package/external/rapidjson/thirdparty/gtest/googletest/samples/prime_tables.h +0 -127
  569. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample1.cc +0 -68
  570. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample1.h +0 -43
  571. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample10_unittest.cc +0 -140
  572. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample1_unittest.cc +0 -154
  573. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample2.cc +0 -56
  574. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample2.h +0 -85
  575. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample2_unittest.cc +0 -110
  576. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample3-inl.h +0 -172
  577. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample3_unittest.cc +0 -152
  578. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample4.cc +0 -46
  579. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample4.h +0 -53
  580. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample4_unittest.cc +0 -49
  581. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample5_unittest.cc +0 -199
  582. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample6_unittest.cc +0 -225
  583. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample7_unittest.cc +0 -118
  584. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample8_unittest.cc +0 -174
  585. package/external/rapidjson/thirdparty/gtest/googletest/samples/sample9_unittest.cc +0 -157
  586. package/external/rapidjson/thirdparty/gtest/googletest/scripts/common.py +0 -83
  587. package/external/rapidjson/thirdparty/gtest/googletest/scripts/fuse_gtest_files.py +0 -253
  588. package/external/rapidjson/thirdparty/gtest/googletest/scripts/gen_gtest_pred_impl.py +0 -730
  589. package/external/rapidjson/thirdparty/gtest/googletest/scripts/gtest-config.in +0 -274
  590. package/external/rapidjson/thirdparty/gtest/googletest/scripts/pump.py +0 -855
  591. package/external/rapidjson/thirdparty/gtest/googletest/scripts/release_docs.py +0 -158
  592. package/external/rapidjson/thirdparty/gtest/googletest/scripts/upload.py +0 -1387
  593. package/external/rapidjson/thirdparty/gtest/googletest/scripts/upload_gtest.py +0 -78
  594. package/external/rapidjson/thirdparty/gtest/googletest/src/gtest-all.cc +0 -48
  595. package/external/rapidjson/thirdparty/gtest/googletest/src/gtest-death-test.cc +0 -1536
  596. package/external/rapidjson/thirdparty/gtest/googletest/src/gtest-filepath.cc +0 -385
  597. package/external/rapidjson/thirdparty/gtest/googletest/src/gtest-internal-inl.h +0 -1175
  598. package/external/rapidjson/thirdparty/gtest/googletest/src/gtest-port.cc +0 -1277
  599. package/external/rapidjson/thirdparty/gtest/googletest/src/gtest-printers.cc +0 -458
  600. package/external/rapidjson/thirdparty/gtest/googletest/src/gtest-test-part.cc +0 -102
  601. package/external/rapidjson/thirdparty/gtest/googletest/src/gtest-typed-test.cc +0 -119
  602. package/external/rapidjson/thirdparty/gtest/googletest/src/gtest.cc +0 -5846
  603. package/external/rapidjson/thirdparty/gtest/googletest/src/gtest_main.cc +0 -38
  604. package/external/rapidjson/thirdparty/gtest/googletest/test/BUILD.bazel +0 -396
  605. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-death-test_ex_test.cc +0 -93
  606. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-death-test_test.cc +0 -1424
  607. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-filepath_test.cc +0 -652
  608. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-linked_ptr_test.cc +0 -154
  609. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-listener_test.cc +0 -311
  610. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-message_test.cc +0 -159
  611. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-options_test.cc +0 -213
  612. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-param-test2_test.cc +0 -61
  613. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-param-test_test.cc +0 -1110
  614. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-param-test_test.h +0 -53
  615. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-port_test.cc +0 -1303
  616. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-printers_test.cc +0 -1737
  617. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-test-part_test.cc +0 -208
  618. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-tuple_test.cc +0 -320
  619. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-typed-test2_test.cc +0 -45
  620. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-typed-test_test.cc +0 -380
  621. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-typed-test_test.h +0 -66
  622. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest-unittest-api_test.cc +0 -341
  623. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_all_test.cc +0 -47
  624. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_assert_by_exception_test.cc +0 -119
  625. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_break_on_failure_unittest.py +0 -210
  626. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_break_on_failure_unittest_.cc +0 -87
  627. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_catch_exceptions_test.py +0 -235
  628. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_catch_exceptions_test_.cc +0 -311
  629. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_color_test.py +0 -129
  630. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_color_test_.cc +0 -63
  631. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_env_var_test.py +0 -119
  632. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_env_var_test_.cc +0 -124
  633. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_environment_test.cc +0 -189
  634. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_filter_unittest.py +0 -638
  635. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_filter_unittest_.cc +0 -138
  636. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_help_test.py +0 -172
  637. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_help_test_.cc +0 -46
  638. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_json_outfiles_test.py +0 -162
  639. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_json_output_unittest.py +0 -611
  640. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_json_test_utils.py +0 -60
  641. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_list_tests_unittest.py +0 -207
  642. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_list_tests_unittest_.cc +0 -157
  643. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_main_unittest.cc +0 -45
  644. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_no_test_unittest.cc +0 -56
  645. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_output_test.py +0 -344
  646. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_output_test_.cc +0 -1067
  647. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_output_test_golden_lin.txt +0 -781
  648. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_pred_impl_unittest.cc +0 -2427
  649. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_premature_exit_test.cc +0 -127
  650. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_prod_test.cc +0 -57
  651. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_repeat_test.cc +0 -236
  652. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_shuffle_test.py +0 -325
  653. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_shuffle_test_.cc +0 -103
  654. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_sole_header_test.cc +0 -57
  655. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_stress_test.cc +0 -250
  656. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_test_utils.py +0 -318
  657. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_testbridge_test.py +0 -65
  658. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_testbridge_test_.cc +0 -44
  659. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_throw_on_failure_ex_test.cc +0 -92
  660. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_throw_on_failure_test.py +0 -171
  661. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_throw_on_failure_test_.cc +0 -72
  662. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_uninitialized_test.py +0 -69
  663. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_uninitialized_test_.cc +0 -43
  664. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_unittest.cc +0 -7797
  665. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_xml_outfile1_test_.cc +0 -48
  666. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_xml_outfile2_test_.cc +0 -48
  667. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_xml_outfiles_test.py +0 -140
  668. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_xml_output_unittest.py +0 -378
  669. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_xml_output_unittest_.cc +0 -179
  670. package/external/rapidjson/thirdparty/gtest/googletest/test/gtest_xml_test_utils.py +0 -196
  671. package/external/rapidjson/thirdparty/gtest/googletest/test/production.cc +0 -36
  672. package/external/rapidjson/thirdparty/gtest/googletest/test/production.h +0 -55
  673. package/external/rapidjson/thirdparty/gtest/googletest/xcode/Config/DebugProject.xcconfig +0 -30
  674. package/external/rapidjson/thirdparty/gtest/googletest/xcode/Config/FrameworkTarget.xcconfig +0 -17
  675. package/external/rapidjson/thirdparty/gtest/googletest/xcode/Config/General.xcconfig +0 -41
  676. package/external/rapidjson/thirdparty/gtest/googletest/xcode/Config/ReleaseProject.xcconfig +0 -32
  677. package/external/rapidjson/thirdparty/gtest/googletest/xcode/Config/StaticLibraryTarget.xcconfig +0 -18
  678. package/external/rapidjson/thirdparty/gtest/googletest/xcode/Config/TestTarget.xcconfig +0 -8
  679. package/external/rapidjson/thirdparty/gtest/googletest/xcode/Resources/Info.plist +0 -30
  680. package/external/rapidjson/thirdparty/gtest/googletest/xcode/Samples/FrameworkSample/Info.plist +0 -28
  681. package/external/rapidjson/thirdparty/gtest/googletest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj +0 -457
  682. package/external/rapidjson/thirdparty/gtest/googletest/xcode/Samples/FrameworkSample/runtests.sh +0 -62
  683. package/external/rapidjson/thirdparty/gtest/googletest/xcode/Samples/FrameworkSample/widget.cc +0 -63
  684. package/external/rapidjson/thirdparty/gtest/googletest/xcode/Samples/FrameworkSample/widget.h +0 -59
  685. package/external/rapidjson/thirdparty/gtest/googletest/xcode/Samples/FrameworkSample/widget_test.cc +0 -68
  686. package/external/rapidjson/thirdparty/gtest/googletest/xcode/Scripts/runtests.sh +0 -65
  687. package/external/rapidjson/thirdparty/gtest/googletest/xcode/Scripts/versiongenerate.py +0 -100
  688. package/external/rapidjson/thirdparty/gtest/googletest/xcode/gtest.xcodeproj/project.pbxproj +0 -1182
  689. package/external/rapidjson/travis-doxygen.sh +0 -121
  690. package/include/.clang-format +0 -76
  691. package/include/eosio/abi.hpp +0 -286
  692. package/include/eosio/asset.hpp +0 -458
  693. package/include/eosio/bytes.hpp +0 -27
  694. package/include/eosio/chain_conversions.hpp +0 -450
  695. package/include/eosio/chain_types.hpp +0 -14
  696. package/include/eosio/check.hpp +0 -178
  697. package/include/eosio/convert.hpp +0 -95
  698. package/include/eosio/crypto.hpp +0 -147
  699. package/include/eosio/eosio_outcome.hpp +0 -41
  700. package/include/eosio/fixed_bytes.hpp +0 -246
  701. package/include/eosio/float.hpp +0 -35
  702. package/include/eosio/for_each_field.hpp +0 -48
  703. package/include/eosio/fpconv.c +0 -336
  704. package/include/eosio/fpconv.h +0 -41
  705. package/include/eosio/fpconv.license +0 -23
  706. package/include/eosio/from_bin.hpp +0 -272
  707. package/include/eosio/from_json.hpp +0 -737
  708. package/include/eosio/from_string.hpp +0 -28
  709. package/include/eosio/map_macro.h +0 -64
  710. package/include/eosio/murmur.hpp +0 -55
  711. package/include/eosio/name.hpp +0 -174
  712. package/include/eosio/opaque.hpp +0 -108
  713. package/include/eosio/operators.hpp +0 -71
  714. package/include/eosio/powers.h +0 -76
  715. package/include/eosio/reflection.hpp +0 -61
  716. package/include/eosio/ship_protocol.hpp +0 -850
  717. package/include/eosio/stream.hpp +0 -231
  718. package/include/eosio/symbol.hpp +0 -300
  719. package/include/eosio/time.hpp +0 -264
  720. package/include/eosio/to_bin.hpp +0 -189
  721. package/include/eosio/to_json.hpp +0 -279
  722. package/include/eosio/to_key.hpp +0 -298
  723. package/include/eosio/types.hpp +0 -97
  724. package/include/eosio/varint.hpp +0 -452
  725. package/include/outcome-basic.hpp +0 -6836
  726. package/src/abi.cpp +0 -297
  727. package/src/abieos.cpp +0 -263
  728. package/src/abieos.h +0 -76
  729. package/src/abieos.hpp +0 -1010
  730. package/src/abieos_exception.hpp +0 -89
  731. package/src/abieos_numeric.hpp +0 -94
  732. package/src/abieos_ripemd160.hpp +0 -417
  733. package/src/crypto.cpp +0 -215
  734. package/src/key_test.cpp +0 -218
  735. package/src/main.cpp +0 -242
  736. package/src/reflect_test.cpp +0 -28
  737. package/src/template_test.cpp +0 -240
  738. package/src/test.cpp +0 -940
  739. package/tools/CMakeLists.txt +0 -9
  740. package/tools/name.cpp +0 -86
@@ -1,3801 +0,0 @@
1
- // The MIT License (MIT)
2
- //
3
- // Copyright (c) 2015, 2016, 2017 Howard Hinnant
4
- // Copyright (c) 2015 Ville Voutilainen
5
- // Copyright (c) 2016 Alexander Kormanovsky
6
- // Copyright (c) 2016, 2017 Jiangang Zhuang
7
- // Copyright (c) 2017 Nicolas Veloz Savino
8
- // Copyright (c) 2017 Florian Dang
9
- // Copyright (c) 2017 Aaron Bishop
10
- //
11
- // Permission is hereby granted, free of charge, to any person obtaining a copy
12
- // of this software and associated documentation files (the "Software"), to deal
13
- // in the Software without restriction, including without limitation the rights
14
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
- // copies of the Software, and to permit persons to whom the Software is
16
- // furnished to do so, subject to the following conditions:
17
- //
18
- // The above copyright notice and this permission notice shall be included in all
19
- // copies or substantial portions of the Software.
20
- //
21
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
- // SOFTWARE.
28
- //
29
- // Our apologies. When the previous paragraph was written, lowercase had not yet
30
- // been invented (that would involve another several millennia of evolution).
31
- // We did not mean to shout.
32
-
33
- #ifdef _WIN32
34
- // windows.h will be included directly and indirectly (e.g. by curl).
35
- // We need to define these macros to prevent windows.h bringing in
36
- // more than we need and do it early so windows.h doesn't get included
37
- // without these macros having been defined.
38
- // min/max macros interfere with the C++ versions.
39
- # ifndef NOMINMAX
40
- # define NOMINMAX
41
- # endif
42
- // We don't need all that Windows has to offer.
43
- # ifndef WIN32_LEAN_AND_MEAN
44
- # define WIN32_LEAN_AND_MEAN
45
- # endif
46
-
47
- // for wcstombs
48
- # ifndef _CRT_SECURE_NO_WARNINGS
49
- # define _CRT_SECURE_NO_WARNINGS
50
- # endif
51
-
52
- // None of this happens with the MS SDK (at least VS14 which I tested), but:
53
- // Compiling with mingw, we get "error: 'KF_FLAG_DEFAULT' was not declared in this scope."
54
- // and error: 'SHGetKnownFolderPath' was not declared in this scope.".
55
- // It seems when using mingw NTDDI_VERSION is undefined and that
56
- // causes KNOWN_FOLDER_FLAG and the KF_ flags to not get defined.
57
- // So we must define NTDDI_VERSION to get those flags on mingw.
58
- // The docs say though here:
59
- // https://msdn.microsoft.com/en-nz/library/windows/desktop/aa383745(v=vs.85).aspx
60
- // that "If you define NTDDI_VERSION, you must also define _WIN32_WINNT."
61
- // So we declare we require Vista or greater.
62
- # ifdef __MINGW32__
63
-
64
- # ifndef NTDDI_VERSION
65
- # define NTDDI_VERSION 0x06000000
66
- # define _WIN32_WINNT _WIN32_WINNT_VISTA
67
- # elif NTDDI_VERSION < 0x06000000
68
- # warning "If this fails to compile NTDDI_VERSION may be to low. See comments above."
69
- # endif
70
- // But once we define the values above we then get this linker error:
71
- // "tz.cpp:(.rdata$.refptr.FOLDERID_Downloads[.refptr.FOLDERID_Downloads]+0x0): "
72
- // "undefined reference to `FOLDERID_Downloads'"
73
- // which #include <initguid.h> cures see:
74
- // https://support.microsoft.com/en-us/kb/130869
75
- # include <initguid.h>
76
- // But with <initguid.h> included, the error moves on to:
77
- // error: 'FOLDERID_Downloads' was not declared in this scope
78
- // Which #include <knownfolders.h> cures.
79
- # include <knownfolders.h>
80
-
81
- # endif // __MINGW32__
82
-
83
- # include <windows.h>
84
- #endif // _WIN32
85
-
86
- #include "date/tz_private.h"
87
-
88
- #ifdef __APPLE__
89
- # include "date/ios.h"
90
- #else
91
- # define TARGET_OS_IPHONE 0
92
- #endif
93
-
94
- #if USE_OS_TZDB
95
- # include <dirent.h>
96
- #endif
97
- #include <algorithm>
98
- #include <cctype>
99
- #include <cstdlib>
100
- #include <cstring>
101
- #include <exception>
102
- #include <fstream>
103
- #include <iostream>
104
- #include <iterator>
105
- #include <memory>
106
- #if USE_OS_TZDB
107
- # include <queue>
108
- #endif
109
- #include <sstream>
110
- #include <string>
111
- #include <tuple>
112
- #include <vector>
113
- #include <sys/stat.h>
114
-
115
- // unistd.h is used on some platforms as part of the the means to get
116
- // the current time zone. On Win32 windows.h provides a means to do it.
117
- // gcc/mingw supports unistd.h on Win32 but MSVC does not.
118
-
119
- #ifdef _WIN32
120
- # ifdef WINAPI_FAMILY
121
- # include <winapifamily.h>
122
- # if WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP
123
- # define WINRT
124
- # define INSTALL .
125
- # endif
126
- # endif
127
-
128
- # include <io.h> // _unlink etc.
129
-
130
- # if defined(__clang__)
131
- struct IUnknown; // fix for issue with static_cast<> in objbase.h
132
- // (see https://github.com/philsquared/Catch/issues/690)
133
- # endif
134
-
135
- # include <shlobj.h> // CoTaskFree, ShGetKnownFolderPath etc.
136
- # if HAS_REMOTE_API
137
- # include <direct.h> // _mkdir
138
- # include <shellapi.h> // ShFileOperation etc.
139
- # endif // HAS_REMOTE_API
140
- #else // !_WIN32
141
- # include <unistd.h>
142
- # if !USE_OS_TZDB
143
- # include <wordexp.h>
144
- # endif
145
- # include <limits.h>
146
- # include <string.h>
147
- # if !USE_SHELL_API
148
- # include <sys/stat.h>
149
- # include <sys/fcntl.h>
150
- # include <dirent.h>
151
- # include <cstring>
152
- # include <sys/wait.h>
153
- # include <sys/types.h>
154
- # endif //!USE_SHELL_API
155
- #endif // !_WIN32
156
-
157
-
158
- #if HAS_REMOTE_API
159
- // Note curl includes windows.h so we must include curl AFTER definitions of things
160
- // that affect windows.h such as NOMINMAX.
161
- #if defined(_MSC_VER) && defined(SHORTENED_CURL_INCLUDE)
162
- // For rmt_curl nuget package
163
- # include <curl.h>
164
- #else
165
- # include <curl/curl.h>
166
- #endif
167
- #endif
168
-
169
- #ifdef _WIN32
170
- static CONSTDATA char folder_delimiter = '\\';
171
- #else // !_WIN32
172
- static CONSTDATA char folder_delimiter = '/';
173
- #endif // !_WIN32
174
-
175
- #if defined(__GNUC__) && __GNUC__ < 5
176
- // GCC 4.9 Bug 61489 Wrong warning with -Wmissing-field-initializers
177
- # pragma GCC diagnostic push
178
- # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
179
- #endif // defined(__GNUC__) && __GNUC__ < 5
180
-
181
- #if !USE_OS_TZDB
182
-
183
- # ifdef _WIN32
184
- # ifndef WINRT
185
-
186
- namespace
187
- {
188
- struct task_mem_deleter
189
- {
190
- void operator()(wchar_t buf[])
191
- {
192
- if (buf != nullptr)
193
- CoTaskMemFree(buf);
194
- }
195
- };
196
- using co_task_mem_ptr = std::unique_ptr<wchar_t[], task_mem_deleter>;
197
- }
198
-
199
- // We might need to know certain locations even if not using the remote API,
200
- // so keep these routines out of that block for now.
201
- static
202
- std::string
203
- get_known_folder(const GUID& folderid)
204
- {
205
- std::string folder;
206
- PWSTR pfolder = nullptr;
207
- HRESULT hr = SHGetKnownFolderPath(folderid, KF_FLAG_DEFAULT, nullptr, &pfolder);
208
- if (SUCCEEDED(hr))
209
- {
210
- co_task_mem_ptr folder_ptr(pfolder);
211
- folder = std::string(folder_ptr.get(), folder_ptr.get() + wcslen(folder_ptr.get()));
212
- }
213
- return folder;
214
- }
215
-
216
- // Usually something like "c:\Users\username\Downloads".
217
- static
218
- std::string
219
- get_download_folder()
220
- {
221
- return get_known_folder(FOLDERID_Downloads);
222
- }
223
-
224
- # endif // WINRT
225
- # else // !_WIN32
226
-
227
- # if !defined(INSTALL) || HAS_REMOTE_API
228
-
229
- static
230
- std::string
231
- expand_path(std::string path)
232
- {
233
- # if TARGET_OS_IPHONE
234
- return date::iOSUtils::get_tzdata_path();
235
- # else // !TARGET_OS_IPHONE
236
- ::wordexp_t w{};
237
- std::unique_ptr<::wordexp_t, void(*)(::wordexp_t*)> hold{&w, ::wordfree};
238
- ::wordexp(path.c_str(), &w, 0);
239
- if (w.we_wordc != 1)
240
- throw std::runtime_error("Cannot expand path: " + path);
241
- path = w.we_wordv[0];
242
- return path;
243
- # endif // !TARGET_OS_IPHONE
244
- }
245
-
246
- static
247
- std::string
248
- get_download_folder()
249
- {
250
- return expand_path("~/Downloads");
251
- }
252
-
253
- # endif // !defined(INSTALL) || HAS_REMOTE_API
254
-
255
- # endif // !_WIN32
256
-
257
- #endif // !USE_OS_TZDB
258
-
259
- namespace date
260
- {
261
- // +---------------------+
262
- // | Begin Configuration |
263
- // +---------------------+
264
-
265
- using namespace detail;
266
-
267
- #if !USE_OS_TZDB
268
-
269
- static
270
- std::string&
271
- access_install()
272
- {
273
- static std::string install
274
- #ifndef INSTALL
275
-
276
- = get_download_folder() + folder_delimiter + "tzdata";
277
-
278
- #else // !INSTALL
279
-
280
- # define STRINGIZEIMP(x) #x
281
- # define STRINGIZE(x) STRINGIZEIMP(x)
282
-
283
- = STRINGIZE(INSTALL) + std::string(1, folder_delimiter) + "tzdata";
284
-
285
- #undef STRINGIZEIMP
286
- #undef STRINGIZE
287
- #endif // !INSTALL
288
-
289
- return install;
290
- }
291
-
292
- void
293
- set_install(const std::string& s)
294
- {
295
- access_install() = s;
296
- }
297
-
298
- static
299
- const std::string&
300
- get_install()
301
- {
302
- static const std::string& ref = access_install();
303
- return ref;
304
- }
305
-
306
- #if HAS_REMOTE_API
307
- static
308
- std::string
309
- get_download_gz_file(const std::string& version)
310
- {
311
- auto file = get_install() + version + ".tar.gz";
312
- return file;
313
- }
314
- #endif // HAS_REMOTE_API
315
-
316
- #endif // !USE_OS_TZDB
317
-
318
- // These can be used to reduce the range of the database to save memory
319
- CONSTDATA auto min_year = date::year::min();
320
- CONSTDATA auto max_year = date::year::max();
321
-
322
- CONSTDATA auto min_day = date::January/1;
323
- CONSTDATA auto max_day = date::December/31;
324
-
325
- #if USE_OS_TZDB
326
-
327
- CONSTCD14 const sys_seconds min_seconds = sys_days(min_year/min_day);
328
-
329
- #endif // USE_OS_TZDB
330
-
331
- #ifndef _WIN32
332
-
333
- static
334
- std::string
335
- discover_tz_dir()
336
- {
337
- struct stat sb;
338
- using namespace std;
339
- # ifndef __APPLE__
340
- CONSTDATA auto tz_dir_default = "/usr/share/zoneinfo";
341
- CONSTDATA auto tz_dir_buildroot = "/usr/share/zoneinfo/uclibc";
342
-
343
- // Check special path which is valid for buildroot with uclibc builds
344
- if(stat(tz_dir_buildroot, &sb) == 0 && S_ISDIR(sb.st_mode))
345
- return tz_dir_buildroot;
346
- else if(stat(tz_dir_default, &sb) == 0 && S_ISDIR(sb.st_mode))
347
- return tz_dir_default;
348
- else
349
- throw runtime_error("discover_tz_dir failed to find zoneinfo\n");
350
- # else // __APPLE__
351
- # if TARGET_OS_IPHONE
352
- return "/var/db/timezone/zoneinfo";
353
- # else
354
- CONSTDATA auto timezone = "/etc/localtime";
355
- if (!(lstat(timezone, &sb) == 0 && S_ISLNK(sb.st_mode) && sb.st_size > 0))
356
- throw runtime_error("discover_tz_dir failed\n");
357
- string result;
358
- char rp[PATH_MAX+1] = {};
359
- if (readlink(timezone, rp, sizeof(rp)-1) > 0)
360
- result = string(rp);
361
- else
362
- throw system_error(errno, system_category(), "readlink() failed");
363
- auto i = result.find("zoneinfo");
364
- if (i == string::npos)
365
- throw runtime_error("discover_tz_dir failed to find zoneinfo\n");
366
- i = result.find('/', i);
367
- if (i == string::npos)
368
- throw runtime_error("discover_tz_dir failed to find '/'\n");
369
- return result.substr(0, i);
370
- # endif
371
- # endif // __APPLE__
372
- }
373
-
374
- static
375
- const std::string&
376
- get_tz_dir()
377
- {
378
- static const std::string tz_dir = discover_tz_dir();
379
- return tz_dir;
380
- }
381
-
382
- #endif
383
-
384
- // +-------------------+
385
- // | End Configuration |
386
- // +-------------------+
387
-
388
- namespace detail
389
- {
390
- struct undocumented {explicit undocumented() = default;};
391
- }
392
-
393
- #ifndef _MSC_VER
394
- static_assert(min_year <= max_year, "Configuration error");
395
- #endif
396
-
397
- static std::unique_ptr<tzdb> init_tzdb();
398
-
399
- tzdb_list::~tzdb_list()
400
- {
401
- const tzdb* ptr = head_;
402
- head_ = nullptr;
403
- while (ptr != nullptr)
404
- {
405
- auto next = ptr->next;
406
- delete ptr;
407
- ptr = next;
408
- }
409
- }
410
-
411
- tzdb_list::tzdb_list(tzdb_list&& x) noexcept
412
- : head_{x.head_.exchange(nullptr)}
413
- {
414
- }
415
-
416
- void
417
- tzdb_list::push_front(tzdb* tzdb) noexcept
418
- {
419
- tzdb->next = head_;
420
- head_ = tzdb;
421
- }
422
-
423
- tzdb_list::const_iterator
424
- tzdb_list::erase_after(const_iterator p) noexcept
425
- {
426
- auto t = p.p_->next;
427
- p.p_->next = p.p_->next->next;
428
- delete t;
429
- return ++p;
430
- }
431
-
432
- struct tzdb_list::undocumented_helper
433
- {
434
- static void push_front(tzdb_list& db_list, tzdb* tzdb) noexcept
435
- {
436
- db_list.push_front(tzdb);
437
- }
438
- };
439
-
440
- static
441
- tzdb_list
442
- create_tzdb()
443
- {
444
- tzdb_list tz_db;
445
- tzdb_list::undocumented_helper::push_front(tz_db, init_tzdb().release());
446
- return tz_db;
447
- }
448
-
449
- tzdb_list&
450
- get_tzdb_list()
451
- {
452
- static tzdb_list tz_db = create_tzdb();
453
- return tz_db;
454
- }
455
-
456
- #if !USE_OS_TZDB
457
-
458
- #ifdef _WIN32
459
-
460
- static
461
- void
462
- sort_zone_mappings(std::vector<date::detail::timezone_mapping>& mappings)
463
- {
464
- std::sort(mappings.begin(), mappings.end(),
465
- [](const date::detail::timezone_mapping& lhs,
466
- const date::detail::timezone_mapping& rhs)->bool
467
- {
468
- auto other_result = lhs.other.compare(rhs.other);
469
- if (other_result < 0)
470
- return true;
471
- else if (other_result == 0)
472
- {
473
- auto territory_result = lhs.territory.compare(rhs.territory);
474
- if (territory_result < 0)
475
- return true;
476
- else if (territory_result == 0)
477
- {
478
- if (lhs.type < rhs.type)
479
- return true;
480
- }
481
- }
482
- return false;
483
- });
484
- }
485
-
486
- static
487
- bool
488
- native_to_standard_timezone_name(const std::string& native_tz_name,
489
- std::string& standard_tz_name)
490
- {
491
- // TOOD! Need be a case insensitive compare?
492
- if (native_tz_name == "UTC")
493
- {
494
- standard_tz_name = "Etc/UTC";
495
- return true;
496
- }
497
- standard_tz_name.clear();
498
- // TODO! we can improve on linear search.
499
- const auto& mappings = date::get_tzdb().mappings;
500
- for (const auto& tzm : mappings)
501
- {
502
- if (tzm.other == native_tz_name)
503
- {
504
- standard_tz_name = tzm.type;
505
- return true;
506
- }
507
- }
508
- return false;
509
- }
510
-
511
- // Parse this XML file:
512
- // http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml
513
- // The parsing method is designed to be simple and quick. It is not overly
514
- // forgiving of change but it should diagnose basic format issues.
515
- // See timezone_mapping structure for more info.
516
- static
517
- std::vector<detail::timezone_mapping>
518
- load_timezone_mappings_from_xml_file(const std::string& input_path)
519
- {
520
- std::size_t line_num = 0;
521
- std::vector<detail::timezone_mapping> mappings;
522
- std::string line;
523
-
524
- std::ifstream is(input_path);
525
- if (!is.is_open())
526
- {
527
- // We don't emit file exceptions because that's an implementation detail.
528
- std::string msg = "Error opening time zone mapping file \"";
529
- msg += input_path;
530
- msg += "\".";
531
- throw std::runtime_error(msg);
532
- }
533
-
534
- auto error = [&input_path, &line_num](const char* info)
535
- {
536
- std::string msg = "Error loading time zone mapping file \"";
537
- msg += input_path;
538
- msg += "\" at line ";
539
- msg += std::to_string(line_num);
540
- msg += ": ";
541
- msg += info;
542
- throw std::runtime_error(msg);
543
- };
544
- // [optional space]a="b"
545
- auto read_attribute = [&line, &error]
546
- (const char* name, std::string& value, std::size_t startPos)
547
- ->std::size_t
548
- {
549
- value.clear();
550
- // Skip leading space before attribute name.
551
- std::size_t spos = line.find_first_not_of(' ', startPos);
552
- if (spos == std::string::npos)
553
- spos = startPos;
554
- // Assume everything up to next = is the attribute name
555
- // and that an = will always delimit that.
556
- std::size_t epos = line.find('=', spos);
557
- if (epos == std::string::npos)
558
- error("Expected \'=\' right after attribute name.");
559
- std::size_t name_len = epos - spos;
560
- // Expect the name we find matches the name we expect.
561
- if (line.compare(spos, name_len, name) != 0)
562
- {
563
- std::string msg;
564
- msg = "Expected attribute name \'";
565
- msg += name;
566
- msg += "\' around position ";
567
- msg += std::to_string(spos);
568
- msg += " but found something else.";
569
- error(msg.c_str());
570
- }
571
- ++epos; // Skip the '=' that is after the attribute name.
572
- spos = epos;
573
- if (spos < line.length() && line[spos] == '\"')
574
- ++spos; // Skip the quote that is before the attribute value.
575
- else
576
- {
577
- std::string msg = "Expected '\"' to begin value of attribute \'";
578
- msg += name;
579
- msg += "\'.";
580
- error(msg.c_str());
581
- }
582
- epos = line.find('\"', spos);
583
- if (epos == std::string::npos)
584
- {
585
- std::string msg = "Expected '\"' to end value of attribute \'";
586
- msg += name;
587
- msg += "\'.";
588
- error(msg.c_str());
589
- }
590
- // Extract everything in between the quotes. Note no escaping is done.
591
- std::size_t value_len = epos - spos;
592
- value.assign(line, spos, value_len);
593
- ++epos; // Skip the quote that is after the attribute value;
594
- return epos;
595
- };
596
-
597
- // Quick but not overly forgiving XML mapping file processing.
598
- bool mapTimezonesOpenTagFound = false;
599
- bool mapTimezonesCloseTagFound = false;
600
- std::size_t mapZonePos = std::string::npos;
601
- std::size_t mapTimezonesPos = std::string::npos;
602
- CONSTDATA char mapTimeZonesOpeningTag[] = { "<mapTimezones " };
603
- CONSTDATA char mapZoneOpeningTag[] = { "<mapZone " };
604
- CONSTDATA std::size_t mapZoneOpeningTagLen = sizeof(mapZoneOpeningTag) /
605
- sizeof(mapZoneOpeningTag[0]) - 1;
606
- while (!mapTimezonesOpenTagFound)
607
- {
608
- std::getline(is, line);
609
- ++line_num;
610
- if (is.eof())
611
- {
612
- // If there is no mapTimezones tag is it an error?
613
- // Perhaps if there are no mapZone mappings it might be ok for
614
- // its parent mapTimezones element to be missing?
615
- // We treat this as an error though on the assumption that if there
616
- // really are no mappings we should still get a mapTimezones parent
617
- // element but no mapZone elements inside. Assuming we must
618
- // find something will hopefully at least catch more drastic formatting
619
- // changes or errors than if we don't do this and assume nothing found.
620
- error("Expected a mapTimezones opening tag.");
621
- }
622
- mapTimezonesPos = line.find(mapTimeZonesOpeningTag);
623
- mapTimezonesOpenTagFound = (mapTimezonesPos != std::string::npos);
624
- }
625
-
626
- // NOTE: We could extract the version info that follows the opening
627
- // mapTimezones tag and compare that to the version of other data we have.
628
- // I would have expected them to be kept in synch but testing has shown
629
- // it typically does not match anyway. So what's the point?
630
- while (!mapTimezonesCloseTagFound)
631
- {
632
- std::ws(is);
633
- std::getline(is, line);
634
- ++line_num;
635
- if (is.eof())
636
- error("Expected a mapTimezones closing tag.");
637
- if (line.empty())
638
- continue;
639
- mapZonePos = line.find(mapZoneOpeningTag);
640
- if (mapZonePos != std::string::npos)
641
- {
642
- mapZonePos += mapZoneOpeningTagLen;
643
- detail::timezone_mapping zm{};
644
- std::size_t pos = read_attribute("other", zm.other, mapZonePos);
645
- pos = read_attribute("territory", zm.territory, pos);
646
- read_attribute("type", zm.type, pos);
647
- mappings.push_back(std::move(zm));
648
-
649
- continue;
650
- }
651
- mapTimezonesPos = line.find("</mapTimezones>");
652
- mapTimezonesCloseTagFound = (mapTimezonesPos != std::string::npos);
653
- if (!mapTimezonesCloseTagFound)
654
- {
655
- std::size_t commentPos = line.find("<!--");
656
- if (commentPos == std::string::npos)
657
- error("Unexpected mapping record found. A xml mapZone or comment "
658
- "attribute or mapTimezones closing tag was expected.");
659
- }
660
- }
661
-
662
- is.close();
663
- return mappings;
664
- }
665
-
666
- #endif // _WIN32
667
-
668
- // Parsing helpers
669
-
670
- static
671
- std::string
672
- parse3(std::istream& in)
673
- {
674
- std::string r(3, ' ');
675
- ws(in);
676
- r[0] = static_cast<char>(in.get());
677
- r[1] = static_cast<char>(in.get());
678
- r[2] = static_cast<char>(in.get());
679
- return r;
680
- }
681
-
682
- static
683
- unsigned
684
- parse_dow(std::istream& in)
685
- {
686
- CONSTDATA char*const dow_names[] =
687
- {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
688
- auto s = parse3(in);
689
- auto dow = std::find(std::begin(dow_names), std::end(dow_names), s) - dow_names;
690
- if (dow >= std::end(dow_names) - std::begin(dow_names))
691
- throw std::runtime_error("oops: bad dow name: " + s);
692
- return static_cast<unsigned>(dow);
693
- }
694
-
695
- static
696
- unsigned
697
- parse_month(std::istream& in)
698
- {
699
- CONSTDATA char*const month_names[] =
700
- {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
701
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
702
- auto s = parse3(in);
703
- auto m = std::find(std::begin(month_names), std::end(month_names), s) - month_names;
704
- if (m >= std::end(month_names) - std::begin(month_names))
705
- throw std::runtime_error("oops: bad month name: " + s);
706
- return static_cast<unsigned>(++m);
707
- }
708
-
709
- static
710
- std::chrono::seconds
711
- parse_unsigned_time(std::istream& in)
712
- {
713
- using namespace std::chrono;
714
- int x;
715
- in >> x;
716
- auto r = seconds{hours{x}};
717
- if (!in.eof() && in.peek() == ':')
718
- {
719
- in.get();
720
- in >> x;
721
- r += minutes{x};
722
- if (!in.eof() && in.peek() == ':')
723
- {
724
- in.get();
725
- in >> x;
726
- r += seconds{x};
727
- }
728
- }
729
- return r;
730
- }
731
-
732
- static
733
- std::chrono::seconds
734
- parse_signed_time(std::istream& in)
735
- {
736
- ws(in);
737
- auto sign = 1;
738
- if (in.peek() == '-')
739
- {
740
- sign = -1;
741
- in.get();
742
- }
743
- else if (in.peek() == '+')
744
- in.get();
745
- return sign * parse_unsigned_time(in);
746
- }
747
-
748
- // MonthDayTime
749
-
750
- detail::MonthDayTime::MonthDayTime(local_seconds tp, tz timezone)
751
- : zone_(timezone)
752
- {
753
- using namespace date;
754
- const auto dp = date::floor<days>(tp);
755
- const auto hms = make_time(tp - dp);
756
- const auto ymd = year_month_day(dp);
757
- u = ymd.month() / ymd.day();
758
- h_ = hms.hours();
759
- m_ = hms.minutes();
760
- s_ = hms.seconds();
761
- }
762
-
763
- detail::MonthDayTime::MonthDayTime(const date::month_day& md, tz timezone)
764
- : zone_(timezone)
765
- {
766
- u = md;
767
- }
768
-
769
- date::day
770
- detail::MonthDayTime::day() const
771
- {
772
- switch (type_)
773
- {
774
- case month_day:
775
- return u.month_day_.day();
776
- case month_last_dow:
777
- return date::day{31};
778
- case lteq:
779
- case gteq:
780
- break;
781
- }
782
- return u.month_day_weekday_.month_day_.day();
783
- }
784
-
785
- date::month
786
- detail::MonthDayTime::month() const
787
- {
788
- switch (type_)
789
- {
790
- case month_day:
791
- return u.month_day_.month();
792
- case month_last_dow:
793
- return u.month_weekday_last_.month();
794
- case lteq:
795
- case gteq:
796
- break;
797
- }
798
- return u.month_day_weekday_.month_day_.month();
799
- }
800
-
801
- int
802
- detail::MonthDayTime::compare(date::year y, const MonthDayTime& x, date::year yx,
803
- std::chrono::seconds offset, std::chrono::minutes prev_save) const
804
- {
805
- if (zone_ != x.zone_)
806
- {
807
- auto dp0 = to_sys_days(y);
808
- auto dp1 = x.to_sys_days(yx);
809
- if (std::abs((dp0-dp1).count()) > 1)
810
- return dp0 < dp1 ? -1 : 1;
811
- if (zone_ == tz::local)
812
- {
813
- auto tp0 = to_time_point(y) - prev_save;
814
- if (x.zone_ == tz::utc)
815
- tp0 -= offset;
816
- auto tp1 = x.to_time_point(yx);
817
- return tp0 < tp1 ? -1 : tp0 == tp1 ? 0 : 1;
818
- }
819
- else if (zone_ == tz::standard)
820
- {
821
- auto tp0 = to_time_point(y);
822
- auto tp1 = x.to_time_point(yx);
823
- if (x.zone_ == tz::local)
824
- tp1 -= prev_save;
825
- else
826
- tp0 -= offset;
827
- return tp0 < tp1 ? -1 : tp0 == tp1 ? 0 : 1;
828
- }
829
- // zone_ == tz::utc
830
- auto tp0 = to_time_point(y);
831
- auto tp1 = x.to_time_point(yx);
832
- if (x.zone_ == tz::local)
833
- tp1 -= offset + prev_save;
834
- else
835
- tp1 -= offset;
836
- return tp0 < tp1 ? -1 : tp0 == tp1 ? 0 : 1;
837
- }
838
- auto const t0 = to_time_point(y);
839
- auto const t1 = x.to_time_point(yx);
840
- return t0 < t1 ? -1 : t0 == t1 ? 0 : 1;
841
- }
842
-
843
- sys_seconds
844
- detail::MonthDayTime::to_sys(date::year y, std::chrono::seconds offset,
845
- std::chrono::seconds save) const
846
- {
847
- using namespace date;
848
- using namespace std::chrono;
849
- auto until_utc = to_time_point(y);
850
- if (zone_ == tz::standard)
851
- until_utc -= offset;
852
- else if (zone_ == tz::local)
853
- until_utc -= offset + save;
854
- return until_utc;
855
- }
856
-
857
- detail::MonthDayTime::U&
858
- detail::MonthDayTime::U::operator=(const date::month_day& x)
859
- {
860
- month_day_ = x;
861
- return *this;
862
- }
863
-
864
- detail::MonthDayTime::U&
865
- detail::MonthDayTime::U::operator=(const date::month_weekday_last& x)
866
- {
867
- month_weekday_last_ = x;
868
- return *this;
869
- }
870
-
871
- detail::MonthDayTime::U&
872
- detail::MonthDayTime::U::operator=(const pair& x)
873
- {
874
- month_day_weekday_ = x;
875
- return *this;
876
- }
877
-
878
- date::sys_days
879
- detail::MonthDayTime::to_sys_days(date::year y) const
880
- {
881
- using namespace std::chrono;
882
- using namespace date;
883
- switch (type_)
884
- {
885
- case month_day:
886
- return sys_days(y/u.month_day_);
887
- case month_last_dow:
888
- return sys_days(y/u.month_weekday_last_);
889
- case lteq:
890
- {
891
- auto const x = y/u.month_day_weekday_.month_day_;
892
- auto const wd1 = weekday(static_cast<sys_days>(x));
893
- auto const wd0 = u.month_day_weekday_.weekday_;
894
- return sys_days(x) - (wd1-wd0);
895
- }
896
- case gteq:
897
- break;
898
- }
899
- auto const x = y/u.month_day_weekday_.month_day_;
900
- auto const wd1 = u.month_day_weekday_.weekday_;
901
- auto const wd0 = weekday(static_cast<sys_days>(x));
902
- return sys_days(x) + (wd1-wd0);
903
- }
904
-
905
- sys_seconds
906
- detail::MonthDayTime::to_time_point(date::year y) const
907
- {
908
- // Add seconds first to promote to largest rep early to prevent overflow
909
- return to_sys_days(y) + s_ + h_ + m_;
910
- }
911
-
912
- void
913
- detail::MonthDayTime::canonicalize(date::year y)
914
- {
915
- using namespace std::chrono;
916
- using namespace date;
917
- switch (type_)
918
- {
919
- case month_day:
920
- return;
921
- case month_last_dow:
922
- {
923
- auto const ymd = year_month_day(sys_days(y/u.month_weekday_last_));
924
- u.month_day_ = ymd.month()/ymd.day();
925
- type_ = month_day;
926
- return;
927
- }
928
- case lteq:
929
- {
930
- auto const x = y/u.month_day_weekday_.month_day_;
931
- auto const wd1 = weekday(static_cast<sys_days>(x));
932
- auto const wd0 = u.month_day_weekday_.weekday_;
933
- auto const ymd = year_month_day(sys_days(x) - (wd1-wd0));
934
- u.month_day_ = ymd.month()/ymd.day();
935
- type_ = month_day;
936
- return;
937
- }
938
- case gteq:
939
- {
940
- auto const x = y/u.month_day_weekday_.month_day_;
941
- auto const wd1 = u.month_day_weekday_.weekday_;
942
- auto const wd0 = weekday(static_cast<sys_days>(x));
943
- auto const ymd = year_month_day(sys_days(x) + (wd1-wd0));
944
- u.month_day_ = ymd.month()/ymd.day();
945
- type_ = month_day;
946
- return;
947
- }
948
- }
949
- }
950
-
951
- std::istream&
952
- detail::operator>>(std::istream& is, MonthDayTime& x)
953
- {
954
- using namespace date;
955
- using namespace std::chrono;
956
- assert(((std::ios::failbit | std::ios::badbit) & is.exceptions()) ==
957
- (std::ios::failbit | std::ios::badbit));
958
- x = MonthDayTime{};
959
- if (!is.eof() && ws(is) && !is.eof() && is.peek() != '#')
960
- {
961
- auto m = parse_month(is);
962
- if (!is.eof() && ws(is) && !is.eof() && is.peek() != '#')
963
- {
964
- if (is.peek() == 'l')
965
- {
966
- for (int i = 0; i < 4; ++i)
967
- is.get();
968
- auto dow = parse_dow(is);
969
- x.type_ = MonthDayTime::month_last_dow;
970
- x.u = date::month(m)/weekday(dow)[last];
971
- }
972
- else if (std::isalpha(is.peek()))
973
- {
974
- auto dow = parse_dow(is);
975
- char c{};
976
- is >> c;
977
- if (c == '<' || c == '>')
978
- {
979
- char c2{};
980
- is >> c2;
981
- if (c2 != '=')
982
- throw std::runtime_error(std::string("bad operator: ") + c + c2);
983
- int d;
984
- is >> d;
985
- if (d < 1 || d > 31)
986
- throw std::runtime_error(std::string("bad operator: ") + c + c2
987
- + std::to_string(d));
988
- x.type_ = c == '<' ? MonthDayTime::lteq : MonthDayTime::gteq;
989
- x.u = MonthDayTime::pair{ date::month(m) / d, date::weekday(dow) };
990
- }
991
- else
992
- throw std::runtime_error(std::string("bad operator: ") + c);
993
- }
994
- else // if (std::isdigit(is.peek())
995
- {
996
- int d;
997
- is >> d;
998
- if (d < 1 || d > 31)
999
- throw std::runtime_error(std::string("day of month: ")
1000
- + std::to_string(d));
1001
- x.type_ = MonthDayTime::month_day;
1002
- x.u = date::month(m)/d;
1003
- }
1004
- if (!is.eof() && ws(is) && !is.eof() && is.peek() != '#')
1005
- {
1006
- int t;
1007
- is >> t;
1008
- x.h_ = hours{t};
1009
- if (!is.eof() && is.peek() == ':')
1010
- {
1011
- is.get();
1012
- is >> t;
1013
- x.m_ = minutes{t};
1014
- if (!is.eof() && is.peek() == ':')
1015
- {
1016
- is.get();
1017
- is >> t;
1018
- x.s_ = seconds{t};
1019
- }
1020
- }
1021
- if (!is.eof() && std::isalpha(is.peek()))
1022
- {
1023
- char c;
1024
- is >> c;
1025
- switch (c)
1026
- {
1027
- case 's':
1028
- x.zone_ = tz::standard;
1029
- break;
1030
- case 'u':
1031
- x.zone_ = tz::utc;
1032
- break;
1033
- }
1034
- }
1035
- }
1036
- }
1037
- else
1038
- {
1039
- x.u = month{m}/1;
1040
- }
1041
- }
1042
- return is;
1043
- }
1044
-
1045
- std::ostream&
1046
- detail::operator<<(std::ostream& os, const MonthDayTime& x)
1047
- {
1048
- switch (x.type_)
1049
- {
1050
- case MonthDayTime::month_day:
1051
- os << x.u.month_day_ << " ";
1052
- break;
1053
- case MonthDayTime::month_last_dow:
1054
- os << x.u.month_weekday_last_ << " ";
1055
- break;
1056
- case MonthDayTime::lteq:
1057
- os << x.u.month_day_weekday_.weekday_ << " on or before "
1058
- << x.u.month_day_weekday_.month_day_ << " ";
1059
- break;
1060
- case MonthDayTime::gteq:
1061
- if ((static_cast<unsigned>(x.day()) - 1) % 7 == 0)
1062
- {
1063
- os << (x.u.month_day_weekday_.month_day_.month() /
1064
- x.u.month_day_weekday_.weekday_[
1065
- (static_cast<unsigned>(x.day()) - 1)/7+1]) << " ";
1066
- }
1067
- else
1068
- {
1069
- os << x.u.month_day_weekday_.weekday_ << " on or after "
1070
- << x.u.month_day_weekday_.month_day_ << " ";
1071
- }
1072
- break;
1073
- }
1074
- os << date::make_time(x.s_ + x.h_ + x.m_);
1075
- if (x.zone_ == tz::utc)
1076
- os << "UTC ";
1077
- else if (x.zone_ == tz::standard)
1078
- os << "STD ";
1079
- else
1080
- os << " ";
1081
- return os;
1082
- }
1083
-
1084
- // Rule
1085
-
1086
- detail::Rule::Rule(const std::string& s)
1087
- {
1088
- try
1089
- {
1090
- using namespace date;
1091
- using namespace std::chrono;
1092
- std::istringstream in(s);
1093
- in.exceptions(std::ios::failbit | std::ios::badbit);
1094
- std::string word;
1095
- in >> word >> name_;
1096
- int x;
1097
- ws(in);
1098
- if (std::isalpha(in.peek()))
1099
- {
1100
- in >> word;
1101
- if (word == "min")
1102
- {
1103
- starting_year_ = year::min();
1104
- }
1105
- else
1106
- throw std::runtime_error("Didn't find expected word: " + word);
1107
- }
1108
- else
1109
- {
1110
- in >> x;
1111
- starting_year_ = year{x};
1112
- }
1113
- std::ws(in);
1114
- if (std::isalpha(in.peek()))
1115
- {
1116
- in >> word;
1117
- if (word == "only")
1118
- {
1119
- ending_year_ = starting_year_;
1120
- }
1121
- else if (word == "max")
1122
- {
1123
- ending_year_ = year::max();
1124
- }
1125
- else
1126
- throw std::runtime_error("Didn't find expected word: " + word);
1127
- }
1128
- else
1129
- {
1130
- in >> x;
1131
- ending_year_ = year{x};
1132
- }
1133
- in >> word; // TYPE (always "-")
1134
- assert(word == "-");
1135
- in >> starting_at_;
1136
- save_ = duration_cast<minutes>(parse_signed_time(in));
1137
- in >> abbrev_;
1138
- if (abbrev_ == "-")
1139
- abbrev_.clear();
1140
- assert(hours{-1} <= save_ && save_ <= hours{2});
1141
- }
1142
- catch (...)
1143
- {
1144
- std::cerr << s << '\n';
1145
- std::cerr << *this << '\n';
1146
- throw;
1147
- }
1148
- }
1149
-
1150
- detail::Rule::Rule(const Rule& r, date::year starting_year, date::year ending_year)
1151
- : name_(r.name_)
1152
- , starting_year_(starting_year)
1153
- , ending_year_(ending_year)
1154
- , starting_at_(r.starting_at_)
1155
- , save_(r.save_)
1156
- , abbrev_(r.abbrev_)
1157
- {
1158
- }
1159
-
1160
- bool
1161
- detail::operator==(const Rule& x, const Rule& y)
1162
- {
1163
- if (std::tie(x.name_, x.save_, x.starting_year_, x.ending_year_) ==
1164
- std::tie(y.name_, y.save_, y.starting_year_, y.ending_year_))
1165
- return x.month() == y.month() && x.day() == y.day();
1166
- return false;
1167
- }
1168
-
1169
- bool
1170
- detail::operator<(const Rule& x, const Rule& y)
1171
- {
1172
- using namespace std::chrono;
1173
- auto const xm = x.month();
1174
- auto const ym = y.month();
1175
- if (std::tie(x.name_, x.starting_year_, xm, x.ending_year_) <
1176
- std::tie(y.name_, y.starting_year_, ym, y.ending_year_))
1177
- return true;
1178
- if (std::tie(x.name_, x.starting_year_, xm, x.ending_year_) >
1179
- std::tie(y.name_, y.starting_year_, ym, y.ending_year_))
1180
- return false;
1181
- return x.day() < y.day();
1182
- }
1183
-
1184
- bool
1185
- detail::operator==(const Rule& x, const date::year& y)
1186
- {
1187
- return x.starting_year_ <= y && y <= x.ending_year_;
1188
- }
1189
-
1190
- bool
1191
- detail::operator<(const Rule& x, const date::year& y)
1192
- {
1193
- return x.ending_year_ < y;
1194
- }
1195
-
1196
- bool
1197
- detail::operator==(const date::year& x, const Rule& y)
1198
- {
1199
- return y.starting_year_ <= x && x <= y.ending_year_;
1200
- }
1201
-
1202
- bool
1203
- detail::operator<(const date::year& x, const Rule& y)
1204
- {
1205
- return x < y.starting_year_;
1206
- }
1207
-
1208
- bool
1209
- detail::operator==(const Rule& x, const std::string& y)
1210
- {
1211
- return x.name() == y;
1212
- }
1213
-
1214
- bool
1215
- detail::operator<(const Rule& x, const std::string& y)
1216
- {
1217
- return x.name() < y;
1218
- }
1219
-
1220
- bool
1221
- detail::operator==(const std::string& x, const Rule& y)
1222
- {
1223
- return y.name() == x;
1224
- }
1225
-
1226
- bool
1227
- detail::operator<(const std::string& x, const Rule& y)
1228
- {
1229
- return x < y.name();
1230
- }
1231
-
1232
- std::ostream&
1233
- detail::operator<<(std::ostream& os, const Rule& r)
1234
- {
1235
- using namespace date;
1236
- using namespace std::chrono;
1237
- detail::save_ostream<char> _(os);
1238
- os.fill(' ');
1239
- os.flags(std::ios::dec | std::ios::left);
1240
- os.width(15);
1241
- os << r.name_;
1242
- os << r.starting_year_ << " " << r.ending_year_ << " ";
1243
- os << r.starting_at_;
1244
- if (r.save_ >= minutes{0})
1245
- os << ' ';
1246
- os << date::make_time(r.save_) << " ";
1247
- os << r.abbrev_;
1248
- return os;
1249
- }
1250
-
1251
- date::day
1252
- detail::Rule::day() const
1253
- {
1254
- return starting_at_.day();
1255
- }
1256
-
1257
- date::month
1258
- detail::Rule::month() const
1259
- {
1260
- return starting_at_.month();
1261
- }
1262
-
1263
- struct find_rule_by_name
1264
- {
1265
- bool operator()(const Rule& x, const std::string& nm) const
1266
- {
1267
- return x.name() < nm;
1268
- }
1269
-
1270
- bool operator()(const std::string& nm, const Rule& x) const
1271
- {
1272
- return nm < x.name();
1273
- }
1274
- };
1275
-
1276
- bool
1277
- detail::Rule::overlaps(const Rule& x, const Rule& y)
1278
- {
1279
- // assume x.starting_year_ <= y.starting_year_;
1280
- if (!(x.starting_year_ <= y.starting_year_))
1281
- {
1282
- std::cerr << x << '\n';
1283
- std::cerr << y << '\n';
1284
- assert(x.starting_year_ <= y.starting_year_);
1285
- }
1286
- if (y.starting_year_ > x.ending_year_)
1287
- return false;
1288
- return !(x.starting_year_ == y.starting_year_ && x.ending_year_ == y.ending_year_);
1289
- }
1290
-
1291
- void
1292
- detail::Rule::split(std::vector<Rule>& rules, std::size_t i, std::size_t k, std::size_t& e)
1293
- {
1294
- using namespace date;
1295
- using difference_type = std::vector<Rule>::iterator::difference_type;
1296
- // rules[i].starting_year_ <= rules[k].starting_year_ &&
1297
- // rules[i].ending_year_ >= rules[k].starting_year_ &&
1298
- // (rules[i].starting_year_ != rules[k].starting_year_ ||
1299
- // rules[i].ending_year_ != rules[k].ending_year_)
1300
- assert(rules[i].starting_year_ <= rules[k].starting_year_ &&
1301
- rules[i].ending_year_ >= rules[k].starting_year_ &&
1302
- (rules[i].starting_year_ != rules[k].starting_year_ ||
1303
- rules[i].ending_year_ != rules[k].ending_year_));
1304
- if (rules[i].starting_year_ == rules[k].starting_year_)
1305
- {
1306
- if (rules[k].ending_year_ < rules[i].ending_year_)
1307
- {
1308
- rules.insert(rules.begin() + static_cast<difference_type>(k+1),
1309
- Rule(rules[i], rules[k].ending_year_ + years{1},
1310
- std::move(rules[i].ending_year_)));
1311
- ++e;
1312
- rules[i].ending_year_ = rules[k].ending_year_;
1313
- }
1314
- else // rules[k].ending_year_ > rules[i].ending_year_
1315
- {
1316
- rules.insert(rules.begin() + static_cast<difference_type>(k+1),
1317
- Rule(rules[k], rules[i].ending_year_ + years{1},
1318
- std::move(rules[k].ending_year_)));
1319
- ++e;
1320
- rules[k].ending_year_ = rules[i].ending_year_;
1321
- }
1322
- }
1323
- else // rules[i].starting_year_ < rules[k].starting_year_
1324
- {
1325
- if (rules[k].ending_year_ < rules[i].ending_year_)
1326
- {
1327
- rules.insert(rules.begin() + static_cast<difference_type>(k),
1328
- Rule(rules[i], rules[k].starting_year_, rules[k].ending_year_));
1329
- ++k;
1330
- rules.insert(rules.begin() + static_cast<difference_type>(k+1),
1331
- Rule(rules[i], rules[k].ending_year_ + years{1},
1332
- std::move(rules[i].ending_year_)));
1333
- rules[i].ending_year_ = rules[k].starting_year_ - years{1};
1334
- e += 2;
1335
- }
1336
- else if (rules[k].ending_year_ > rules[i].ending_year_)
1337
- {
1338
- rules.insert(rules.begin() + static_cast<difference_type>(k),
1339
- Rule(rules[i], rules[k].starting_year_, rules[i].ending_year_));
1340
- ++k;
1341
- rules.insert(rules.begin() + static_cast<difference_type>(k+1),
1342
- Rule(rules[k], rules[i].ending_year_ + years{1},
1343
- std::move(rules[k].ending_year_)));
1344
- e += 2;
1345
- rules[k].ending_year_ = std::move(rules[i].ending_year_);
1346
- rules[i].ending_year_ = rules[k].starting_year_ - years{1};
1347
- }
1348
- else // rules[k].ending_year_ == rules[i].ending_year_
1349
- {
1350
- rules.insert(rules.begin() + static_cast<difference_type>(k),
1351
- Rule(rules[i], rules[k].starting_year_,
1352
- std::move(rules[i].ending_year_)));
1353
- ++k;
1354
- ++e;
1355
- rules[i].ending_year_ = rules[k].starting_year_ - years{1};
1356
- }
1357
- }
1358
- }
1359
-
1360
- void
1361
- detail::Rule::split_overlaps(std::vector<Rule>& rules, std::size_t i, std::size_t& e)
1362
- {
1363
- using difference_type = std::vector<Rule>::iterator::difference_type;
1364
- auto j = i;
1365
- for (; i + 1 < e; ++i)
1366
- {
1367
- for (auto k = i + 1; k < e; ++k)
1368
- {
1369
- if (overlaps(rules[i], rules[k]))
1370
- {
1371
- split(rules, i, k, e);
1372
- std::sort(rules.begin() + static_cast<difference_type>(i),
1373
- rules.begin() + static_cast<difference_type>(e));
1374
- }
1375
- }
1376
- }
1377
- for (; j < e; ++j)
1378
- {
1379
- if (rules[j].starting_year() == rules[j].ending_year())
1380
- rules[j].starting_at_.canonicalize(rules[j].starting_year());
1381
- }
1382
- }
1383
-
1384
- void
1385
- detail::Rule::split_overlaps(std::vector<Rule>& rules)
1386
- {
1387
- using difference_type = std::vector<Rule>::iterator::difference_type;
1388
- for (std::size_t i = 0; i < rules.size();)
1389
- {
1390
- auto e = static_cast<std::size_t>(std::upper_bound(
1391
- rules.cbegin()+static_cast<difference_type>(i), rules.cend(), rules[i].name(),
1392
- [](const std::string& nm, const Rule& x)
1393
- {
1394
- return nm < x.name();
1395
- }) - rules.cbegin());
1396
- split_overlaps(rules, i, e);
1397
- auto first_rule = rules.begin() + static_cast<difference_type>(i);
1398
- auto last_rule = rules.begin() + static_cast<difference_type>(e);
1399
- auto t = std::lower_bound(first_rule, last_rule, min_year);
1400
- if (t > first_rule+1)
1401
- {
1402
- if (t == last_rule || t->starting_year() >= min_year)
1403
- --t;
1404
- auto d = static_cast<std::size_t>(t - first_rule);
1405
- rules.erase(first_rule, t);
1406
- e -= d;
1407
- }
1408
- first_rule = rules.begin() + static_cast<difference_type>(i);
1409
- last_rule = rules.begin() + static_cast<difference_type>(e);
1410
- t = std::upper_bound(first_rule, last_rule, max_year);
1411
- if (t != last_rule)
1412
- {
1413
- auto d = static_cast<std::size_t>(last_rule - t);
1414
- rules.erase(t, last_rule);
1415
- e -= d;
1416
- }
1417
- i = e;
1418
- }
1419
- rules.shrink_to_fit();
1420
- }
1421
-
1422
- // Find the rule that comes chronologically before Rule r. For multi-year rules,
1423
- // y specifies which rules in r. For single year rules, y is assumed to be equal
1424
- // to the year specified by r.
1425
- // Returns a pointer to the chronologically previous rule, and the year within
1426
- // that rule. If there is no previous rule, returns nullptr and year::min().
1427
- // Preconditions:
1428
- // r->starting_year() <= y && y <= r->ending_year()
1429
- static
1430
- std::pair<const Rule*, date::year>
1431
- find_previous_rule(const Rule* r, date::year y)
1432
- {
1433
- using namespace date;
1434
- auto const& rules = get_tzdb().rules;
1435
- if (y == r->starting_year())
1436
- {
1437
- if (r == &rules.front() || r->name() != r[-1].name())
1438
- std::terminate(); // never called with first rule
1439
- --r;
1440
- if (y == r->starting_year())
1441
- return {r, y};
1442
- return {r, r->ending_year()};
1443
- }
1444
- if (r == &rules.front() || r->name() != r[-1].name() ||
1445
- r[-1].starting_year() < r->starting_year())
1446
- {
1447
- while (r < &rules.back() && r->name() == r[1].name() &&
1448
- r->starting_year() == r[1].starting_year())
1449
- ++r;
1450
- return {r, --y};
1451
- }
1452
- --r;
1453
- return {r, y};
1454
- }
1455
-
1456
- // Find the rule that comes chronologically after Rule r. For multi-year rules,
1457
- // y specifies which rules in r. For single year rules, y is assumed to be equal
1458
- // to the year specified by r.
1459
- // Returns a pointer to the chronologically next rule, and the year within
1460
- // that rule. If there is no next rule, return a pointer to a defaulted rule
1461
- // and y+1.
1462
- // Preconditions:
1463
- // first <= r && r < last && r->starting_year() <= y && y <= r->ending_year()
1464
- // [first, last) all have the same name
1465
- static
1466
- std::pair<const Rule*, date::year>
1467
- find_next_rule(const Rule* first_rule, const Rule* last_rule, const Rule* r, date::year y)
1468
- {
1469
- using namespace date;
1470
- if (y == r->ending_year())
1471
- {
1472
- if (r == last_rule-1)
1473
- return {nullptr, year::max()};
1474
- ++r;
1475
- if (y == r->ending_year())
1476
- return {r, y};
1477
- return {r, r->starting_year()};
1478
- }
1479
- if (r == last_rule-1 || r->ending_year() < r[1].ending_year())
1480
- {
1481
- while (r > first_rule && r->starting_year() == r[-1].starting_year())
1482
- --r;
1483
- return {r, ++y};
1484
- }
1485
- ++r;
1486
- return {r, y};
1487
- }
1488
-
1489
- // Find the rule that comes chronologically after Rule r. For multi-year rules,
1490
- // y specifies which rules in r. For single year rules, y is assumed to be equal
1491
- // to the year specified by r.
1492
- // Returns a pointer to the chronologically next rule, and the year within
1493
- // that rule. If there is no next rule, return nullptr and year::max().
1494
- // Preconditions:
1495
- // r->starting_year() <= y && y <= r->ending_year()
1496
- static
1497
- std::pair<const Rule*, date::year>
1498
- find_next_rule(const Rule* r, date::year y)
1499
- {
1500
- using namespace date;
1501
- auto const& rules = get_tzdb().rules;
1502
- if (y == r->ending_year())
1503
- {
1504
- if (r == &rules.back() || r->name() != r[1].name())
1505
- return {nullptr, year::max()};
1506
- ++r;
1507
- if (y == r->ending_year())
1508
- return {r, y};
1509
- return {r, r->starting_year()};
1510
- }
1511
- if (r == &rules.back() || r->name() != r[1].name() ||
1512
- r->ending_year() < r[1].ending_year())
1513
- {
1514
- while (r > &rules.front() && r->name() == r[-1].name() &&
1515
- r->starting_year() == r[-1].starting_year())
1516
- --r;
1517
- return {r, ++y};
1518
- }
1519
- ++r;
1520
- return {r, y};
1521
- }
1522
-
1523
- static
1524
- const Rule*
1525
- find_first_std_rule(const std::pair<const Rule*, const Rule*>& eqr)
1526
- {
1527
- auto r = eqr.first;
1528
- auto ry = r->starting_year();
1529
- while (r->save() != std::chrono::minutes{0})
1530
- {
1531
- std::tie(r, ry) = find_next_rule(eqr.first, eqr.second, r, ry);
1532
- if (r == nullptr)
1533
- throw std::runtime_error("Could not find standard offset in rule "
1534
- + eqr.first->name());
1535
- }
1536
- return r;
1537
- }
1538
-
1539
- static
1540
- std::pair<const Rule*, date::year>
1541
- find_rule_for_zone(const std::pair<const Rule*, const Rule*>& eqr,
1542
- const date::year& y, const std::chrono::seconds& offset,
1543
- const MonthDayTime& mdt)
1544
- {
1545
- assert(eqr.first != nullptr);
1546
- assert(eqr.second != nullptr);
1547
-
1548
- using namespace std::chrono;
1549
- using namespace date;
1550
- auto r = eqr.first;
1551
- auto ry = r->starting_year();
1552
- auto prev_save = minutes{0};
1553
- auto prev_year = year::min();
1554
- const Rule* prev_rule = nullptr;
1555
- while (r != nullptr)
1556
- {
1557
- if (mdt.compare(y, r->mdt(), ry, offset, prev_save) <= 0)
1558
- break;
1559
- prev_rule = r;
1560
- prev_year = ry;
1561
- prev_save = prev_rule->save();
1562
- std::tie(r, ry) = find_next_rule(eqr.first, eqr.second, r, ry);
1563
- }
1564
- return {prev_rule, prev_year};
1565
- }
1566
-
1567
- static
1568
- std::pair<const Rule*, date::year>
1569
- find_rule_for_zone(const std::pair<const Rule*, const Rule*>& eqr,
1570
- const sys_seconds& tp_utc,
1571
- const local_seconds& tp_std,
1572
- const local_seconds& tp_loc)
1573
- {
1574
- using namespace std::chrono;
1575
- using namespace date;
1576
- auto r = eqr.first;
1577
- auto ry = r->starting_year();
1578
- auto prev_save = minutes{0};
1579
- auto prev_year = year::min();
1580
- const Rule* prev_rule = nullptr;
1581
- while (r != nullptr)
1582
- {
1583
- bool found = false;
1584
- switch (r->mdt().zone())
1585
- {
1586
- case tz::utc:
1587
- found = tp_utc < r->mdt().to_time_point(ry);
1588
- break;
1589
- case tz::standard:
1590
- found = sys_seconds{tp_std.time_since_epoch()} < r->mdt().to_time_point(ry);
1591
- break;
1592
- case tz::local:
1593
- found = sys_seconds{tp_loc.time_since_epoch()} < r->mdt().to_time_point(ry);
1594
- break;
1595
- }
1596
- if (found)
1597
- break;
1598
- prev_rule = r;
1599
- prev_year = ry;
1600
- prev_save = prev_rule->save();
1601
- std::tie(r, ry) = find_next_rule(eqr.first, eqr.second, r, ry);
1602
- }
1603
- return {prev_rule, prev_year};
1604
- }
1605
-
1606
- static
1607
- sys_info
1608
- find_rule(const std::pair<const Rule*, date::year>& first_rule,
1609
- const std::pair<const Rule*, date::year>& last_rule,
1610
- const date::year& y, const std::chrono::seconds& offset,
1611
- const MonthDayTime& mdt, const std::chrono::minutes& initial_save,
1612
- const std::string& initial_abbrev)
1613
- {
1614
- using namespace std::chrono;
1615
- using namespace date;
1616
- auto r = first_rule.first;
1617
- auto ry = first_rule.second;
1618
- sys_info x{sys_days(year::min()/min_day), sys_days(year::max()/max_day),
1619
- seconds{0}, initial_save, initial_abbrev};
1620
- while (r != nullptr)
1621
- {
1622
- auto tr = r->mdt().to_sys(ry, offset, x.save);
1623
- auto tx = mdt.to_sys(y, offset, x.save);
1624
- // Find last rule where tx >= tr
1625
- if (tx <= tr || (r == last_rule.first && ry == last_rule.second))
1626
- {
1627
- if (tx < tr && r == first_rule.first && ry == first_rule.second)
1628
- {
1629
- x.end = r->mdt().to_sys(ry, offset, x.save);
1630
- break;
1631
- }
1632
- if (tx < tr)
1633
- {
1634
- std::tie(r, ry) = find_previous_rule(r, ry); // can't return nullptr for r
1635
- assert(r != nullptr);
1636
- }
1637
- // r != nullptr && tx >= tr (if tr were to be recomputed)
1638
- auto prev_save = initial_save;
1639
- if (!(r == first_rule.first && ry == first_rule.second))
1640
- prev_save = find_previous_rule(r, ry).first->save();
1641
- x.begin = r->mdt().to_sys(ry, offset, prev_save);
1642
- x.save = r->save();
1643
- x.abbrev = r->abbrev();
1644
- if (!(r == last_rule.first && ry == last_rule.second))
1645
- {
1646
- std::tie(r, ry) = find_next_rule(r, ry); // can't return nullptr for r
1647
- assert(r != nullptr);
1648
- x.end = r->mdt().to_sys(ry, offset, x.save);
1649
- }
1650
- else
1651
- x.end = sys_days(year::max()/max_day);
1652
- break;
1653
- }
1654
- x.save = r->save();
1655
- std::tie(r, ry) = find_next_rule(r, ry); // Can't return nullptr for r
1656
- assert(r != nullptr);
1657
- }
1658
- return x;
1659
- }
1660
-
1661
- // zonelet
1662
-
1663
- detail::zonelet::~zonelet()
1664
- {
1665
- #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
1666
- using minutes = std::chrono::minutes;
1667
- using string = std::string;
1668
- if (tag_ == has_save)
1669
- u.save_.~minutes();
1670
- else
1671
- u.rule_.~string();
1672
- #endif
1673
- }
1674
-
1675
- detail::zonelet::zonelet()
1676
- {
1677
- #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
1678
- ::new(&u.rule_) std::string();
1679
- #endif
1680
- }
1681
-
1682
- detail::zonelet::zonelet(const zonelet& i)
1683
- : gmtoff_(i.gmtoff_)
1684
- , tag_(i.tag_)
1685
- , format_(i.format_)
1686
- , until_year_(i.until_year_)
1687
- , until_date_(i.until_date_)
1688
- , until_utc_(i.until_utc_)
1689
- , until_std_(i.until_std_)
1690
- , until_loc_(i.until_loc_)
1691
- , initial_save_(i.initial_save_)
1692
- , initial_abbrev_(i.initial_abbrev_)
1693
- , first_rule_(i.first_rule_)
1694
- , last_rule_(i.last_rule_)
1695
- {
1696
- #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
1697
- if (tag_ == has_save)
1698
- ::new(&u.save_) std::chrono::minutes(i.u.save_);
1699
- else
1700
- ::new(&u.rule_) std::string(i.u.rule_);
1701
- #else
1702
- if (tag_ == has_save)
1703
- u.save_ = i.u.save_;
1704
- else
1705
- u.rule_ = i.u.rule_;
1706
- #endif
1707
- }
1708
-
1709
- #endif // !USE_OS_TZDB
1710
-
1711
- // time_zone
1712
-
1713
- #if USE_OS_TZDB
1714
-
1715
- time_zone::time_zone(const std::string& s, detail::undocumented)
1716
- : name_(s)
1717
- , adjusted_(new std::once_flag{})
1718
- {
1719
- }
1720
-
1721
- enum class endian
1722
- {
1723
- native = __BYTE_ORDER__,
1724
- little = __ORDER_LITTLE_ENDIAN__,
1725
- big = __ORDER_BIG_ENDIAN__
1726
- };
1727
-
1728
- static
1729
- inline
1730
- std::uint32_t
1731
- reverse_bytes(std::uint32_t i)
1732
- {
1733
- return
1734
- (i & 0xff000000u) >> 24 |
1735
- (i & 0x00ff0000u) >> 8 |
1736
- (i & 0x0000ff00u) << 8 |
1737
- (i & 0x000000ffu) << 24;
1738
- }
1739
-
1740
- static
1741
- inline
1742
- std::uint64_t
1743
- reverse_bytes(std::uint64_t i)
1744
- {
1745
- return
1746
- (i & 0xff00000000000000ull) >> 56 |
1747
- (i & 0x00ff000000000000ull) >> 40 |
1748
- (i & 0x0000ff0000000000ull) >> 24 |
1749
- (i & 0x000000ff00000000ull) >> 8 |
1750
- (i & 0x00000000ff000000ull) << 8 |
1751
- (i & 0x0000000000ff0000ull) << 24 |
1752
- (i & 0x000000000000ff00ull) << 40 |
1753
- (i & 0x00000000000000ffull) << 56;
1754
- }
1755
-
1756
- template <class T>
1757
- static
1758
- inline
1759
- void
1760
- maybe_reverse_bytes(T&, std::false_type)
1761
- {
1762
- }
1763
-
1764
- static
1765
- inline
1766
- void
1767
- maybe_reverse_bytes(std::int32_t& t, std::true_type)
1768
- {
1769
- t = static_cast<std::int32_t>(reverse_bytes(static_cast<std::uint32_t>(t)));
1770
- }
1771
-
1772
- static
1773
- inline
1774
- void
1775
- maybe_reverse_bytes(std::int64_t& t, std::true_type)
1776
- {
1777
- t = static_cast<std::int64_t>(reverse_bytes(static_cast<std::uint64_t>(t)));
1778
- }
1779
-
1780
- template <class T>
1781
- static
1782
- inline
1783
- void
1784
- maybe_reverse_bytes(T& t)
1785
- {
1786
- maybe_reverse_bytes(t, std::integral_constant<bool,
1787
- endian::native == endian::little>{});
1788
- }
1789
-
1790
- static
1791
- void
1792
- load_header(std::istream& inf)
1793
- {
1794
- // Read TZif
1795
- auto t = inf.get();
1796
- auto z = inf.get();
1797
- auto i = inf.get();
1798
- auto f = inf.get();
1799
- #ifndef NDEBUG
1800
- assert(t == 'T');
1801
- assert(z == 'Z');
1802
- assert(i == 'i');
1803
- assert(f == 'f');
1804
- #else
1805
- (void)t;
1806
- (void)z;
1807
- (void)i;
1808
- (void)f;
1809
- #endif
1810
- }
1811
-
1812
- static
1813
- unsigned char
1814
- load_version(std::istream& inf)
1815
- {
1816
- // Read version
1817
- auto v = inf.get();
1818
- assert(v != EOF);
1819
- return static_cast<unsigned char>(v);
1820
- }
1821
-
1822
- static
1823
- void
1824
- skip_reserve(std::istream& inf)
1825
- {
1826
- inf.ignore(15);
1827
- }
1828
-
1829
- static
1830
- void
1831
- load_counts(std::istream& inf,
1832
- std::int32_t& tzh_ttisgmtcnt, std::int32_t& tzh_ttisstdcnt,
1833
- std::int32_t& tzh_leapcnt, std::int32_t& tzh_timecnt,
1834
- std::int32_t& tzh_typecnt, std::int32_t& tzh_charcnt)
1835
- {
1836
- // Read counts;
1837
- inf.read(reinterpret_cast<char*>(&tzh_ttisgmtcnt), 4);
1838
- maybe_reverse_bytes(tzh_ttisgmtcnt);
1839
- inf.read(reinterpret_cast<char*>(&tzh_ttisstdcnt), 4);
1840
- maybe_reverse_bytes(tzh_ttisstdcnt);
1841
- inf.read(reinterpret_cast<char*>(&tzh_leapcnt), 4);
1842
- maybe_reverse_bytes(tzh_leapcnt);
1843
- inf.read(reinterpret_cast<char*>(&tzh_timecnt), 4);
1844
- maybe_reverse_bytes(tzh_timecnt);
1845
- inf.read(reinterpret_cast<char*>(&tzh_typecnt), 4);
1846
- maybe_reverse_bytes(tzh_typecnt);
1847
- inf.read(reinterpret_cast<char*>(&tzh_charcnt), 4);
1848
- maybe_reverse_bytes(tzh_charcnt);
1849
- }
1850
-
1851
- template <class TimeType>
1852
- static
1853
- std::vector<detail::transition>
1854
- load_transitions(std::istream& inf, std::int32_t tzh_timecnt)
1855
- {
1856
- // Read transitions
1857
- using namespace std::chrono;
1858
- std::vector<detail::transition> transitions;
1859
- transitions.reserve(static_cast<unsigned>(tzh_timecnt));
1860
- for (std::int32_t i = 0; i < tzh_timecnt; ++i)
1861
- {
1862
- TimeType t;
1863
- inf.read(reinterpret_cast<char*>(&t), sizeof(t));
1864
- maybe_reverse_bytes(t);
1865
- transitions.emplace_back(sys_seconds{seconds{t}});
1866
- if (transitions.back().timepoint < min_seconds)
1867
- transitions.back().timepoint = min_seconds;
1868
- }
1869
- return transitions;
1870
- }
1871
-
1872
- static
1873
- std::vector<std::uint8_t>
1874
- load_indices(std::istream& inf, std::int32_t tzh_timecnt)
1875
- {
1876
- // Read indices
1877
- std::vector<std::uint8_t> indices;
1878
- indices.reserve(static_cast<unsigned>(tzh_timecnt));
1879
- for (std::int32_t i = 0; i < tzh_timecnt; ++i)
1880
- {
1881
- std::uint8_t t;
1882
- inf.read(reinterpret_cast<char*>(&t), sizeof(t));
1883
- indices.emplace_back(t);
1884
- }
1885
- return indices;
1886
- }
1887
-
1888
- static
1889
- std::vector<ttinfo>
1890
- load_ttinfo(std::istream& inf, std::int32_t tzh_typecnt)
1891
- {
1892
- // Read ttinfo
1893
- std::vector<ttinfo> ttinfos;
1894
- ttinfos.reserve(static_cast<unsigned>(tzh_typecnt));
1895
- for (std::int32_t i = 0; i < tzh_typecnt; ++i)
1896
- {
1897
- ttinfo t;
1898
- inf.read(reinterpret_cast<char*>(&t), 6);
1899
- maybe_reverse_bytes(t.tt_gmtoff);
1900
- ttinfos.emplace_back(t);
1901
- }
1902
- return ttinfos;
1903
- }
1904
-
1905
- static
1906
- std::string
1907
- load_abbreviations(std::istream& inf, std::int32_t tzh_charcnt)
1908
- {
1909
- // Read abbreviations
1910
- std::string abbrev;
1911
- abbrev.resize(static_cast<unsigned>(tzh_charcnt), '\0');
1912
- inf.read(&abbrev[0], tzh_charcnt);
1913
- return abbrev;
1914
- }
1915
-
1916
- #if !MISSING_LEAP_SECONDS
1917
-
1918
- template <class TimeType>
1919
- static
1920
- std::vector<leap>
1921
- load_leaps(std::istream& inf, std::int32_t tzh_leapcnt)
1922
- {
1923
- // Read tzh_leapcnt pairs
1924
- using namespace std::chrono;
1925
- std::vector<leap> leap_seconds;
1926
- leap_seconds.reserve(tzh_leapcnt);
1927
- for (std::int32_t i = 0; i < tzh_leapcnt; ++i)
1928
- {
1929
- TimeType t0;
1930
- std::int32_t t1;
1931
- inf.read(reinterpret_cast<char*>(&t0), sizeof(t0));
1932
- inf.read(reinterpret_cast<char*>(&t1), sizeof(t1));
1933
- maybe_reverse_bytes(t0);
1934
- maybe_reverse_bytes(t1);
1935
- leap_seconds.emplace_back(sys_seconds{seconds{t0 - (t1-1)}},
1936
- detail::undocumented{});
1937
- }
1938
- return leap_seconds;
1939
- }
1940
-
1941
- template <class TimeType>
1942
- static
1943
- std::vector<leap>
1944
- load_leap_data(std::istream& inf,
1945
- std::int32_t tzh_leapcnt, std::int32_t tzh_timecnt,
1946
- std::int32_t tzh_typecnt, std::int32_t tzh_charcnt)
1947
- {
1948
- inf.ignore(tzh_timecnt*sizeof(TimeType) + tzh_timecnt + tzh_typecnt*6 + tzh_charcnt);
1949
- return load_leaps<TimeType>(inf, tzh_leapcnt);
1950
- }
1951
-
1952
- static
1953
- std::vector<leap>
1954
- load_just_leaps(std::istream& inf)
1955
- {
1956
- // Read tzh_leapcnt pairs
1957
- using namespace std::chrono;
1958
- load_header(inf);
1959
- auto v = load_version(inf);
1960
- std::int32_t tzh_ttisgmtcnt, tzh_ttisstdcnt, tzh_leapcnt,
1961
- tzh_timecnt, tzh_typecnt, tzh_charcnt;
1962
- skip_reserve(inf);
1963
- load_counts(inf, tzh_ttisgmtcnt, tzh_ttisstdcnt, tzh_leapcnt,
1964
- tzh_timecnt, tzh_typecnt, tzh_charcnt);
1965
- if (v == 0)
1966
- return load_leap_data<int32_t>(inf, tzh_leapcnt, tzh_timecnt, tzh_typecnt,
1967
- tzh_charcnt);
1968
- #if !defined(NDEBUG)
1969
- inf.ignore((4+1)*tzh_timecnt + 6*tzh_typecnt + tzh_charcnt + 8*tzh_leapcnt +
1970
- tzh_ttisstdcnt + tzh_ttisgmtcnt);
1971
- load_header(inf);
1972
- auto v2 = load_version(inf);
1973
- assert(v == v2);
1974
- skip_reserve(inf);
1975
- #else // defined(NDEBUG)
1976
- inf.ignore((4+1)*tzh_timecnt + 6*tzh_typecnt + tzh_charcnt + 8*tzh_leapcnt +
1977
- tzh_ttisstdcnt + tzh_ttisgmtcnt + (4+1+15));
1978
- #endif // defined(NDEBUG)
1979
- load_counts(inf, tzh_ttisgmtcnt, tzh_ttisstdcnt, tzh_leapcnt,
1980
- tzh_timecnt, tzh_typecnt, tzh_charcnt);
1981
- return load_leap_data<int64_t>(inf, tzh_leapcnt, tzh_timecnt, tzh_typecnt,
1982
- tzh_charcnt);
1983
- }
1984
-
1985
- #endif // !MISSING_LEAP_SECONDS
1986
-
1987
- template <class TimeType>
1988
- void
1989
- time_zone::load_data(std::istream& inf,
1990
- std::int32_t tzh_leapcnt, std::int32_t tzh_timecnt,
1991
- std::int32_t tzh_typecnt, std::int32_t tzh_charcnt)
1992
- {
1993
- using namespace std::chrono;
1994
- transitions_ = load_transitions<TimeType>(inf, tzh_timecnt);
1995
- auto indices = load_indices(inf, tzh_timecnt);
1996
- auto infos = load_ttinfo(inf, tzh_typecnt);
1997
- auto abbrev = load_abbreviations(inf, tzh_charcnt);
1998
- #if !MISSING_LEAP_SECONDS
1999
- auto& leap_seconds = get_tzdb_list().front().leaps;
2000
- if (leap_seconds.empty() && tzh_leapcnt > 0)
2001
- leap_seconds = load_leaps<TimeType>(inf, tzh_leapcnt);
2002
- #endif
2003
- ttinfos_.reserve(infos.size());
2004
- for (auto& info : infos)
2005
- {
2006
- ttinfos_.push_back({seconds{info.tt_gmtoff},
2007
- abbrev.c_str() + info.tt_abbrind,
2008
- info.tt_isdst != 0});
2009
- }
2010
- auto i = 0u;
2011
- if (transitions_.empty() || transitions_.front().timepoint != min_seconds)
2012
- {
2013
- transitions_.emplace(transitions_.begin(), min_seconds);
2014
- auto tf = std::find_if(ttinfos_.begin(), ttinfos_.end(),
2015
- [](const expanded_ttinfo& ti)
2016
- {return ti.is_dst == 0;});
2017
- if (tf == ttinfos_.end())
2018
- tf = ttinfos_.begin();
2019
- transitions_[i].info = &*tf;
2020
- ++i;
2021
- }
2022
- for (auto j = 0u; i < transitions_.size(); ++i, ++j)
2023
- transitions_[i].info = ttinfos_.data() + indices[j];
2024
- }
2025
-
2026
- void
2027
- time_zone::init_impl()
2028
- {
2029
- using namespace std;
2030
- using namespace std::chrono;
2031
- auto name = get_tz_dir() + ('/' + name_);
2032
- std::ifstream inf(name);
2033
- if (!inf.is_open())
2034
- throw std::runtime_error{"Unable to open " + name};
2035
- inf.exceptions(std::ios::failbit | std::ios::badbit);
2036
- load_header(inf);
2037
- auto v = load_version(inf);
2038
- std::int32_t tzh_ttisgmtcnt, tzh_ttisstdcnt, tzh_leapcnt,
2039
- tzh_timecnt, tzh_typecnt, tzh_charcnt;
2040
- skip_reserve(inf);
2041
- load_counts(inf, tzh_ttisgmtcnt, tzh_ttisstdcnt, tzh_leapcnt,
2042
- tzh_timecnt, tzh_typecnt, tzh_charcnt);
2043
- if (v == 0)
2044
- {
2045
- load_data<int32_t>(inf, tzh_leapcnt, tzh_timecnt, tzh_typecnt, tzh_charcnt);
2046
- }
2047
- else
2048
- {
2049
- #if !defined(NDEBUG)
2050
- inf.ignore((4+1)*tzh_timecnt + 6*tzh_typecnt + tzh_charcnt + 8*tzh_leapcnt +
2051
- tzh_ttisstdcnt + tzh_ttisgmtcnt);
2052
- load_header(inf);
2053
- auto v2 = load_version(inf);
2054
- assert(v == v2);
2055
- skip_reserve(inf);
2056
- #else // defined(NDEBUG)
2057
- inf.ignore((4+1)*tzh_timecnt + 6*tzh_typecnt + tzh_charcnt + 8*tzh_leapcnt +
2058
- tzh_ttisstdcnt + tzh_ttisgmtcnt + (4+1+15));
2059
- #endif // defined(NDEBUG)
2060
- load_counts(inf, tzh_ttisgmtcnt, tzh_ttisstdcnt, tzh_leapcnt,
2061
- tzh_timecnt, tzh_typecnt, tzh_charcnt);
2062
- load_data<int64_t>(inf, tzh_leapcnt, tzh_timecnt, tzh_typecnt, tzh_charcnt);
2063
- }
2064
- #if !MISSING_LEAP_SECONDS
2065
- if (tzh_leapcnt > 0)
2066
- {
2067
- auto& leap_seconds = get_tzdb_list().front().leaps;
2068
- auto itr = leap_seconds.begin();
2069
- auto l = itr->date();
2070
- seconds leap_count{0};
2071
- for (auto t = std::upper_bound(transitions_.begin(), transitions_.end(), l,
2072
- [](const sys_seconds& x, const transition& ct)
2073
- {
2074
- return x < ct.timepoint;
2075
- });
2076
- t != transitions_.end(); ++t)
2077
- {
2078
- while (t->timepoint >= l)
2079
- {
2080
- ++leap_count;
2081
- if (++itr == leap_seconds.end())
2082
- l = sys_days(max_year/max_day);
2083
- else
2084
- l = itr->date() + leap_count;
2085
- }
2086
- t->timepoint -= leap_count;
2087
- }
2088
- }
2089
- #endif // !MISSING_LEAP_SECONDS
2090
- auto b = transitions_.begin();
2091
- auto i = transitions_.end();
2092
- if (i != b)
2093
- {
2094
- for (--i; i != b; --i)
2095
- {
2096
- if (i->info->offset == i[-1].info->offset &&
2097
- i->info->abbrev == i[-1].info->abbrev &&
2098
- i->info->is_dst == i[-1].info->is_dst)
2099
- i = transitions_.erase(i);
2100
- }
2101
- }
2102
- }
2103
-
2104
- void
2105
- time_zone::init() const
2106
- {
2107
- std::call_once(*adjusted_, [this]() {const_cast<time_zone*>(this)->init_impl();});
2108
- }
2109
-
2110
- sys_info
2111
- time_zone::load_sys_info(std::vector<detail::transition>::const_iterator i) const
2112
- {
2113
- using namespace std::chrono;
2114
- assert(!transitions_.empty());
2115
- assert(i != transitions_.begin());
2116
- sys_info r;
2117
- r.begin = i[-1].timepoint;
2118
- r.end = i != transitions_.end() ? i->timepoint :
2119
- sys_seconds(sys_days(year::max()/max_day));
2120
- r.offset = i[-1].info->offset;
2121
- r.save = i[-1].info->is_dst ? minutes{1} : minutes{0};
2122
- r.abbrev = i[-1].info->abbrev;
2123
- return r;
2124
- }
2125
-
2126
- sys_info
2127
- time_zone::get_info_impl(sys_seconds tp) const
2128
- {
2129
- using namespace std;
2130
- init();
2131
- return load_sys_info(upper_bound(transitions_.begin(), transitions_.end(), tp,
2132
- [](const sys_seconds& x, const transition& t)
2133
- {
2134
- return x < t.timepoint;
2135
- }));
2136
- }
2137
-
2138
- local_info
2139
- time_zone::get_info_impl(local_seconds tp) const
2140
- {
2141
- using namespace std::chrono;
2142
- init();
2143
- local_info i;
2144
- i.result = local_info::unique;
2145
- auto tr = upper_bound(transitions_.begin(), transitions_.end(), tp,
2146
- [](const local_seconds& x, const transition& t)
2147
- {
2148
- return sys_seconds{x.time_since_epoch()} -
2149
- t.info->offset < t.timepoint;
2150
- });
2151
- i.first = load_sys_info(tr);
2152
- auto tps = sys_seconds{(tp - i.first.offset).time_since_epoch()};
2153
- if (tps < i.first.begin + days{1} && tr != transitions_.begin())
2154
- {
2155
- i.second = load_sys_info(--tr);
2156
- tps = sys_seconds{(tp - i.second.offset).time_since_epoch()};
2157
- if (tps < i.second.end)
2158
- {
2159
- i.result = local_info::ambiguous;
2160
- std::swap(i.first, i.second);
2161
- }
2162
- else
2163
- {
2164
- i.second = {};
2165
- }
2166
- }
2167
- else if (tps >= i.first.end && tr != transitions_.end())
2168
- {
2169
- i.second = load_sys_info(++tr);
2170
- tps = sys_seconds{(tp - i.second.offset).time_since_epoch()};
2171
- if (tps < i.second.begin)
2172
- i.result = local_info::nonexistent;
2173
- else
2174
- i.second = {};
2175
- }
2176
- return i;
2177
- }
2178
-
2179
- std::ostream&
2180
- operator<<(std::ostream& os, const time_zone& z)
2181
- {
2182
- using namespace std::chrono;
2183
- z.init();
2184
- os << z.name_ << '\n';
2185
- os << "Initially: ";
2186
- auto const& t = z.transitions_.front();
2187
- if (t.info->offset >= seconds{0})
2188
- os << '+';
2189
- os << make_time(t.info->offset);
2190
- if (t.info->is_dst > 0)
2191
- os << " daylight ";
2192
- else
2193
- os << " standard ";
2194
- os << t.info->abbrev << '\n';
2195
- for (auto i = std::next(z.transitions_.cbegin()); i < z.transitions_.cend(); ++i)
2196
- os << *i << '\n';
2197
- return os;
2198
- }
2199
-
2200
- #if !MISSING_LEAP_SECONDS
2201
-
2202
- leap::leap(const sys_seconds& s, detail::undocumented)
2203
- : date_(s)
2204
- {
2205
- }
2206
-
2207
- #endif // !MISSING_LEAP_SECONDS
2208
-
2209
- #else // !USE_OS_TZDB
2210
-
2211
- time_zone::time_zone(const std::string& s, detail::undocumented)
2212
- : adjusted_(new std::once_flag{})
2213
- {
2214
- try
2215
- {
2216
- using namespace date;
2217
- std::istringstream in(s);
2218
- in.exceptions(std::ios::failbit | std::ios::badbit);
2219
- std::string word;
2220
- in >> word >> name_;
2221
- parse_info(in);
2222
- }
2223
- catch (...)
2224
- {
2225
- std::cerr << s << '\n';
2226
- std::cerr << *this << '\n';
2227
- zonelets_.pop_back();
2228
- throw;
2229
- }
2230
- }
2231
-
2232
- sys_info
2233
- time_zone::get_info_impl(sys_seconds tp) const
2234
- {
2235
- return get_info_impl(tp, static_cast<int>(tz::utc));
2236
- }
2237
-
2238
- local_info
2239
- time_zone::get_info_impl(local_seconds tp) const
2240
- {
2241
- using namespace std::chrono;
2242
- local_info i{};
2243
- i.first = get_info_impl(sys_seconds{tp.time_since_epoch()}, static_cast<int>(tz::local));
2244
- auto tps = sys_seconds{(tp - i.first.offset).time_since_epoch()};
2245
- if (tps < i.first.begin)
2246
- {
2247
- i.second = std::move(i.first);
2248
- i.first = get_info_impl(i.second.begin - seconds{1}, static_cast<int>(tz::utc));
2249
- i.result = local_info::nonexistent;
2250
- }
2251
- else if (i.first.end - tps <= days{1})
2252
- {
2253
- i.second = get_info_impl(i.first.end, static_cast<int>(tz::utc));
2254
- tps = sys_seconds{(tp - i.second.offset).time_since_epoch()};
2255
- if (tps >= i.second.begin)
2256
- i.result = local_info::ambiguous;
2257
- else
2258
- i.second = {};
2259
- }
2260
- return i;
2261
- }
2262
-
2263
- void
2264
- time_zone::add(const std::string& s)
2265
- {
2266
- try
2267
- {
2268
- std::istringstream in(s);
2269
- in.exceptions(std::ios::failbit | std::ios::badbit);
2270
- ws(in);
2271
- if (!in.eof() && in.peek() != '#')
2272
- parse_info(in);
2273
- }
2274
- catch (...)
2275
- {
2276
- std::cerr << s << '\n';
2277
- std::cerr << *this << '\n';
2278
- zonelets_.pop_back();
2279
- throw;
2280
- }
2281
- }
2282
-
2283
- void
2284
- time_zone::parse_info(std::istream& in)
2285
- {
2286
- using namespace date;
2287
- using namespace std::chrono;
2288
- zonelets_.emplace_back();
2289
- auto& zonelet = zonelets_.back();
2290
- zonelet.gmtoff_ = parse_signed_time(in);
2291
- in >> zonelet.u.rule_;
2292
- if (zonelet.u.rule_ == "-")
2293
- zonelet.u.rule_.clear();
2294
- in >> zonelet.format_;
2295
- if (!in.eof())
2296
- ws(in);
2297
- if (in.eof() || in.peek() == '#')
2298
- {
2299
- zonelet.until_year_ = year::max();
2300
- zonelet.until_date_ = MonthDayTime(max_day, tz::utc);
2301
- }
2302
- else
2303
- {
2304
- int y;
2305
- in >> y;
2306
- zonelet.until_year_ = year{y};
2307
- in >> zonelet.until_date_;
2308
- zonelet.until_date_.canonicalize(zonelet.until_year_);
2309
- }
2310
- if ((zonelet.until_year_ < min_year) ||
2311
- (zonelets_.size() > 1 && zonelets_.end()[-2].until_year_ > max_year))
2312
- zonelets_.pop_back();
2313
- }
2314
-
2315
- void
2316
- time_zone::adjust_infos(const std::vector<Rule>& rules)
2317
- {
2318
- using namespace std::chrono;
2319
- using namespace date;
2320
- const zonelet* prev_zonelet = nullptr;
2321
- for (auto& z : zonelets_)
2322
- {
2323
- std::pair<const Rule*, const Rule*> eqr{};
2324
- std::istringstream in;
2325
- in.exceptions(std::ios::failbit | std::ios::badbit);
2326
- // Classify info as rule-based, has save, or neither
2327
- if (!z.u.rule_.empty())
2328
- {
2329
- // Find out if this zonelet has a rule or a save
2330
- eqr = std::equal_range(rules.data(), rules.data() + rules.size(), z.u.rule_);
2331
- if (eqr.first == eqr.second)
2332
- {
2333
- // The rule doesn't exist. Assume this is a save
2334
- try
2335
- {
2336
- using namespace std::chrono;
2337
- using string = std::string;
2338
- in.str(z.u.rule_);
2339
- auto tmp = duration_cast<minutes>(parse_signed_time(in));
2340
- #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
2341
- z.u.rule_.~string();
2342
- z.tag_ = zonelet::has_save;
2343
- ::new(&z.u.save_) minutes(tmp);
2344
- #else
2345
- z.u.rule_.clear();
2346
- z.tag_ = zonelet::has_save;
2347
- z.u.save_ = tmp;
2348
- #endif
2349
- }
2350
- catch (...)
2351
- {
2352
- std::cerr << name_ << " : " << z.u.rule_ << '\n';
2353
- throw;
2354
- }
2355
- }
2356
- }
2357
- else
2358
- {
2359
- // This zone::zonelet has no rule and no save
2360
- z.tag_ = zonelet::is_empty;
2361
- }
2362
-
2363
- minutes final_save{0};
2364
- if (z.tag_ == zonelet::has_save)
2365
- {
2366
- final_save = z.u.save_;
2367
- }
2368
- else if (z.tag_ == zonelet::has_rule)
2369
- {
2370
- z.last_rule_ = find_rule_for_zone(eqr, z.until_year_, z.gmtoff_,
2371
- z.until_date_);
2372
- if (z.last_rule_.first != nullptr)
2373
- final_save = z.last_rule_.first->save();
2374
- }
2375
- z.until_utc_ = z.until_date_.to_sys(z.until_year_, z.gmtoff_, final_save);
2376
- z.until_std_ = local_seconds{z.until_utc_.time_since_epoch()} + z.gmtoff_;
2377
- z.until_loc_ = z.until_std_ + final_save;
2378
-
2379
- if (z.tag_ == zonelet::has_rule)
2380
- {
2381
- if (prev_zonelet != nullptr)
2382
- {
2383
- z.first_rule_ = find_rule_for_zone(eqr, prev_zonelet->until_utc_,
2384
- prev_zonelet->until_std_,
2385
- prev_zonelet->until_loc_);
2386
- if (z.first_rule_.first != nullptr)
2387
- {
2388
- z.initial_save_ = z.first_rule_.first->save();
2389
- z.initial_abbrev_ = z.first_rule_.first->abbrev();
2390
- if (z.first_rule_ != z.last_rule_)
2391
- {
2392
- z.first_rule_ = find_next_rule(eqr.first, eqr.second,
2393
- z.first_rule_.first,
2394
- z.first_rule_.second);
2395
- }
2396
- else
2397
- {
2398
- z.first_rule_ = std::make_pair(nullptr, year::min());
2399
- z.last_rule_ = std::make_pair(nullptr, year::max());
2400
- }
2401
- }
2402
- }
2403
- if (z.first_rule_.first == nullptr && z.last_rule_.first != nullptr)
2404
- {
2405
- z.first_rule_ = std::make_pair(eqr.first, eqr.first->starting_year());
2406
- z.initial_abbrev_ = find_first_std_rule(eqr)->abbrev();
2407
- }
2408
- }
2409
-
2410
- #ifndef NDEBUG
2411
- if (z.first_rule_.first == nullptr)
2412
- {
2413
- assert(z.first_rule_.second == year::min());
2414
- assert(z.last_rule_.first == nullptr);
2415
- assert(z.last_rule_.second == year::max());
2416
- }
2417
- else
2418
- {
2419
- assert(z.last_rule_.first != nullptr);
2420
- }
2421
- #endif
2422
- prev_zonelet = &z;
2423
- }
2424
- }
2425
-
2426
- static
2427
- std::string
2428
- format_abbrev(std::string format, const std::string& variable, std::chrono::seconds off,
2429
- std::chrono::minutes save)
2430
- {
2431
- using namespace std::chrono;
2432
- auto k = format.find("%s");
2433
- if (k != std::string::npos)
2434
- {
2435
- format.replace(k, 2, variable);
2436
- }
2437
- else
2438
- {
2439
- k = format.find('/');
2440
- if (k != std::string::npos)
2441
- {
2442
- if (save == minutes{0})
2443
- format.erase(k);
2444
- else
2445
- format.erase(0, k+1);
2446
- }
2447
- else
2448
- {
2449
- k = format.find("%z");
2450
- if (k != std::string::npos)
2451
- {
2452
- std::string temp;
2453
- if (off < seconds{0})
2454
- {
2455
- temp = '-';
2456
- off = -off;
2457
- }
2458
- else
2459
- temp = '+';
2460
- auto h = date::floor<hours>(off);
2461
- off -= h;
2462
- if (h < hours{10})
2463
- temp += '0';
2464
- temp += std::to_string(h.count());
2465
- if (off > seconds{0})
2466
- {
2467
- auto m = date::floor<minutes>(off);
2468
- off -= m;
2469
- if (m < minutes{10})
2470
- temp += '0';
2471
- temp += std::to_string(m.count());
2472
- if (off > seconds{0})
2473
- {
2474
- if (off < seconds{10})
2475
- temp += '0';
2476
- temp += std::to_string(off.count());
2477
- }
2478
- }
2479
- format.replace(k, 2, temp);
2480
- }
2481
- }
2482
- }
2483
- return format;
2484
- }
2485
-
2486
- sys_info
2487
- time_zone::get_info_impl(sys_seconds tp, int tz_int) const
2488
- {
2489
- using namespace std::chrono;
2490
- using namespace date;
2491
- tz timezone = static_cast<tz>(tz_int);
2492
- assert(timezone != tz::standard);
2493
- auto y = year_month_day(floor<days>(tp)).year();
2494
- if (y < min_year || y > max_year)
2495
- throw std::runtime_error("The year " + std::to_string(static_cast<int>(y)) +
2496
- " is out of range:[" + std::to_string(static_cast<int>(min_year)) + ", "
2497
- + std::to_string(static_cast<int>(max_year)) + "]");
2498
- std::call_once(*adjusted_,
2499
- [this]()
2500
- {
2501
- const_cast<time_zone*>(this)->adjust_infos(get_tzdb().rules);
2502
- });
2503
- auto i = std::upper_bound(zonelets_.begin(), zonelets_.end(), tp,
2504
- [timezone](sys_seconds t, const zonelet& zl)
2505
- {
2506
- return timezone == tz::utc ? t < zl.until_utc_ :
2507
- t < sys_seconds{zl.until_loc_.time_since_epoch()};
2508
- });
2509
-
2510
- sys_info r{};
2511
- if (i != zonelets_.end())
2512
- {
2513
- if (i->tag_ == zonelet::has_save)
2514
- {
2515
- if (i != zonelets_.begin())
2516
- r.begin = i[-1].until_utc_;
2517
- else
2518
- r.begin = sys_days(year::min()/min_day);
2519
- r.end = i->until_utc_;
2520
- r.offset = i->gmtoff_ + i->u.save_;
2521
- r.save = i->u.save_;
2522
- }
2523
- else if (i->u.rule_.empty())
2524
- {
2525
- if (i != zonelets_.begin())
2526
- r.begin = i[-1].until_utc_;
2527
- else
2528
- r.begin = sys_days(year::min()/min_day);
2529
- r.end = i->until_utc_;
2530
- r.offset = i->gmtoff_;
2531
- }
2532
- else
2533
- {
2534
- r = find_rule(i->first_rule_, i->last_rule_, y, i->gmtoff_,
2535
- MonthDayTime(local_seconds{tp.time_since_epoch()}, timezone),
2536
- i->initial_save_, i->initial_abbrev_);
2537
- r.offset = i->gmtoff_ + r.save;
2538
- if (i != zonelets_.begin() && r.begin < i[-1].until_utc_)
2539
- r.begin = i[-1].until_utc_;
2540
- if (r.end > i->until_utc_)
2541
- r.end = i->until_utc_;
2542
- }
2543
- r.abbrev = format_abbrev(i->format_, r.abbrev, r.offset, r.save);
2544
- assert(r.begin < r.end);
2545
- }
2546
- return r;
2547
- }
2548
-
2549
- std::ostream&
2550
- operator<<(std::ostream& os, const time_zone& z)
2551
- {
2552
- using namespace date;
2553
- using namespace std::chrono;
2554
- detail::save_ostream<char> _(os);
2555
- os.fill(' ');
2556
- os.flags(std::ios::dec | std::ios::left);
2557
- std::call_once(*z.adjusted_,
2558
- [&z]()
2559
- {
2560
- const_cast<time_zone&>(z).adjust_infos(get_tzdb().rules);
2561
- });
2562
- os.width(35);
2563
- os << z.name_;
2564
- std::string indent;
2565
- for (auto const& s : z.zonelets_)
2566
- {
2567
- os << indent;
2568
- if (s.gmtoff_ >= seconds{0})
2569
- os << ' ';
2570
- os << make_time(s.gmtoff_) << " ";
2571
- os.width(15);
2572
- if (s.tag_ != zonelet::has_save)
2573
- os << s.u.rule_;
2574
- else
2575
- {
2576
- std::ostringstream tmp;
2577
- tmp << make_time(s.u.save_);
2578
- os << tmp.str();
2579
- }
2580
- os.width(8);
2581
- os << s.format_ << " ";
2582
- os << s.until_year_ << ' ' << s.until_date_;
2583
- os << " " << s.until_utc_ << " UTC";
2584
- os << " " << s.until_std_ << " STD";
2585
- os << " " << s.until_loc_;
2586
- os << " " << make_time(s.initial_save_);
2587
- os << " " << s.initial_abbrev_;
2588
- if (s.first_rule_.first != nullptr)
2589
- os << " {" << *s.first_rule_.first << ", " << s.first_rule_.second << '}';
2590
- else
2591
- os << " {" << "nullptr" << ", " << s.first_rule_.second << '}';
2592
- if (s.last_rule_.first != nullptr)
2593
- os << " {" << *s.last_rule_.first << ", " << s.last_rule_.second << '}';
2594
- else
2595
- os << " {" << "nullptr" << ", " << s.last_rule_.second << '}';
2596
- os << '\n';
2597
- if (indent.empty())
2598
- indent = std::string(35, ' ');
2599
- }
2600
- return os;
2601
- }
2602
-
2603
- #endif // !USE_OS_TZDB
2604
-
2605
- #if !MISSING_LEAP_SECONDS
2606
-
2607
- std::ostream&
2608
- operator<<(std::ostream& os, const leap& x)
2609
- {
2610
- using namespace date;
2611
- return os << x.date_ << " +";
2612
- }
2613
-
2614
- #endif // !MISSING_LEAP_SECONDS
2615
-
2616
- #if USE_OS_TZDB
2617
-
2618
- # ifdef __APPLE__
2619
- static
2620
- std::string
2621
- get_version()
2622
- {
2623
- using namespace std;
2624
- auto path = get_tz_dir() + string("/+VERSION");
2625
- ifstream in{path};
2626
- string version;
2627
- in >> version;
2628
- if (in.fail())
2629
- throw std::runtime_error("Unable to get Timezone database version from " + path);
2630
- return version;
2631
- }
2632
- # endif
2633
-
2634
- static
2635
- std::unique_ptr<tzdb>
2636
- init_tzdb()
2637
- {
2638
- std::unique_ptr<tzdb> db(new tzdb);
2639
-
2640
- //Iterate through folders
2641
- std::queue<std::string> subfolders;
2642
- subfolders.emplace(get_tz_dir());
2643
- struct dirent* d;
2644
- struct stat s;
2645
- while (!subfolders.empty())
2646
- {
2647
- auto dirname = std::move(subfolders.front());
2648
- subfolders.pop();
2649
- auto dir = opendir(dirname.c_str());
2650
- if (!dir)
2651
- continue;
2652
- while ((d = readdir(dir)) != nullptr)
2653
- {
2654
- // Ignore these files:
2655
- if (d->d_name[0] == '.' || // curdir, prevdir, hidden
2656
- memcmp(d->d_name, "posix", 5) == 0 || // starts with posix
2657
- strcmp(d->d_name, "Factory") == 0 ||
2658
- strcmp(d->d_name, "iso3166.tab") == 0 ||
2659
- strcmp(d->d_name, "right") == 0 ||
2660
- strcmp(d->d_name, "+VERSION") == 0 ||
2661
- strcmp(d->d_name, "zone.tab") == 0 ||
2662
- strcmp(d->d_name, "zone1970.tab") == 0 ||
2663
- strcmp(d->d_name, "tzdata.zi") == 0 ||
2664
- strcmp(d->d_name, "leapseconds") == 0 ||
2665
- strcmp(d->d_name, "leap-seconds.list") == 0 )
2666
- continue;
2667
- auto subname = dirname + folder_delimiter + d->d_name;
2668
- if(stat(subname.c_str(), &s) == 0)
2669
- {
2670
- if(S_ISDIR(s.st_mode))
2671
- {
2672
- if(!S_ISLNK(s.st_mode))
2673
- {
2674
- subfolders.push(subname);
2675
- }
2676
- }
2677
- else
2678
- {
2679
- db->zones.emplace_back(subname.substr(get_tz_dir().size()+1),
2680
- detail::undocumented{});
2681
- }
2682
- }
2683
- }
2684
- closedir(dir);
2685
- }
2686
- db->zones.shrink_to_fit();
2687
- std::sort(db->zones.begin(), db->zones.end());
2688
- # if !MISSING_LEAP_SECONDS
2689
- std::ifstream in(get_tz_dir() + std::string(1, folder_delimiter) + "right/UTC",
2690
- std::ios_base::binary);
2691
- if (in)
2692
- {
2693
- in.exceptions(std::ios::failbit | std::ios::badbit);
2694
- db->leaps = load_just_leaps(in);
2695
- }
2696
- else
2697
- {
2698
- in.clear();
2699
- in.open(get_tz_dir() + std::string(1, folder_delimiter) +
2700
- "UTC", std::ios_base::binary);
2701
- if (!in)
2702
- throw std::runtime_error("Unable to extract leap second information");
2703
- in.exceptions(std::ios::failbit | std::ios::badbit);
2704
- db->leaps = load_just_leaps(in);
2705
- }
2706
- # endif // !MISSING_LEAP_SECONDS
2707
- # ifdef __APPLE__
2708
- db->version = get_version();
2709
- # endif
2710
- return db;
2711
- }
2712
-
2713
- #else // !USE_OS_TZDB
2714
-
2715
- // link
2716
-
2717
- link::link(const std::string& s)
2718
- {
2719
- using namespace date;
2720
- std::istringstream in(s);
2721
- in.exceptions(std::ios::failbit | std::ios::badbit);
2722
- std::string word;
2723
- in >> word >> target_ >> name_;
2724
- }
2725
-
2726
- std::ostream&
2727
- operator<<(std::ostream& os, const link& x)
2728
- {
2729
- using namespace date;
2730
- detail::save_ostream<char> _(os);
2731
- os.fill(' ');
2732
- os.flags(std::ios::dec | std::ios::left);
2733
- os.width(35);
2734
- return os << x.name_ << " --> " << x.target_;
2735
- }
2736
-
2737
- // leap
2738
-
2739
- leap::leap(const std::string& s, detail::undocumented)
2740
- {
2741
- using namespace date;
2742
- std::istringstream in(s);
2743
- in.exceptions(std::ios::failbit | std::ios::badbit);
2744
- std::string word;
2745
- int y;
2746
- MonthDayTime date;
2747
- in >> word >> y >> date;
2748
- date_ = date.to_time_point(year(y));
2749
- }
2750
-
2751
- static
2752
- bool
2753
- file_exists(const std::string& filename)
2754
- {
2755
- #ifdef _WIN32
2756
- return ::_access(filename.c_str(), 0) == 0;
2757
- #else
2758
- return ::access(filename.c_str(), F_OK) == 0;
2759
- #endif
2760
- }
2761
-
2762
- #if HAS_REMOTE_API
2763
-
2764
- // CURL tools
2765
-
2766
- static
2767
- int
2768
- curl_global()
2769
- {
2770
- if (::curl_global_init(CURL_GLOBAL_DEFAULT) != 0)
2771
- throw std::runtime_error("CURL global initialization failed");
2772
- return 0;
2773
- }
2774
-
2775
- namespace
2776
- {
2777
-
2778
- struct curl_deleter
2779
- {
2780
- void operator()(CURL* p) const
2781
- {
2782
- ::curl_easy_cleanup(p);
2783
- }
2784
- };
2785
-
2786
- } // unnamed namespace
2787
-
2788
- static
2789
- std::unique_ptr<CURL, curl_deleter>
2790
- curl_init()
2791
- {
2792
- static const auto curl_is_now_initiailized = curl_global();
2793
- (void)curl_is_now_initiailized;
2794
- return std::unique_ptr<CURL, curl_deleter>{::curl_easy_init()};
2795
- }
2796
-
2797
- static
2798
- bool
2799
- download_to_string(const std::string& url, std::string& str)
2800
- {
2801
- str.clear();
2802
- auto curl = curl_init();
2803
- if (!curl)
2804
- return false;
2805
- std::string version;
2806
- curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str());
2807
- curl_write_callback write_cb = [](char* contents, std::size_t size, std::size_t nmemb,
2808
- void* userp) -> std::size_t
2809
- {
2810
- auto& userstr = *static_cast<std::string*>(userp);
2811
- auto realsize = size * nmemb;
2812
- userstr.append(contents, realsize);
2813
- return realsize;
2814
- };
2815
- curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, write_cb);
2816
- curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &str);
2817
- curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, false);
2818
- auto res = curl_easy_perform(curl.get());
2819
- return (res == CURLE_OK);
2820
- }
2821
-
2822
- namespace
2823
- {
2824
- enum class download_file_options { binary, text };
2825
- }
2826
-
2827
- static
2828
- bool
2829
- download_to_file(const std::string& url, const std::string& local_filename,
2830
- download_file_options opts)
2831
- {
2832
- auto curl = curl_init();
2833
- if (!curl)
2834
- return false;
2835
- curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str());
2836
- curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, false);
2837
- curl_write_callback write_cb = [](char* contents, std::size_t size, std::size_t nmemb,
2838
- void* userp) -> std::size_t
2839
- {
2840
- auto& of = *static_cast<std::ofstream*>(userp);
2841
- auto realsize = size * nmemb;
2842
- of.write(contents, static_cast<std::streamsize>(realsize));
2843
- return realsize;
2844
- };
2845
- curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, write_cb);
2846
- decltype(curl_easy_perform(curl.get())) res;
2847
- {
2848
- std::ofstream of(local_filename,
2849
- opts == download_file_options::binary ?
2850
- std::ofstream::out | std::ofstream::binary :
2851
- std::ofstream::out);
2852
- of.exceptions(std::ios::badbit);
2853
- curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &of);
2854
- res = curl_easy_perform(curl.get());
2855
- }
2856
- return res == CURLE_OK;
2857
- }
2858
-
2859
- std::string
2860
- remote_version()
2861
- {
2862
- std::string version;
2863
- std::string str;
2864
- if (download_to_string("https://www.iana.org/time-zones", str))
2865
- {
2866
- CONSTDATA char db[] = "/time-zones/releases/tzdata";
2867
- CONSTDATA auto db_size = sizeof(db) - 1;
2868
- auto p = str.find(db, 0, db_size);
2869
- const int ver_str_len = 5;
2870
- if (p != std::string::npos && p + (db_size + ver_str_len) <= str.size())
2871
- version = str.substr(p + db_size, ver_str_len);
2872
- }
2873
- return version;
2874
- }
2875
-
2876
-
2877
- // TODO! Using system() create a process and a console window.
2878
- // This is useful to see what errors may occur but is slow and distracting.
2879
- // Consider implementing this functionality more directly, such as
2880
- // using _mkdir and CreateProcess etc.
2881
- // But use the current means now as matches Unix implementations and while
2882
- // in proof of concept / testing phase.
2883
- // TODO! Use <filesystem> eventually.
2884
- static
2885
- bool
2886
- remove_folder_and_subfolders(const std::string& folder)
2887
- {
2888
- # ifdef _WIN32
2889
- # if USE_SHELL_API
2890
- // Delete the folder contents by deleting the folder.
2891
- std::string cmd = "rd /s /q \"";
2892
- cmd += folder;
2893
- cmd += '\"';
2894
- return std::system(cmd.c_str()) == EXIT_SUCCESS;
2895
- # else // !USE_SHELL_API
2896
- // Create a buffer containing the path to delete. It must be terminated
2897
- // by two nuls. Who designs these API's...
2898
- std::vector<char> from;
2899
- from.assign(folder.begin(), folder.end());
2900
- from.push_back('\0');
2901
- from.push_back('\0');
2902
- SHFILEOPSTRUCT fo{}; // Zero initialize.
2903
- fo.wFunc = FO_DELETE;
2904
- fo.pFrom = from.data();
2905
- fo.fFlags = FOF_NO_UI;
2906
- int ret = SHFileOperation(&fo);
2907
- if (ret == 0 && !fo.fAnyOperationsAborted)
2908
- return true;
2909
- return false;
2910
- # endif // !USE_SHELL_API
2911
- # else // !_WIN32
2912
- # if USE_SHELL_API
2913
- return std::system(("rm -R " + folder).c_str()) == EXIT_SUCCESS;
2914
- # else // !USE_SHELL_API
2915
- struct dir_deleter {
2916
- dir_deleter() {}
2917
- void operator()(DIR* d) const
2918
- {
2919
- if (d != nullptr)
2920
- {
2921
- int result = closedir(d);
2922
- assert(result == 0);
2923
- }
2924
- }
2925
- };
2926
- using closedir_ptr = std::unique_ptr<DIR, dir_deleter>;
2927
-
2928
- std::string filename;
2929
- struct stat statbuf;
2930
- std::size_t folder_len = folder.length();
2931
- struct dirent* p = nullptr;
2932
-
2933
- closedir_ptr d(opendir(folder.c_str()));
2934
- bool r = d.get() != nullptr;
2935
- while (r && (p=readdir(d.get())) != nullptr)
2936
- {
2937
- if (strcmp(p->d_name, ".") == 0 || strcmp(p->d_name, "..") == 0)
2938
- continue;
2939
-
2940
- // + 2 for path delimiter and nul terminator.
2941
- std::size_t buf_len = folder_len + strlen(p->d_name) + 2;
2942
- filename.resize(buf_len);
2943
- std::size_t path_len = static_cast<std::size_t>(
2944
- snprintf(&filename[0], buf_len, "%s/%s", folder.c_str(), p->d_name));
2945
- assert(path_len == buf_len - 1);
2946
- filename.resize(path_len);
2947
-
2948
- if (stat(filename.c_str(), &statbuf) == 0)
2949
- r = S_ISDIR(statbuf.st_mode)
2950
- ? remove_folder_and_subfolders(filename)
2951
- : unlink(filename.c_str()) == 0;
2952
- }
2953
- d.reset();
2954
-
2955
- if (r)
2956
- r = rmdir(folder.c_str()) == 0;
2957
-
2958
- return r;
2959
- # endif // !USE_SHELL_API
2960
- # endif // !_WIN32
2961
- }
2962
-
2963
- static
2964
- bool
2965
- make_directory(const std::string& folder)
2966
- {
2967
- # ifdef _WIN32
2968
- # if USE_SHELL_API
2969
- // Re-create the folder.
2970
- std::string cmd = "mkdir \"";
2971
- cmd += folder;
2972
- cmd += '\"';
2973
- return std::system(cmd.c_str()) == EXIT_SUCCESS;
2974
- # else // !USE_SHELL_API
2975
- return _mkdir(folder.c_str()) == 0;
2976
- # endif // !USE_SHELL_API
2977
- # else // !_WIN32
2978
- # if USE_SHELL_API
2979
- return std::system(("mkdir -p " + folder).c_str()) == EXIT_SUCCESS;
2980
- # else // !USE_SHELL_API
2981
- return mkdir(folder.c_str(), 0777) == 0;
2982
- # endif // !USE_SHELL_API
2983
- # endif // !_WIN32
2984
- }
2985
-
2986
- static
2987
- bool
2988
- delete_file(const std::string& file)
2989
- {
2990
- # ifdef _WIN32
2991
- # if USE_SHELL_API
2992
- std::string cmd = "del \"";
2993
- cmd += file;
2994
- cmd += '\"';
2995
- return std::system(cmd.c_str()) == 0;
2996
- # else // !USE_SHELL_API
2997
- return _unlink(file.c_str()) == 0;
2998
- # endif // !USE_SHELL_API
2999
- # else // !_WIN32
3000
- # if USE_SHELL_API
3001
- return std::system(("rm " + file).c_str()) == EXIT_SUCCESS;
3002
- # else // !USE_SHELL_API
3003
- return unlink(file.c_str()) == 0;
3004
- # endif // !USE_SHELL_API
3005
- # endif // !_WIN32
3006
- }
3007
-
3008
- # ifdef _WIN32
3009
-
3010
- static
3011
- bool
3012
- move_file(const std::string& from, const std::string& to)
3013
- {
3014
- # if USE_SHELL_API
3015
- std::string cmd = "move \"";
3016
- cmd += from;
3017
- cmd += "\" \"";
3018
- cmd += to;
3019
- cmd += '\"';
3020
- return std::system(cmd.c_str()) == EXIT_SUCCESS;
3021
- # else // !USE_SHELL_API
3022
- return !!::MoveFile(from.c_str(), to.c_str());
3023
- # endif // !USE_SHELL_API
3024
- }
3025
-
3026
- // Usually something like "c:\Program Files".
3027
- static
3028
- std::string
3029
- get_program_folder()
3030
- {
3031
- return get_known_folder(FOLDERID_ProgramFiles);
3032
- }
3033
-
3034
- // Note folder can and usually does contain spaces.
3035
- static
3036
- std::string
3037
- get_unzip_program()
3038
- {
3039
- std::string path;
3040
-
3041
- // 7-Zip appears to note its location in the registry.
3042
- // If that doesn't work, fall through and take a guess, but it will likely be wrong.
3043
- HKEY hKey = nullptr;
3044
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\7-Zip", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
3045
- {
3046
- char value_buffer[MAX_PATH + 1]; // fyi 260 at time of writing.
3047
- // in/out parameter. Documentation say that size is a count of bytes not chars.
3048
- DWORD size = sizeof(value_buffer) - sizeof(value_buffer[0]);
3049
- DWORD tzi_type = REG_SZ;
3050
- // Testing shows Path key value is "C:\Program Files\7-Zip\" i.e. always with trailing \.
3051
- bool got_value = (RegQueryValueExA(hKey, "Path", nullptr, &tzi_type,
3052
- reinterpret_cast<LPBYTE>(value_buffer), &size) == ERROR_SUCCESS);
3053
- RegCloseKey(hKey); // Close now incase of throw later.
3054
- if (got_value)
3055
- {
3056
- // Function does not guarantee to null terminate.
3057
- value_buffer[size / sizeof(value_buffer[0])] = '\0';
3058
- path = value_buffer;
3059
- if (!path.empty())
3060
- {
3061
- path += "7z.exe";
3062
- return path;
3063
- }
3064
- }
3065
- }
3066
- path += get_program_folder();
3067
- path += folder_delimiter;
3068
- path += "7-Zip\\7z.exe";
3069
- return path;
3070
- }
3071
-
3072
- # if !USE_SHELL_API
3073
- static
3074
- int
3075
- run_program(const std::string& command)
3076
- {
3077
- STARTUPINFO si{};
3078
- si.cb = sizeof(si);
3079
- PROCESS_INFORMATION pi{};
3080
-
3081
- // Allegedly CreateProcess overwrites the command line. Ugh.
3082
- std::string mutable_command(command);
3083
- if (CreateProcess(nullptr, &mutable_command[0],
3084
- nullptr, nullptr, FALSE, CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi))
3085
- {
3086
- WaitForSingleObject(pi.hProcess, INFINITE);
3087
- DWORD exit_code;
3088
- bool got_exit_code = !!GetExitCodeProcess(pi.hProcess, &exit_code);
3089
- CloseHandle(pi.hProcess);
3090
- CloseHandle(pi.hThread);
3091
- // Not 100% sure about this still active thing is correct,
3092
- // but I'm going with it because I *think* WaitForSingleObject might
3093
- // return in some cases without INFINITE-ly waiting.
3094
- // But why/wouldn't GetExitCodeProcess return false in that case?
3095
- if (got_exit_code && exit_code != STILL_ACTIVE)
3096
- return static_cast<int>(exit_code);
3097
- }
3098
- return EXIT_FAILURE;
3099
- }
3100
- # endif // !USE_SHELL_API
3101
-
3102
- static
3103
- std::string
3104
- get_download_tar_file(const std::string& version)
3105
- {
3106
- auto file = get_install();
3107
- file += folder_delimiter;
3108
- file += "tzdata";
3109
- file += version;
3110
- file += ".tar";
3111
- return file;
3112
- }
3113
-
3114
- static
3115
- bool
3116
- extract_gz_file(const std::string& version, const std::string& gz_file,
3117
- const std::string& dest_folder)
3118
- {
3119
- auto unzip_prog = get_unzip_program();
3120
- bool unzip_result = false;
3121
- // Use the unzip program to extract the tar file from the archive.
3122
-
3123
- // Aim to create a string like:
3124
- // "C:\Program Files\7-Zip\7z.exe" x "C:\Users\SomeUser\Downloads\tzdata2016d.tar.gz"
3125
- // -o"C:\Users\SomeUser\Downloads\tzdata"
3126
- std::string cmd;
3127
- cmd = '\"';
3128
- cmd += unzip_prog;
3129
- cmd += "\" x \"";
3130
- cmd += gz_file;
3131
- cmd += "\" -o\"";
3132
- cmd += dest_folder;
3133
- cmd += '\"';
3134
-
3135
- # if USE_SHELL_API
3136
- // When using shelling out with std::system() extra quotes are required around the
3137
- // whole command. It's weird but necessary it seems, see:
3138
- // http://stackoverflow.com/q/27975969/576911
3139
-
3140
- cmd = "\"" + cmd + "\"";
3141
- if (std::system(cmd.c_str()) == EXIT_SUCCESS)
3142
- unzip_result = true;
3143
- # else // !USE_SHELL_API
3144
- if (run_program(cmd) == EXIT_SUCCESS)
3145
- unzip_result = true;
3146
- # endif // !USE_SHELL_API
3147
- if (unzip_result)
3148
- delete_file(gz_file);
3149
-
3150
- // Use the unzip program extract the data from the tar file that was
3151
- // just extracted from the archive.
3152
- auto tar_file = get_download_tar_file(version);
3153
- cmd = '\"';
3154
- cmd += unzip_prog;
3155
- cmd += "\" x \"";
3156
- cmd += tar_file;
3157
- cmd += "\" -o\"";
3158
- cmd += get_install();
3159
- cmd += '\"';
3160
- # if USE_SHELL_API
3161
- cmd = "\"" + cmd + "\"";
3162
- if (std::system(cmd.c_str()) == EXIT_SUCCESS)
3163
- unzip_result = true;
3164
- # else // !USE_SHELL_API
3165
- if (run_program(cmd) == EXIT_SUCCESS)
3166
- unzip_result = true;
3167
- # endif // !USE_SHELL_API
3168
-
3169
- if (unzip_result)
3170
- delete_file(tar_file);
3171
-
3172
- return unzip_result;
3173
- }
3174
-
3175
- static
3176
- std::string
3177
- get_download_mapping_file(const std::string& version)
3178
- {
3179
- auto file = get_install() + version + "windowsZones.xml";
3180
- return file;
3181
- }
3182
-
3183
- # else // !_WIN32
3184
-
3185
- # if !USE_SHELL_API
3186
- static
3187
- int
3188
- run_program(const char* prog, const char*const args[])
3189
- {
3190
- pid_t pid = fork();
3191
- if (pid == -1) // Child failed to start.
3192
- return EXIT_FAILURE;
3193
-
3194
- if (pid != 0)
3195
- {
3196
- // We are in the parent. Child started. Wait for it.
3197
- pid_t ret;
3198
- int status;
3199
- while ((ret = waitpid(pid, &status, 0)) == -1)
3200
- {
3201
- if (errno != EINTR)
3202
- break;
3203
- }
3204
- if (ret != -1)
3205
- {
3206
- if (WIFEXITED(status))
3207
- return WEXITSTATUS(status);
3208
- }
3209
- printf("Child issues!\n");
3210
-
3211
- return EXIT_FAILURE; // Not sure what status of child is.
3212
- }
3213
- else // We are in the child process. Start the program the parent wants to run.
3214
- {
3215
-
3216
- if (execv(prog, const_cast<char**>(args)) == -1) // Does not return.
3217
- {
3218
- perror("unreachable 0\n");
3219
- _Exit(127);
3220
- }
3221
- printf("unreachable 2\n");
3222
- }
3223
- printf("unreachable 2\n");
3224
- // Unreachable.
3225
- assert(false);
3226
- exit(EXIT_FAILURE);
3227
- return EXIT_FAILURE;
3228
- }
3229
- # endif // !USE_SHELL_API
3230
-
3231
- static
3232
- bool
3233
- extract_gz_file(const std::string&, const std::string& gz_file, const std::string&)
3234
- {
3235
- # if USE_SHELL_API
3236
- bool unzipped = std::system(("tar -xzf " + gz_file + " -C " + get_install()).c_str()) == EXIT_SUCCESS;
3237
- # else // !USE_SHELL_API
3238
- const char prog[] = {"/usr/bin/tar"};
3239
- const char*const args[] =
3240
- {
3241
- prog, "-xzf", gz_file.c_str(), "-C", get_install().c_str(), nullptr
3242
- };
3243
- bool unzipped = (run_program(prog, args) == EXIT_SUCCESS);
3244
- # endif // !USE_SHELL_API
3245
- if (unzipped)
3246
- {
3247
- delete_file(gz_file);
3248
- return true;
3249
- }
3250
- return false;
3251
- }
3252
-
3253
- # endif // !_WIN32
3254
-
3255
- bool
3256
- remote_download(const std::string& version)
3257
- {
3258
- assert(!version.empty());
3259
-
3260
- # ifdef _WIN32
3261
- // Download folder should be always available for Windows
3262
- # else // !_WIN32
3263
- // Create download folder if it does not exist on UNIX system
3264
- auto download_folder = get_install();
3265
- if (!file_exists(download_folder))
3266
- {
3267
- if (!make_directory(download_folder))
3268
- return false;
3269
- }
3270
- # endif // _WIN32
3271
-
3272
- auto url = "https://data.iana.org/time-zones/releases/tzdata" + version +
3273
- ".tar.gz";
3274
- bool result = download_to_file(url, get_download_gz_file(version),
3275
- download_file_options::binary);
3276
- # ifdef _WIN32
3277
- if (result)
3278
- {
3279
- auto mapping_file = get_download_mapping_file(version);
3280
- result = download_to_file("http://unicode.org/repos/cldr/trunk/common/"
3281
- "supplemental/windowsZones.xml",
3282
- mapping_file, download_file_options::text);
3283
- }
3284
- # endif // _WIN32
3285
- return result;
3286
- }
3287
-
3288
- bool
3289
- remote_install(const std::string& version)
3290
- {
3291
- auto success = false;
3292
- assert(!version.empty());
3293
-
3294
- std::string install = get_install();
3295
- auto gz_file = get_download_gz_file(version);
3296
- if (file_exists(gz_file))
3297
- {
3298
- if (file_exists(install))
3299
- remove_folder_and_subfolders(install);
3300
- if (make_directory(install))
3301
- {
3302
- if (extract_gz_file(version, gz_file, install))
3303
- success = true;
3304
- # ifdef _WIN32
3305
- auto mapping_file_source = get_download_mapping_file(version);
3306
- auto mapping_file_dest = get_install();
3307
- mapping_file_dest += folder_delimiter;
3308
- mapping_file_dest += "windowsZones.xml";
3309
- if (!move_file(mapping_file_source, mapping_file_dest))
3310
- success = false;
3311
- # endif // _WIN32
3312
- }
3313
- }
3314
- return success;
3315
- }
3316
-
3317
- #endif // HAS_REMOTE_API
3318
-
3319
- static
3320
- std::string
3321
- get_version(const std::string& path)
3322
- {
3323
- std::string version;
3324
- std::ifstream infile(path + "version");
3325
- if (infile.is_open())
3326
- {
3327
- infile >> version;
3328
- if (!infile.fail())
3329
- return version;
3330
- }
3331
- else
3332
- {
3333
- infile.open(path + "NEWS");
3334
- while (infile)
3335
- {
3336
- infile >> version;
3337
- if (version == "Release")
3338
- {
3339
- infile >> version;
3340
- return version;
3341
- }
3342
- }
3343
- }
3344
- throw std::runtime_error("Unable to get Timezone database version from " + path);
3345
- }
3346
-
3347
- static
3348
- std::unique_ptr<tzdb>
3349
- init_tzdb()
3350
- {
3351
- using namespace date;
3352
- const std::string install = get_install();
3353
- const std::string path = install + folder_delimiter;
3354
- std::string line;
3355
- bool continue_zone = false;
3356
- std::unique_ptr<tzdb> db(new tzdb);
3357
-
3358
- #if AUTO_DOWNLOAD
3359
- if (!file_exists(install))
3360
- {
3361
- auto rv = remote_version();
3362
- if (!rv.empty() && remote_download(rv))
3363
- {
3364
- if (!remote_install(rv))
3365
- {
3366
- std::string msg = "Timezone database version \"";
3367
- msg += rv;
3368
- msg += "\" did not install correctly to \"";
3369
- msg += install;
3370
- msg += "\"";
3371
- throw std::runtime_error(msg);
3372
- }
3373
- }
3374
- if (!file_exists(install))
3375
- {
3376
- std::string msg = "Timezone database not found at \"";
3377
- msg += install;
3378
- msg += "\"";
3379
- throw std::runtime_error(msg);
3380
- }
3381
- db->version = get_version(path);
3382
- }
3383
- else
3384
- {
3385
- db->version = get_version(path);
3386
- auto rv = remote_version();
3387
- if (!rv.empty() && db->version != rv)
3388
- {
3389
- if (remote_download(rv))
3390
- {
3391
- remote_install(rv);
3392
- db->version = get_version(path);
3393
- }
3394
- }
3395
- }
3396
- #else // !AUTO_DOWNLOAD
3397
- if (!file_exists(install))
3398
- {
3399
- std::string msg = "Timezone database not found at \"";
3400
- msg += install;
3401
- msg += "\"";
3402
- throw std::runtime_error(msg);
3403
- }
3404
- db->version = get_version(path);
3405
- #endif // !AUTO_DOWNLOAD
3406
-
3407
- CONSTDATA char*const files[] =
3408
- {
3409
- "africa", "antarctica", "asia", "australasia", "backward", "etcetera", "europe",
3410
- "pacificnew", "northamerica", "southamerica", "systemv", "leapseconds"
3411
- };
3412
-
3413
- for (const auto& filename : files)
3414
- {
3415
- std::ifstream infile(path + filename);
3416
- while (infile)
3417
- {
3418
- std::getline(infile, line);
3419
- if (!line.empty() && line[0] != '#')
3420
- {
3421
- std::istringstream in(line);
3422
- std::string word;
3423
- in >> word;
3424
- if (word == "Rule")
3425
- {
3426
- db->rules.push_back(Rule(line));
3427
- continue_zone = false;
3428
- }
3429
- else if (word == "Link")
3430
- {
3431
- db->links.push_back(link(line));
3432
- continue_zone = false;
3433
- }
3434
- else if (word == "Leap")
3435
- {
3436
- db->leaps.push_back(leap(line, detail::undocumented{}));
3437
- continue_zone = false;
3438
- }
3439
- else if (word == "Zone")
3440
- {
3441
- db->zones.push_back(time_zone(line, detail::undocumented{}));
3442
- continue_zone = true;
3443
- }
3444
- else if (line[0] == '\t' && continue_zone)
3445
- {
3446
- db->zones.back().add(line);
3447
- }
3448
- else
3449
- {
3450
- std::cerr << line << '\n';
3451
- }
3452
- }
3453
- }
3454
- }
3455
- std::sort(db->rules.begin(), db->rules.end());
3456
- Rule::split_overlaps(db->rules);
3457
- std::sort(db->zones.begin(), db->zones.end());
3458
- db->zones.shrink_to_fit();
3459
- std::sort(db->links.begin(), db->links.end());
3460
- db->links.shrink_to_fit();
3461
- std::sort(db->leaps.begin(), db->leaps.end());
3462
- db->leaps.shrink_to_fit();
3463
-
3464
- #ifdef _WIN32
3465
- std::string mapping_file = get_install() + folder_delimiter + "windowsZones.xml";
3466
- db->mappings = load_timezone_mappings_from_xml_file(mapping_file);
3467
- sort_zone_mappings(db->mappings);
3468
- #endif // _WIN32
3469
-
3470
- return db;
3471
- }
3472
-
3473
- const tzdb&
3474
- reload_tzdb()
3475
- {
3476
- #if AUTO_DOWNLOAD
3477
- auto const& v = get_tzdb_list().front().version;
3478
- if (!v.empty() && v == remote_version())
3479
- return get_tzdb_list().front();
3480
- #endif // AUTO_DOWNLOAD
3481
- tzdb_list::undocumented_helper::push_front(get_tzdb_list(), init_tzdb().release());
3482
- return get_tzdb_list().front();
3483
- }
3484
-
3485
- #endif // !USE_OS_TZDB
3486
-
3487
- const tzdb&
3488
- get_tzdb()
3489
- {
3490
- return get_tzdb_list().front();
3491
- }
3492
-
3493
- const time_zone*
3494
- #if HAS_STRING_VIEW
3495
- tzdb::locate_zone(std::string_view tz_name) const
3496
- #else
3497
- tzdb::locate_zone(const std::string& tz_name) const
3498
- #endif
3499
- {
3500
- auto zi = std::lower_bound(zones.begin(), zones.end(), tz_name,
3501
- #if HAS_STRING_VIEW
3502
- [](const time_zone& z, const std::string_view& nm)
3503
- #else
3504
- [](const time_zone& z, const std::string& nm)
3505
- #endif
3506
- {
3507
- return z.name() < nm;
3508
- });
3509
- if (zi == zones.end() || zi->name() != tz_name)
3510
- {
3511
- #if !USE_OS_TZDB
3512
- auto li = std::lower_bound(links.begin(), links.end(), tz_name,
3513
- #if HAS_STRING_VIEW
3514
- [](const link& z, const std::string_view& nm)
3515
- #else
3516
- [](const link& z, const std::string& nm)
3517
- #endif
3518
- {
3519
- return z.name() < nm;
3520
- });
3521
- if (li != links.end() && li->name() == tz_name)
3522
- {
3523
- zi = std::lower_bound(zones.begin(), zones.end(), li->target(),
3524
- [](const time_zone& z, const std::string& nm)
3525
- {
3526
- return z.name() < nm;
3527
- });
3528
- if (zi != zones.end() && zi->name() == li->target())
3529
- return &*zi;
3530
- }
3531
- #endif // !USE_OS_TZDB
3532
- throw std::runtime_error(std::string(tz_name) + " not found in timezone database");
3533
- }
3534
- return &*zi;
3535
- }
3536
-
3537
- const time_zone*
3538
- #if HAS_STRING_VIEW
3539
- locate_zone(std::string_view tz_name)
3540
- #else
3541
- locate_zone(const std::string& tz_name)
3542
- #endif
3543
- {
3544
- return get_tzdb().locate_zone(tz_name);
3545
- }
3546
-
3547
- #if USE_OS_TZDB
3548
-
3549
- std::ostream&
3550
- operator<<(std::ostream& os, const tzdb& db)
3551
- {
3552
- os << "Version: " << db.version << "\n\n";
3553
- for (const auto& x : db.zones)
3554
- os << x << '\n';
3555
- #if !MISSING_LEAP_SECONDS
3556
- os << '\n';
3557
- for (const auto& x : db.leaps)
3558
- os << x << '\n';
3559
- #endif // !MISSING_LEAP_SECONDS
3560
- return os;
3561
- }
3562
-
3563
- #else // !USE_OS_TZDB
3564
-
3565
- std::ostream&
3566
- operator<<(std::ostream& os, const tzdb& db)
3567
- {
3568
- os << "Version: " << db.version << '\n';
3569
- std::string title("--------------------------------------------"
3570
- "--------------------------------------------\n"
3571
- "Name ""Start Y ""End Y "
3572
- "Beginning ""Offset "
3573
- "Designator\n"
3574
- "--------------------------------------------"
3575
- "--------------------------------------------\n");
3576
- int count = 0;
3577
- for (const auto& x : db.rules)
3578
- {
3579
- if (count++ % 50 == 0)
3580
- os << title;
3581
- os << x << '\n';
3582
- }
3583
- os << '\n';
3584
- title = std::string("---------------------------------------------------------"
3585
- "--------------------------------------------------------\n"
3586
- "Name ""Offset "
3587
- "Rule ""Abrev ""Until\n"
3588
- "---------------------------------------------------------"
3589
- "--------------------------------------------------------\n");
3590
- count = 0;
3591
- for (const auto& x : db.zones)
3592
- {
3593
- if (count++ % 10 == 0)
3594
- os << title;
3595
- os << x << '\n';
3596
- }
3597
- os << '\n';
3598
- title = std::string("---------------------------------------------------------"
3599
- "--------------------------------------------------------\n"
3600
- "Alias ""To\n"
3601
- "---------------------------------------------------------"
3602
- "--------------------------------------------------------\n");
3603
- count = 0;
3604
- for (const auto& x : db.links)
3605
- {
3606
- if (count++ % 45 == 0)
3607
- os << title;
3608
- os << x << '\n';
3609
- }
3610
- os << '\n';
3611
- title = std::string("---------------------------------------------------------"
3612
- "--------------------------------------------------------\n"
3613
- "Leap second on\n"
3614
- "---------------------------------------------------------"
3615
- "--------------------------------------------------------\n");
3616
- os << title;
3617
- for (const auto& x : db.leaps)
3618
- os << x << '\n';
3619
- return os;
3620
- }
3621
-
3622
- #endif // !USE_OS_TZDB
3623
-
3624
- // -----------------------
3625
-
3626
- #ifdef _WIN32
3627
-
3628
- static
3629
- std::string
3630
- getTimeZoneKeyName()
3631
- {
3632
- DYNAMIC_TIME_ZONE_INFORMATION dtzi{};
3633
- auto result = GetDynamicTimeZoneInformation(&dtzi);
3634
- if (result == TIME_ZONE_ID_INVALID)
3635
- throw std::runtime_error("current_zone(): GetDynamicTimeZoneInformation()"
3636
- " reported TIME_ZONE_ID_INVALID.");
3637
- auto wlen = wcslen(dtzi.TimeZoneKeyName);
3638
- char buf[128] = {};
3639
- assert(sizeof(buf) >= wlen+1);
3640
- wcstombs(buf, dtzi.TimeZoneKeyName, wlen);
3641
- if (strcmp(buf, "Coordinated Universal Time") == 0)
3642
- return "UTC";
3643
- return buf;
3644
- }
3645
-
3646
- const time_zone*
3647
- tzdb::current_zone() const
3648
- {
3649
- std::string win_tzid = getTimeZoneKeyName();
3650
- std::string standard_tzid;
3651
- if (!native_to_standard_timezone_name(win_tzid, standard_tzid))
3652
- {
3653
- std::string msg;
3654
- msg = "current_zone() failed: A mapping from the Windows Time Zone id \"";
3655
- msg += win_tzid;
3656
- msg += "\" was not found in the time zone mapping database.";
3657
- throw std::runtime_error(msg);
3658
- }
3659
- return locate_zone(standard_tzid);
3660
- }
3661
-
3662
- #else // !_WIN32
3663
-
3664
- const time_zone*
3665
- tzdb::current_zone() const
3666
- {
3667
- // On some OS's a file called /etc/localtime may
3668
- // exist and it may be either a real file
3669
- // containing time zone details or a symlink to such a file.
3670
- // On MacOS and BSD Unix if this file is a symlink it
3671
- // might resolve to a path like this:
3672
- // "/usr/share/zoneinfo/America/Los_Angeles"
3673
- // If it does, we try to determine the current
3674
- // timezone from the remainder of the path by removing the prefix
3675
- // and hoping the rest resolves to a valid timezone.
3676
- // It may not always work though. If it doesn't then an
3677
- // exception will be thrown by local_timezone.
3678
- // The path may also take a relative form:
3679
- // "../usr/share/zoneinfo/America/Los_Angeles".
3680
- {
3681
- struct stat sb;
3682
- CONSTDATA auto timezone = "/etc/localtime";
3683
- if (lstat(timezone, &sb) == 0 && S_ISLNK(sb.st_mode) && sb.st_size > 0) {
3684
- using namespace std;
3685
- string result;
3686
- char rp[PATH_MAX+1] = {};
3687
- if (readlink(timezone, rp, sizeof(rp)-1) > 0)
3688
- result = string(rp);
3689
- else
3690
- throw system_error(errno, system_category(), "readlink() failed");
3691
-
3692
- const size_t pos = result.find(get_tz_dir());
3693
- if (pos != result.npos)
3694
- result.erase(0, get_tz_dir().size() + 1 + pos);
3695
- return locate_zone(result);
3696
- }
3697
- }
3698
- // On embedded systems e.g. buildroot with uclibc the timezone is linked
3699
- // into /etc/TZ which is a symlink to path like this:
3700
- // "/usr/share/zoneinfo/uclibc/America/Los_Angeles"
3701
- // If it does, we try to determine the current
3702
- // timezone from the remainder of the path by removing the prefix
3703
- // and hoping the rest resolves to valid timezone.
3704
- // It may not always work though. If it doesn't then an
3705
- // exception will be thrown by local_timezone.
3706
- // The path may also take a relative form:
3707
- // "../usr/share/zoneinfo/uclibc/America/Los_Angeles".
3708
- {
3709
- struct stat sb;
3710
- CONSTDATA auto timezone = "/etc/TZ";
3711
- if (lstat(timezone, &sb) == 0 && S_ISLNK(sb.st_mode) && sb.st_size > 0) {
3712
- using namespace std;
3713
- string result;
3714
- char rp[PATH_MAX+1] = {};
3715
- if (readlink(timezone, rp, sizeof(rp)-1) > 0)
3716
- result = string(rp);
3717
- else
3718
- throw system_error(errno, system_category(), "readlink() failed");
3719
-
3720
- const size_t pos = result.find(get_tz_dir());
3721
- if (pos != result.npos)
3722
- result.erase(0, get_tz_dir().size() + 1 + pos);
3723
- return locate_zone(result);
3724
- }
3725
- }
3726
- {
3727
- // On some versions of some linux distro's (e.g. Ubuntu),
3728
- // the current timezone might be in the first line of
3729
- // the /etc/timezone file.
3730
- std::ifstream timezone_file("/etc/timezone");
3731
- if (timezone_file.is_open())
3732
- {
3733
- std::string result;
3734
- std::getline(timezone_file, result);
3735
- if (!result.empty())
3736
- return locate_zone(result);
3737
- }
3738
- // Fall through to try other means.
3739
- }
3740
- {
3741
- // On some versions of some bsd distro's (e.g. FreeBSD),
3742
- // the current timezone might be in the first line of
3743
- // the /var/db/zoneinfo file.
3744
- std::ifstream timezone_file("/var/db/zoneinfo");
3745
- if (timezone_file.is_open())
3746
- {
3747
- std::string result;
3748
- std::getline(timezone_file, result);
3749
- if (!result.empty())
3750
- return locate_zone(result);
3751
- }
3752
- // Fall through to try other means.
3753
- }
3754
- {
3755
- // On some versions of some bsd distro's (e.g. iOS),
3756
- // it is not possible to use file based approach,
3757
- // we switch to system API, calling functions in
3758
- // CoreFoundation framework.
3759
- #if TARGET_OS_IPHONE
3760
- std::string result = date::iOSUtils::get_current_timezone();
3761
- if (!result.empty())
3762
- return locate_zone(result);
3763
- #endif
3764
- // Fall through to try other means.
3765
- }
3766
- {
3767
- // On some versions of some linux distro's (e.g. Red Hat),
3768
- // the current timezone might be in the first line of
3769
- // the /etc/sysconfig/clock file as:
3770
- // ZONE="US/Eastern"
3771
- std::ifstream timezone_file("/etc/sysconfig/clock");
3772
- std::string result;
3773
- while (timezone_file)
3774
- {
3775
- std::getline(timezone_file, result);
3776
- auto p = result.find("ZONE=\"");
3777
- if (p != std::string::npos)
3778
- {
3779
- result.erase(p, p+6);
3780
- result.erase(result.rfind('"'));
3781
- return locate_zone(result);
3782
- }
3783
- }
3784
- // Fall through to try other means.
3785
- }
3786
- throw std::runtime_error("Could not get current timezone");
3787
- }
3788
-
3789
- #endif // !_WIN32
3790
-
3791
- const time_zone*
3792
- current_zone()
3793
- {
3794
- return get_tzdb().current_zone();
3795
- }
3796
-
3797
- } // namespace date
3798
-
3799
- #if defined(__GNUC__) && __GNUC__ < 5
3800
- # pragma GCC diagnostic pop
3801
- #endif