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