@@ -2546,6 +2546,14 @@ MeasureUnit MeasureUnit::getToJp() {
25462546
25472547// End generated code for measunit.cpp
25482548
2549+ /* *
2550+ * Generic binary search function for string arrays.
2551+ * @param array the array of strings to search in
2552+ * @param start the starting index (inclusive)
2553+ * @param end the ending index (exclusive)
2554+ * @param key the string to search for
2555+ * @return the index if found, -1 if not found
2556+ */
25492557static int32_t binarySearch (
25502558 const char * const * array, int32_t start, int32_t end, StringPiece key) {
25512559 while (start < end) {
@@ -2563,6 +2571,33 @@ static int32_t binarySearch(
25632571 return -1 ;
25642572}
25652573
2574+ /* *
2575+ * Helper function to get the subtype range for a given type index.
2576+ * @param typeIdx the type index (0 to UPRV_LENGTHOF(gTypes)-1)
2577+ * @param start will be set to the starting index in gSubTypes
2578+ * @param end will be set to the ending index in gSubTypes (exclusive)
2579+ * @return the length of the range (end - start)
2580+ */
2581+ static int32_t getSubtypeRange (int32_t typeIdx, int32_t &start, int32_t &end) {
2582+ U_ASSERT (typeIdx >= 0 && typeIdx < UPRV_LENGTHOF (gTypes ));
2583+ start = gOffsets [typeIdx];
2584+ end = gOffsets [typeIdx + 1 ];
2585+ return end - start;
2586+ }
2587+
2588+ /* *
2589+ * Binary search function that searches for a subtype in gSubTypes within the range
2590+ * corresponding to the given type.
2591+ * @param typeIdx the type index (0 to UPRV_LENGTHOF(gTypes)-1)
2592+ * @param key the subtype string to search for
2593+ * @return the index in gSubTypes if found, -1 if not found
2594+ */
2595+ static int32_t binarySearch (int32_t typeIdx, StringPiece key) {
2596+ int32_t start, end;
2597+ (void )getSubtypeRange (typeIdx, start, end);
2598+ return binarySearch (gSubTypes , start, end, key);
2599+ }
2600+
25662601MeasureUnit::MeasureUnit () : MeasureUnit(kBaseTypeIdx , kBaseSubTypeIdx ) {
25672602}
25682603
@@ -2680,7 +2715,8 @@ int32_t MeasureUnit::getAvailable(
26802715 }
26812716 int32_t idx = 0 ;
26822717 for (int32_t typeIdx = 0 ; typeIdx < UPRV_LENGTHOF (gTypes ); ++typeIdx) {
2683- int32_t len = gOffsets [typeIdx + 1 ] - gOffsets [typeIdx];
2718+ int32_t start, end;
2719+ int32_t len = getSubtypeRange (typeIdx, start, end);
26842720 for (int32_t subTypeIdx = 0 ; subTypeIdx < len; ++subTypeIdx) {
26852721 dest[idx].setTo (typeIdx, subTypeIdx);
26862722 ++idx;
@@ -2702,7 +2738,8 @@ int32_t MeasureUnit::getAvailable(
27022738 if (typeIdx == -1 ) {
27032739 return 0 ;
27042740 }
2705- int32_t len = gOffsets [typeIdx + 1 ] - gOffsets [typeIdx];
2741+ int32_t start, end;
2742+ int32_t len = getSubtypeRange (typeIdx, start, end);
27062743 if (destCapacity < len) {
27072744 errorCode = U_BUFFER_OVERFLOW_ERROR;
27082745 return len;
@@ -2729,6 +2766,24 @@ StringEnumeration* MeasureUnit::getAvailableTypes(UErrorCode &errorCode) {
27292766 return result;
27302767}
27312768
2769+ bool MeasureUnit::validateAndGet (StringPiece type, StringPiece subtype, MeasureUnit &result) {
2770+ // Find the type index using binary search
2771+ int32_t typeIdx = binarySearch (gTypes , 0 , UPRV_LENGTHOF (gTypes ), type);
2772+ if (typeIdx == -1 ) {
2773+ return false ; // Type not found
2774+ }
2775+
2776+ // Find the subtype within the type's range using binary search
2777+ int32_t subtypeIdx = binarySearch (typeIdx, subtype);
2778+ if (subtypeIdx == -1 ) {
2779+ return false ; // Subtype not found
2780+ }
2781+
2782+ // Create the MeasureUnit and return it
2783+ result.setTo (typeIdx, subtypeIdx - gOffsets [typeIdx]);
2784+ return true ;
2785+ }
2786+
27322787bool MeasureUnit::findBySubType (StringPiece subType, MeasureUnit* output) {
27332788 // Sanity checking kCurrencyOffset and final entry in gOffsets
27342789 U_ASSERT (uprv_strcmp (gTypes [kCurrencyOffset ], " currency" ) == 0 );
@@ -2739,7 +2794,7 @@ bool MeasureUnit::findBySubType(StringPiece subType, MeasureUnit* output) {
27392794 if (t == kCurrencyOffset ) {
27402795 continue ;
27412796 }
2742- int32_t st = binarySearch (gSubTypes , gOffsets [t], gOffsets [t + 1 ] , subType);
2797+ int32_t st = binarySearch (t , subType);
27432798 if (st >= 0 ) {
27442799 output->setTo (t, st - gOffsets [t]);
27452800 return true ;
@@ -2763,7 +2818,7 @@ void MeasureUnit::initTime(const char *timeId) {
27632818 int32_t result = binarySearch (gTypes , 0 , UPRV_LENGTHOF (gTypes ), " duration" );
27642819 U_ASSERT (result != -1 );
27652820 fTypeId = result;
2766- result = binarySearch (gSubTypes , gOffsets [ fTypeId ], gOffsets [ fTypeId + 1 ] , timeId);
2821+ result = binarySearch (fTypeId , timeId);
27672822 U_ASSERT (result != -1 );
27682823 fSubTypeId = result - gOffsets [fTypeId ];
27692824}
@@ -2772,8 +2827,7 @@ void MeasureUnit::initCurrency(StringPiece isoCurrency) {
27722827 int32_t result = binarySearch (gTypes , 0 , UPRV_LENGTHOF (gTypes ), " currency" );
27732828 U_ASSERT (result != -1 );
27742829 fTypeId = result;
2775- result = binarySearch (
2776- gSubTypes , gOffsets [fTypeId ], gOffsets [fTypeId + 1 ], isoCurrency);
2830+ result = binarySearch (fTypeId , isoCurrency);
27772831 if (result == -1 ) {
27782832 UErrorCode status = U_ZERO_ERROR;
27792833 fImpl = new MeasureUnitImpl (MeasureUnitImpl::forCurrencyCode (isoCurrency, status));
0 commit comments