fmtable.cpp 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052
  1. // Copyright (C) 2016 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. /*
  4. *******************************************************************************
  5. * Copyright (C) 1997-2016, International Business Machines Corporation and
  6. * others. All Rights Reserved.
  7. *******************************************************************************
  8. *
  9. * File FMTABLE.CPP
  10. *
  11. * Modification History:
  12. *
  13. * Date Name Description
  14. * 03/25/97 clhuang Initial Implementation.
  15. ********************************************************************************
  16. */
  17. #include "unicode/utypes.h"
  18. #if !UCONFIG_NO_FORMATTING
  19. #include <math.h>
  20. #include "unicode/fmtable.h"
  21. #include "unicode/ustring.h"
  22. #include "unicode/measure.h"
  23. #include "unicode/curramt.h"
  24. #include "unicode/uformattable.h"
  25. #include "charstr.h"
  26. #include "cmemory.h"
  27. #include "cstring.h"
  28. #include "decNumber.h"
  29. #include "digitlst.h"
  30. #include "fmtableimp.h"
  31. // *****************************************************************************
  32. // class Formattable
  33. // *****************************************************************************
  34. U_NAMESPACE_BEGIN
  35. UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Formattable)
  36. //-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
  37. // NOTE: As of 3.0, there are limitations to the UObject API. It does
  38. // not (yet) support cloning, operator=, nor operator==. To
  39. // work around this, I implement some simple inlines here. Later
  40. // these can be modified or removed. [alan]
  41. // NOTE: These inlines assume that all fObjects are in fact instances
  42. // of the Measure class, which is true as of 3.0. [alan]
  43. // Return TRUE if *a == *b.
  44. static inline UBool objectEquals(const UObject* a, const UObject* b) {
  45. // LATER: return *a == *b;
  46. return *((const Measure*) a) == *((const Measure*) b);
  47. }
  48. // Return a clone of *a.
  49. static inline UObject* objectClone(const UObject* a) {
  50. // LATER: return a->clone();
  51. return ((const Measure*) a)->clone();
  52. }
  53. // Return TRUE if *a is an instance of Measure.
  54. static inline UBool instanceOfMeasure(const UObject* a) {
  55. return dynamic_cast<const Measure*>(a) != NULL;
  56. }
  57. /**
  58. * Creates a new Formattable array and copies the values from the specified
  59. * original.
  60. * @param array the original array
  61. * @param count the original array count
  62. * @return the new Formattable array.
  63. */
  64. static Formattable* createArrayCopy(const Formattable* array, int32_t count) {
  65. Formattable *result = new Formattable[count];
  66. if (result != NULL) {
  67. for (int32_t i=0; i<count; ++i)
  68. result[i] = array[i]; // Don't memcpy!
  69. }
  70. return result;
  71. }
  72. //-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
  73. /**
  74. * Set 'ec' to 'err' only if 'ec' is not already set to a failing UErrorCode.
  75. */
  76. static void setError(UErrorCode& ec, UErrorCode err) {
  77. if (U_SUCCESS(ec)) {
  78. ec = err;
  79. }
  80. }
  81. //
  82. // Common initialization code, shared by constructors.
  83. // Put everything into a known state.
  84. //
  85. void Formattable::init() {
  86. fValue.fInt64 = 0;
  87. fType = kLong;
  88. fDecimalStr = NULL;
  89. fDecimalNum = NULL;
  90. fBogus.setToBogus();
  91. }
  92. // -------------------------------------
  93. // default constructor.
  94. // Creates a formattable object with a long value 0.
  95. Formattable::Formattable() {
  96. init();
  97. }
  98. // -------------------------------------
  99. // Creates a formattable object with a Date instance.
  100. Formattable::Formattable(UDate date, ISDATE /*isDate*/)
  101. {
  102. init();
  103. fType = kDate;
  104. fValue.fDate = date;
  105. }
  106. // -------------------------------------
  107. // Creates a formattable object with a double value.
  108. Formattable::Formattable(double value)
  109. {
  110. init();
  111. fType = kDouble;
  112. fValue.fDouble = value;
  113. }
  114. // -------------------------------------
  115. // Creates a formattable object with an int32_t value.
  116. Formattable::Formattable(int32_t value)
  117. {
  118. init();
  119. fValue.fInt64 = value;
  120. }
  121. // -------------------------------------
  122. // Creates a formattable object with an int64_t value.
  123. Formattable::Formattable(int64_t value)
  124. {
  125. init();
  126. fType = kInt64;
  127. fValue.fInt64 = value;
  128. }
  129. // -------------------------------------
  130. // Creates a formattable object with a decimal number value from a string.
  131. Formattable::Formattable(StringPiece number, UErrorCode &status) {
  132. init();
  133. setDecimalNumber(number, status);
  134. }
  135. // -------------------------------------
  136. // Creates a formattable object with a UnicodeString instance.
  137. Formattable::Formattable(const UnicodeString& stringToCopy)
  138. {
  139. init();
  140. fType = kString;
  141. fValue.fString = new UnicodeString(stringToCopy);
  142. }
  143. // -------------------------------------
  144. // Creates a formattable object with a UnicodeString* value.
  145. // (adopting symantics)
  146. Formattable::Formattable(UnicodeString* stringToAdopt)
  147. {
  148. init();
  149. fType = kString;
  150. fValue.fString = stringToAdopt;
  151. }
  152. Formattable::Formattable(UObject* objectToAdopt)
  153. {
  154. init();
  155. fType = kObject;
  156. fValue.fObject = objectToAdopt;
  157. }
  158. // -------------------------------------
  159. Formattable::Formattable(const Formattable* arrayToCopy, int32_t count)
  160. : UObject(), fType(kArray)
  161. {
  162. init();
  163. fType = kArray;
  164. fValue.fArrayAndCount.fArray = createArrayCopy(arrayToCopy, count);
  165. fValue.fArrayAndCount.fCount = count;
  166. }
  167. // -------------------------------------
  168. // copy constructor
  169. Formattable::Formattable(const Formattable &source)
  170. : UObject(*this)
  171. {
  172. init();
  173. *this = source;
  174. }
  175. // -------------------------------------
  176. // assignment operator
  177. Formattable&
  178. Formattable::operator=(const Formattable& source)
  179. {
  180. if (this != &source)
  181. {
  182. // Disposes the current formattable value/setting.
  183. dispose();
  184. // Sets the correct data type for this value.
  185. fType = source.fType;
  186. switch (fType)
  187. {
  188. case kArray:
  189. // Sets each element in the array one by one and records the array count.
  190. fValue.fArrayAndCount.fCount = source.fValue.fArrayAndCount.fCount;
  191. fValue.fArrayAndCount.fArray = createArrayCopy(source.fValue.fArrayAndCount.fArray,
  192. source.fValue.fArrayAndCount.fCount);
  193. break;
  194. case kString:
  195. // Sets the string value.
  196. fValue.fString = new UnicodeString(*source.fValue.fString);
  197. break;
  198. case kDouble:
  199. // Sets the double value.
  200. fValue.fDouble = source.fValue.fDouble;
  201. break;
  202. case kLong:
  203. case kInt64:
  204. // Sets the long value.
  205. fValue.fInt64 = source.fValue.fInt64;
  206. break;
  207. case kDate:
  208. // Sets the Date value.
  209. fValue.fDate = source.fValue.fDate;
  210. break;
  211. case kObject:
  212. fValue.fObject = objectClone(source.fValue.fObject);
  213. break;
  214. }
  215. UErrorCode status = U_ZERO_ERROR;
  216. if (source.fDecimalNum != NULL) {
  217. fDecimalNum = new DigitList(*source.fDecimalNum); // TODO: use internal digit list
  218. }
  219. if (source.fDecimalStr != NULL) {
  220. fDecimalStr = new CharString(*source.fDecimalStr, status);
  221. if (U_FAILURE(status)) {
  222. delete fDecimalStr;
  223. fDecimalStr = NULL;
  224. }
  225. }
  226. }
  227. return *this;
  228. }
  229. // -------------------------------------
  230. UBool
  231. Formattable::operator==(const Formattable& that) const
  232. {
  233. int32_t i;
  234. if (this == &that) return TRUE;
  235. // Returns FALSE if the data types are different.
  236. if (fType != that.fType) return FALSE;
  237. // Compares the actual data values.
  238. UBool equal = TRUE;
  239. switch (fType) {
  240. case kDate:
  241. equal = (fValue.fDate == that.fValue.fDate);
  242. break;
  243. case kDouble:
  244. equal = (fValue.fDouble == that.fValue.fDouble);
  245. break;
  246. case kLong:
  247. case kInt64:
  248. equal = (fValue.fInt64 == that.fValue.fInt64);
  249. break;
  250. case kString:
  251. equal = (*(fValue.fString) == *(that.fValue.fString));
  252. break;
  253. case kArray:
  254. if (fValue.fArrayAndCount.fCount != that.fValue.fArrayAndCount.fCount) {
  255. equal = FALSE;
  256. break;
  257. }
  258. // Checks each element for equality.
  259. for (i=0; i<fValue.fArrayAndCount.fCount; ++i) {
  260. if (fValue.fArrayAndCount.fArray[i] != that.fValue.fArrayAndCount.fArray[i]) {
  261. equal = FALSE;
  262. break;
  263. }
  264. }
  265. break;
  266. case kObject:
  267. if (fValue.fObject == NULL || that.fValue.fObject == NULL) {
  268. equal = FALSE;
  269. } else {
  270. equal = objectEquals(fValue.fObject, that.fValue.fObject);
  271. }
  272. break;
  273. }
  274. // TODO: compare digit lists if numeric.
  275. return equal;
  276. }
  277. // -------------------------------------
  278. Formattable::~Formattable()
  279. {
  280. dispose();
  281. }
  282. // -------------------------------------
  283. void Formattable::dispose()
  284. {
  285. // Deletes the data value if necessary.
  286. switch (fType) {
  287. case kString:
  288. delete fValue.fString;
  289. break;
  290. case kArray:
  291. delete[] fValue.fArrayAndCount.fArray;
  292. break;
  293. case kObject:
  294. delete fValue.fObject;
  295. break;
  296. default:
  297. break;
  298. }
  299. fType = kLong;
  300. fValue.fInt64 = 0;
  301. delete fDecimalStr;
  302. fDecimalStr = NULL;
  303. FmtStackData *stackData = (FmtStackData*)fStackData;
  304. if(fDecimalNum != &(stackData->stackDecimalNum)) {
  305. delete fDecimalNum;
  306. } else {
  307. fDecimalNum->~DigitList(); // destruct, don't deallocate
  308. }
  309. fDecimalNum = NULL;
  310. }
  311. Formattable *
  312. Formattable::clone() const {
  313. return new Formattable(*this);
  314. }
  315. // -------------------------------------
  316. // Gets the data type of this Formattable object.
  317. Formattable::Type
  318. Formattable::getType() const
  319. {
  320. return fType;
  321. }
  322. UBool
  323. Formattable::isNumeric() const {
  324. switch (fType) {
  325. case kDouble:
  326. case kLong:
  327. case kInt64:
  328. return TRUE;
  329. default:
  330. return FALSE;
  331. }
  332. }
  333. // -------------------------------------
  334. int32_t
  335. //Formattable::getLong(UErrorCode* status) const
  336. Formattable::getLong(UErrorCode& status) const
  337. {
  338. if (U_FAILURE(status)) {
  339. return 0;
  340. }
  341. switch (fType) {
  342. case Formattable::kLong:
  343. return (int32_t)fValue.fInt64;
  344. case Formattable::kInt64:
  345. if (fValue.fInt64 > INT32_MAX) {
  346. status = U_INVALID_FORMAT_ERROR;
  347. return INT32_MAX;
  348. } else if (fValue.fInt64 < INT32_MIN) {
  349. status = U_INVALID_FORMAT_ERROR;
  350. return INT32_MIN;
  351. } else {
  352. return (int32_t)fValue.fInt64;
  353. }
  354. case Formattable::kDouble:
  355. if (fValue.fDouble > INT32_MAX) {
  356. status = U_INVALID_FORMAT_ERROR;
  357. return INT32_MAX;
  358. } else if (fValue.fDouble < INT32_MIN) {
  359. status = U_INVALID_FORMAT_ERROR;
  360. return INT32_MIN;
  361. } else {
  362. return (int32_t)fValue.fDouble; // loses fraction
  363. }
  364. case Formattable::kObject:
  365. if (fValue.fObject == NULL) {
  366. status = U_MEMORY_ALLOCATION_ERROR;
  367. return 0;
  368. }
  369. // TODO Later replace this with instanceof call
  370. if (instanceOfMeasure(fValue.fObject)) {
  371. return ((const Measure*) fValue.fObject)->
  372. getNumber().getLong(status);
  373. }
  374. U_FALLTHROUGH;
  375. default:
  376. status = U_INVALID_FORMAT_ERROR;
  377. return 0;
  378. }
  379. }
  380. // -------------------------------------
  381. // Maximum int that can be represented exactly in a double. (53 bits)
  382. // Larger ints may be rounded to a near-by value as not all are representable.
  383. // TODO: move this constant elsewhere, possibly configure it for different
  384. // floating point formats, if any non-standard ones are still in use.
  385. static const int64_t U_DOUBLE_MAX_EXACT_INT = 9007199254740992LL;
  386. int64_t
  387. Formattable::getInt64(UErrorCode& status) const
  388. {
  389. if (U_FAILURE(status)) {
  390. return 0;
  391. }
  392. switch (fType) {
  393. case Formattable::kLong:
  394. case Formattable::kInt64:
  395. return fValue.fInt64;
  396. case Formattable::kDouble:
  397. if (fValue.fDouble > (double)U_INT64_MAX) {
  398. status = U_INVALID_FORMAT_ERROR;
  399. return U_INT64_MAX;
  400. } else if (fValue.fDouble < (double)U_INT64_MIN) {
  401. status = U_INVALID_FORMAT_ERROR;
  402. return U_INT64_MIN;
  403. } else if (fabs(fValue.fDouble) > U_DOUBLE_MAX_EXACT_INT && fDecimalNum != NULL) {
  404. int64_t val = fDecimalNum->getInt64();
  405. if (val != 0) {
  406. return val;
  407. } else {
  408. status = U_INVALID_FORMAT_ERROR;
  409. return fValue.fDouble > 0 ? U_INT64_MAX : U_INT64_MIN;
  410. }
  411. } else {
  412. return (int64_t)fValue.fDouble;
  413. }
  414. case Formattable::kObject:
  415. if (fValue.fObject == NULL) {
  416. status = U_MEMORY_ALLOCATION_ERROR;
  417. return 0;
  418. }
  419. if (instanceOfMeasure(fValue.fObject)) {
  420. return ((const Measure*) fValue.fObject)->
  421. getNumber().getInt64(status);
  422. }
  423. U_FALLTHROUGH;
  424. default:
  425. status = U_INVALID_FORMAT_ERROR;
  426. return 0;
  427. }
  428. }
  429. // -------------------------------------
  430. double
  431. Formattable::getDouble(UErrorCode& status) const
  432. {
  433. if (U_FAILURE(status)) {
  434. return 0;
  435. }
  436. switch (fType) {
  437. case Formattable::kLong:
  438. case Formattable::kInt64: // loses precision
  439. return (double)fValue.fInt64;
  440. case Formattable::kDouble:
  441. return fValue.fDouble;
  442. case Formattable::kObject:
  443. if (fValue.fObject == NULL) {
  444. status = U_MEMORY_ALLOCATION_ERROR;
  445. return 0;
  446. }
  447. // TODO Later replace this with instanceof call
  448. if (instanceOfMeasure(fValue.fObject)) {
  449. return ((const Measure*) fValue.fObject)->
  450. getNumber().getDouble(status);
  451. }
  452. U_FALLTHROUGH;
  453. default:
  454. status = U_INVALID_FORMAT_ERROR;
  455. return 0;
  456. }
  457. }
  458. const UObject*
  459. Formattable::getObject() const {
  460. return (fType == kObject) ? fValue.fObject : NULL;
  461. }
  462. // -------------------------------------
  463. // Sets the value to a double value d.
  464. void
  465. Formattable::setDouble(double d)
  466. {
  467. dispose();
  468. fType = kDouble;
  469. fValue.fDouble = d;
  470. }
  471. // -------------------------------------
  472. // Sets the value to a long value l.
  473. void
  474. Formattable::setLong(int32_t l)
  475. {
  476. dispose();
  477. fType = kLong;
  478. fValue.fInt64 = l;
  479. }
  480. // -------------------------------------
  481. // Sets the value to an int64 value ll.
  482. void
  483. Formattable::setInt64(int64_t ll)
  484. {
  485. dispose();
  486. fType = kInt64;
  487. fValue.fInt64 = ll;
  488. }
  489. // -------------------------------------
  490. // Sets the value to a Date instance d.
  491. void
  492. Formattable::setDate(UDate d)
  493. {
  494. dispose();
  495. fType = kDate;
  496. fValue.fDate = d;
  497. }
  498. // -------------------------------------
  499. // Sets the value to a string value stringToCopy.
  500. void
  501. Formattable::setString(const UnicodeString& stringToCopy)
  502. {
  503. dispose();
  504. fType = kString;
  505. fValue.fString = new UnicodeString(stringToCopy);
  506. }
  507. // -------------------------------------
  508. // Sets the value to an array of Formattable objects.
  509. void
  510. Formattable::setArray(const Formattable* array, int32_t count)
  511. {
  512. dispose();
  513. fType = kArray;
  514. fValue.fArrayAndCount.fArray = createArrayCopy(array, count);
  515. fValue.fArrayAndCount.fCount = count;
  516. }
  517. // -------------------------------------
  518. // Adopts the stringToAdopt value.
  519. void
  520. Formattable::adoptString(UnicodeString* stringToAdopt)
  521. {
  522. dispose();
  523. fType = kString;
  524. fValue.fString = stringToAdopt;
  525. }
  526. // -------------------------------------
  527. // Adopts the array value and its count.
  528. void
  529. Formattable::adoptArray(Formattable* array, int32_t count)
  530. {
  531. dispose();
  532. fType = kArray;
  533. fValue.fArrayAndCount.fArray = array;
  534. fValue.fArrayAndCount.fCount = count;
  535. }
  536. void
  537. Formattable::adoptObject(UObject* objectToAdopt) {
  538. dispose();
  539. fType = kObject;
  540. fValue.fObject = objectToAdopt;
  541. }
  542. // -------------------------------------
  543. UnicodeString&
  544. Formattable::getString(UnicodeString& result, UErrorCode& status) const
  545. {
  546. if (fType != kString) {
  547. setError(status, U_INVALID_FORMAT_ERROR);
  548. result.setToBogus();
  549. } else {
  550. if (fValue.fString == NULL) {
  551. setError(status, U_MEMORY_ALLOCATION_ERROR);
  552. } else {
  553. result = *fValue.fString;
  554. }
  555. }
  556. return result;
  557. }
  558. // -------------------------------------
  559. const UnicodeString&
  560. Formattable::getString(UErrorCode& status) const
  561. {
  562. if (fType != kString) {
  563. setError(status, U_INVALID_FORMAT_ERROR);
  564. return *getBogus();
  565. }
  566. if (fValue.fString == NULL) {
  567. setError(status, U_MEMORY_ALLOCATION_ERROR);
  568. return *getBogus();
  569. }
  570. return *fValue.fString;
  571. }
  572. // -------------------------------------
  573. UnicodeString&
  574. Formattable::getString(UErrorCode& status)
  575. {
  576. if (fType != kString) {
  577. setError(status, U_INVALID_FORMAT_ERROR);
  578. return *getBogus();
  579. }
  580. if (fValue.fString == NULL) {
  581. setError(status, U_MEMORY_ALLOCATION_ERROR);
  582. return *getBogus();
  583. }
  584. return *fValue.fString;
  585. }
  586. // -------------------------------------
  587. const Formattable*
  588. Formattable::getArray(int32_t& count, UErrorCode& status) const
  589. {
  590. if (fType != kArray) {
  591. setError(status, U_INVALID_FORMAT_ERROR);
  592. count = 0;
  593. return NULL;
  594. }
  595. count = fValue.fArrayAndCount.fCount;
  596. return fValue.fArrayAndCount.fArray;
  597. }
  598. // -------------------------------------
  599. // Gets the bogus string, ensures mondo bogosity.
  600. UnicodeString*
  601. Formattable::getBogus() const
  602. {
  603. return (UnicodeString*)&fBogus; /* cast away const :-( */
  604. }
  605. // --------------------------------------
  606. StringPiece Formattable::getDecimalNumber(UErrorCode &status) {
  607. if (U_FAILURE(status)) {
  608. return "";
  609. }
  610. if (fDecimalStr != NULL) {
  611. return fDecimalStr->toStringPiece();
  612. }
  613. CharString *decimalStr = internalGetCharString(status);
  614. if(decimalStr == NULL) {
  615. return ""; // getDecimalNumber returns "" for error cases
  616. } else {
  617. return decimalStr->toStringPiece();
  618. }
  619. }
  620. CharString *Formattable::internalGetCharString(UErrorCode &status) {
  621. if(fDecimalStr == NULL) {
  622. if (fDecimalNum == NULL) {
  623. // No decimal number for the formattable yet. Which means the value was
  624. // set directly by the user as an int, int64 or double. If the value came
  625. // from parsing, or from the user setting a decimal number, fDecimalNum
  626. // would already be set.
  627. //
  628. fDecimalNum = new DigitList; // TODO: use internal digit list
  629. if (fDecimalNum == NULL) {
  630. status = U_MEMORY_ALLOCATION_ERROR;
  631. return NULL;
  632. }
  633. switch (fType) {
  634. case kDouble:
  635. fDecimalNum->set(this->getDouble());
  636. break;
  637. case kLong:
  638. fDecimalNum->set(this->getLong());
  639. break;
  640. case kInt64:
  641. fDecimalNum->set(this->getInt64());
  642. break;
  643. default:
  644. // The formattable's value is not a numeric type.
  645. status = U_INVALID_STATE_ERROR;
  646. return NULL;
  647. }
  648. }
  649. fDecimalStr = new CharString;
  650. if (fDecimalStr == NULL) {
  651. status = U_MEMORY_ALLOCATION_ERROR;
  652. return NULL;
  653. }
  654. fDecimalNum->getDecimal(*fDecimalStr, status);
  655. }
  656. return fDecimalStr;
  657. }
  658. DigitList *
  659. Formattable::getInternalDigitList() {
  660. FmtStackData *stackData = (FmtStackData*)fStackData;
  661. if(fDecimalNum != &(stackData->stackDecimalNum)) {
  662. delete fDecimalNum;
  663. fDecimalNum = new (&(stackData->stackDecimalNum), kOnStack) DigitList();
  664. } else {
  665. fDecimalNum->clear();
  666. }
  667. return fDecimalNum;
  668. }
  669. // ---------------------------------------
  670. void
  671. Formattable::adoptDigitList(DigitList *dl) {
  672. if(fDecimalNum==dl) {
  673. fDecimalNum = NULL; // don't delete
  674. }
  675. dispose();
  676. fDecimalNum = dl;
  677. if(dl==NULL) { // allow adoptDigitList(NULL) to clear
  678. return;
  679. }
  680. // Set the value into the Union of simple type values.
  681. // Cannot use the set() functions because they would delete the fDecimalNum value,
  682. if (fDecimalNum->fitsIntoLong(FALSE)) {
  683. fType = kLong;
  684. fValue.fInt64 = fDecimalNum->getLong();
  685. } else if (fDecimalNum->fitsIntoInt64(FALSE)) {
  686. fType = kInt64;
  687. fValue.fInt64 = fDecimalNum->getInt64();
  688. } else {
  689. fType = kDouble;
  690. fValue.fDouble = fDecimalNum->getDouble();
  691. }
  692. }
  693. // ---------------------------------------
  694. void
  695. Formattable::setDecimalNumber(StringPiece numberString, UErrorCode &status) {
  696. if (U_FAILURE(status)) {
  697. return;
  698. }
  699. dispose();
  700. // Copy the input string and nul-terminate it.
  701. // The decNumber library requires nul-terminated input. StringPiece input
  702. // is not guaranteed nul-terminated. Too bad.
  703. // CharString automatically adds the nul.
  704. DigitList *dnum = new DigitList(); // TODO: use getInternalDigitList
  705. if (dnum == NULL) {
  706. status = U_MEMORY_ALLOCATION_ERROR;
  707. return;
  708. }
  709. dnum->set(CharString(numberString, status).toStringPiece(), status);
  710. if (U_FAILURE(status)) {
  711. delete dnum;
  712. return; // String didn't contain a decimal number.
  713. }
  714. adoptDigitList(dnum);
  715. // Note that we do not hang on to the caller's input string.
  716. // If we are asked for the string, we will regenerate one from fDecimalNum.
  717. }
  718. #if 0
  719. //----------------------------------------------------
  720. // console I/O
  721. //----------------------------------------------------
  722. #ifdef _DEBUG
  723. #include <iostream>
  724. using namespace std;
  725. #include "unicode/datefmt.h"
  726. #include "unistrm.h"
  727. class FormattableStreamer /* not : public UObject because all methods are static */ {
  728. public:
  729. static void streamOut(ostream& stream, const Formattable& obj);
  730. private:
  731. FormattableStreamer() {} // private - forbid instantiation
  732. };
  733. // This is for debugging purposes only. This will send a displayable
  734. // form of the Formattable object to the output stream.
  735. void
  736. FormattableStreamer::streamOut(ostream& stream, const Formattable& obj)
  737. {
  738. static DateFormat *defDateFormat = 0;
  739. UnicodeString buffer;
  740. switch(obj.getType()) {
  741. case Formattable::kDate :
  742. // Creates a DateFormat instance for formatting the
  743. // Date instance.
  744. if (defDateFormat == 0) {
  745. defDateFormat = DateFormat::createInstance();
  746. }
  747. defDateFormat->format(obj.getDate(), buffer);
  748. stream << buffer;
  749. break;
  750. case Formattable::kDouble :
  751. // Output the double as is.
  752. stream << obj.getDouble() << 'D';
  753. break;
  754. case Formattable::kLong :
  755. // Output the double as is.
  756. stream << obj.getLong() << 'L';
  757. break;
  758. case Formattable::kString:
  759. // Output the double as is. Please see UnicodeString console
  760. // I/O routine for more details.
  761. stream << '"' << obj.getString(buffer) << '"';
  762. break;
  763. case Formattable::kArray:
  764. int32_t i, count;
  765. const Formattable* array;
  766. array = obj.getArray(count);
  767. stream << '[';
  768. // Recursively calling the console I/O routine for each element in the array.
  769. for (i=0; i<count; ++i) {
  770. FormattableStreamer::streamOut(stream, array[i]);
  771. stream << ( (i==(count-1)) ? "" : ", " );
  772. }
  773. stream << ']';
  774. break;
  775. default:
  776. // Not a recognizable Formattable object.
  777. stream << "INVALID_Formattable";
  778. }
  779. stream.flush();
  780. }
  781. #endif
  782. #endif
  783. U_NAMESPACE_END
  784. /* ---- UFormattable implementation ---- */
  785. U_NAMESPACE_USE
  786. U_DRAFT UFormattable* U_EXPORT2
  787. ufmt_open(UErrorCode *status) {
  788. if( U_FAILURE(*status) ) {
  789. return NULL;
  790. }
  791. UFormattable *fmt = (new Formattable())->toUFormattable();
  792. if( fmt == NULL ) {
  793. *status = U_MEMORY_ALLOCATION_ERROR;
  794. }
  795. return fmt;
  796. }
  797. U_DRAFT void U_EXPORT2
  798. ufmt_close(UFormattable *fmt) {
  799. Formattable *obj = Formattable::fromUFormattable(fmt);
  800. delete obj;
  801. }
  802. U_INTERNAL UFormattableType U_EXPORT2
  803. ufmt_getType(const UFormattable *fmt, UErrorCode *status) {
  804. if(U_FAILURE(*status)) {
  805. return (UFormattableType)UFMT_COUNT;
  806. }
  807. const Formattable *obj = Formattable::fromUFormattable(fmt);
  808. return (UFormattableType)obj->getType();
  809. }
  810. U_INTERNAL UBool U_EXPORT2
  811. ufmt_isNumeric(const UFormattable *fmt) {
  812. const Formattable *obj = Formattable::fromUFormattable(fmt);
  813. return obj->isNumeric();
  814. }
  815. U_DRAFT UDate U_EXPORT2
  816. ufmt_getDate(const UFormattable *fmt, UErrorCode *status) {
  817. const Formattable *obj = Formattable::fromUFormattable(fmt);
  818. return obj->getDate(*status);
  819. }
  820. U_DRAFT double U_EXPORT2
  821. ufmt_getDouble(UFormattable *fmt, UErrorCode *status) {
  822. Formattable *obj = Formattable::fromUFormattable(fmt);
  823. return obj->getDouble(*status);
  824. }
  825. U_DRAFT int32_t U_EXPORT2
  826. ufmt_getLong(UFormattable *fmt, UErrorCode *status) {
  827. Formattable *obj = Formattable::fromUFormattable(fmt);
  828. return obj->getLong(*status);
  829. }
  830. U_DRAFT const void *U_EXPORT2
  831. ufmt_getObject(const UFormattable *fmt, UErrorCode *status) {
  832. const Formattable *obj = Formattable::fromUFormattable(fmt);
  833. const void *ret = obj->getObject();
  834. if( ret==NULL &&
  835. (obj->getType() != Formattable::kObject) &&
  836. U_SUCCESS( *status )) {
  837. *status = U_INVALID_FORMAT_ERROR;
  838. }
  839. return ret;
  840. }
  841. U_DRAFT const UChar* U_EXPORT2
  842. ufmt_getUChars(UFormattable *fmt, int32_t *len, UErrorCode *status) {
  843. Formattable *obj = Formattable::fromUFormattable(fmt);
  844. // avoid bogosity by checking the type first.
  845. if( obj->getType() != Formattable::kString ) {
  846. if( U_SUCCESS(*status) ){
  847. *status = U_INVALID_FORMAT_ERROR;
  848. }
  849. return NULL;
  850. }
  851. // This should return a valid string
  852. UnicodeString &str = obj->getString(*status);
  853. if( U_SUCCESS(*status) && len != NULL ) {
  854. *len = str.length();
  855. }
  856. return str.getTerminatedBuffer();
  857. }
  858. U_DRAFT int32_t U_EXPORT2
  859. ufmt_getArrayLength(const UFormattable* fmt, UErrorCode *status) {
  860. const Formattable *obj = Formattable::fromUFormattable(fmt);
  861. int32_t count;
  862. (void)obj->getArray(count, *status);
  863. return count;
  864. }
  865. U_DRAFT UFormattable * U_EXPORT2
  866. ufmt_getArrayItemByIndex(UFormattable* fmt, int32_t n, UErrorCode *status) {
  867. Formattable *obj = Formattable::fromUFormattable(fmt);
  868. int32_t count;
  869. (void)obj->getArray(count, *status);
  870. if(U_FAILURE(*status)) {
  871. return NULL;
  872. } else if(n<0 || n>=count) {
  873. setError(*status, U_INDEX_OUTOFBOUNDS_ERROR);
  874. return NULL;
  875. } else {
  876. return (*obj)[n].toUFormattable(); // returns non-const Formattable
  877. }
  878. }
  879. U_DRAFT const char * U_EXPORT2
  880. ufmt_getDecNumChars(UFormattable *fmt, int32_t *len, UErrorCode *status) {
  881. if(U_FAILURE(*status)) {
  882. return "";
  883. }
  884. Formattable *obj = Formattable::fromUFormattable(fmt);
  885. CharString *charString = obj->internalGetCharString(*status);
  886. if(U_FAILURE(*status)) {
  887. return "";
  888. }
  889. if(charString == NULL) {
  890. *status = U_MEMORY_ALLOCATION_ERROR;
  891. return "";
  892. } else {
  893. if(len!=NULL) {
  894. *len = charString->length();
  895. }
  896. return charString->data();
  897. }
  898. }
  899. U_DRAFT int64_t U_EXPORT2
  900. ufmt_getInt64(UFormattable *fmt, UErrorCode *status) {
  901. Formattable *obj = Formattable::fromUFormattable(fmt);
  902. return obj->getInt64(*status);
  903. }
  904. #endif /* #if !UCONFIG_NO_FORMATTING */
  905. //eof