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