<commit_before>#ifndef BLUETOE_SERVICE_HPP
#define BLUETOE_SERVICE_HPP

#include <bluetoe/attribute.hpp>
#include <bluetoe/codes.hpp>
#include <bluetoe/options.hpp>

#include <cstddef>
#include <cassert>
#include <algorithm>

namespace bluetoe {

    template < const char* const >
    class service_name {};

    namespace details {
        template < std::uint32_t A, std::uint16_t B, std::uint16_t C, std::uint16_t D, std::uint64_t E >
        struct check_service_uuid_parameters
        {
            static_assert( E < 0x1000000000000l, "service_uuid: last group of bytes can not be larger than 6 bytes." );
            typedef void type;
        };

        struct service_uuid_meta_type {};
        struct service_meta_type {};

        inline std::uint8_t* write_big( std::uint16_t v, std::uint8_t* p, std::uint8_t* end )
        {
            if ( p != end )
            {
                *p = v >> 8;
                ++p;
            }

            if ( p != end )
            {
                *p = v & 0xff;
                ++p;
            }

            return p;
        }

        inline std::uint8_t* write_big( std::uint32_t v, std::uint8_t* p, std::uint8_t* end )
        {
            return write_big( static_cast< std::uint16_t >( v & 0xffff ), write_big( static_cast< std::uint16_t >( v >> 16 ), p, end ), end );
        }

    }

    /**
     * @brief a 128-Bit UUID used to identify a service.
     *
     * The class takes 5 parameters to store the UUID in the usual form like this:
     * bluetoe::service_uuid< 0xF0426E52, 0x4450, 0x4F3B, 0xB058, 0x5BAB1191D92A >
     */
    template <
        std::uint32_t A,
        std::uint16_t B,
        std::uint16_t C,
        std::uint16_t D,
        std::uint64_t E,
        typename = typename details::check_service_uuid_parameters< A, B, C, D, E >::type >
    class service_uuid
    {
    public:
        static details::attribute_access_result attribute_access( details::attribute_access_arguments& );

        typedef details::service_uuid_meta_type meta_type;
    };

    /**
     * @brief a service with zero or more characteristics
     */
    template < typename ... Options >
    class service
    {
    public:
        // a service is a list of attributes
        static constexpr std::size_t number_of_attributes = 1;

        static details::attribute attribute_at( std::size_t );

        typedef details::service_meta_type meta_type;
    };

    template <
        std::uint32_t A,
        std::uint16_t B,
        std::uint16_t C,
        std::uint16_t D,
        std::uint64_t E,
        typename F >
    // service_uuid implementation
    details::attribute_access_result service_uuid< A, B, C, D, E, F >::attribute_access( details::attribute_access_arguments& args )
    {
        if ( args.type == details::attribute_access_type::read )
        {
            std::uint8_t* const end = args.buffer + args.buffer_size;
            std::uint8_t*       ptr = args.buffer;
            ptr = details::write_big( A, ptr, end );
            ptr = details::write_big( B, ptr, end );
            ptr = details::write_big( C, ptr, end );
            ptr = details::write_big( D, ptr, end );
            ptr = details::write_big( static_cast< std::uint32_t >( E >> 16 ), ptr, end );
            ptr = details::write_big( static_cast< std::uint16_t >( E & 0xffff ), ptr, end );

            args.buffer_size = std::min< std::size_t >( 16, args.buffer_size );

            return args.buffer_size == 16
                ? details::attribute_access_result::success
                : details::attribute_access_result::read_truncated;
        }

        return details::attribute_access_result::write_not_permitted;
    }

