1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 **********************************************************************
5 * Copyright (c) 2004-2016, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 **********************************************************************
9 * Created: April 26, 2004
11 **********************************************************************
13 #include "utypeinfo.h" // for 'typeid' to work
15 #include "unicode/measunit.h"
17 #if !UCONFIG_NO_FORMATTING
19 #include "unicode/uenum.h"
26 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(MeasureUnit
)
28 // All code between the "Start generated code" comment and
29 // the "End generated code" comment is auto generated code
30 // and must not be edited manually. For instructions on how to correctly
31 // update this code, refer to:
32 // http://site.icu-project.org/design/formatting/measureformat/updating-measure-unit
34 // Start generated code
37 static const int32_t gOffsets
[] = {
61 static const int32_t gIndexes
[] = {
85 // Must be sorted alphabetically.
86 static const char * const gTypes
[] = {
109 // Must be grouped by type and sorted alphabetically within each type.
110 static const char * const gSubTypes
[] = {
112 "meter-per-second-squared",
128 "milligram-per-deciliter",
129 "millimole-per-liter",
131 "liter-per-100kilometers",
132 "liter-per-kilometer",
134 "mile-per-gallon-imperial",
511 "millimeter-of-mercury",
512 "pound-per-square-inch",
513 "kilometer-per-hour",
548 // Must be sorted by first value and then second value.
549 static int32_t unitPerUnitToSingleUnit
[][4] = {
560 // Shortcuts to the base unit in order to make the default constructor fast
561 static const int32_t kBaseTypeIdx
= 14;
562 static const int32_t kBaseSubTypeIdx
= 0;
564 MeasureUnit
*MeasureUnit::createGForce(UErrorCode
&status
) {
565 return MeasureUnit::create(0, 0, status
);
568 MeasureUnit
*MeasureUnit::createMeterPerSecondSquared(UErrorCode
&status
) {
569 return MeasureUnit::create(0, 1, status
);
572 MeasureUnit
*MeasureUnit::createArcMinute(UErrorCode
&status
) {
573 return MeasureUnit::create(1, 0, status
);
576 MeasureUnit
*MeasureUnit::createArcSecond(UErrorCode
&status
) {
577 return MeasureUnit::create(1, 1, status
);
580 MeasureUnit
*MeasureUnit::createDegree(UErrorCode
&status
) {
581 return MeasureUnit::create(1, 2, status
);
584 MeasureUnit
*MeasureUnit::createRadian(UErrorCode
&status
) {
585 return MeasureUnit::create(1, 3, status
);
588 MeasureUnit
*MeasureUnit::createRevolutionAngle(UErrorCode
&status
) {
589 return MeasureUnit::create(1, 4, status
);
592 MeasureUnit
*MeasureUnit::createAcre(UErrorCode
&status
) {
593 return MeasureUnit::create(2, 0, status
);
596 MeasureUnit
*MeasureUnit::createHectare(UErrorCode
&status
) {
597 return MeasureUnit::create(2, 1, status
);
600 MeasureUnit
*MeasureUnit::createSquareCentimeter(UErrorCode
&status
) {
601 return MeasureUnit::create(2, 2, status
);
604 MeasureUnit
*MeasureUnit::createSquareFoot(UErrorCode
&status
) {
605 return MeasureUnit::create(2, 3, status
);
608 MeasureUnit
*MeasureUnit::createSquareInch(UErrorCode
&status
) {
609 return MeasureUnit::create(2, 4, status
);
612 MeasureUnit
*MeasureUnit::createSquareKilometer(UErrorCode
&status
) {
613 return MeasureUnit::create(2, 5, status
);
616 MeasureUnit
*MeasureUnit::createSquareMeter(UErrorCode
&status
) {
617 return MeasureUnit::create(2, 6, status
);
620 MeasureUnit
*MeasureUnit::createSquareMile(UErrorCode
&status
) {
621 return MeasureUnit::create(2, 7, status
);
624 MeasureUnit
*MeasureUnit::createSquareYard(UErrorCode
&status
) {
625 return MeasureUnit::create(2, 8, status
);
628 MeasureUnit
*MeasureUnit::createKarat(UErrorCode
&status
) {
629 return MeasureUnit::create(3, 0, status
);
632 MeasureUnit
*MeasureUnit::createMilligramPerDeciliter(UErrorCode
&status
) {
633 return MeasureUnit::create(3, 1, status
);
636 MeasureUnit
*MeasureUnit::createMillimolePerLiter(UErrorCode
&status
) {
637 return MeasureUnit::create(3, 2, status
);
640 MeasureUnit
*MeasureUnit::createPartPerMillion(UErrorCode
&status
) {
641 return MeasureUnit::create(3, 3, status
);
644 MeasureUnit
*MeasureUnit::createLiterPer100Kilometers(UErrorCode
&status
) {
645 return MeasureUnit::create(4, 0, status
);
648 MeasureUnit
*MeasureUnit::createLiterPerKilometer(UErrorCode
&status
) {
649 return MeasureUnit::create(4, 1, status
);
652 MeasureUnit
*MeasureUnit::createMilePerGallon(UErrorCode
&status
) {
653 return MeasureUnit::create(4, 2, status
);
656 MeasureUnit
*MeasureUnit::createMilePerGallonImperial(UErrorCode
&status
) {
657 return MeasureUnit::create(4, 3, status
);
660 MeasureUnit
*MeasureUnit::createBit(UErrorCode
&status
) {
661 return MeasureUnit::create(6, 0, status
);
664 MeasureUnit
*MeasureUnit::createByte(UErrorCode
&status
) {
665 return MeasureUnit::create(6, 1, status
);
668 MeasureUnit
*MeasureUnit::createGigabit(UErrorCode
&status
) {
669 return MeasureUnit::create(6, 2, status
);
672 MeasureUnit
*MeasureUnit::createGigabyte(UErrorCode
&status
) {
673 return MeasureUnit::create(6, 3, status
);
676 MeasureUnit
*MeasureUnit::createKilobit(UErrorCode
&status
) {
677 return MeasureUnit::create(6, 4, status
);
680 MeasureUnit
*MeasureUnit::createKilobyte(UErrorCode
&status
) {
681 return MeasureUnit::create(6, 5, status
);
684 MeasureUnit
*MeasureUnit::createMegabit(UErrorCode
&status
) {
685 return MeasureUnit::create(6, 6, status
);
688 MeasureUnit
*MeasureUnit::createMegabyte(UErrorCode
&status
) {
689 return MeasureUnit::create(6, 7, status
);
692 MeasureUnit
*MeasureUnit::createTerabit(UErrorCode
&status
) {
693 return MeasureUnit::create(6, 8, status
);
696 MeasureUnit
*MeasureUnit::createTerabyte(UErrorCode
&status
) {
697 return MeasureUnit::create(6, 9, status
);
700 MeasureUnit
*MeasureUnit::createCentury(UErrorCode
&status
) {
701 return MeasureUnit::create(7, 0, status
);
704 MeasureUnit
*MeasureUnit::createDay(UErrorCode
&status
) {
705 return MeasureUnit::create(7, 1, status
);
708 MeasureUnit
*MeasureUnit::createHour(UErrorCode
&status
) {
709 return MeasureUnit::create(7, 2, status
);
712 MeasureUnit
*MeasureUnit::createMicrosecond(UErrorCode
&status
) {
713 return MeasureUnit::create(7, 3, status
);
716 MeasureUnit
*MeasureUnit::createMillisecond(UErrorCode
&status
) {
717 return MeasureUnit::create(7, 4, status
);
720 MeasureUnit
*MeasureUnit::createMinute(UErrorCode
&status
) {
721 return MeasureUnit::create(7, 5, status
);
724 MeasureUnit
*MeasureUnit::createMonth(UErrorCode
&status
) {
725 return MeasureUnit::create(7, 6, status
);
728 MeasureUnit
*MeasureUnit::createNanosecond(UErrorCode
&status
) {
729 return MeasureUnit::create(7, 7, status
);
732 MeasureUnit
*MeasureUnit::createSecond(UErrorCode
&status
) {
733 return MeasureUnit::create(7, 8, status
);
736 MeasureUnit
*MeasureUnit::createWeek(UErrorCode
&status
) {
737 return MeasureUnit::create(7, 9, status
);
740 MeasureUnit
*MeasureUnit::createYear(UErrorCode
&status
) {
741 return MeasureUnit::create(7, 10, status
);
744 MeasureUnit
*MeasureUnit::createAmpere(UErrorCode
&status
) {
745 return MeasureUnit::create(8, 0, status
);
748 MeasureUnit
*MeasureUnit::createMilliampere(UErrorCode
&status
) {
749 return MeasureUnit::create(8, 1, status
);
752 MeasureUnit
*MeasureUnit::createOhm(UErrorCode
&status
) {
753 return MeasureUnit::create(8, 2, status
);
756 MeasureUnit
*MeasureUnit::createVolt(UErrorCode
&status
) {
757 return MeasureUnit::create(8, 3, status
);
760 MeasureUnit
*MeasureUnit::createCalorie(UErrorCode
&status
) {
761 return MeasureUnit::create(9, 0, status
);
764 MeasureUnit
*MeasureUnit::createFoodcalorie(UErrorCode
&status
) {
765 return MeasureUnit::create(9, 1, status
);
768 MeasureUnit
*MeasureUnit::createJoule(UErrorCode
&status
) {
769 return MeasureUnit::create(9, 2, status
);
772 MeasureUnit
*MeasureUnit::createKilocalorie(UErrorCode
&status
) {
773 return MeasureUnit::create(9, 3, status
);
776 MeasureUnit
*MeasureUnit::createKilojoule(UErrorCode
&status
) {
777 return MeasureUnit::create(9, 4, status
);
780 MeasureUnit
*MeasureUnit::createKilowattHour(UErrorCode
&status
) {
781 return MeasureUnit::create(9, 5, status
);
784 MeasureUnit
*MeasureUnit::createGigahertz(UErrorCode
&status
) {
785 return MeasureUnit::create(10, 0, status
);
788 MeasureUnit
*MeasureUnit::createHertz(UErrorCode
&status
) {
789 return MeasureUnit::create(10, 1, status
);
792 MeasureUnit
*MeasureUnit::createKilohertz(UErrorCode
&status
) {
793 return MeasureUnit::create(10, 2, status
);
796 MeasureUnit
*MeasureUnit::createMegahertz(UErrorCode
&status
) {
797 return MeasureUnit::create(10, 3, status
);
800 MeasureUnit
*MeasureUnit::createAstronomicalUnit(UErrorCode
&status
) {
801 return MeasureUnit::create(11, 0, status
);
804 MeasureUnit
*MeasureUnit::createCentimeter(UErrorCode
&status
) {
805 return MeasureUnit::create(11, 1, status
);
808 MeasureUnit
*MeasureUnit::createDecimeter(UErrorCode
&status
) {
809 return MeasureUnit::create(11, 2, status
);
812 MeasureUnit
*MeasureUnit::createFathom(UErrorCode
&status
) {
813 return MeasureUnit::create(11, 3, status
);
816 MeasureUnit
*MeasureUnit::createFoot(UErrorCode
&status
) {
817 return MeasureUnit::create(11, 4, status
);
820 MeasureUnit
*MeasureUnit::createFurlong(UErrorCode
&status
) {
821 return MeasureUnit::create(11, 5, status
);
824 MeasureUnit
*MeasureUnit::createInch(UErrorCode
&status
) {
825 return MeasureUnit::create(11, 6, status
);
828 MeasureUnit
*MeasureUnit::createKilometer(UErrorCode
&status
) {
829 return MeasureUnit::create(11, 7, status
);
832 MeasureUnit
*MeasureUnit::createLightYear(UErrorCode
&status
) {
833 return MeasureUnit::create(11, 8, status
);
836 MeasureUnit
*MeasureUnit::createMeter(UErrorCode
&status
) {
837 return MeasureUnit::create(11, 9, status
);
840 MeasureUnit
*MeasureUnit::createMicrometer(UErrorCode
&status
) {
841 return MeasureUnit::create(11, 10, status
);
844 MeasureUnit
*MeasureUnit::createMile(UErrorCode
&status
) {
845 return MeasureUnit::create(11, 11, status
);
848 MeasureUnit
*MeasureUnit::createMileScandinavian(UErrorCode
&status
) {
849 return MeasureUnit::create(11, 12, status
);
852 MeasureUnit
*MeasureUnit::createMillimeter(UErrorCode
&status
) {
853 return MeasureUnit::create(11, 13, status
);
856 MeasureUnit
*MeasureUnit::createNanometer(UErrorCode
&status
) {
857 return MeasureUnit::create(11, 14, status
);
860 MeasureUnit
*MeasureUnit::createNauticalMile(UErrorCode
&status
) {
861 return MeasureUnit::create(11, 15, status
);
864 MeasureUnit
*MeasureUnit::createParsec(UErrorCode
&status
) {
865 return MeasureUnit::create(11, 16, status
);
868 MeasureUnit
*MeasureUnit::createPicometer(UErrorCode
&status
) {
869 return MeasureUnit::create(11, 17, status
);
872 MeasureUnit
*MeasureUnit::createPoint(UErrorCode
&status
) {
873 return MeasureUnit::create(11, 18, status
);
876 MeasureUnit
*MeasureUnit::createYard(UErrorCode
&status
) {
877 return MeasureUnit::create(11, 19, status
);
880 MeasureUnit
*MeasureUnit::createLux(UErrorCode
&status
) {
881 return MeasureUnit::create(12, 0, status
);
884 MeasureUnit
*MeasureUnit::createCarat(UErrorCode
&status
) {
885 return MeasureUnit::create(13, 0, status
);
888 MeasureUnit
*MeasureUnit::createGram(UErrorCode
&status
) {
889 return MeasureUnit::create(13, 1, status
);
892 MeasureUnit
*MeasureUnit::createKilogram(UErrorCode
&status
) {
893 return MeasureUnit::create(13, 2, status
);
896 MeasureUnit
*MeasureUnit::createMetricTon(UErrorCode
&status
) {
897 return MeasureUnit::create(13, 3, status
);
900 MeasureUnit
*MeasureUnit::createMicrogram(UErrorCode
&status
) {
901 return MeasureUnit::create(13, 4, status
);
904 MeasureUnit
*MeasureUnit::createMilligram(UErrorCode
&status
) {
905 return MeasureUnit::create(13, 5, status
);
908 MeasureUnit
*MeasureUnit::createOunce(UErrorCode
&status
) {
909 return MeasureUnit::create(13, 6, status
);
912 MeasureUnit
*MeasureUnit::createOunceTroy(UErrorCode
&status
) {
913 return MeasureUnit::create(13, 7, status
);
916 MeasureUnit
*MeasureUnit::createPound(UErrorCode
&status
) {
917 return MeasureUnit::create(13, 8, status
);
920 MeasureUnit
*MeasureUnit::createStone(UErrorCode
&status
) {
921 return MeasureUnit::create(13, 9, status
);
924 MeasureUnit
*MeasureUnit::createTon(UErrorCode
&status
) {
925 return MeasureUnit::create(13, 10, status
);
928 MeasureUnit
*MeasureUnit::createGigawatt(UErrorCode
&status
) {
929 return MeasureUnit::create(15, 0, status
);
932 MeasureUnit
*MeasureUnit::createHorsepower(UErrorCode
&status
) {
933 return MeasureUnit::create(15, 1, status
);
936 MeasureUnit
*MeasureUnit::createKilowatt(UErrorCode
&status
) {
937 return MeasureUnit::create(15, 2, status
);
940 MeasureUnit
*MeasureUnit::createMegawatt(UErrorCode
&status
) {
941 return MeasureUnit::create(15, 3, status
);
944 MeasureUnit
*MeasureUnit::createMilliwatt(UErrorCode
&status
) {
945 return MeasureUnit::create(15, 4, status
);
948 MeasureUnit
*MeasureUnit::createWatt(UErrorCode
&status
) {
949 return MeasureUnit::create(15, 5, status
);
952 MeasureUnit
*MeasureUnit::createHectopascal(UErrorCode
&status
) {
953 return MeasureUnit::create(16, 0, status
);
956 MeasureUnit
*MeasureUnit::createInchHg(UErrorCode
&status
) {
957 return MeasureUnit::create(16, 1, status
);
960 MeasureUnit
*MeasureUnit::createMillibar(UErrorCode
&status
) {
961 return MeasureUnit::create(16, 2, status
);
964 MeasureUnit
*MeasureUnit::createMillimeterOfMercury(UErrorCode
&status
) {
965 return MeasureUnit::create(16, 3, status
);
968 MeasureUnit
*MeasureUnit::createPoundPerSquareInch(UErrorCode
&status
) {
969 return MeasureUnit::create(16, 4, status
);
972 MeasureUnit
*MeasureUnit::createKilometerPerHour(UErrorCode
&status
) {
973 return MeasureUnit::create(17, 0, status
);
976 MeasureUnit
*MeasureUnit::createKnot(UErrorCode
&status
) {
977 return MeasureUnit::create(17, 1, status
);
980 MeasureUnit
*MeasureUnit::createMeterPerSecond(UErrorCode
&status
) {
981 return MeasureUnit::create(17, 2, status
);
984 MeasureUnit
*MeasureUnit::createMilePerHour(UErrorCode
&status
) {
985 return MeasureUnit::create(17, 3, status
);
988 MeasureUnit
*MeasureUnit::createCelsius(UErrorCode
&status
) {
989 return MeasureUnit::create(18, 0, status
);
992 MeasureUnit
*MeasureUnit::createFahrenheit(UErrorCode
&status
) {
993 return MeasureUnit::create(18, 1, status
);
996 MeasureUnit
*MeasureUnit::createGenericTemperature(UErrorCode
&status
) {
997 return MeasureUnit::create(18, 2, status
);
1000 MeasureUnit
*MeasureUnit::createKelvin(UErrorCode
&status
) {
1001 return MeasureUnit::create(18, 3, status
);
1004 MeasureUnit
*MeasureUnit::createAcreFoot(UErrorCode
&status
) {
1005 return MeasureUnit::create(19, 0, status
);
1008 MeasureUnit
*MeasureUnit::createBushel(UErrorCode
&status
) {
1009 return MeasureUnit::create(19, 1, status
);
1012 MeasureUnit
*MeasureUnit::createCentiliter(UErrorCode
&status
) {
1013 return MeasureUnit::create(19, 2, status
);
1016 MeasureUnit
*MeasureUnit::createCubicCentimeter(UErrorCode
&status
) {
1017 return MeasureUnit::create(19, 3, status
);
1020 MeasureUnit
*MeasureUnit::createCubicFoot(UErrorCode
&status
) {
1021 return MeasureUnit::create(19, 4, status
);
1024 MeasureUnit
*MeasureUnit::createCubicInch(UErrorCode
&status
) {
1025 return MeasureUnit::create(19, 5, status
);
1028 MeasureUnit
*MeasureUnit::createCubicKilometer(UErrorCode
&status
) {
1029 return MeasureUnit::create(19, 6, status
);
1032 MeasureUnit
*MeasureUnit::createCubicMeter(UErrorCode
&status
) {
1033 return MeasureUnit::create(19, 7, status
);
1036 MeasureUnit
*MeasureUnit::createCubicMile(UErrorCode
&status
) {
1037 return MeasureUnit::create(19, 8, status
);
1040 MeasureUnit
*MeasureUnit::createCubicYard(UErrorCode
&status
) {
1041 return MeasureUnit::create(19, 9, status
);
1044 MeasureUnit
*MeasureUnit::createCup(UErrorCode
&status
) {
1045 return MeasureUnit::create(19, 10, status
);
1048 MeasureUnit
*MeasureUnit::createCupMetric(UErrorCode
&status
) {
1049 return MeasureUnit::create(19, 11, status
);
1052 MeasureUnit
*MeasureUnit::createDeciliter(UErrorCode
&status
) {
1053 return MeasureUnit::create(19, 12, status
);
1056 MeasureUnit
*MeasureUnit::createFluidOunce(UErrorCode
&status
) {
1057 return MeasureUnit::create(19, 13, status
);
1060 MeasureUnit
*MeasureUnit::createGallon(UErrorCode
&status
) {
1061 return MeasureUnit::create(19, 14, status
);
1064 MeasureUnit
*MeasureUnit::createGallonImperial(UErrorCode
&status
) {
1065 return MeasureUnit::create(19, 15, status
);
1068 MeasureUnit
*MeasureUnit::createHectoliter(UErrorCode
&status
) {
1069 return MeasureUnit::create(19, 16, status
);
1072 MeasureUnit
*MeasureUnit::createLiter(UErrorCode
&status
) {
1073 return MeasureUnit::create(19, 17, status
);
1076 MeasureUnit
*MeasureUnit::createMegaliter(UErrorCode
&status
) {
1077 return MeasureUnit::create(19, 18, status
);
1080 MeasureUnit
*MeasureUnit::createMilliliter(UErrorCode
&status
) {
1081 return MeasureUnit::create(19, 19, status
);
1084 MeasureUnit
*MeasureUnit::createPint(UErrorCode
&status
) {
1085 return MeasureUnit::create(19, 20, status
);
1088 MeasureUnit
*MeasureUnit::createPintMetric(UErrorCode
&status
) {
1089 return MeasureUnit::create(19, 21, status
);
1092 MeasureUnit
*MeasureUnit::createQuart(UErrorCode
&status
) {
1093 return MeasureUnit::create(19, 22, status
);
1096 MeasureUnit
*MeasureUnit::createTablespoon(UErrorCode
&status
) {
1097 return MeasureUnit::create(19, 23, status
);
1100 MeasureUnit
*MeasureUnit::createTeaspoon(UErrorCode
&status
) {
1101 return MeasureUnit::create(19, 24, status
);
1104 // End generated code
1106 static int32_t binarySearch(
1107 const char * const * array
, int32_t start
, int32_t end
, const char * key
) {
1108 while (start
< end
) {
1109 int32_t mid
= (start
+ end
) / 2;
1110 int32_t cmp
= uprv_strcmp(array
[mid
], key
);
1123 MeasureUnit::MeasureUnit() {
1125 fTypeId
= kBaseTypeIdx
;
1126 fSubTypeId
= kBaseSubTypeIdx
;
1129 MeasureUnit::MeasureUnit(const MeasureUnit
&other
)
1130 : fTypeId(other
.fTypeId
), fSubTypeId(other
.fSubTypeId
) {
1131 uprv_strcpy(fCurrency
, other
.fCurrency
);
1134 MeasureUnit
&MeasureUnit::operator=(const MeasureUnit
&other
) {
1135 if (this == &other
) {
1138 fTypeId
= other
.fTypeId
;
1139 fSubTypeId
= other
.fSubTypeId
;
1140 uprv_strcpy(fCurrency
, other
.fCurrency
);
1144 UObject
*MeasureUnit::clone() const {
1145 return new MeasureUnit(*this);
1148 MeasureUnit::~MeasureUnit() {
1151 const char *MeasureUnit::getType() const {
1152 return gTypes
[fTypeId
];
1155 const char *MeasureUnit::getSubtype() const {
1156 return fCurrency
[0] == 0 ? gSubTypes
[getOffset()] : fCurrency
;
1159 UBool
MeasureUnit::operator==(const UObject
& other
) const {
1160 if (this == &other
) { // Same object, equal
1163 if (typeid(*this) != typeid(other
)) { // Different types, not equal
1166 const MeasureUnit
&rhs
= static_cast<const MeasureUnit
&>(other
);
1168 fTypeId
== rhs
.fTypeId
1169 && fSubTypeId
== rhs
.fSubTypeId
1170 && uprv_strcmp(fCurrency
, rhs
.fCurrency
) == 0);
1173 int32_t MeasureUnit::getIndex() const {
1174 return gIndexes
[fTypeId
] + fSubTypeId
;
1177 int32_t MeasureUnit::getAvailable(
1179 int32_t destCapacity
,
1180 UErrorCode
&errorCode
) {
1181 if (U_FAILURE(errorCode
)) {
1184 if (destCapacity
< UPRV_LENGTHOF(gSubTypes
)) {
1185 errorCode
= U_BUFFER_OVERFLOW_ERROR
;
1186 return UPRV_LENGTHOF(gSubTypes
);
1189 for (int32_t typeIdx
= 0; typeIdx
< UPRV_LENGTHOF(gTypes
); ++typeIdx
) {
1190 int32_t len
= gOffsets
[typeIdx
+ 1] - gOffsets
[typeIdx
];
1191 for (int32_t subTypeIdx
= 0; subTypeIdx
< len
; ++subTypeIdx
) {
1192 dest
[idx
].setTo(typeIdx
, subTypeIdx
);
1196 U_ASSERT(idx
== UPRV_LENGTHOF(gSubTypes
));
1197 return UPRV_LENGTHOF(gSubTypes
);
1200 int32_t MeasureUnit::getAvailable(
1203 int32_t destCapacity
,
1204 UErrorCode
&errorCode
) {
1205 if (U_FAILURE(errorCode
)) {
1208 int32_t typeIdx
= binarySearch(gTypes
, 0, UPRV_LENGTHOF(gTypes
), type
);
1209 if (typeIdx
== -1) {
1212 int32_t len
= gOffsets
[typeIdx
+ 1] - gOffsets
[typeIdx
];
1213 if (destCapacity
< len
) {
1214 errorCode
= U_BUFFER_OVERFLOW_ERROR
;
1217 for (int subTypeIdx
= 0; subTypeIdx
< len
; ++subTypeIdx
) {
1218 dest
[subTypeIdx
].setTo(typeIdx
, subTypeIdx
);
1223 StringEnumeration
* MeasureUnit::getAvailableTypes(UErrorCode
&errorCode
) {
1224 UEnumeration
*uenum
= uenum_openCharStringsEnumeration(
1225 gTypes
, UPRV_LENGTHOF(gTypes
), &errorCode
);
1226 if (U_FAILURE(errorCode
)) {
1230 StringEnumeration
*result
= new UStringEnumeration(uenum
);
1231 if (result
== NULL
) {
1232 errorCode
= U_MEMORY_ALLOCATION_ERROR
;
1239 int32_t MeasureUnit::getIndexCount() {
1240 return gIndexes
[UPRV_LENGTHOF(gIndexes
) - 1];
1243 int32_t MeasureUnit::internalGetIndexForTypeAndSubtype(const char *type
, const char *subtype
) {
1244 int32_t t
= binarySearch(gTypes
, 0, UPRV_LENGTHOF(gTypes
), type
);
1248 int32_t st
= binarySearch(gSubTypes
, gOffsets
[t
], gOffsets
[t
+ 1], subtype
);
1252 return gIndexes
[t
] + st
- gOffsets
[t
];
1255 MeasureUnit
MeasureUnit::resolveUnitPerUnit(
1256 const MeasureUnit
&unit
, const MeasureUnit
&perUnit
, bool* isResolved
) {
1257 int32_t unitOffset
= unit
.getOffset();
1258 int32_t perUnitOffset
= perUnit
.getOffset();
1260 // binary search for (unitOffset, perUnitOffset)
1262 int32_t end
= UPRV_LENGTHOF(unitPerUnitToSingleUnit
);
1263 while (start
< end
) {
1264 int32_t mid
= (start
+ end
) / 2;
1265 int32_t *midRow
= unitPerUnitToSingleUnit
[mid
];
1266 if (unitOffset
< midRow
[0]) {
1268 } else if (unitOffset
> midRow
[0]) {
1270 } else if (perUnitOffset
< midRow
[1]) {
1272 } else if (perUnitOffset
> midRow
[1]) {
1275 // We found a resolution for our unit / per-unit combo
1278 return MeasureUnit(midRow
[2], midRow
[3]);
1282 *isResolved
= false;
1283 return MeasureUnit();
1286 MeasureUnit
*MeasureUnit::create(int typeId
, int subTypeId
, UErrorCode
&status
) {
1287 if (U_FAILURE(status
)) {
1290 MeasureUnit
*result
= new MeasureUnit(typeId
, subTypeId
);
1291 if (result
== NULL
) {
1292 status
= U_MEMORY_ALLOCATION_ERROR
;
1297 void MeasureUnit::initTime(const char *timeId
) {
1298 int32_t result
= binarySearch(gTypes
, 0, UPRV_LENGTHOF(gTypes
), "duration");
1299 U_ASSERT(result
!= -1);
1301 result
= binarySearch(gSubTypes
, gOffsets
[fTypeId
], gOffsets
[fTypeId
+ 1], timeId
);
1302 U_ASSERT(result
!= -1);
1303 fSubTypeId
= result
- gOffsets
[fTypeId
];
1306 void MeasureUnit::initCurrency(const char *isoCurrency
) {
1307 int32_t result
= binarySearch(gTypes
, 0, UPRV_LENGTHOF(gTypes
), "currency");
1308 U_ASSERT(result
!= -1);
1310 result
= binarySearch(
1311 gSubTypes
, gOffsets
[fTypeId
], gOffsets
[fTypeId
+ 1], isoCurrency
);
1313 fSubTypeId
= result
- gOffsets
[fTypeId
];
1315 uprv_strncpy(fCurrency
, isoCurrency
, UPRV_LENGTHOF(fCurrency
));
1320 void MeasureUnit::initNoUnit(const char *subtype
) {
1321 int32_t result
= binarySearch(gTypes
, 0, UPRV_LENGTHOF(gTypes
), "none");
1322 U_ASSERT(result
!= -1);
1324 result
= binarySearch(gSubTypes
, gOffsets
[fTypeId
], gOffsets
[fTypeId
+ 1], subtype
);
1325 U_ASSERT(result
!= -1);
1326 fSubTypeId
= result
- gOffsets
[fTypeId
];
1329 void MeasureUnit::setTo(int32_t typeId
, int32_t subTypeId
) {
1331 fSubTypeId
= subTypeId
;
1335 int32_t MeasureUnit::getOffset() const {
1336 return gOffsets
[fTypeId
] + fSubTypeId
;
1341 #endif /* !UNCONFIG_NO_FORMATTING */