|
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2022 - Raw Material Software Limited
-
- JUCE is an open source library subject to commercial or open-source
- licensing.
-
- By using JUCE, you agree to the terms of both the JUCE 7 End-User License
- Agreement and JUCE Privacy Policy.
-
- End User License Agreement: www.juce.com/juce-7-licence
- Privacy Policy: www.juce.com/juce-privacy-policy
-
- Or: You may also use this code under the terms of the GPL v3 (see
- www.gnu.org/licenses).
-
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
- DISCLAIMED.
-
- ==============================================================================
- */
-
- namespace juce::midi_ci
- {
-
- #define JUCE_SUBSCRIPTION_COMMANDS X(start) X(partial) X(full) X(notify) X(end)
-
- /**
- Kinds of command that may be sent as part of a subscription update.
-
- Check the Property Exchange specification to find the meaning of the
- different kinds.
-
- @tags{Audio}
- */
- enum class PropertySubscriptionCommand
- {
- #define X(str) str,
- JUCE_SUBSCRIPTION_COMMANDS
- #undef X
- };
-
- /**
- Functions to use with PropertySubscriptionCommand.
-
- @tags{Audio}
- */
- struct PropertySubscriptionCommandUtils
- {
- PropertySubscriptionCommandUtils() = delete;
-
- /** Converts a command to a human-readable string. */
- static const char* toString (PropertySubscriptionCommand x)
- {
- switch (x)
- {
- #define X(str) case PropertySubscriptionCommand::str: return #str;
- JUCE_SUBSCRIPTION_COMMANDS
- #undef X
- }
-
- return nullptr;
- }
-
- /** Converts a command string from a property exchange JSON header to
- an PropertySubscriptionCommand.
- */
- static std::optional<PropertySubscriptionCommand> toCommand (const char* str)
- {
- #define X(name) if (std::string_view (str) == std::string_view (#name)) return PropertySubscriptionCommand::name;
- JUCE_SUBSCRIPTION_COMMANDS
- #undef X
-
- return {};
- }
- };
-
- #undef JUCE_SUBSCRIPTION_COMMANDS
-
- /**
- A struct containing data members that correspond to common fields in a
- property subscription header.
-
- Check the Property Exchange specification to find the meaning of the
- different fields.
-
- @tags{Audio}
- */
- struct PropertySubscriptionHeader
- {
- String resource;
- String resId;
- Encoding mutualEncoding = Encoding::ascii;
- String mediaType = "application/json";
- PropertySubscriptionCommand command { -1 };
- String subscribeId;
- std::map<Identifier, var> extended;
-
- /** Converts a JSON object to a PropertyRequestHeader.
-
- Unspecified fields will use their default values.
- */
- static PropertySubscriptionHeader parseCondensed (const var&);
-
- /** Converts a PropertySubscriptionHeader to a JSON object suitable for use as
- a MIDI-CI message header after conversion to 7-bit ASCII.
- */
- var toVarCondensed() const;
- };
-
- /**
- Contains information about the pagination of a request.
-
- Check the Property Exchange specification to find the meaning of the
- different fields.
-
- @tags{Audio}
- */
- struct Pagination
- {
- int offset = 0;
- int limit = 1;
- };
-
- /**
- A struct containing data members that correspond to common fields in a
- property request header.
-
- Check the Property Exchange specification to find the meaning of the
- different fields.
-
- @tags{Audio}
- */
- struct PropertyRequestHeader
- {
- String resource;
- String resId;
- Encoding mutualEncoding = Encoding::ascii;
- String mediaType = "application/json";
- bool setPartial = false;
- std::optional<Pagination> pagination;
- std::map<Identifier, var> extended;
-
- /** Converts a JSON object to a PropertyRequestHeader.
-
- Unspecified fields will use their default values.
- */
- static PropertyRequestHeader parseCondensed (const var&);
-
- /** Converts a PropertyRequestHeader to a JSON object suitable for use as
- a MIDI-CI message header after conversion to 7-bit ASCII.
- */
- var toVarCondensed() const;
- };
-
- /**
- Bundles together a property request header and a data payload.
-
- @tags{Audio}
- */
- struct PropertyRequestData
- {
- PropertyRequestHeader header;
- Span<const std::byte> body;
- };
-
- /**
- A struct containing data members that correspond to common fields in a
- reply to a property exchange request.
-
- Check the Property Exchange specification to find the meaning of the
- different fields.
-
- For extended attributes that don't correspond to any of the defined data
- members, use the 'extended' map.
-
- @tags{Audio}
- */
- struct PropertyReplyHeader
- {
- int status = 200;
- String message;
- Encoding mutualEncoding = Encoding::ascii;
- int cacheTime = 0;
- String mediaType = "application/json";
- std::map<Identifier, var> extended;
-
- /** Converts a JSON object to a PropertyReplyHeader.
-
- Unspecified fields will use their default values.
- */
- static PropertyReplyHeader parseCondensed (const var&);
-
- /** Converts a PropertyReplyHeader to a JSON object suitable for use as
- a MIDI-CI message header after conversion to 7-bit ASCII.
- */
- var toVarCondensed() const;
- };
-
- /**
- Bundles together a property reply header and a data payload.
-
- @tags{Audio}
- */
- struct PropertyReplyData
- {
- PropertyReplyHeader header;
- std::vector<std::byte> body;
- };
-
- /**
- An interface with methods that can be overridden to customise how a Device
- implementing properties responds to property inquiries.
-
- @tags{Audio}
- */
- struct PropertyDelegate
- {
- PropertyDelegate() = default;
- virtual ~PropertyDelegate() = default;
- PropertyDelegate (const PropertyDelegate&) = default;
- PropertyDelegate (PropertyDelegate&&) = default;
- PropertyDelegate& operator= (const PropertyDelegate&) = default;
- PropertyDelegate& operator= (PropertyDelegate&&) = default;
-
- /** Returns the max number of simultaneous property exchange messages that can be processed. */
- virtual uint8_t getNumSimultaneousRequestsSupported() const { return 127; }
-
- /** Returns a header/body containing the requested data.
- To report an error, you can return a failure status code in the header and leave the body empty.
- */
- virtual PropertyReplyData propertyGetDataRequested (MUID, const PropertyRequestHeader&) = 0;
-
- /** Returns a header that describes the result of the set operation. */
- virtual PropertyReplyHeader propertySetDataRequested (MUID, const PropertyRequestData&) = 0;
-
- /** Returns true to allow the subscription, or false otherwise. */
- virtual bool subscriptionStartRequested (MUID, const PropertySubscriptionHeader&) = 0;
-
- /** Called with the corresponding subscription token after a subscription has started. */
- virtual void subscriptionDidStart (MUID, const String& subId, const PropertySubscriptionHeader&) = 0;
-
- /** Called when a device requests for an ongoing subscription to end. */
- virtual void subscriptionWillEnd (MUID, const Subscription& sub) = 0;
- };
-
- } // namespace juce::midi_ci
-
- #ifndef DOXYGEN
-
- namespace juce
- {
-
- template <>
- struct SerialisationTraits<midi_ci::PropertySubscriptionCommand>
- {
- static constexpr auto marshallingVersion = std::nullopt;
-
- template <typename Archive>
- void load (Archive& archive, midi_ci::PropertySubscriptionCommand& t)
- {
- String command;
- archive (command);
- t = midi_ci::PropertySubscriptionCommandUtils::toCommand (command.toRawUTF8()).value_or (midi_ci::PropertySubscriptionCommand{});
- }
-
- template <typename Archive>
- void save (Archive& archive, const midi_ci::PropertySubscriptionCommand& t)
- {
- archive (midi_ci::PropertySubscriptionCommandUtils::toString (t));
- }
- };
-
- } // namespace juce
-
- #endif // ifndef DOXYGEN
|