/* * Copyright (C) 2018 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. */ #define DEBUG false #include "Log.h" #include "FieldValue.h" #include "HashableDimensionKey.h" namespace android { namespace os { namespace statsd { bool Field::matches(const Matcher& matcher) const { if (mTag != matcher.mMatcher.getTag()) { return false; } if ((mField & matcher.mMask) == matcher.mMatcher.getField()) { return true; } return false; }; void translateFieldMatcher(int tag, const FieldMatcher& matcher, int depth, int* pos, int* mask, std::vector* output) { if (depth > kMaxLogDepth) { ALOGE("depth > 2"); return; } pos[depth] = matcher.field(); mask[depth] = 0x7f; if (matcher.has_position()) { depth++; if (depth > 2) { return; } switch (matcher.position()) { case Position::ANY: pos[depth] = 0; mask[depth] = 0; break; case Position::FIRST: pos[depth] = 1; mask[depth] = 0x7f; break; case Position::LAST: pos[depth] = 0x80; mask[depth] = 0x80; break; case Position::POSITION_UNKNOWN: pos[depth] = 0; mask[depth] = 0; break; } } if (matcher.child_size() == 0) { output->push_back(Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth))); Matcher matcher = Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth)); } else { for (const auto& child : matcher.child()) { translateFieldMatcher(tag, child, depth + 1, pos, mask, output); } } } void translateFieldMatcher(const FieldMatcher& matcher, std::vector* output) { int pos[] = {1, 1, 1}; int mask[] = {0x7f, 0x7f, 0x7f}; int tag = matcher.field(); for (const auto& child : matcher.child()) { translateFieldMatcher(tag, child, 0, pos, mask, output); } } bool isAttributionUidField(const FieldValue& value) { int field = value.mField.getField() & 0xff007f; if (field == 0x10001 && value.mValue.getType() == INT) { return true; } return false; } bool isAttributionUidField(const Field& field, const Value& value) { int f = field.getField() & 0xff007f; if (f == 0x10001 && value.getType() == INT) { return true; } return false; } Value::Value(const Value& from) { type = from.getType(); switch (type) { case INT: int_value = from.int_value; break; case LONG: long_value = from.long_value; break; case FLOAT: float_value = from.float_value; break; case STRING: str_value = from.str_value; break; } } std::string Value::toString() const { switch (type) { case INT: return std::to_string(int_value) + "[I]"; case LONG: return std::to_string(long_value) + "[L]"; case FLOAT: return std::to_string(float_value) + "[F]"; case STRING: return str_value + "[S]"; } } bool Value::operator==(const Value& that) const { if (type != that.getType()) return false; switch (type) { case INT: return int_value == that.int_value; case LONG: return long_value == that.long_value; case FLOAT: return float_value == that.float_value; case STRING: return str_value == that.str_value; } } bool Value::operator!=(const Value& that) const { if (type != that.getType()) return true; switch (type) { case INT: return int_value != that.int_value; case LONG: return long_value != that.long_value; case FLOAT: return float_value != that.float_value; case STRING: return str_value != that.str_value; } } bool Value::operator<(const Value& that) const { if (type != that.getType()) return type < that.getType(); switch (type) { case INT: return int_value < that.int_value; case LONG: return long_value < that.long_value; case FLOAT: return float_value < that.float_value; case STRING: return str_value < that.str_value; default: return false; } } } // namespace statsd } // namespace os } // namespace android