ResourceFilter.cpp revision a2ef5c0d4fb863c0382e77ae00f986a019b11cbe
1//
2// Copyright 2011 The Android Open Source Project
3//
4// Build resource files from raw assets.
5//
6
7#include "ResourceFilter.h"
8
9status_t
10ResourceFilter::parse(const char* arg)
11{
12    if (arg == NULL) {
13        return 0;
14    }
15
16    const char* p = arg;
17    const char* q;
18
19    while (true) {
20        q = strchr(p, ',');
21        if (q == NULL) {
22            q = p + strlen(p);
23        }
24
25        String8 part(p, q-p);
26
27        if (part == "en_XA") {
28            mContainsPseudoAccented = true;
29        } else if (part == "ar_XB") {
30            mContainsPseudoBidi = true;
31        }
32        int axis;
33        AxisValue value;
34        if (!AaptGroupEntry::parseFilterNamePart(part, &axis, &value)) {
35            fprintf(stderr, "Invalid configuration: %s\n", arg);
36            fprintf(stderr, "                       ");
37            for (int i=0; i<p-arg; i++) {
38                fprintf(stderr, " ");
39            }
40            for (int i=0; i<q-p; i++) {
41                fprintf(stderr, "^");
42            }
43            fprintf(stderr, "\n");
44            return 1;
45        }
46
47        ssize_t index = mData.indexOfKey(axis);
48        if (index < 0) {
49            mData.add(axis, SortedVector<AxisValue>());
50        }
51        SortedVector<AxisValue>& sv = mData.editValueFor(axis);
52        sv.add(value);
53
54        // If it's a locale with a region, script or variant, we should also match an
55        // unmodified locale of the same language
56        if (axis == AXIS_LOCALE) {
57            if (value.localeValue.region[0] || value.localeValue.script[0] ||
58                value.localeValue.variant[0]) {
59                AxisValue copy;
60                memcpy(copy.localeValue.language, value.localeValue.language,
61                       sizeof(value.localeValue.language));
62                sv.add(copy);
63            }
64        }
65        p = q;
66        if (!*p) break;
67        p++;
68    }
69
70    return NO_ERROR;
71}
72
73bool
74ResourceFilter::isEmpty() const
75{
76    return mData.size() == 0;
77}
78
79bool
80ResourceFilter::match(int axis, const AxisValue& value) const
81{
82    if (value.intValue == 0 && (value.localeValue.language[0] == 0)) {
83        // they didn't specify anything so take everything
84        return true;
85    }
86    ssize_t index = mData.indexOfKey(axis);
87    if (index < 0) {
88        // we didn't request anything on this axis so take everything
89        return true;
90    }
91    const SortedVector<AxisValue>& sv = mData.valueAt(index);
92    return sv.indexOf(value) >= 0;
93}
94
95bool
96ResourceFilter::match(int axis, const ResTable_config& config) const
97{
98    return match(axis, AaptGroupEntry::getConfigValueForAxis(config, axis));
99}
100
101bool
102ResourceFilter::match(const ResTable_config& config) const
103{
104    for (int i=AXIS_START; i<=AXIS_END; i++) {
105        if (!match(i, AaptGroupEntry::getConfigValueForAxis(config, i))) {
106            return false;
107        }
108    }
109    return true;
110}
111
112const SortedVector<AxisValue>* ResourceFilter::configsForAxis(int axis) const
113{
114    ssize_t index = mData.indexOfKey(axis);
115    if (index < 0) {
116        return NULL;
117    }
118    return &mData.valueAt(index);
119}
120