1/*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#ifndef FTRACE_PARSE_HELPERS_H
16#define FTRACE_PARSE_HELPERS_H
17#include <string>
18#include <vector>
19#include "ftrace_common_type.h"
20
21FTRACE_NS_BEGIN
22using VoidPtr = std::unique_ptr<void>::pointer;
23
24class FtraceFieldParser {
25public:
26    template <typename T> static T ParseIntField(const FieldFormat& format, uint8_t data[], size_t size)
27    {
28        static_assert(std::is_integral<T>::value, "Integral type T required.");
29        T retval = {};
30        auto end = data + size;
31        auto start = data + format.offset;
32        ReadData(start, end, &retval, format.size);
33        return retval;
34    }
35
36    template <typename T>
37    static std::vector<T> ParseVectorIntField(const std::vector<FieldFormat>& fields,
38                                              size_t id, uint8_t data[], size_t size)
39    {
40        static_assert(std::is_integral<T>::value, "Integral type T required.");
41        if (fields.size() <= id) {
42            return {};
43        }
44
45        FieldFormat format = fields[id];
46        std::vector<T> retvalVec = {};
47        size_t retvalSize = sizeof(unsigned long);
48        size_t count = format.size / retvalSize;
49        for (size_t i = 0; i < count; i++) {
50            auto start = data + format.offset + i * retvalSize;
51            auto end = start + retvalSize;
52            T retval = {};
53            ReadData(start, end, &retval, retvalSize);
54            retvalVec.push_back(retval);
55        }
56        return retvalVec;
57    }
58
59    template <typename T>
60    static T ParseIntField(const std::vector<FieldFormat>& fields, size_t id, uint8_t data[], size_t size)
61    {
62        static_assert(std::is_integral<T>::value, "Integral type T required.");
63        if (fields.size() > id) {
64            return ParseIntField<T>(fields[id], data, size);
65        }
66        return {};
67    }
68
69    static std::string ParseStrField(const FieldFormat& format, uint8_t data[], size_t size);
70
71    static std::string ParseStrField(const std::vector<FieldFormat>& fields, size_t id, uint8_t data[], size_t size)
72    {
73        if (fields.size() > id) {
74            return ParseStrField(fields[id], data, size);
75        }
76        return "";
77    }
78
79private:
80    static bool ReadData(const uint8_t start[], const uint8_t end[], VoidPtr out, size_t size);
81};
82FTRACE_NS_END
83#endif
84