]> granicus.if.org Git - icu/commitdiff
Add consistency checks for input and output units.
authorHugo van der Merwe <17109322+hugovdm@users.noreply.github.com>
Fri, 27 Mar 2020 15:01:18 +0000 (16:01 +0100)
committerHugo van der Merwe <17109322+hugovdm@users.noreply.github.com>
Fri, 27 Mar 2020 15:25:43 +0000 (16:25 +0100)
icu4c/source/i18n/getunitsdata.cpp
icu4c/source/i18n/getunitsdata.h

index 7724f4cce445bb965e35ce7f30f7fb658e1f5eae..830d89a0ed38cf6127c17efcf17af5dcef3eddbf 100644 (file)
@@ -300,36 +300,43 @@ MaybeStackVector<ConversionRateInfo> getConversionRatesInfo(const MeasureUnit so
     ures_getByKey(unitsBundle.getAlias(), "convertUnits", convertUnitsBundle.getAlias(), &status);
 
     ConversionRateDataSink convertSink(result);
-    if (baseCompoundUnit != NULL) {
-        *baseCompoundUnit = MeasureUnit();
-    }
+    MeasureUnit sourceBaseUnit;
     for (int i = 0; i < sourceUnitsLength; i++) {
         MeasureUnit baseUnit;
         processSingleUnit(sourceUnits[i], convertUnitsBundle.getAlias(), convertSink, &baseUnit, status);
-        if (baseCompoundUnit != NULL) {
-            if (source.getComplexity(status) == UMEASURE_UNIT_SEQUENCE) {
-                // TODO(hugovdm): add consistency checks.
-                *baseCompoundUnit = baseUnit;
+        if (source.getComplexity(status) == UMEASURE_UNIT_SEQUENCE) {
+            if (i == 0) {
+                sourceBaseUnit = baseUnit;
             } else {
-                *baseCompoundUnit = baseCompoundUnit->product(baseUnit, status);
+                if (baseUnit != sourceBaseUnit) {
+                    status = U_ILLEGAL_ARGUMENT_ERROR;
+                    return result;
+                }
             }
+        } else {
+            sourceBaseUnit = sourceBaseUnit.product(baseUnit, status);
         }
     }
-    if (baseCompoundUnit != NULL) {
-        *baseCompoundUnit = MeasureUnit();
-    }
+    MeasureUnit targetBaseUnit;
     for (int i = 0; i < targetUnitsLength; i++) {
         MeasureUnit baseUnit;
         processSingleUnit(targetUnits[i], convertUnitsBundle.getAlias(), convertSink, &baseUnit, status);
-        if (baseCompoundUnit != NULL) {
-            if (target.getComplexity(status) == UMEASURE_UNIT_SEQUENCE) {
-                // TODO(hugovdm): add consistency checks.
-                *baseCompoundUnit = baseUnit;
-            } else {
-                *baseCompoundUnit = baseCompoundUnit->product(baseUnit, status);
+        if (target.getComplexity(status) == UMEASURE_UNIT_SEQUENCE) {
+            // WIP/TODO(hugovdm): add consistency checks.
+            if (baseUnit != sourceBaseUnit) {
+                status = U_ILLEGAL_ARGUMENT_ERROR;
+                return result;
             }
+            targetBaseUnit = baseUnit;
+        } else {
+            targetBaseUnit = targetBaseUnit.product(baseUnit, status);
         }
     }
+    if (targetBaseUnit != sourceBaseUnit) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return result;
+    }
+    if (baseCompoundUnit != NULL) { *baseCompoundUnit = sourceBaseUnit; }
     return result;
 }
 
index 3b9e0fb500543fca832b0a678034c9e8a1b86ad0..1437b686f8d27b5d8c4a223da77a57b86f1910f7 100644 (file)
@@ -49,10 +49,13 @@ struct U_I18N_API UnitPreference {
  * Collects and returns ConversionRateInfo needed to convert from source to
  * baseUnit.
  *
+ * If source and target are not compatible for conversion, status will be set to
+ * U_ILLEGAL_ARGUMENT_ERROR.
+ *
  * @param source The source unit (the unit type converted from).
  * @param target The target unit (the unit type converted to).
  * @param baseCompoundUnit Output parameter: if not NULL, it will be set to the
- * base unit type used as pivot for converting from source to target.
+ * compound base unit type used as pivot for converting from source to target.
  * @param status Receives status.
  */
 MaybeStackVector<ConversionRateInfo> U_I18N_API getConversionRatesInfo(MeasureUnit source,