]> granicus.if.org Git - icu/commitdiff
Move wip_units_resource_loader.* code into unitsrouter.*
authorHugo van der Merwe <17109322+hugovdm@users.noreply.github.com>
Wed, 18 Mar 2020 17:34:38 +0000 (18:34 +0100)
committerHugo van der Merwe <17109322+hugovdm@users.noreply.github.com>
Wed, 18 Mar 2020 17:58:06 +0000 (18:58 +0100)
icu4c/source/i18n/Makefile.in
icu4c/source/i18n/unitsrouter.cpp
icu4c/source/i18n/unitsrouter.h
icu4c/source/test/intltest/Makefile.in
icu4c/source/test/intltest/unitstest.cpp
icu4c/source/test/intltest/wip_units_resource_loader.cpp [deleted file]
icu4c/source/test/intltest/wip_units_resource_loader.h [deleted file]

index 827f2c207badf43e5cd36b2acbac6340f4d4d710..0df439b7e90e53ae9c336b418c218c498618cb42 100644 (file)
@@ -115,7 +115,7 @@ numparse_affixes.o numparse_compositions.o numparse_validators.o \
 numrange_fluent.o numrange_impl.o \
 erarules.o \
 formattedvalue.o formattedval_iterimpl.o formattedval_sbimpl.o formatted_string_builder.o \
-unitconverter.o
+unitconverter.o unitsrouter.o
 
 ## Header files to install
 HEADERS = $(srcdir)/unicode/*.h
index 9da50ef06474c43b8583e0ec52627a3c7d1b0aad..50aab0dda141990b2315b9a4931a1ca34b4f0329 100644 (file)
 #if !UCONFIG_NO_FORMATTING
 
 #include "cmemory.h"
+#include "cstring.h"
+#include "number_decimalquantity.h"
+#include "resource.h"
 #include "unitsrouter.h"
+#include "uresimp.h"
 
 U_NAMESPACE_BEGIN
 
 namespace {
 /* Internal Data */
