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