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        uint32_t value;
32        if (AaptGroupEntry::parseNamePart(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<uint32_t>());
48        }
49        SortedVector<uint32_t>& sv = mData.editValueFor(axis);
50        sv.add(value);
51        // if it's a locale with a region, also match an unmodified locale of the
52        // same language
53        if (axis == AXIS_LANGUAGE) {
54            if (value & 0xffff0000) {
55                sv.add(value & 0x0000ffff);
56            }
57        }
58        p = q;
59        if (!*p) break;
60        p++;
61    }
62
63    return NO_ERROR;
64}
65
66bool
67ResourceFilter::isEmpty() const
68{
69    return mData.size() == 0;
70}
71
72bool
73ResourceFilter::match(int axis, uint32_t value) const
74{
75    if (value == 0) {
76        // they didn't specify anything so take everything
77        return true;
78    }
79    ssize_t index = mData.indexOfKey(axis);
80    if (index < 0) {
81        // we didn't request anything on this axis so take everything
82        return true;
83    }
84    const SortedVector<uint32_t>& sv = mData.valueAt(index);
85    return sv.indexOf(value) >= 0;
86}
87
88bool
89ResourceFilter::match(int axis, const ResTable_config& config) const
90{
91    return match(axis, AaptGroupEntry::getConfigValueForAxis(config, axis));
92}
93
94bool
95ResourceFilter::match(const ResTable_config& config) const
96{
97    for (int i=AXIS_START; i<=AXIS_END; i++) {
98        if (!match(i, AaptGroupEntry::getConfigValueForAxis(config, i))) {
99            return false;
100        }
101    }
102    return true;
103}
104
105const SortedVector<uint32_t>* ResourceFilter::configsForAxis(int axis) const
106{
107    ssize_t index = mData.indexOfKey(axis);
108    if (index < 0) {
109        return NULL;
110    }
111    return &mData.valueAt(index);
112}
113