-// Preference of a single unit.
-struct UnitPreference {
-    StringPiece identifier;
-
-    // Represents the limit of the largest unit in the identifier that the quantity must be greater than
-    // or equal.
-    // e.g. geq: 0.3 for a unit "foot-and-inch"
-    double limit;
+// // Preference of a single unit.
+// struct UnitPreference {
+//     StringPiece identifier;
+
+//     // Represents the limit of the largest unit in the identifier that the quantity must be greater than
+//     // or equal.
+//     // e.g. geq: 0.3 for a unit "foot-and-inch"
+//     double limit;
+// };
+
+// MaybeStackVector<UnitPreference> extractUnitPreferences(StringPiece locale, StringPiece usage,
+//                                                         StringPiece category) {
+//     MaybeStackVector<UnitPreference> result;
+
+//     // TODO(hugovdm): extract from the database all the UnitPreference for the `locale`, `category` and
+//     // `usage` in order.
+
+//     return result;
+// }
+
+// StringPiece extractUnitCategory(MeasureUnit unit) {
+//     StringPiece result;
+
+//     // TODO(hugovdm): extract the category of a unit from their MeasureUnits.
+
+//     return result;
+// }
+
+using namespace ::hugovdm_wip;
+using icu::number::impl::DecimalQuantity;
+
+class ConvertUnitsSink : public ResourceSink {
+  public:
+    explicit ConvertUnitsSink(MaybeStackVector<ConversionRateInfo> &out) : outVector(out) {}
+
+    // WIP: look into noFallback
+    void put(const char *key, ResourceValue &value, UBool /*noFallback*/, UErrorCode &status) {
+        ResourceTable conversionRateTable = value.getTable(status);
+        if (U_FAILURE(status)) {
+            // fprintf(stderr, "%s: getTable failed\n", u_errorName(status));
+            return;
+        }
+
+        ConversionRateInfo *cr = outVector.emplaceBack();
+        if (!cr) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+
+        int32_t length = uprv_strlen(key);
+        cr->source.append(key, length, status);
+        if (U_FAILURE(status)) {
+            // fprintf(stderr, "%s: source.append failed\n", u_errorName(status));
+            return;
+        }
+        for (int32_t i = 0; conversionRateTable.getKeyAndValue(i, key, value); ++i) {
+            if (uprv_strcmp(key, "factor") == 0) {
+                int32_t length;
+                const UChar *f = value.getString(length, status);
+                cr->factor.appendInvariantChars(f, length, status);
+                cr->factorUChar = f;
+            } else if (uprv_strcmp(key, "offset") == 0) {
+                int32_t length;
+                const UChar *o = value.getString(length, status);
+                cr->offset.appendInvariantChars(o, length, status);
+                cr->offsetUChar = o;
+            } else if (uprv_strcmp(key, "target") == 0) {
+                int32_t length;
+                const UChar *t = value.getString(length, status);
+                cr->target.appendInvariantChars(t, length, status);
+                cr->targetUChar = t;
+            }
+        }
+    }
+
+  private:
+    MaybeStackVector<ConversionRateInfo> &outVector;
 };
 
-MaybeStackVector<UnitPreference> extractUnitPreferences(StringPiece locale, StringPiece usage,
-                                                        StringPiece category) {
-    MaybeStackVector<UnitPreference> result;
+class UnitPreferencesSink : public ResourceSink {
+  public:
+    explicit UnitPreferencesSink(MaybeStackVector<UnitPreference> &out) : outVector(out) {}
 
-    // TODO(hugovdm): extract from the database all the UnitPreference for the `locale`, `category` and
-    // `usage` in order.
+    // WIP: look into noFallback
+    void put(const char *key, ResourceValue &value, UBool /*noFallback*/, UErrorCode &status) {
+        if (U_FAILURE(status)) { return; }
+        int32_t prefLen;
+        ResourceArray unitPrefs = value.getArray(status);
+        if (U_FAILURE(status)) { return; }
+        prefLen = unitPrefs.getSize();
+        for (int32_t i = 0; unitPrefs.getValue(i, value); i++) {
+            UnitPreference *up = outVector.emplaceBack();
+            if (!up) {
+                status = U_MEMORY_ALLOCATION_ERROR;
+                return;
+            }
+            ResourceTable unitPref = value.getTable(status);
+            if (U_FAILURE(status)) { return; }
+            for (int32_t i = 0; unitPref.getKeyAndValue(i, key, value); ++i) {
+                if (uprv_strcmp(key, "unit") == 0) {
+                    int32_t length;
+                    const UChar *u = value.getString(length, status);
+                    up->unit.appendInvariantChars(u, length, status);
+                } else if (uprv_strcmp(key, "geq") == 0) {
+                    int32_t length;
+                    const UChar *g = value.getString(length, status);
+                    CharString geq;
+                    geq.appendInvariantChars(g, length, status);
+                    DecimalQuantity dq;
+                    dq.setToDecNumber(geq.data(), status);
+                    up->geq = dq.toDouble();
+                } else if (uprv_strcmp(key, "skeleton") == 0) {
+                    int32_t length;
+                    const UChar *s = value.getString(length, status);
+                    up->skeleton.appendInvariantChars(s, length, status);
+                }
+            }
+        }
+    }
 
-    return result;
-}
+  private:
+    MaybeStackVector<UnitPreference> &outVector;
+};
 
-StringPiece extractUnitCategory(MeasureUnit unit) {
-    StringPiece result;
+void putUnitPref(UResourceBundle *usageData, MaybeStackVector<UnitPreference> &outVector,
+                 UErrorCode &status) {
+    if (U_FAILURE(status)) { return; }
 
-    // TODO(hugovdm): extract the category of a unit from their MeasureUnits.
+    UResourceBundle *prefBundle = NULL;
+    int32_t numPrefs = ures_getSize(usageData);
+    for (int32_t i = 0; i < numPrefs; i++) {
+        prefBundle = ures_getByIndex(usageData, i, prefBundle, &status);
+        if (U_FAILURE(status)) {
+            // fprintf(stderr, "failed getting index %d/%d: %s\n", i, numPrefs, u_errorName(status));
+            status = U_ZERO_ERROR;
+            break;
+        }
+        int32_t len;
+        const UChar *unitIdent = ures_getStringByKey(prefBundle, "unit", &len, &status);
+        if (U_FAILURE(status)) {
+            // fprintf(stderr, "open unit failed: %s\n", u_errorName(status));
+            break;
+        }
 
-    return result;
+        UnitPreference *up = outVector.emplaceBack();
+        if (!up) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+        up->unit.appendInvariantChars(unitIdent, len, status);
+        if (U_FAILURE(status)) {
+            // fprintf(stderr, "failed appending unitIdent: %s\n", u_errorName(status));
+            status = U_ZERO_ERROR;
+            break;
+        }
+        const UChar *geq = ures_getStringByKey(prefBundle, "geq", &len, &status);
+        if (U_SUCCESS(status)) {
+            CharString cGeq;
+            cGeq.appendInvariantChars(geq, len, status);
+            DecimalQuantity dq;
+            dq.setToDecNumber(StringPiece(cGeq.data()), status);
+            // fprintf(stderr, "status: %s, geq: %s, dq.toDouble(): %f\n", u_errorName(status),
+            // cGeq.data(),
+            //         dq.toDouble());
+            up->geq = dq.toDouble();
+        } else if (status == U_MISSING_RESOURCE_ERROR) {
+            status = U_ZERO_ERROR;
+        }
+        if (U_FAILURE(status)) {
+            // fprintf(stderr, "failed appending geq: %s\n", u_errorName(status));
+            break;
+        }
+        const UChar *skel = ures_getStringByKey(prefBundle, "skeleton", &len, &status);
+        if (U_SUCCESS(status)) {
+            up->skeleton.appendInvariantChars(skel, len, status);
+        } else if (status == U_MISSING_RESOURCE_ERROR) {
+            status = U_ZERO_ERROR;
+        }
+    }
+    ures_close(prefBundle);
 }
 
 } // namespace
 
+namespace hugovdm_wip {
+
+/**
+ * Fetches required data FIXME.
+ *
+ * @param inputUnit the unit for which input is expected. (NOTE/WIP: If this is
+ * known to be a base unit already, we could strip some logic here.)
+ */
+void getUnitsData(const char *outputRegion, const char *usage, const MeasureUnit &inputUnit,
+                  CharString &category, MeasureUnit &baseUnit,
+                  MaybeStackVector<ConversionRateInfo> &conversionInfo,
+                  MaybeStackVector<UnitPreference> &unitPreferences, UErrorCode &status) {
+    // One can also use a StackUResourceBundle as a fill-in.
+    LocalUResourceBundlePointer unitsBundle(ures_openDirect(NULL, "units", &status));
+    if (U_FAILURE(status)) {
+        // fprintf(stderr, "%s: ures_openDirect %s\n", u_errorName(status), "units");
+        return;
+    }
+
+    MeasureUnit inputBase = inputUnit.withSIPrefix(UMEASURE_SI_PREFIX_ONE, status);
+    if (uprv_strcmp(inputBase.getIdentifier(), "gram") == 0) { inputBase = MeasureUnit::getKilogram(); }
+    // if (U_FAILURE(status)) fprintf(stderr, "failed getting inputBase: %s\n", u_errorName(status));
+
+    StackUResourceBundle stackBundle;
+    // CharString has initial capacity 40. Key appending only gets slow when we
+    // go beyond. TODO(hugovdm): look at how often this might happen though?
+    // Each append could be a re-allocation.
+    CharString key;
+    // key.append("convertUnits/", status);
+    key.append(inputBase.getIdentifier(), status);
+    ConvertUnitsSink convertSink(conversionInfo);
+    ures_getByKey(unitsBundle.getAlias(), "convertUnits", stackBundle.getAlias(), &status);
+    ures_getAllItemsWithFallback(stackBundle.getAlias(), key.data(), convertSink, status);
+    const CharString &baseIdentifier = conversionInfo[0]->target;
+    baseUnit = MeasureUnit::forIdentifier(baseIdentifier.data(), status);
+
+    // key.clear();
+    // key.append("unitQuantities/", status);
+    // key.append(baseIdentifier, status);
+    // ures_findSubResource(unitsBundle.getAlias(), key.data(), fillIn, &status);
+    // Now we still need to convert to string.
+    LocalUResourceBundlePointer unitQuantities(
+        ures_getByKey(unitsBundle.getAlias(), "unitQuantities", NULL, &status));
+    int32_t categoryLength;
+    const UChar *uCategory =
+        ures_getStringByKey(unitQuantities.getAlias(), baseIdentifier.data(), &categoryLength, &status);
+    category.appendInvariantChars(uCategory, categoryLength, status);
+
+    // We load the region-specific unit preferences into stackBundle, reusing it
+    // for fill-in every step of the way:
+    ures_getByKey(unitsBundle.getAlias(), "unitPreferenceData", stackBundle.getAlias(), &status);
+    ures_getByKey(stackBundle.getAlias(), category.data(), stackBundle.getAlias(), &status);
+    if (U_FAILURE(status)) { return; }
+    ures_getByKey(stackBundle.getAlias(), usage, stackBundle.getAlias(), &status);
+    if (status == U_MISSING_RESOURCE_ERROR) {
+        // Requested usage does not exist, use "default".
+        status = U_ZERO_ERROR;
+        ures_getByKey(stackBundle.getAlias(), "default", stackBundle.getAlias(), &status);
+    }
+    // if (U_FAILURE(status)) fprintf(stderr, "failed getting usage %s: %s\n", usage,
+    // u_errorName(status));
+    ures_getByKey(stackBundle.getAlias(), outputRegion, stackBundle.getAlias(), &status);
+    if (status == U_MISSING_RESOURCE_ERROR) {
+        // Requested region does not exist, use "001".
+        status = U_ZERO_ERROR;
+        ures_getByKey(stackBundle.getAlias(), "001", stackBundle.getAlias(), &status);
+    }
+    // if (U_FAILURE(status)) fprintf(stderr, "failed getting region %s: %s\n", outputRegion,
+    // u_errorName(status));
+    putUnitPref(stackBundle.getAlias(), unitPreferences, status);
+    // if (U_FAILURE(status)) fprintf(stderr, "putUnitPref failed: %s\n", u_errorName(status));
+
+    // An alterantive for the above "We load ..." block, I don't think this is neater:
+    // key.clear();
+    // key.append("unitPreferenceData/", status);
+    // key.append(category, status).append("/", status);
+    // key.append(usage, status).append("/", status); // FIXME: fall back to "default"
+    // key.append(outputRegion, status); // FIXME: fall back to "001"
+    // UnitPreferencesSink prefsSink(unitPreferences);
+    // ures_getAllItemsWithFallback(unitsBundle.getAlias(), key.data(), prefsSink, status);
+}
+
+} // namespace hugovdm_wip
+
 UnitsRouter::UnitsRouter(MeasureUnit inputUnit, StringPiece locale, StringPiece usage,
                          UErrorCode &status) {
-    StringPiece unitCategory = extractUnitCategory(inputUnit);
-    MaybeStackVector<UnitPreference> preferences = extractUnitPreferences(locale, usage, unitCategory);
-
-    for (int i = 0, n = preferences.length(); i < n; ++i) {
-        const auto &preference = *preferences[i];
-        MeasureUnit complexTargetUnit = MeasureUnit::forIdentifier(preference.identifier, status);
-        converterPreferences_.emplaceBack(
-            ConverterPreference(inputUnit, complexTargetUnit, preference.limit, status));
+    // StringPiece unitCategory = extractUnitCategory(inputUnit);
+    // MaybeStackVector<UnitPreference> preferences = extractUnitPreferences(locale, usage, unitCategory);
+    const char *region = "001"; // FIXME extract from locale.
+    CharString category;
+    MeasureUnit baseUnit;
+    MaybeStackVector<ConversionRateInfo> conversionInfo;
+    MaybeStackVector<UnitPreference> unitPreferences;
+    getUnitsData(region, usage.data(), inputUnit, category, baseUnit, conversionInfo, unitPreferences,
+                 status);
+
+    for (int i = 0, n = unitPreferences.length(); i < n; ++i) {
+        const auto &preference = *unitPreferences[i];
+        MeasureUnit complexTargetUnit = MeasureUnit::forIdentifier(preference.unit.data(), status);
+        // This fails to compile - it tries to copy a ConverterPreference
+        // instance but converter member has no copy-constructor:
+        // converterPreferences_.emplaceBack(
+        //     ConverterPreference(inputUnit, complexTargetUnit, preference.geq, status));
     }
 }
 
@@ -67,6 +318,7 @@ MaybeStackVector<Measure> UnitsRouter::route(double quantity, UErrorCode &status
             return converterPreference.converter.convert(quantity, status);
         }
     }
+    // FIXME: return <...>;
 }
 
 U_NAMESPACE_END
