blob: dc8adac18396f55b248b3b8a92b109728624bbdd [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "fidl/ordinals.h"
#include <optional>
#define BORINGSSL_NO_CXX
#include <openssl/sha.h>
namespace fidl {
namespace ordinals {
std::string GetSelector(const raw::AttributeList* attributes, SourceSpan name) {
if (attributes != nullptr) {
const size_t size = attributes->attributes.size();
for (size_t i = 0; i < size; i++) {
if (attributes->attributes[i].name == "Selector") {
return attributes->attributes[i].value;
}
}
}
return std::string(name.data().data(), name.data().size());
}
namespace {
uint64_t CalcOrdinal(const std::string_view& full_name) {
uint8_t digest[SHA256_DIGEST_LENGTH];
SHA256(reinterpret_cast<const uint8_t*>(full_name.data()), full_name.size(), digest);
// The following dance ensures that we treat the bytes as a little-endian
// int64 regardless of host byte order.
// clang-format off
uint64_t ordinal =
static_cast<uint64_t>(digest[0]) |
static_cast<uint64_t>(digest[1]) << 8 |
static_cast<uint64_t>(digest[2]) << 16 |
static_cast<uint64_t>(digest[3]) << 24 |
static_cast<uint64_t>(digest[4]) << 32 |
static_cast<uint64_t>(digest[5]) << 40 |
static_cast<uint64_t>(digest[6]) << 48 |
static_cast<uint64_t>(digest[7]) << 56;
// clang-format on
return ordinal & 0x7fffffffffffffff;
}
} // namespace
raw::Ordinal64 GetGeneratedOrdinal64(const std::vector<std::string_view>& library_name,
const std::string_view& protocol_name,
const std::string_view& selector_name,
const raw::SourceElement& source_element) {
if (selector_name.find("/") != selector_name.npos)
return raw::Ordinal64(source_element, CalcOrdinal(selector_name));
// TODO(pascallouis): Move this closer (code wise) to NameFlatName, ideally
// sharing code.
std::string full_name;
bool once = false;
for (std::string_view id : library_name) {
if (once) {
full_name.push_back('.');
} else {
once = true;
}
full_name.append(id.data(), id.size());
}
// TODO(pascallouis/yifeit): Remove this once fuchsia.io has been renamed to
// fuchsia.io1.
//
// In order to make room for the new fuchsia.io library (dubbed fuchsia.io2
// currently), we are piggybacking the rename of the currently named
// `fuchsia.io` library to `fuchsia.io1`. In short, from an ABI standpoint,
// both `fuchsia.io` and `fuchsia.io1` are the same.
if (full_name == "fuchsia.io") {
full_name = "fuchsia.io1";
}
full_name.append("/");
full_name.append(protocol_name.data(), protocol_name.size());
full_name.append(".");
full_name.append(selector_name);
return raw::Ordinal64(source_element, CalcOrdinal(full_name));
}
} // namespace ordinals
} // namespace fidl