    // service implementation
    template < typename ... Options >
    details::attribute service< Options... >::attribute_at( std::size_t index )
    {
        assert( index == 0 );
        return details::attribute{ bits( gatt_uuids::primary_service ), &details::find_by_meta_type< details::service_uuid_meta_type, Options... >::type::attribute_access };<commit_msg>more resonable uuid access function<commit_after>#ifndef BLUETOE_SERVICE_HPP
#define BLUETOE_SERVICE_HPP

#include <bluetoe/attribute.hpp>
#include <bluetoe/codes.hpp>
#include <bluetoe/options.hpp>

#include <cstddef>
#include <cassert>
#include <algorithm>

namespace bluetoe {

    template < const char* const >
    class service_name {};

    namespace details {
        template < std::uint32_t A, std::uint16_t B, std::uint16_t C, std::uint16_t D, std::uint64_t E >
        struct check_service_uuid_parameters
        {
            static_assert( E < 0x1000000000000l, "service_uuid: last group of bytes can not be larger than 6 bytes." );
            typedef void type;
        };

        struct service_uuid_meta_type {};
        struct service_meta_type {};
    }

    /**
     * @brief a 128-Bit UUID used to identify a service.
     *
     * The class takes 5 parameters to store the UUID in the usual form like this:
     * bluetoe::service_uuid< 0xF0426E52, 0x4450, 0x4F3B, 0xB058, 0x5BAB1191D92A >
     */
    template <
        std::uint32_t A,
        std::uint16_t B,
        std::uint16_t C,
        std::uint16_t D,
        std::uint64_t E,
        typename = typename details::check_service_uuid_parameters< A, B, C, D, E >::type >
    class service_uuid
    {
    public:
        static details::attribute_access_result attribute_access( details::attribute_access_arguments& );

        typedef details::service_uuid_meta_type meta_type;
    };

    /**
     * @brief a service with zero or more characteristics
     */
    template < typename ... Options >
    class service
    {
    public:
        // a service is a list of attributes
        static constexpr std::size_t number_of_attributes = 1;

        static details::attribute attribute_at( std::size_t );

        typedef details::service_meta_type meta_type;
    };

    template <
        std::uint32_t A,
        std::uint16_t B,
        std::uint16_t C,
        std::uint16_t D,
        std::uint64_t E,
        typename F >
    // service_uuid implementation
    details::attribute_access_result service_uuid< A, B, C, D, E, F >::attribute_access( details::attribute_access_arguments& args )
    {
        static constexpr uint8_t uuid[ 16 ] = {
            ( A >> 24 ) & 0xff,
            ( A >> 16 ) & 0xff,
            ( A >> 8  ) & 0xff,
            ( A >> 0  ) & 0xff,
            ( B >> 8  ) & 0xff,
            ( B >> 0  ) & 0xff,
            ( C >> 8  ) & 0xff,
            ( C >> 0  ) & 0xff,
            ( D >> 8  ) & 0xff,
            ( D >> 0  ) & 0xff,
            ( E >> 40 ) & 0xff,
            ( E >> 32 ) & 0xff,
            ( E >> 24 ) & 0xff,
            ( E >> 16 ) & 0xff,
            ( E >> 8  ) & 0xff,
            ( E >> 0  ) & 0xff
        };

        if ( args.type == details::attribute_access_type::read )
        {
            args.buffer_size = std::min< std::size_t >( 16, args.buffer_size );

            std::copy( std::begin( uuid ), std::begin( uuid ) + args.buffer_size, args.buffer );

            return args.buffer_size == 16
                ? details::attribute_access_result::success
                : details::attribute_access_result::read_truncated;
        }

        return details::attribute_access_result::write_not_permitted;
    }

    // service implementation
    template < typename ... Options >
    details::attribute service< Options... >::attribute_at( std::size_t index )
    {
        assert( index == 0 );
        return details::attribute{ bits( gatt_uuids::primary_service ), &details::find_by_meta_type< details::service_uuid_meta_type, Options... >::type::attribute_access };
{'fraction_non_alphanumeric': 0.1146049896049896, 'fraction_numerical': 0.030275467775467777, 'mean_word_length': 2.2030794839783603, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1158693', 'n_tokens_mistral': 2591, 'n_tokens_neox': 2359, 'n_words': 590}