PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/hphp/runtime/ext/icu/ext_icu_date_pattern_gen.cpp

https://gitlab.com/Blueprint-Marketing/hhvm
C++ | 388 lines | 290 code | 89 blank | 9 comment | 6 complexity | 20e54d73b5a51cab5aa367d7a120dd8a MD5 | raw file
  1. #include "hphp/runtime/ext/icu/ext_icu_date_pattern_gen.h"
  2. #include "hphp/runtime/ext/icu/ext_icu_iterator.h"
  3. namespace HPHP { namespace Intl {
  4. //////////////////////////////////////////////////////////////////////////////
  5. // Internal Resource Data
  6. const StaticString s_IntlDatePatternGenerator("IntlDatePatternGenerator");
  7. Class* IntlDatePatternGenerator::c_IntlDatePatternGenerator = nullptr;
  8. #define GENERATOR_GET(dest, src) \
  9. auto dest = IntlDatePatternGenerator::Get(src); \
  10. if (!dest) { \
  11. throw data->getException("Invalid date pattern generator"); \
  12. }
  13. #define ICU_ERR_CHECK(data, ec) \
  14. if (U_FAILURE(ec)) { \
  15. data->setError(ec); \
  16. throw data->getException("Date pattern generator error: %d (%s)", \
  17. error, u_errorName(error)); \
  18. }
  19. #define ICU_ERR_CHECK_MSG(data, ec, msg) \
  20. if (U_FAILURE(ec)) { \
  21. data->setError(ec, msg); \
  22. throw data->getException(#msg ": %d (%s)", ec, u_errorName(ec)); \
  23. }
  24. static UDateTimePatternField cast_ptn_field(IntlError *errorHandler,
  25. int64_t fieldInt) {
  26. // The pattern fields are in an enum and should be less than the field count
  27. if ((fieldInt < 0) || (fieldInt >= UDATPG_FIELD_COUNT)) {
  28. const char *msg = "Invalid value: %ld for pattern field";
  29. errorHandler->setError(U_ILLEGAL_ARGUMENT_ERROR, msg, fieldInt);
  30. throw errorHandler->getException(msg, fieldInt);
  31. }
  32. return static_cast<UDateTimePatternField>(fieldInt);
  33. }
  34. //////////////////////////////////////////////////////////////////////////////
  35. // class IntlDatePatternGenerator
  36. static Object HHVM_STATIC_METHOD(IntlDatePatternGenerator, createInstance,
  37. const String& locale) {
  38. if (locale.empty()) {
  39. throw s_intl_error->getException("No locale provided");
  40. }
  41. auto loc = icu::Locale::createFromName(locale.c_str());
  42. UErrorCode error = U_ZERO_ERROR;
  43. auto generator = std::unique_ptr<icu::DateTimePatternGenerator>(
  44. icu::DateTimePatternGenerator::createInstance(loc, error));
  45. ICU_ERR_CHECK_MSG(s_intl_error, error,
  46. "Error creating ICU DateTimePatternGenerator object");
  47. return IntlDatePatternGenerator::newInstance(std::move(generator));
  48. }
  49. static Object HHVM_STATIC_METHOD(IntlDatePatternGenerator,
  50. createEmptyInstance) {
  51. UErrorCode error = U_ZERO_ERROR;
  52. auto generator = std::unique_ptr<icu::DateTimePatternGenerator>(
  53. icu::DateTimePatternGenerator::createEmptyInstance(error));
  54. ICU_ERR_CHECK_MSG(s_intl_error, error,
  55. "Error creating ICU DateTimePatternGenerator object");
  56. return IntlDatePatternGenerator::newInstance(std::move(generator));
  57. }
  58. static String HHVM_METHOD(IntlDatePatternGenerator,
  59. getSkeleton,
  60. const String& pattern) {
  61. GENERATOR_GET(data, this_);
  62. UErrorCode error = U_ZERO_ERROR;
  63. icu::UnicodeString ptn(u16(pattern, error));
  64. ICU_ERR_CHECK(data, error);
  65. icu::UnicodeString ret = data->generator().getSkeleton(ptn, error);
  66. ICU_ERR_CHECK_MSG(data, error, "Error getting skeleton");
  67. String out(u8(ret, error));
  68. ICU_ERR_CHECK(data, error);
  69. return out;
  70. }
  71. static String HHVM_METHOD(IntlDatePatternGenerator,
  72. getBaseSkeleton,
  73. const String& pattern) {
  74. GENERATOR_GET(data, this_);
  75. UErrorCode error = U_ZERO_ERROR;
  76. icu::UnicodeString ptn(u16(pattern, error));
  77. ICU_ERR_CHECK(data, error);
  78. icu::UnicodeString ret = data->generator().getBaseSkeleton(ptn, error);
  79. ICU_ERR_CHECK_MSG(data, error, "Error getting base skeleton");
  80. String out(u8(ret, error));
  81. ICU_ERR_CHECK(data, error);
  82. return out;
  83. }
  84. static int64_t HHVM_METHOD(IntlDatePatternGenerator,
  85. addPattern,
  86. const String& pattern,
  87. bool override) {
  88. GENERATOR_GET(data, this_);
  89. UErrorCode error = U_ZERO_ERROR;
  90. icu::UnicodeString ptn(u16(pattern, error));
  91. icu::UnicodeString conflictingPtn;
  92. ICU_ERR_CHECK(data, error);
  93. int64_t ret;
  94. ret = data->generator().addPattern(ptn, override, conflictingPtn, error);
  95. ICU_ERR_CHECK_MSG(data, error, "Error adding pattern");
  96. return ret;
  97. }
  98. static void HHVM_METHOD(IntlDatePatternGenerator,
  99. setAppendItemFormat,
  100. int64_t fieldInt,
  101. const String& format) {
  102. GENERATOR_GET(data, this_);
  103. UErrorCode error = U_ZERO_ERROR;
  104. icu::UnicodeString fmt(u16(format, error));
  105. ICU_ERR_CHECK(data, error);
  106. data->generator().setAppendItemFormat(cast_ptn_field(data, fieldInt), fmt);
  107. ICU_ERR_CHECK_MSG(data, error, "Error setting append item format");
  108. }
  109. static String HHVM_METHOD(IntlDatePatternGenerator,
  110. getAppendItemFormat,
  111. int64_t fieldInt) {
  112. GENERATOR_GET(data, this_);
  113. icu::UnicodeString ret;
  114. ret = data->generator().getAppendItemFormat(cast_ptn_field(data, fieldInt));
  115. UErrorCode error = U_ZERO_ERROR;
  116. String out(u8(ret, error));
  117. ICU_ERR_CHECK(data, error);
  118. return out;
  119. }
  120. static void HHVM_METHOD(IntlDatePatternGenerator,
  121. setAppendItemName,
  122. int64_t fieldInt,
  123. const String& name) {
  124. GENERATOR_GET(data, this_);
  125. UErrorCode error = U_ZERO_ERROR;
  126. icu::UnicodeString value(u16(name, error));
  127. ICU_ERR_CHECK(data, error);
  128. data->generator().setAppendItemName(cast_ptn_field(data, fieldInt), value);
  129. ICU_ERR_CHECK_MSG(data, error, "Error setting append item name");
  130. }
  131. static String HHVM_METHOD(IntlDatePatternGenerator,
  132. getAppendItemName,
  133. int64_t fieldInt) {
  134. GENERATOR_GET(data, this_);
  135. icu::UnicodeString ret;
  136. ret = data->generator().getAppendItemName(cast_ptn_field(data, fieldInt));
  137. UErrorCode error = U_ZERO_ERROR;
  138. String out(u8(ret, error));
  139. ICU_ERR_CHECK(data, error);
  140. return out;
  141. }
  142. static void HHVM_METHOD(IntlDatePatternGenerator,
  143. setDateTimeFormat,
  144. const String& dateTimeFormat) {
  145. GENERATOR_GET(data, this_);
  146. UErrorCode error = U_ZERO_ERROR;
  147. icu::UnicodeString fmt(u16(dateTimeFormat, error));
  148. ICU_ERR_CHECK(data, error);
  149. data->generator().setDateTimeFormat(fmt);
  150. ICU_ERR_CHECK_MSG(data, error, "Error setting date time format");
  151. }
  152. static String HHVM_METHOD(IntlDatePatternGenerator, getDateTimeFormat) {
  153. GENERATOR_GET(data, this_);
  154. icu::UnicodeString ret = data->generator().getDateTimeFormat();
  155. UErrorCode error = U_ZERO_ERROR;
  156. String out(u8(ret, error));
  157. ICU_ERR_CHECK(data, error);
  158. return out;
  159. }
  160. static String HHVM_METHOD(IntlDatePatternGenerator,
  161. getBestPattern,
  162. const String& skeleton) {
  163. GENERATOR_GET(data, this_);
  164. UErrorCode error = U_ZERO_ERROR;
  165. icu::UnicodeString skel(u16(skeleton, error));
  166. ICU_ERR_CHECK(data, error);
  167. icu::UnicodeString ret = data->generator().getBestPattern(skel, error);
  168. ICU_ERR_CHECK_MSG(data, error, "Error getting best pattern");
  169. String out(u8(ret, error));
  170. ICU_ERR_CHECK(data, error);
  171. return out;
  172. }
  173. static String HHVM_METHOD(IntlDatePatternGenerator,
  174. replaceFieldTypes,
  175. const String& pattern,
  176. const String& skeleton) {
  177. GENERATOR_GET(data, this_);
  178. UErrorCode error = U_ZERO_ERROR;
  179. icu::UnicodeString ptn(u16(pattern, error));
  180. ICU_ERR_CHECK(data, error);
  181. icu::UnicodeString skel(u16(skeleton, error));
  182. ICU_ERR_CHECK(data, error);
  183. icu::UnicodeString ret;
  184. ret = data->generator().replaceFieldTypes(ptn, skel, error);
  185. ICU_ERR_CHECK_MSG(data, error, "Error replacing field types");
  186. String out(u8(ret, error));
  187. ICU_ERR_CHECK(data, error);
  188. return out;
  189. }
  190. static Object HHVM_METHOD(IntlDatePatternGenerator, getSkeletons) {
  191. GENERATOR_GET(data, this_);
  192. UErrorCode error = U_ZERO_ERROR;
  193. icu::StringEnumeration *se = data->generator().getSkeletons(error);
  194. ICU_ERR_CHECK_MSG(data, error, "Error getting skeletons");
  195. return IntlIterator::newInstance(se);
  196. }
  197. static String HHVM_METHOD(IntlDatePatternGenerator,
  198. getPatternForSkeleton,
  199. const String& skeleton) {
  200. GENERATOR_GET(data, this_);
  201. UErrorCode error = U_ZERO_ERROR;
  202. icu::UnicodeString skel(u16(skeleton, error));
  203. ICU_ERR_CHECK(data, error);
  204. icu::UnicodeString ret = data->generator().getPatternForSkeleton(skel);
  205. String out(u8(ret, error));
  206. ICU_ERR_CHECK(data, error);
  207. return out;
  208. }
  209. static Object HHVM_METHOD(IntlDatePatternGenerator, getBaseSkeletons) {
  210. GENERATOR_GET(data, this_);
  211. UErrorCode error = U_ZERO_ERROR;
  212. icu::StringEnumeration *se = data->generator().getBaseSkeletons(error);
  213. ICU_ERR_CHECK_MSG(data, error, "Error getting base skeletons");
  214. return IntlIterator::newInstance(se);
  215. }
  216. static void HHVM_METHOD(IntlDatePatternGenerator,
  217. setDecimal,
  218. const String& decimal) {
  219. GENERATOR_GET(data, this_);
  220. UErrorCode error = U_ZERO_ERROR;
  221. icu::UnicodeString dec(u16(decimal, error));
  222. ICU_ERR_CHECK(data, error);
  223. data->generator().setDecimal(dec);
  224. }
  225. static String HHVM_METHOD(IntlDatePatternGenerator, getDecimal) {
  226. GENERATOR_GET(data, this_);
  227. icu::UnicodeString ret = data->generator().getDecimal();
  228. UErrorCode error = U_ZERO_ERROR;
  229. String out(u8(ret, error));
  230. ICU_ERR_CHECK(data, error);
  231. return out;
  232. }
  233. static int64_t HHVM_METHOD(IntlDatePatternGenerator, getErrorCode) {
  234. GENERATOR_GET(data, this_);
  235. return data->getErrorCode();
  236. }
  237. static String HHVM_METHOD(IntlDatePatternGenerator, getErrorMessage) {
  238. GENERATOR_GET(data, this_);
  239. return data->getErrorMessage();
  240. }
  241. //////////////////////////////////////////////////////////////////////////////
  242. #define UDATPG_CONST_FIELD(nm)Native::registerClassConstant<KindOfInt64>( \
  243. s_IntlDatePatternGenerator.get(), \
  244. makeStaticString(#nm "_PATTERN_FIELD"), \
  245. UDATPG_ ## nm ## _FIELD);
  246. #define UDATPG_CONST(nm)Native::registerClassConstant<KindOfInt64>( \
  247. s_IntlDatePatternGenerator.get(), \
  248. makeStaticString("PATTERN_" #nm), \
  249. UDATPG_ ## nm);
  250. void IntlExtension::initDatePatternGenerator() {
  251. // UDateTimePatternField
  252. UDATPG_CONST_FIELD(ERA);
  253. UDATPG_CONST_FIELD(YEAR);
  254. UDATPG_CONST_FIELD(QUARTER);
  255. UDATPG_CONST_FIELD(MONTH);
  256. UDATPG_CONST_FIELD(WEEK_OF_YEAR);
  257. UDATPG_CONST_FIELD(WEEK_OF_MONTH);
  258. UDATPG_CONST_FIELD(WEEKDAY);
  259. UDATPG_CONST_FIELD(DAY_OF_YEAR);
  260. UDATPG_CONST_FIELD(DAY_OF_WEEK_IN_MONTH);
  261. UDATPG_CONST_FIELD(DAY);
  262. UDATPG_CONST_FIELD(DAYPERIOD);
  263. UDATPG_CONST_FIELD(HOUR);
  264. UDATPG_CONST_FIELD(MINUTE);
  265. UDATPG_CONST_FIELD(SECOND);
  266. UDATPG_CONST_FIELD(FRACTIONAL_SECOND);
  267. UDATPG_CONST_FIELD(ZONE);
  268. UDATPG_CONST(FIELD_COUNT);
  269. // UDateTimePatternConflict
  270. UDATPG_CONST(NO_CONFLICT);
  271. UDATPG_CONST(BASE_CONFLICT);
  272. UDATPG_CONST(CONFLICT);
  273. UDATPG_CONST(CONFLICT_COUNT);
  274. HHVM_STATIC_ME(IntlDatePatternGenerator, createInstance);
  275. HHVM_STATIC_ME(IntlDatePatternGenerator, createEmptyInstance);
  276. HHVM_ME(IntlDatePatternGenerator, getSkeleton);
  277. HHVM_ME(IntlDatePatternGenerator, getBaseSkeleton);
  278. HHVM_ME(IntlDatePatternGenerator, addPattern);
  279. HHVM_ME(IntlDatePatternGenerator, setAppendItemFormat);
  280. HHVM_ME(IntlDatePatternGenerator, getAppendItemFormat);
  281. HHVM_ME(IntlDatePatternGenerator, setAppendItemName);
  282. HHVM_ME(IntlDatePatternGenerator, getAppendItemName);
  283. HHVM_ME(IntlDatePatternGenerator, setDateTimeFormat);
  284. HHVM_ME(IntlDatePatternGenerator, getDateTimeFormat);
  285. HHVM_ME(IntlDatePatternGenerator, getBestPattern);
  286. HHVM_ME(IntlDatePatternGenerator, replaceFieldTypes);
  287. HHVM_ME(IntlDatePatternGenerator, getSkeletons);
  288. HHVM_ME(IntlDatePatternGenerator, getPatternForSkeleton);
  289. HHVM_ME(IntlDatePatternGenerator, getBaseSkeletons);
  290. HHVM_ME(IntlDatePatternGenerator, setDecimal);
  291. HHVM_ME(IntlDatePatternGenerator, getDecimal);
  292. HHVM_ME(IntlDatePatternGenerator, getErrorCode);
  293. HHVM_ME(IntlDatePatternGenerator, getErrorMessage);
  294. auto gen = s_IntlDatePatternGenerator.get();
  295. Native::registerNativeDataInfo<IntlDatePatternGenerator>(gen);
  296. loadSystemlib("icu_date_pattern_gen");
  297. }
  298. //////////////////////////////////////////////////////////////////////////////
  299. }} // namespace HPHP::Intl