ResourceFilter.cpp revision 788fa41482b9d398591b7db8b0b01839029611ad
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 == "zz_ZZ") {
28            mContainsPseudo = true;
29        }
30        int axis;
31        AxisValue value;
32        if (!AaptGroupEntry::parseFilterNamePart(part, &axis, &value)) {
33            fprintf(stderr, "Invalid configuration: %s\n", arg);
34            fprintf(stderr, "                       ");
35            for (int i=0; i<p-arg; i++) {
36                fprintf(stderr, " ");
37            }
38            for (int i=0; i<q-p; i++) {
39                fprintf(stderr, "^");
40            }
41            fprintf(stderr, "\n");
42            return 1;
43        }
44
45        ssize_t index = mData.indexOfKey(axis);
46        if (index < 0) {
47            mData.add(axis, SortedVector<AxisValue>());
48        }
49        SortedVector<AxisValue>& sv = mData.editValueFor(axis);
50        sv.add(value);
51
52        // If it's a locale with a region, script or variant, we should also match an
53        // unmodified locale of the same language
54        if (axis == AXIS_LOCALE) {
55            if (value.localeValue.region[0] || value.localeValue.script[0] ||
56                value.localeValue.variant[0]) {
57                AxisValue copy;
58                memcpy(copy.localeValue.language, value.localeValue.language,
59                       sizeof(value.localeValue.language));
60                sv.add(copy);
61            }
62        }
63        p = q;
64        if (!*p) break;
65        p++;
66    }
67
68    return NO_ERROR;
69}
70
71bool
72ResourceFilter::isEmpty() const
73{
74    return mData.size() == 0;
75}
76
77bool
78ResourceFilter::match(int axis, const AxisValue& value) const
79{
80    if (value.intValue == 0 && (value.localeValue.language[0] == 0)) {
81        // they didn't specify anything so take everything
82        return true;
83    }
84    ssize_t index = mData.indexOfKey(axis);
85    if (index < 0) {
86        // we didn't request anything on this axis so take everything
87        return true;
88    }
89    const SortedVector<AxisValue>& sv = mData.valueAt(index);
90    return sv.indexOf(value) >= 0;
91}
92
93bool
94ResourceFilter::match(int axis, const ResTable_config& config) const
95{
96    return match(axis, AaptGroupEntry::getConfigValueForAxis(config, axis));
97}
98
99bool
100ResourceFilter::match(const ResTable_config& config) const
101{
102    for (int i=AXIS_START; i<=AXIS_END; i++) {
103        if (!match(i, AaptGroupEntry::getConfigValueForAxis(config, i))) {
104            return false;
105        }
106    }
107    return true;
108}
109
110const SortedVector<AxisValue>* ResourceFilter::configsForAxis(int axis) const
111{
112    ssize_t index = mData.indexOfKey(axis);
113    if (index < 0) {
114        return NULL;
115    }
116    return &mData.valueAt(index);
117}
118