FieldValue.cpp revision 13fb7e4eeaf7aee408821afe7ee55a5167e49e59
1/* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define DEBUG false 18#include "Log.h" 19#include "FieldValue.h" 20#include "HashableDimensionKey.h" 21 22namespace android { 23namespace os { 24namespace statsd { 25 26int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth) { 27 int32_t field = 0; 28 for (int32_t i = 0; i <= depth; i++) { 29 int32_t shiftBits = 8 * (kMaxLogDepth - i); 30 field |= (pos[i] << shiftBits); 31 } 32 33 if (includeDepth) { 34 field |= (depth << 24); 35 } 36 return field; 37} 38 39int32_t encodeMatcherMask(int32_t mask[], int32_t depth) { 40 return getEncodedField(mask, depth, false) | 0xff000000; 41} 42 43bool Field::matches(const Matcher& matcher) const { 44 if (mTag != matcher.mMatcher.getTag()) { 45 return false; 46 } 47 if ((mField & matcher.mMask) == matcher.mMatcher.getField()) { 48 return true; 49 } 50 51 return false; 52} 53 54void translateFieldMatcher(int tag, const FieldMatcher& matcher, int depth, int* pos, int* mask, 55 std::vector<Matcher>* output) { 56 if (depth > kMaxLogDepth) { 57 ALOGE("depth > 2"); 58 return; 59 } 60 61 pos[depth] = matcher.field(); 62 mask[depth] = 0x7f; 63 64 if (matcher.has_position()) { 65 depth++; 66 if (depth > 2) { 67 return; 68 } 69 switch (matcher.position()) { 70 case Position::ANY: 71 pos[depth] = 0; 72 mask[depth] = 0; 73 break; 74 case Position::FIRST: 75 pos[depth] = 1; 76 mask[depth] = 0x7f; 77 break; 78 case Position::LAST: 79 pos[depth] = 0x80; 80 mask[depth] = 0x80; 81 break; 82 case Position::POSITION_UNKNOWN: 83 pos[depth] = 0; 84 mask[depth] = 0; 85 break; 86 } 87 } 88 89 if (matcher.child_size() == 0) { 90 output->push_back(Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth))); 91 } else { 92 for (const auto& child : matcher.child()) { 93 translateFieldMatcher(tag, child, depth + 1, pos, mask, output); 94 } 95 } 96} 97 98void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output) { 99 int pos[] = {1, 1, 1}; 100 int mask[] = {0x7f, 0x7f, 0x7f}; 101 int tag = matcher.field(); 102 for (const auto& child : matcher.child()) { 103 translateFieldMatcher(tag, child, 0, pos, mask, output); 104 } 105} 106 107bool isAttributionUidField(const FieldValue& value) { 108 int field = value.mField.getField() & 0xff007f; 109 if (field == 0x10001 && value.mValue.getType() == INT) { 110 return true; 111 } 112 return false; 113} 114 115bool isAttributionUidField(const Field& field, const Value& value) { 116 int f = field.getField() & 0xff007f; 117 if (f == 0x10001 && value.getType() == INT) { 118 return true; 119 } 120 return false; 121} 122 123Value::Value(const Value& from) { 124 type = from.getType(); 125 switch (type) { 126 case INT: 127 int_value = from.int_value; 128 break; 129 case LONG: 130 long_value = from.long_value; 131 break; 132 case FLOAT: 133 float_value = from.float_value; 134 break; 135 case STRING: 136 str_value = from.str_value; 137 break; 138 default: 139 break; 140 } 141} 142 143std::string Value::toString() const { 144 switch (type) { 145 case INT: 146 return std::to_string(int_value) + "[I]"; 147 case LONG: 148 return std::to_string(long_value) + "[L]"; 149 case FLOAT: 150 return std::to_string(float_value) + "[F]"; 151 case STRING: 152 return str_value + "[S]"; 153 default: 154 return "[UNKNOWN]"; 155 } 156} 157 158bool Value::operator==(const Value& that) const { 159 if (type != that.getType()) return false; 160 161 switch (type) { 162 case INT: 163 return int_value == that.int_value; 164 case LONG: 165 return long_value == that.long_value; 166 case FLOAT: 167 return float_value == that.float_value; 168 case STRING: 169 return str_value == that.str_value; 170 default: 171 return false; 172 } 173} 174 175bool Value::operator!=(const Value& that) const { 176 if (type != that.getType()) return true; 177 switch (type) { 178 case INT: 179 return int_value != that.int_value; 180 case LONG: 181 return long_value != that.long_value; 182 case FLOAT: 183 return float_value != that.float_value; 184 case STRING: 185 return str_value != that.str_value; 186 default: 187 return false; 188 } 189} 190 191bool Value::operator<(const Value& that) const { 192 if (type != that.getType()) return type < that.getType(); 193 194 switch (type) { 195 case INT: 196 return int_value < that.int_value; 197 case LONG: 198 return long_value < that.long_value; 199 case FLOAT: 200 return float_value < that.float_value; 201 case STRING: 202 return str_value < that.str_value; 203 default: 204 return false; 205 } 206} 207 208bool equalDimensions(const std::vector<Matcher>& dimension_a, 209 const std::vector<Matcher>& dimension_b) { 210 bool eq = dimension_a.size() == dimension_b.size(); 211 for (size_t i = 0; eq && i < dimension_a.size(); ++i) { 212 if (dimension_b[i] != dimension_a[i]) { 213 eq = false; 214 } 215 } 216 return eq; 217} 218 219bool HasPositionANY(const FieldMatcher& matcher) { 220 if (matcher.has_position() && matcher.position() == Position::ANY) { 221 return true; 222 } 223 for (const auto& child : matcher.child()) { 224 if (HasPositionANY(child)) { 225 return true; 226 } 227 } 228 return false; 229} 230 231} // namespace statsd 232} // namespace os 233} // namespace android