123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- /*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include "Rule.h"
- #include <utils/String8.h>
- using namespace android;
- namespace split {
- inline static void indentStr(String8& str, int indent) {
- while (indent > 0) {
- str.append(" ");
- indent--;
- }
- }
- Rule::Rule(const Rule& rhs)
- : RefBase()
- , op(rhs.op)
- , key(rhs.key)
- , negate(rhs.negate)
- , stringArgs(rhs.stringArgs)
- , longArgs(rhs.longArgs)
- , subrules(rhs.subrules) {
- }
- String8 Rule::toJson(int indent) const {
- String8 str;
- indentStr(str, indent);
- str.append("{\n");
- indent++;
- indentStr(str, indent);
- str.append("\"op\": \"");
- switch (op) {
- case ALWAYS_TRUE:
- str.append("ALWAYS_TRUE");
- break;
- case GREATER_THAN:
- str.append("GREATER_THAN");
- break;
- case LESS_THAN:
- str.append("LESS_THAN");
- break;
- case EQUALS:
- str.append("EQUALS");
- break;
- case AND_SUBRULES:
- str.append("AND_SUBRULES");
- break;
- case OR_SUBRULES:
- str.append("OR_SUBRULES");
- break;
- case CONTAINS_ANY:
- str.append("CONTAINS_ANY");
- break;
- default:
- str.appendFormat("%d", op);
- break;
- }
- str.append("\"");
- if (negate) {
- str.append(",\n");
- indentStr(str, indent);
- str.append("\"negate\": true");
- }
- bool includeKey = true;
- switch (op) {
- case AND_SUBRULES:
- case OR_SUBRULES:
- includeKey = false;
- break;
- default:
- break;
- }
- if (includeKey) {
- str.append(",\n");
- indentStr(str, indent);
- str.append("\"property\": \"");
- switch (key) {
- case NONE:
- str.append("NONE");
- break;
- case SDK_VERSION:
- str.append("SDK_VERSION");
- break;
- case SCREEN_DENSITY:
- str.append("SCREEN_DENSITY");
- break;
- case NATIVE_PLATFORM:
- str.append("NATIVE_PLATFORM");
- break;
- case LANGUAGE:
- str.append("LANGUAGE");
- break;
- default:
- str.appendFormat("%d", key);
- break;
- }
- str.append("\"");
- }
- if (op == AND_SUBRULES || op == OR_SUBRULES) {
- str.append(",\n");
- indentStr(str, indent);
- str.append("\"subrules\": [\n");
- const size_t subruleCount = subrules.size();
- for (size_t i = 0; i < subruleCount; i++) {
- str.append(subrules[i]->toJson(indent + 1));
- if (i != subruleCount - 1) {
- str.append(",");
- }
- str.append("\n");
- }
- indentStr(str, indent);
- str.append("]");
- } else {
- switch (key) {
- case SDK_VERSION:
- case SCREEN_DENSITY: {
- str.append(",\n");
- indentStr(str, indent);
- str.append("\"args\": [");
- const size_t argCount = longArgs.size();
- for (size_t i = 0; i < argCount; i++) {
- if (i != 0) {
- str.append(", ");
- }
- str.appendFormat("%d", longArgs[i]);
- }
- str.append("]");
- break;
- }
- case LANGUAGE:
- case NATIVE_PLATFORM: {
- str.append(",\n");
- indentStr(str, indent);
- str.append("\"args\": [");
- const size_t argCount = stringArgs.size();
- for (size_t i = 0; i < argCount; i++) {
- if (i != 0) {
- str.append(", ");
- }
- str.append(stringArgs[i]);
- }
- str.append("]");
- break;
- }
- default:
- break;
- }
- }
- str.append("\n");
- indent--;
- indentStr(str, indent);
- str.append("}");
- return str;
- }
- sp<Rule> Rule::simplify(sp<Rule> rule) {
- if (rule->op != AND_SUBRULES && rule->op != OR_SUBRULES) {
- return rule;
- }
- Vector<sp<Rule> > newSubrules;
- newSubrules.setCapacity(rule->subrules.size());
- const size_t subruleCount = rule->subrules.size();
- for (size_t i = 0; i < subruleCount; i++) {
- sp<Rule> simplifiedRule = simplify(rule->subrules.editItemAt(i));
- if (simplifiedRule != NULL) {
- if (simplifiedRule->op == rule->op) {
- newSubrules.appendVector(simplifiedRule->subrules);
- } else {
- newSubrules.add(simplifiedRule);
- }
- }
- }
- const size_t newSubruleCount = newSubrules.size();
- if (newSubruleCount == 0) {
- return NULL;
- } else if (subruleCount == 1) {
- return newSubrules.editTop();
- }
- rule->subrules = newSubrules;
- return rule;
- }
- } // namespace split
|