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 // maps our unit element to the corresponding ICU unit 27 static const TimeUnit::UTimeUnitFields skUnitMap[] = { 28 TimeUnit::UTIMEUNIT_YEAR, 29 TimeUnit::UTIMEUNIT_MONTH, 30 TimeUnit::UTIMEUNIT_WEEK, 31 TimeUnit::UTIMEUNIT_DAY, 32 TimeUnit::UTIMEUNIT_HOUR, 33 TimeUnit::UTIMEUNIT_MINUTE, 34 TimeUnit::UTIMEUNIT_SECOND, 35 }; 36 37 //maps our unit style to the corresponding ICU unit 38 static const UTimeUnitFormatStyle kTimeUnitStyleToICU[] = { 39 UTMUTFMT_ABBREVIATED_STYLE, 40 UTMUTFMT_FULL_STYLE, 41 }; 42 43 44 BTimeUnitFormat::BTimeUnitFormat(const time_unit_style style) 45 : Inherited() 46 { 47 Locale icuLocale(fLanguage.Code()); 48 UErrorCode icuStatus = U_ZERO_ERROR; 49 if (style != B_TIME_UNIT_ABBREVIATED && style != B_TIME_UNIT_FULL) { 50 fFormatter = NULL; 51 fInitStatus = B_BAD_VALUE; 52 return; 53 } 54 55 fFormatter = new TimeUnitFormat(icuLocale, kTimeUnitStyleToICU[style], 56 icuStatus); 57 if (fFormatter == NULL) { 58 fInitStatus = B_NO_MEMORY; 59 return; 60 } 61 62 if (!U_SUCCESS(icuStatus)) 63 fInitStatus = B_ERROR; 64 } 65 66 67 BTimeUnitFormat::BTimeUnitFormat(const BLanguage& language, 68 const BFormattingConventions& conventions, 69 const time_unit_style style) 70 : Inherited(language, conventions) 71 { 72 Locale icuLocale(fLanguage.Code()); 73 UErrorCode icuStatus = U_ZERO_ERROR; 74 if (style != B_TIME_UNIT_ABBREVIATED && style != B_TIME_UNIT_FULL) { 75 fFormatter = NULL; 76 fInitStatus = B_BAD_VALUE; 77 return; 78 } 79 80 fFormatter = new TimeUnitFormat(icuLocale, kTimeUnitStyleToICU[style], 81 icuStatus); 82 if (fFormatter == NULL) { 83 fInitStatus = B_NO_MEMORY; 84 return; 85 } 86 87 if (!U_SUCCESS(icuStatus)) 88 fInitStatus = B_ERROR; 89 } 90 91 92 BTimeUnitFormat::BTimeUnitFormat(const BTimeUnitFormat& other) 93 : 94 Inherited(other), 95 fFormatter(other.fFormatter != NULL 96 ? new TimeUnitFormat(*other.fFormatter) : NULL) 97 { 98 if (fFormatter == NULL && other.fFormatter != NULL) 99 fInitStatus = B_NO_MEMORY; 100 } 101 102 103 BTimeUnitFormat::~BTimeUnitFormat() 104 { 105 delete fFormatter; 106 } 107 108 109 status_t 110 BTimeUnitFormat::Format(BString& buffer, const int32 value, 111 const time_unit_element unit) const 112 { 113 if (unit < 0 || unit > B_TIME_UNIT_LAST) 114 return B_BAD_VALUE; 115 116 if (fFormatter == NULL) 117 return B_NO_INIT; 118 119 UErrorCode icuStatus = U_ZERO_ERROR; 120 TimeUnitAmount* timeUnitAmount 121 = new TimeUnitAmount((double)value, skUnitMap[unit], icuStatus); 122 if (timeUnitAmount == NULL) 123 return B_NO_MEMORY; 124 if (!U_SUCCESS(icuStatus)) 125 return B_ERROR; 126 127 Formattable formattable; 128 formattable.adoptObject(timeUnitAmount); 129 FieldPosition pos(FieldPosition::DONT_CARE); 130 UnicodeString unicodeResult; 131 fFormatter->format(formattable, unicodeResult, pos, icuStatus); 132 if (!U_SUCCESS(icuStatus)) 133 return B_ERROR; 134 135 BStringByteSink byteSink(&buffer); 136 unicodeResult.toUTF8(byteSink); 137 138 return B_OK; 139 } 140