| // 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 (int 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 StringView& 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<StringView>& library_name, |
| const StringView& 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 (StringView 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(StringView(full_name), source_element); |
| } |
| |
| raw::Ordinal GetGeneratedOrdinal(const std::vector<StringView>& library_name, |
| const StringView& 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<StringView>& library_name, |
| const StringView& 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<StringView>& library_name, |
| const StringView& 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 |