1 /* 2 * Copyright 2010, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Adrien Destugues <pulkomandy@gmail.com> 7 * Oliver Tappe <zooey@hirschkaefer.de> 8 */ 9 10 11 #include <unicode/uversion.h> 12 #include <TimeUnitFormat.h> 13 14 #include <new> 15 16 #include <unicode/format.h> 17 #include <unicode/locid.h> 18 #include <unicode/tmutfmt.h> 19 #include <unicode/utypes.h> 20 #include <ICUWrapper.h> 21 22 #include <Language.h> 23 #include <Locale.h> 24 #include <LocaleRoster.h> 25 26 27 U_NAMESPACE_USE 28 29 30 // maps our unit element to the corresponding ICU unit 31 static const TimeUnit::UTimeUnitFields skUnitMap[] = { 32 TimeUnit::UTIMEUNIT_YEAR, 33 TimeUnit::UTIMEUNIT_MONTH, 34 TimeUnit::UTIMEUNIT_WEEK, 35 TimeUnit::UTIMEUNIT_DAY, 36 TimeUnit::UTIMEUNIT_HOUR, 37 TimeUnit::UTIMEUNIT_MINUTE, 38 TimeUnit::UTIMEUNIT_SECOND, 39 }; 40 41 //maps our unit style to the corresponding ICU unit 42 static const UTimeUnitFormatStyle kTimeUnitStyleToICU[] = { 43 UTMUTFMT_ABBREVIATED_STYLE, 44 UTMUTFMT_FULL_STYLE, 45 }; 46 47 48 BTimeUnitFormat::BTimeUnitFormat(const time_unit_style style) 49 : Inherited() 50 { 51 Locale icuLocale(fLanguage.Code()); 52 UErrorCode icuStatus = U_ZERO_ERROR; 53 if (style != B_TIME_UNIT_ABBREVIATED && style != B_TIME_UNIT_FULL) { 54 fFormatter = NULL; 55 fInitStatus = B_BAD_VALUE; 56 return; 57 } 58 59 fFormatter = new TimeUnitFormat(icuLocale, kTimeUnitStyleToICU[style], 60 icuStatus); 61 if (fFormatter == NULL) { 62 fInitStatus = B_NO_MEMORY; 63 return; 64 } 65 66 if (!U_SUCCESS(icuStatus)) 67 fInitStatus = B_ERROR; 68 } 69 70 71 BTimeUnitFormat::BTimeUnitFormat(const BLanguage& language, 72 const BFormattingConventions& conventions, 73 const time_unit_style style) 74 : Inherited(language, conventions) 75 { 76 Locale icuLocale(fLanguage.Code()); 77 UErrorCode icuStatus = U_ZERO_ERROR; 78 if (style != B_TIME_UNIT_ABBREVIATED && style != B_TIME_UNIT_FULL) { 79 fFormatter = NULL; 80 fInitStatus = B_BAD_VALUE; 81 return; 82 } 83 84 fFormatter = new TimeUnitFormat(icuLocale, kTimeUnitStyleToICU[style], 85 icuStatus); 86 if (fFormatter == NULL) { 87 fInitStatus = B_NO_MEMORY; 88 return; 89 } 90 91 if (!U_SUCCESS(icuStatus)) 92 fInitStatus = B_ERROR; 93 } 94 95 96 BTimeUnitFormat::BTimeUnitFormat(const BTimeUnitFormat& other) 97 : 98 Inherited(other), 99 fFormatter(other.fFormatter != NULL 100 ? new TimeUnitFormat(*other.fFormatter) : NULL) 101 { 102 if (fFormatter == NULL && other.fFormatter != NULL) 103 fInitStatus = B_NO_MEMORY; 104 } 105 106 107 BTimeUnitFormat::~BTimeUnitFormat() 108 { 109 delete fFormatter; 110 } 111 112 113 status_t 114 BTimeUnitFormat::Format(BString& buffer, const int32 value, 115 const time_unit_element unit) const 116 { 117 if (unit < 0 || unit > B_TIME_UNIT_LAST) 118 return B_BAD_VALUE; 119 120 if (fFormatter == NULL) 121 return B_NO_INIT; 122 123 UErrorCode icuStatus = U_ZERO_ERROR; 124 TimeUnitAmount* timeUnitAmount 125 = new TimeUnitAmount((double)value, skUnitMap[unit], icuStatus); 126 if (timeUnitAmount == NULL) 127 return B_NO_MEMORY; 128 if (!U_SUCCESS(icuStatus)) { 129 delete timeUnitAmount; 130 return B_ERROR; 131 } 132 133 Formattable formattable; 134 formattable.adoptObject(timeUnitAmount); 135 FieldPosition pos(FieldPosition::DONT_CARE); 136 UnicodeString unicodeResult; 137 fFormatter->format(formattable, unicodeResult, pos, icuStatus); 138 if (!U_SUCCESS(icuStatus)) 139 return B_ERROR; 140 141 BStringByteSink byteSink(&buffer); 142 unicodeResult.toUTF8(byteSink); 143 144 return B_OK; 145 } 146