index 4fb9e9cdb8993703fcd05535bed0233d412f80d7..98a9029b6dc4ba587f7fdadcbce657e337f375fc 100644 (file)
@@ -7,6 +7,7 @@
 #ifndef __UNITSROUTER_H__
 #define __UNITSROUTER_H__
 
+#include "charstr.h" // CharString
 #include "cmemory.h"
 #include "complexunitsconverter.h"
 #include "unicode/errorcode.h"
@@ -36,6 +37,44 @@ class U_I18N_API UnitsRouter {
 
 U_NAMESPACE_END
 
+namespace hugovdm_wip {
+// This namespace contains code from hugovdm that hasn't been reviewed by sffc
+// yet. It still needs thorough review and a "final resting place".
+
+using icu::CharString;
+using icu::MaybeStackVector;
+using icu::MeasureUnit;
+
+struct ConversionRateInfo {
+    CharString source;
+    CharString target;
+    CharString factor;
+    CharString offset;
+
+    const UChar *factorUChar;
+    const UChar *offsetUChar;
+    // WIP: This is a UChar* so that it can point at the resource. We could
+    // convert it to a CharString and own it ourselves, or if we can trust
+    // another owner's lifetime management we can make it a char*.
+    const UChar *targetUChar;
+
+    bool reciprocal = false;
+};
+
+struct UnitPreference {
+    UnitPreference() : geq(0) {}
+    CharString unit;
+    double geq;
+    CharString skeleton;
+};
+
+void getUnitsData(const char *outputRegion, const char *usage, const MeasureUnit &inputUnit,
+                  CharString &category, MeasureUnit &baseUnit,
+                  MaybeStackVector<ConversionRateInfo> &conversionInfo,
+                  MaybeStackVector<UnitPreference> &unitPreferences, UErrorCode &status);
+
+} // namespace hugo_wip
+
 #endif //__UNITSROUTER_H__
 
 #endif /* #if !UCONFIG_NO_FORMATTING */
index 63487318a64cac5fdbd621989187d2906f802abe..594d491f6f73efe65eb534e3ae019c0857556b24 100644 (file)
@@ -69,7 +69,7 @@ string_segment_test.o \
 numbertest_parse.o numbertest_doubleconversion.o numbertest_skeletons.o \
 static_unisets_test.o numfmtdatadriventest.o numbertest_range.o erarulestest.o \
 formattedvaluetest.o formatted_string_builder_test.o numbertest_permutation.o \
-unitstest.o wip_units_resource_loader.o
+unitstest.o
 
 DEPS = $(OBJECTS:.o=.d)
 
index e46f2de4d921606eeb3644466d56660c33a8ccd1..b2da82d107d6af7a85088b6ef7b13383ab8e933d 100644 (file)
@@ -14,6 +14,7 @@
 #include "unicode/unistr.h"
 #include "unicode/unum.h"
 #include "unitconverter.h"
+#include "unitsrouter.h"
 #include "uparse.h"
 #include <iostream>
 
@@ -25,6 +26,7 @@ struct UnitConversionTestCase {
 };
 
 using icu::number::impl::DecimalQuantity;
+using namespace ::hugovdm_wip;
 
 class UnitsTest : public IntlTest {
   public:
@@ -806,8 +808,8 @@ void UnitsTest::testGetUnitsData() {
         MeasureUnit baseUnit;
         MaybeStackVector<ConversionRateInfo> conversionInfo;
         MaybeStackVector<UnitPreference> unitPreferences;
-        getUnitsData(t.outputRegion, t.usage, inputUnit, category, baseUnit, conversionInfo,
-                     unitPreferences, status);
+        hugovdm_wip::getUnitsData(t.outputRegion, t.usage, inputUnit, category, baseUnit, conversionInfo,
+                                  unitPreferences, status);
         if (status.errIfFailureAndReset("getUnitsData(\"%s\", \"%s\", \"%s\", ...)", t.outputRegion, t.usage, t.inputUnit)) {
             continue;
         }
diff --git a/icu4c/source/test/intltest/wip_units_resource_loader.cpp b/icu4c/source/test/intltest/wip_units_resource_loader.cpp
deleted file mode 100644 (file)
index 256c336..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-#include "wip_units_resource_loader.h"
-#include "cstring.h" // uprv_strcmp
-#include "cmemory.h" // MaybeStackVector
-#include "number_decimalquantity.h" // DecimalQuantity
-#include "uresimp.h" // ures_getAllItemsWithFallback
-
-using namespace icu;
-using icu::number::impl::DecimalQuantity;
-
-namespace {
-
-// Resources. It should be migrated to a permanent location with updated API,
-// once we know what that will look like and where that will be.
-
-class ConvertUnitsSink : public ResourceSink {
-  public:
-    explicit ConvertUnitsSink(MaybeStackVector<ConversionRateInfo> &out) : outVector(out) {}
-
-    // WIP: look into noFallback
-    void put(const char *key, ResourceValue &value, UBool /*noFallback*/, UErrorCode &status) {
-        ResourceTable conversionRateTable = value.getTable(status);
-        if (U_FAILURE(status)) {
-            // fprintf(stderr, "%s: getTable failed\n", u_errorName(status));
-            return;
-        }
-
-        ConversionRateInfo *cr = outVector.emplaceBack();
-        if (!cr) {
-            status = U_MEMORY_ALLOCATION_ERROR;
-            return;
-        }
-
-        int32_t length = uprv_strlen(key);
-        cr->source.append(key, length, status);
-        if (U_FAILURE(status)) {
-            // fprintf(stderr, "%s: source.append failed\n", u_errorName(status));
-            return;
-        }
-        for (int32_t i = 0; conversionRateTable.getKeyAndValue(i, key, value); ++i) {
-            if (uprv_strcmp(key, "factor") == 0) {
-                int32_t length;
-                const UChar *f = value.getString(length, status);
-                cr->factor.appendInvariantChars(f, length, status);
-                cr->factorUChar = f;
-            } else if (uprv_strcmp(key, "offset") == 0) {
-                int32_t length;
-                const UChar *o = value.getString(length, status);
-                cr->offset.appendInvariantChars(o, length, status);
-                cr->offsetUChar = o;
-            } else if (uprv_strcmp(key, "target") == 0) {
-                int32_t length;
-                const UChar *t = value.getString(length, status);
-                cr->target.appendInvariantChars(t, length, status);
-                cr->targetUChar = t;
-            }
-        }
-    }
-  private:
-    MaybeStackVector<ConversionRateInfo> &outVector;
-};
-
-class UnitPreferencesSink : public ResourceSink {
-  public:
-    explicit UnitPreferencesSink(MaybeStackVector<UnitPreference> &out) : outVector(out) {}
-
-    // WIP: look into noFallback
-    void put(const char *key, ResourceValue &value, UBool /*noFallback*/, UErrorCode &status) {
-        if (U_FAILURE(status)) { return; }
-        int32_t prefLen;
-        ResourceArray unitPrefs = value.getArray(status);
-        if (U_FAILURE(status)) { return; }
-        prefLen = unitPrefs.getSize();
-        for (int32_t i = 0; unitPrefs.getValue(i, value); i++) {
-            UnitPreference *up = outVector.emplaceBack();
-            if (!up) {
-                status = U_MEMORY_ALLOCATION_ERROR;
-                return;
-            }
-            ResourceTable unitPref = value.getTable(status);
-            if (U_FAILURE(status)) { return; }
-            for (int32_t i = 0; unitPref.getKeyAndValue(i, key, value); ++i) {
-                if (uprv_strcmp(key, "unit") == 0) {
-                    int32_t length;
-                    const UChar *u = value.getString(length, status);
-                    up->unit.appendInvariantChars(u, length, status);
-                } else if (uprv_strcmp(key, "geq") == 0) {
-                    int32_t length;
-                    const UChar *g = value.getString(length, status);
-                    CharString geq;
-                    geq.appendInvariantChars(g, length, status);
-                    DecimalQuantity dq;
-                    dq.setToDecNumber(geq.data(), status);
-                    up->geq = dq.toDouble();
-                } else if (uprv_strcmp(key, "skeleton") == 0) {
-                    int32_t length;
-                    const UChar *s = value.getString(length, status);
-                    up->skeleton.appendInvariantChars(s, length, status);
-                }
-            }
-        }
-    }
-  private:
-    MaybeStackVector<UnitPreference> &outVector;
-};
-
-void putUnitPref(UResourceBundle *usageData,
-                 MaybeStackVector<UnitPreference> &outVector, UErrorCode &status) {
-    if (U_FAILURE(status)) { return; }
-
-    UResourceBundle *prefBundle = NULL;
-    int32_t numPrefs = ures_getSize(usageData);
-    for (int32_t i = 0; i < numPrefs; i++) {
-        prefBundle = ures_getByIndex(usageData, i, prefBundle, &status);
-        if (U_FAILURE(status)) {
-            // fprintf(stderr, "failed getting index %d/%d: %s\n", i, numPrefs, u_errorName(status));
-            status = U_ZERO_ERROR;
-            break;
-        }
-        int32_t len;
-        const UChar *unitIdent = ures_getStringByKey(prefBundle, "unit", &len, &status);
-        if (U_FAILURE(status)) {
-            // fprintf(stderr, "open unit failed: %s\n", u_errorName(status));
-            break;
-        }
-
-        UnitPreference *up = outVector.emplaceBack();
-        if (!up) {
-            status = U_MEMORY_ALLOCATION_ERROR;
-            return;
-        }
-        up->unit.appendInvariantChars(unitIdent, len, status);
-        if (U_FAILURE(status)) {
-            // fprintf(stderr, "failed appending unitIdent: %s\n", u_errorName(status));
-            status = U_ZERO_ERROR;
-            break;
-        }
-        const UChar *geq = ures_getStringByKey(prefBundle, "geq", &len, &status);
-        if (U_SUCCESS(status)) {
-            CharString cGeq;
-            cGeq.appendInvariantChars(geq, len, status);
-            DecimalQuantity dq;
-            dq.setToDecNumber(StringPiece(cGeq.data()), status);
-            // fprintf(stderr, "status: %s, geq: %s, dq.toDouble(): %f\n", u_errorName(status), cGeq.data(),
-            //         dq.toDouble());
-            up->geq = dq.toDouble();
-        } else if (status == U_MISSING_RESOURCE_ERROR) {
-            status = U_ZERO_ERROR;
-        }
-        if (U_FAILURE(status)) {
-            // fprintf(stderr, "failed appending geq: %s\n", u_errorName(status));
-            break;
-        }
-        const UChar *skel = ures_getStringByKey(prefBundle, "skeleton", &len, &status);
-        if (U_SUCCESS(status)) {
-            up->skeleton.appendInvariantChars(skel, len, status);
-        } else if (status == U_MISSING_RESOURCE_ERROR) {
-            status = U_ZERO_ERROR;
-        }
-    }
-    ures_close(prefBundle);
-}
-
-} // namespace
-
-/**
- * Fetches required data FIXME.
- *
- * @param inputUnit the unit for which input is expected. (NOTE/WIP: If this is
- * known to be a base unit already, we could strip some logic here.)
- */
-void getUnitsData(const char *outputRegion, const char *usage, const MeasureUnit &inputUnit,
-                  CharString &category, MeasureUnit &baseUnit,
-                  MaybeStackVector<ConversionRateInfo> &conversionInfo,
-                  MaybeStackVector<UnitPreference> &unitPreferences, UErrorCode &status) {
-    // One can also use a StackUResourceBundle as a fill-in.
-    LocalUResourceBundlePointer unitsBundle(ures_openDirect(NULL, "units", &status));
-    if (U_FAILURE(status)) {
-        // fprintf(stderr, "%s: ures_openDirect %s\n", u_errorName(status), "units");
-        return;
-    }
-
-    MeasureUnit inputBase = inputUnit.withSIPrefix(UMEASURE_SI_PREFIX_ONE, status);
-    if (uprv_strcmp(inputBase.getIdentifier(), "gram") == 0) { inputBase = MeasureUnit::getKilogram(); }
-    // if (U_FAILURE(status)) fprintf(stderr, "failed getting inputBase: %s\n", u_errorName(status));
-
-    StackUResourceBundle stackBundle;
-    // CharString has initial capacity 40. Key appending only gets slow when we
-    // go beyond. TODO(hugovdm): look at how often this might happen though?
-    // Each append could be a re-allocation.
-    CharString key;
-    // key.append("convertUnits/", status);
-    key.append(inputBase.getIdentifier(), status);
-    ConvertUnitsSink convertSink(conversionInfo);
-    ures_getByKey(unitsBundle.getAlias(), "convertUnits", stackBundle.getAlias(), &status);
-    ures_getAllItemsWithFallback(stackBundle.getAlias(), key.data(), convertSink, status);
-    const CharString &baseIdentifier = conversionInfo[0]->target;
-    baseUnit = MeasureUnit::forIdentifier(baseIdentifier.data(), status);
-
-    // key.clear();
-    // key.append("unitQuantities/", status);
-    // key.append(baseIdentifier, status);
-    // ures_findSubResource(unitsBundle.getAlias(), key.data(), fillIn, &status);
-    // Now we still need to convert to string.
-    LocalUResourceBundlePointer unitQuantities(
-        ures_getByKey(unitsBundle.getAlias(), "unitQuantities", NULL, &status));
-    int32_t categoryLength;
-    const UChar *uCategory =
-        ures_getStringByKey(unitQuantities.getAlias(), baseIdentifier.data(), &categoryLength, &status);
-    category.appendInvariantChars(uCategory, categoryLength, status);
-
-    // We load the region-specific unit preferences into stackBundle, reusing it
-    // for fill-in every step of the way:
-    ures_getByKey(unitsBundle.getAlias(), "unitPreferenceData", stackBundle.getAlias(), &status);
-    ures_getByKey(stackBundle.getAlias(), category.data(), stackBundle.getAlias(), &status);
-    if (U_FAILURE(status)) { return; }
-    ures_getByKey(stackBundle.getAlias(), usage, stackBundle.getAlias(), &status);
-    if (status == U_MISSING_RESOURCE_ERROR) {
-        // Requested usage does not exist, use "default".
-        status = U_ZERO_ERROR;
-        ures_getByKey(stackBundle.getAlias(), "default", stackBundle.getAlias(), &status);
-    }
-    // if (U_FAILURE(status)) fprintf(stderr, "failed getting usage %s: %s\n", usage, u_errorName(status));
-    ures_getByKey(stackBundle.getAlias(), outputRegion, stackBundle.getAlias(), &status);
-    if (status == U_MISSING_RESOURCE_ERROR) {
-        // Requested region does not exist, use "001".
-        status = U_ZERO_ERROR;
-        ures_getByKey(stackBundle.getAlias(), "001", stackBundle.getAlias(), &status);
-    }
-    // if (U_FAILURE(status)) fprintf(stderr, "failed getting region %s: %s\n", outputRegion, u_errorName(status));
-    putUnitPref(stackBundle.getAlias(), unitPreferences, status);
-    // if (U_FAILURE(status)) fprintf(stderr, "putUnitPref failed: %s\n", u_errorName(status));
-
-    // An alterantive for the above "We load ..." block, I don't think this is neater:
-    // key.clear();
-    // key.append("unitPreferenceData/", status);
-    // key.append(category, status).append("/", status);
-    // key.append(usage, status).append("/", status); // FIXME: fall back to "default"
-    // key.append(outputRegion, status); // FIXME: fall back to "001"
-    // UnitPreferencesSink prefsSink(unitPreferences);
-    // ures_getAllItemsWithFallback(unitsBundle.getAlias(), key.data(), prefsSink, status);
-}
diff --git a/icu4c/source/test/intltest/wip_units_resource_loader.h b/icu4c/source/test/intltest/wip_units_resource_loader.h
deleted file mode 100644 (file)
index 36f923c..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef WIP_UNITS_RESOURCE_LOADER_H
-#define WIP_UNITS_RESOURCE_LOADER_H
-
-#include "charstr.h" // CharString
-#include "unicode/measunit.h" // MeasureUnit
-
-using icu::CharString;
-using icu::MaybeStackVector;
-using icu::MeasureUnit;
-
-struct ConversionRateInfo {
-    CharString source;
-    CharString target;
-    CharString factor;
-    CharString offset;
-
-    const UChar *factorUChar;
-    const UChar *offsetUChar;
-    // WIP: This is a UChar* so that it can point at the resource. We could
-    // convert it to a CharString and own it ourselves, or if we can trust
-    // another owner's lifetime management we can make it a char*.
-    const UChar *targetUChar;
-
-    bool reciprocal = false;
-};
-
-struct UnitPreference {
-    UnitPreference() : geq(0) {}
-    CharString unit;
-    double geq;
-    CharString skeleton;
-};
-
-void getUnitsData(const char *outputRegion, const char *usage, const MeasureUnit &inputUnit,
-                  CharString &category, MeasureUnit &baseUnit,
-                  MaybeStackVector<ConversionRateInfo> &conversionInfo,
-                  MaybeStackVector<UnitPreference> &unitPreferences, UErrorCode &status);
-
-#endif // WIP_UNITS_RESOURCE_LOADER_H