blob: 69def2ed3d694fd5ea5dc605db04e0b46124fdad [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,
SourceLocation 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());
}
raw::Ordinal GetGeneratedOrdinal(const std::string_view& full_name,
const raw::SourceElement& source_element) {
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
// int32 regardless of host byte order.
uint32_t ordinal = static_cast<uint32_t>(digest[0]) |
static_cast<uint32_t>(digest[1]) << 8 |
static_cast<uint32_t>(digest[2]) << 16 |
static_cast<uint32_t>(digest[3]) << 24;
ordinal &= 0x7fffffff;
return raw::Ordinal(source_element, ordinal);
}
raw::Ordinal GetGeneratedOrdinal(const std::vector<std::string_view>& library_name,
const std::string_view& container_name,
const raw::AttributeList* attributes,
SourceLocation name,
const raw::SourceElement& source_element) {
std::string method_name = GetSelector(attributes, name);
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());
}
full_name.append(".");
full_name.append(container_name.data(), container_name.size());
full_name.append("/");
full_name.append(method_name);
return GetGeneratedOrdinal(std::string_view(full_name), source_element);
}
raw::Ordinal GetGeneratedOrdinal(const std::vector<std::string_view>& library_name,
const std::string_view& interface_name,
const raw::InterfaceMethod& method) {
return GetGeneratedOrdinal(library_name, interface_name, method.attributes.get(), method.identifier->location(), method);
}
raw::Ordinal GetOrdinal(const std::vector<std::string_view>& library_name,
const std::string_view& interface_name,
const raw::InterfaceMethod& method) {
if (method.ordinal != nullptr)
return *method.ordinal;
return GetGeneratedOrdinal(library_name, interface_name, method);
}
raw::Ordinal GetOrdinal(const std::vector<std::string_view>& library_name,
const std::string_view& xunion_declaration_name,
const raw::XUnionMember& xunion_member) {
// Note that this ordinal hashing for xunion members uses the same ordinal
// hashing algorithm as for FIDL methods, which results in 31 bits, not 32.
return GetGeneratedOrdinal(library_name, xunion_declaration_name, xunion_member.attributes.get(), xunion_member.identifier->location(), xunion_member);
}
} // namespace ordinals
} // namespace fidl