blob: 91b938bde3f626dbc95fe5a20bdd01cea888984e [file]
/*
* Copyright (C) 2026 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.
*/
#ifndef SRC_TRACE_PROCESSOR_UTIL_SQL_BUNDLE_H_
#define SRC_TRACE_PROCESSOR_UTIL_SQL_BUNDLE_H_
#include <array>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <string_view>
#include "perfetto/base/logging.h"
namespace perfetto::trace_processor {
// Iterates a packed (path, sql) bundle generated by
// tools/gen_amalgamated_sql.py and embedded as a `constexpr std::array<uint8_t,
// N>` via the perfetto_cpp_blob_header build primitive.
//
// Wire format (all integers little-endian, no padding):
// uint32_t count;
// for (count) {
// uint32_t path_size; // excluding the trailing NUL.
// char path[path_size];
// char nul; // 0x00.
// uint32_t sql_size;
// char sql[sql_size];
// }
class SqlBundle {
public:
struct FileToSql {
const char* path; // NUL-terminated, points into the blob.
std::string_view sql; // Points into the blob.
std::string_view sql_view() const { return sql; }
};
SqlBundle(const uint8_t* data, size_t size) : data_(data), size_(size) {
PERFETTO_CHECK(size_ >= sizeof(uint32_t));
}
template <size_t N>
explicit SqlBundle(const std::array<uint8_t, N>& blob)
: SqlBundle(blob.data(), blob.size()) {}
class Iterator {
public:
Iterator(const uint8_t* p, const uint8_t* end) : next_(p), end_(end) {
Advance();
}
bool operator!=(const Iterator& o) const { return cur_ != o.cur_; }
const FileToSql& operator*() const { return entry_; }
const FileToSql* operator->() const { return &entry_; }
Iterator& operator++() {
Advance();
return *this;
}
private:
void Advance() {
cur_ = next_;
if (cur_ >= end_)
return;
uint32_t path_size;
std::memcpy(&path_size, next_, sizeof(path_size));
next_ += sizeof(path_size);
entry_.path = reinterpret_cast<const char*>(next_);
next_ += path_size + 1; // +1 for the NUL terminator.
uint32_t sql_size;
std::memcpy(&sql_size, next_, sizeof(sql_size));
next_ += sizeof(sql_size);
entry_.sql =
std::string_view(reinterpret_cast<const char*>(next_), sql_size);
next_ += sql_size;
}
const uint8_t* cur_ = nullptr;
const uint8_t* next_;
const uint8_t* end_;
FileToSql entry_{};
};
Iterator begin() const {
return Iterator(data_ + sizeof(uint32_t), data_ + size_);
}
Iterator end() const { return Iterator(data_ + size_, data_ + size_); }
private:
const uint8_t* data_;
size_t size_;
};
} // namespace perfetto::trace_processor
#endif // SRC_TRACE_PROCESSOR_UTIL_SQL_BUNDLE_H_