diff --git a/packages/video_player_videohole/CHANGELOG.md b/packages/video_player_videohole/CHANGELOG.md index 36f77e276..ae5200c0e 100644 --- a/packages/video_player_videohole/CHANGELOG.md +++ b/packages/video_player_videohole/CHANGELOG.md @@ -1,7 +1,10 @@ -## 0.5.11 +## 0.6.0 -* Replace ecore-wl2 code with tizen window manager plugin. * Resolve `strict_top_level_inference` lint. +* Migrate from Platform Channels to Dart FFI. +* Replace EventChannel with FFI port for event callbacks. +* Add JSON serialization for complex parameters. +* Add pending seekTo handling. ## 0.5.10 diff --git a/packages/video_player_videohole/README.md b/packages/video_player_videohole/README.md index 1ffc9f3ed..d0b628a9b 100644 --- a/packages/video_player_videohole/README.md +++ b/packages/video_player_videohole/README.md @@ -12,7 +12,7 @@ To use this package, add `video_player_videohole` as a dependency in your `pubsp ```yaml dependencies: - video_player_videohole: ^0.5.11 + video_player_videohole: ^0.6.0 ``` Then you can import `video_player_videohole` in your Dart code: diff --git a/packages/video_player_videohole/example/lib/main.dart b/packages/video_player_videohole/example/lib/main.dart index f430341fd..26de08ab7 100644 --- a/packages/video_player_videohole/example/lib/main.dart +++ b/packages/video_player_videohole/example/lib/main.dart @@ -70,7 +70,7 @@ class _HlsRomoteVideoState extends State<_HlsRomoteVideo> { void initState() { super.initState(); _controller = VideoPlayerController.network( - 'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8', + 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8', ); _controller.addListener(() { @@ -388,7 +388,7 @@ class _TrackTestState extends State<_TrackTest> { super.initState(); _controller = VideoPlayerController.network( - 'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8', + 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8', ); _controller.addListener(() { @@ -761,7 +761,7 @@ class _TestRemoteVideoState extends State<_TestRemoteVideo> { void initState() { super.initState(); _controller = VideoPlayerController.network( - 'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8', + 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8', ); _controller.addListener(() { diff --git a/packages/video_player_videohole/lib/src/ffi_messages.dart b/packages/video_player_videohole/lib/src/ffi_messages.dart new file mode 100644 index 000000000..ae30d7fce --- /dev/null +++ b/packages/video_player_videohole/lib/src/ffi_messages.dart @@ -0,0 +1,765 @@ +// Copyright 2026 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:convert' show jsonDecode, jsonEncode, utf8; +import 'dart:ffi' as ffi; +import 'dart:isolate' show RawReceivePort, ReceivePort; + +import 'package:ffi/ffi.dart' show calloc; +import 'package:flutter/services.dart'; + +/// Represents track information returned from the native player. +class TrackMessage { + /// Creates a [TrackMessage] with the given [playerId] and [tracks]. + TrackMessage({required this.playerId, required this.tracks}); + + /// The unique identifier of the player. + int playerId; + + /// The list of available tracks for the player. + List?> tracks; + + /// Serializes this message to a JSON string. + String toJson() { + final Map jsonMap = { + 'playerId': playerId, + 'tracks': tracks, + }; + return jsonEncode(jsonMap); + } + + /// Deserializes a JSON string into a [TrackMessage]. + static TrackMessage fromJson(String jsonString) { + final Map jsonMap = + jsonDecode(jsonString) as Map; + return TrackMessage( + playerId: jsonMap['playerId'] as int, + tracks: (jsonMap['tracks'] as List) + .map((e) => (e as Map).cast()) + .toList(), + ); + } +} + +/// Represents the parameters for creating a new video player instance. +class CreateMessage { + /// Creates a [CreateMessage] with optional parameters. + CreateMessage({ + this.asset, + this.uri, + this.packageName, + this.formatHint, + this.httpHeaders, + this.drmConfigs, + this.playerOptions, + }); + + /// The asset path for local video resources. + String? asset; + + /// The URI of the video to play. + String? uri; + + /// The package name for asset resolution. + String? packageName; + + /// The format hint for the video. + String? formatHint; + + /// HTTP headers for the video request. + Map? httpHeaders; + + /// DRM configuration for protected content. + Map? drmConfigs; + + /// Additional player options. + Map? playerOptions; + + /// Serializes this message to a JSON string. + String toJson() { + final Map jsonMap = {}; + if (asset != null && asset!.isNotEmpty) { + jsonMap['asset'] = asset; + } + if (uri != null && uri!.isNotEmpty) { + jsonMap['uri'] = uri; + } + if (packageName != null && packageName!.isNotEmpty) { + jsonMap['packageName'] = packageName; + } + if (formatHint != null && formatHint!.isNotEmpty) { + jsonMap['formatHint'] = formatHint; + } + if (httpHeaders != null && httpHeaders!.isNotEmpty) { + jsonMap['httpHeaders'] = httpHeaders; + } + if (drmConfigs != null && drmConfigs!.isNotEmpty) { + jsonMap['drmConfigs'] = drmConfigs; + } + if (playerOptions != null && playerOptions!.isNotEmpty) { + jsonMap['playerOptions'] = playerOptions; + } + return jsonEncode(jsonMap); + } + + /// Deserializes a JSON string into a [CreateMessage]. + static CreateMessage fromJson(String jsonString) { + final Map jsonMap = + jsonDecode(jsonString) as Map; + return CreateMessage( + asset: jsonMap['asset'] as String?, + uri: jsonMap['uri'] as String?, + packageName: jsonMap['packageName'] as String?, + formatHint: jsonMap['formatHint'] as String?, + httpHeaders: (jsonMap['httpHeaders'] as Map?)?.cast(), + drmConfigs: (jsonMap['drmConfigs'] as Map?)?.cast(), + playerOptions: + (jsonMap['playerOptions'] as Map?)?.cast(), + ); + } +} + +/// Represents the duration information of a video player. +class DurationMessage { + /// Creates a [DurationMessage] with the given [playerId] and optional [durationRange]. + DurationMessage({required this.playerId, this.durationRange}); + + /// The unique identifier of the player. + int playerId; + + /// The duration range [min, max] in milliseconds. + List? durationRange; + + /// Serializes this message to a JSON string. + String toJson() { + final Map jsonMap = { + 'playerId': playerId, + if (durationRange != null) 'durationRange': durationRange, + }; + return jsonEncode(jsonMap); + } + + /// Deserializes a JSON string into a [DurationMessage]. + static DurationMessage fromJson(String jsonString) { + final Map jsonMap = + jsonDecode(jsonString) as Map; + return DurationMessage( + playerId: jsonMap['playerId'] as int, + durationRange: (jsonMap['durationRange'] as List?) + ?.map((e) => (e as num).toInt()) + .toList(), + ); + } +} + +typedef _FFIInitializeNative = ffi.Int32 Function(); +typedef _FFIInitializeDart = int Function(); + +typedef _FFICreateNative = ffi.Int64 Function(ffi.Pointer); +typedef _FFICreateDart = int Function(ffi.Pointer); + +typedef _FFIPrepareNative = ffi.Int32 Function(ffi.Int64); +typedef _FFIPrepareDart = int Function(int); + +typedef _FFIDisposeNative = ffi.Int32 Function(ffi.Int64); +typedef _FFIDisposeDart = int Function(int); + +typedef _FFIPlayNative = ffi.Int32 Function(ffi.Int64); +typedef _FFIPlayDart = int Function(int); + +typedef _FFIPauseNative = ffi.Int32 Function(ffi.Int64); +typedef _FFIPauseDart = int Function(int); + +typedef _FFISeekToNative = ffi.Int32 Function(ffi.Int64, ffi.Int64); +typedef _FFISeekToDart = int Function(int, int); + +typedef _FFIGetPositionNative = ffi.Int64 Function(ffi.Int64); +typedef _FFIGetPositionDart = int Function(int); + +typedef _FFIGetDurationNative = ffi.Pointer Function(ffi.Int64); +typedef _FFIGetDurationDart = ffi.Pointer Function(int); + +typedef _FFISetVolumeNative = ffi.Int32 Function(ffi.Int64, ffi.Double); +typedef _FFISetVolumeDart = int Function(int, double); + +typedef _FFISetPlaybackSpeedNative = ffi.Int32 Function(ffi.Int64, ffi.Double); +typedef _FFISetPlaybackSpeedDart = int Function(int, double); + +typedef _FFISetLoopingNative = ffi.Int32 Function(ffi.Int64, ffi.Bool); +typedef _FFISetLoopingDart = int Function(int, bool); + +typedef _FFIGetTrackInfoNative = ffi.Pointer Function( + ffi.Int64, ffi.Pointer); +typedef _FFIGetTrackInfoDart = ffi.Pointer Function( + int, ffi.Pointer); + +typedef _FFISetTrackSelectionNative = ffi.Int32 Function( + ffi.Int64, ffi.Int64, ffi.Pointer); +typedef _FFISetTrackSelectionDart = int Function( + int, int, ffi.Pointer); + +typedef _FFISetDisplayGeometryNative = ffi.Int32 Function( + ffi.Int64, ffi.Int32, ffi.Int32, ffi.Int32, ffi.Int32); +typedef _FFISetDisplayGeometryDart = int Function(int, int, int, int, int); + +typedef _FFISetDisplayRotateNative = ffi.Int32 Function(ffi.Int64, ffi.Int32); +typedef _FFISetDisplayRotateDart = int Function(int, int); + +typedef _FFISetActivateNative = ffi.Int32 Function(ffi.Int64); +typedef _FFISetActivateDart = int Function(int); + +typedef _FFISetDeactivateNative = ffi.Int32 Function(ffi.Int64); +typedef _FFISetDeactivateDart = int Function(int); + +typedef _FFISetMixWithOthersNative = ffi.Int32 Function(ffi.Bool); +typedef _FFISetMixWithOthersDart = int Function(bool); + +typedef _FFISuspendNative = ffi.Int32 Function(ffi.Int64); +typedef _FFISuspendDart = int Function(int); + +typedef _FFIRestoreNative = ffi.Int32 Function( + ffi.Int64, ffi.Pointer, ffi.Int64); +typedef _FFIRestoreDart = int Function(int, ffi.Pointer, int); + +typedef _FFIFreeStringNative = ffi.Void Function(ffi.Pointer); +typedef _FFIFreeStringDart = void Function(ffi.Pointer); + +ffi.Pointer _toPointer(String? str) { + if (str == null) { + return ffi.nullptr; + } + final Uint8List units = utf8.encode(str); + final ffi.Pointer result = + calloc.allocate(units.length + 1); + final Uint8List nativeString = result.asTypedList(units.length + 1); + nativeString.setAll(0, units); + nativeString[units.length] = 0; + return result.cast(); +} + +void _freePointer(ffi.Pointer ptr) { + if (ptr != ffi.nullptr) { + calloc.free(ptr); + } +} + +/// Manages FFI bindings to the native video player library. +class VideoPlayerFFIBindings { + VideoPlayerFFIBindings._(); + static VideoPlayerFFIBindings? _instance; + ffi.DynamicLibrary? _lib; + + late int Function() _ffiInitialize; + late int Function(ffi.Pointer) _ffiCreate; + late int Function(int) _ffiPrepare; + + late int Function(int) _ffiDispose; + late int Function(int) _ffiPlay; + late int Function(int) _ffiPause; + late int Function(int, int) _ffiSeekTo; + late int Function(int) _ffiGetPosition; + late ffi.Pointer Function(int) _ffiGetDuration; + late int Function(int, double) _ffiSetVolume; + late int Function(int, double) _ffiSetPlaybackSpeed; + late int Function(int, bool) _ffiSetLooping; + late ffi.Pointer Function(int, ffi.Pointer) + _ffiGetTrackInfo; + late int Function(int, int, ffi.Pointer) _ffiSetTrackSelection; + late int Function(int, int, int, int, int) _ffiSetDisplayGeometry; + late int Function(int, int) _ffiSetDisplayRotate; + late int Function(int) _ffiSuspend; + late int Function(int, ffi.Pointer, int) _ffiRestore; + late int Function(int) _ffiSetActivate; + late int Function(int) _ffiSetDeactivate; + late int Function(bool) _ffiSetMixWithOthers; + late void Function(ffi.Pointer) _ffiFreeString; + late void Function(int) _ffiRegisterDartPort; + late void Function() _ffiUnregisterDartPort; + + /// Returns the singleton instance of [VideoPlayerFFIBindings]. + static VideoPlayerFFIBindings get instance { + _instance ??= VideoPlayerFFIBindings._(); + return _instance!; + } + + /// Loads the native library and resolves all FFI function symbols. + void load() { + if (_lib != null) { + return; + } + + try { + _lib = ffi.DynamicLibrary.process(); + + _ffiInitialize = _lib! + .lookup>('ffi_initialize') + .asFunction<_FFIInitializeDart>(); + + _ffiCreate = _lib! + .lookup>('ffi_create') + .asFunction<_FFICreateDart>(); + + _ffiPrepare = _lib! + .lookup>('ffi_prepare') + .asFunction<_FFIPrepareDart>(); + + _ffiDispose = _lib! + .lookup>('ffi_dispose') + .asFunction<_FFIDisposeDart>(); + + _ffiPlay = _lib! + .lookup>('ffi_play') + .asFunction<_FFIPlayDart>(); + + _ffiPause = _lib! + .lookup>('ffi_pause') + .asFunction<_FFIPauseDart>(); + + _ffiSeekTo = _lib! + .lookup>('ffi_seek_to') + .asFunction<_FFISeekToDart>(); + + _ffiGetPosition = _lib! + .lookup>('ffi_get_position') + .asFunction<_FFIGetPositionDart>(); + + _ffiGetDuration = _lib! + .lookup>('ffi_get_duration') + .asFunction<_FFIGetDurationDart>(); + + _ffiSetVolume = _lib! + .lookup>('ffi_set_volume') + .asFunction<_FFISetVolumeDart>(); + + _ffiSetPlaybackSpeed = _lib! + .lookup>( + 'ffi_set_playback_speed') + .asFunction<_FFISetPlaybackSpeedDart>(); + + _ffiSetLooping = _lib! + .lookup>('ffi_set_looping') + .asFunction<_FFISetLoopingDart>(); + + _ffiGetTrackInfo = _lib! + .lookup>( + 'ffi_get_track_info') + .asFunction<_FFIGetTrackInfoDart>(); + + _ffiSetTrackSelection = _lib! + .lookup>( + 'ffi_set_track_selection') + .asFunction<_FFISetTrackSelectionDart>(); + + _ffiSetDisplayGeometry = _lib! + .lookup>( + 'ffi_set_display_geometry') + .asFunction<_FFISetDisplayGeometryDart>(); + + _ffiSetDisplayRotate = _lib! + .lookup>( + 'ffi_set_display_rotate') + .asFunction<_FFISetDisplayRotateDart>(); + + _ffiSuspend = _lib! + .lookup>('ffi_suspend') + .asFunction<_FFISuspendDart>(); + + _ffiRestore = _lib! + .lookup>('ffi_restore') + .asFunction<_FFIRestoreDart>(); + + _ffiSetActivate = _lib! + .lookup>('ffi_set_activate') + .asFunction<_FFISetActivateDart>(); + + _ffiSetDeactivate = _lib! + .lookup>( + 'ffi_set_deactivate') + .asFunction<_FFISetDeactivateDart>(); + + _ffiSetMixWithOthers = _lib! + .lookup>( + 'ffi_set_mix_with_others') + .asFunction<_FFISetMixWithOthersDart>(); + + _ffiFreeString = _lib! + .lookup>('ffi_free_string') + .asFunction<_FFIFreeStringDart>(); + + _ffiRegisterDartPort = _lib! + .lookup>( + 'ffi_register_dart_port') + .asFunction<_FFIRegisterEventPortDart>(); + _ffiUnregisterDartPort = _lib! + .lookup>( + 'ffi_unregister_dart_port') + .asFunction<_FFIUnregisterEventPortDart>(); + } catch (e) { + _lib = null; + throw PlatformException( + code: 'FFI_LIBRARY_LOAD_FAILED', + message: 'Failed to load FFI bindings', + ); + } + } + + /// Whether the native library has been loaded. + bool get isLoaded => _lib != null; +} + +/// Provides the Dart-facing API for the native video player via FFI. +class VideoPlayerVideoholeFFIApi { + /// Initializes the native video player library. + int initialize() { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiInitialize(); + } + + /// Creates a new native video player instance from [message]. + int create(CreateMessage message) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + final String jsonString = message.toJson(); + final ffi.Pointer jsonPtr = _toPointer(jsonString); + try { + return bindings._ffiCreate(jsonPtr); + } finally { + _freePointer(jsonPtr); + } + } + + /// Prepares the player for playback asynchronously. + int prepare(int playerId) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiPrepare(playerId); + } + + /// Restores a previously suspended player with optional [message] and [resumeTime]. + int restore(int playerId, CreateMessage? message, int resumeTime) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + final String? jsonString = message?.toJson(); + final ffi.Pointer createMessagePtr = _toPointer(jsonString); + try { + return bindings._ffiRestore(playerId, createMessagePtr, resumeTime); + } finally { + _freePointer(createMessagePtr); + } + } + + /// Disposes the native player identified by [playerId]. + int dispose(int playerId) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiDispose(playerId); + } + + /// Starts playback of the player identified by [playerId]. + int play(int playerId) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiPlay(playerId); + } + + /// Pauses playback of the player identified by [playerId]. + int pause(int playerId) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiPause(playerId); + } + + /// Seeks to [positionMs] in the player identified by [playerId]. + int seekTo(int playerId, int positionMs) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiSeekTo(playerId, positionMs); + } + + /// Returns the current playback position in milliseconds. + int getPosition(int playerId) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiGetPosition(playerId); + } + + /// Returns the duration information of the player identified by [playerId]. + DurationMessage duration(int playerId) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + final ffi.Pointer ptr = bindings._ffiGetDuration(playerId); + if (ptr == ffi.nullptr) { + throw PlatformException( + code: 'FFI_GET_DURATION_FAILED', + message: 'FFI getDuration failed - returned null pointer', + ); + } + try { + final ffi.Pointer bytes = ptr.cast(); + int length = 0; + while (bytes[length] != 0) { + length++; + } + final String jsonString = utf8.decode(bytes.asTypedList(length)); + if (jsonString == '-1') { + throw PlatformException( + code: 'FFI_GET_DURATION_FAILED', + message: 'FFI getDuration failed', + ); + } + return DurationMessage.fromJson(jsonString); + } finally { + bindings._ffiFreeString(ptr); + } + } + + /// Sets the playback volume for the player identified by [playerId]. + int setVolume(int playerId, double volume) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiSetVolume(playerId, volume); + } + + /// Sets the playback speed for the player identified by [playerId]. + int setPlaybackSpeed(int playerId, double speed) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiSetPlaybackSpeed(playerId, speed); + } + + /// Enables or disables looping for the player identified by [playerId]. + int setLooping(int playerId, bool isLooping) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiSetLooping(playerId, isLooping); + } + + /// Sets the display geometry (position and size) for the player. + int setDisplayGeometry(int playerId, int x, int y, int width, int height) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiSetDisplayGeometry(playerId, x, y, width, height); + } + + /// Sets the display rotation for the player identified by [playerId]. + int setDisplayRotate(int playerId, int rotation) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiSetDisplayRotate(playerId, rotation); + } + + /// Suspends the player identified by [playerId]. + int suspend(int playerId) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiSuspend(playerId); + } + + /// Activates the player identified by [playerId]. + int setActivate(int playerId) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiSetActivate(playerId); + } + + /// Deactivates the player identified by [playerId]. + int setDeactivate(int playerId) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiSetDeactivate(playerId); + } + + /// Retrieves track information for the player identified by [playerId]. + TrackMessage getTrackInfo(int playerId, String trackType) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + final ffi.Pointer trackTypePtr = _toPointer(trackType); + ffi.Pointer? ptr; + try { + ptr = bindings._ffiGetTrackInfo(playerId, trackTypePtr); + if (ptr == ffi.nullptr) { + throw PlatformException( + code: 'FFI_GET_TRACK_INFO_FAILED', + message: 'FFI getTrackInfo failed - returned null pointer', + ); + } + final ffi.Pointer bytes = ptr.cast(); + int length = 0; + while (bytes[length] != 0) { + length++; + } + final String jsonString = utf8.decode(bytes.asTypedList(length)); + if (jsonString == '-1') { + throw PlatformException( + code: 'FFI_GET_TRACK_INFO_FAILED', + message: 'FFI getTrackInfo failed', + ); + } + return TrackMessage.fromJson(jsonString); + } finally { + if (ptr != null) { + bindings._ffiFreeString(ptr); + } + _freePointer(trackTypePtr); + } + } + + /// Selects a track by [trackId] and [trackType] for the player. + int setTrackSelection(int playerId, int trackId, String trackType) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + final ffi.Pointer trackTypePtr = _toPointer(trackType); + try { + return bindings._ffiSetTrackSelection(playerId, trackId, trackTypePtr); + } finally { + _freePointer(trackTypePtr); + } + } + + /// Sets whether audio should mix with other audio sources. + int setMixWithOthers(bool mixWithOthers) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + return bindings._ffiSetMixWithOthers(mixWithOthers); + } +} + +typedef _FFIInitializeApiDlNative = ffi.Int32 Function(ffi.Pointer); +typedef _FFIInitializeApiDlDart = int Function(ffi.Pointer); + +typedef _FFIRegisterEventPortNative = ffi.Void Function(ffi.Int64); +typedef _FFIRegisterEventPortDart = void Function(int); + +typedef _FFIUnregisterEventPortNative = ffi.Void Function(); +typedef _FFIUnregisterEventPortDart = void Function(); + +late ffi.Pointer>? + _ffiInitializeApiDlPtr; + +/// Whether the Dart API DL has been initialized. +bool _apiDlInitialized = false; + +/// Initializes the Dart API DL for native-to-Dart communication. +void ffiInitializeApiDL() { + if (_apiDlInitialized) { + return; + } + + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + final ffi.DynamicLibrary? lib = bindings._lib; + if (lib == null) { + throw PlatformException( + code: 'FFI_LIBRARY_NOT_LOADED', + message: 'FFI library is not loaded', + ); + } + + try { + _ffiInitializeApiDlPtr = + lib.lookup>( + 'ffi_initialize_api_dl'); + } catch (e) { + throw PlatformException( + code: 'FFI_API_DL_LOOKUP_FAILED', + message: 'Failed to lookup ffi_initialize_api_dl', + ); + } + + final int result = _ffiInitializeApiDlPtr! + .asFunction<_FFIInitializeApiDlDart>()(ffi.NativeApi.initializeApiDLData); + if (result != 0) { + throw PlatformException( + code: 'FFI_API_DL_INITIALIZATION_FAILED', + message: 'Dart API DL initialization failed with code: $result', + ); + } + + _apiDlInitialized = true; +} + +/// Extension on [RawReceivePort] to expose the native port ID. +extension RawReceivePortNativePort on RawReceivePort { + /// Returns the native port ID of this [RawReceivePort]. + int get nativePort => _rawReceivePortNativePort(this); +} + +/// Extension on [ReceivePort] to expose the native port ID. +extension ReceivePortNativePort on ReceivePort { + /// Returns the native port ID of this [ReceivePort]. + int get nativePort => _receivePortNativePort(this); +} + +@pragma('vm:never-inline') +int _rawReceivePortNativePort(RawReceivePort port) { + return port.sendPort.nativePort; +} + +@pragma('vm:never-inline') +int _receivePortNativePort(ReceivePort port) { + return port.sendPort.nativePort; +} + +/// Registers the Dart event [port] with the native player for receiving events. +void ffiRegisterEventPort(int port) { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + bindings._ffiRegisterDartPort(port); +} + +/// Unregisters the Dart event port from the native player. +void ffiUnregisterEventPort() { + final VideoPlayerFFIBindings bindings = VideoPlayerFFIBindings.instance; + if (!bindings.isLoaded) { + bindings.load(); + } + bindings._ffiUnregisterDartPort(); +} diff --git a/packages/video_player_videohole/lib/src/messages.g.dart b/packages/video_player_videohole/lib/src/messages.g.dart deleted file mode 100644 index fad56e06d..000000000 --- a/packages/video_player_videohole/lib/src/messages.g.dart +++ /dev/null @@ -1,946 +0,0 @@ -// Autogenerated from Pigeon (v10.1.6), do not edit directly. -// See also: https://pub.dev/packages/pigeon -// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import - -import 'dart:async'; -import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; - -import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; -import 'package:flutter/services.dart'; - -class PlayerMessage { - PlayerMessage({required this.playerId}); - - int playerId; - - Object encode() { - return [playerId]; - } - - static PlayerMessage decode(Object result) { - result as List; - return PlayerMessage(playerId: result[0]! as int); - } -} - -class LoopingMessage { - LoopingMessage({required this.playerId, required this.isLooping}); - - int playerId; - - bool isLooping; - - Object encode() { - return [playerId, isLooping]; - } - - static LoopingMessage decode(Object result) { - result as List; - return LoopingMessage( - playerId: result[0]! as int, - isLooping: result[1]! as bool, - ); - } -} - -class VolumeMessage { - VolumeMessage({required this.playerId, required this.volume}); - - int playerId; - - double volume; - - Object encode() { - return [playerId, volume]; - } - - static VolumeMessage decode(Object result) { - result as List; - return VolumeMessage( - playerId: result[0]! as int, - volume: result[1]! as double, - ); - } -} - -class PlaybackSpeedMessage { - PlaybackSpeedMessage({required this.playerId, required this.speed}); - - int playerId; - - double speed; - - Object encode() { - return [playerId, speed]; - } - - static PlaybackSpeedMessage decode(Object result) { - result as List; - return PlaybackSpeedMessage( - playerId: result[0]! as int, - speed: result[1]! as double, - ); - } -} - -class TrackMessage { - TrackMessage({required this.playerId, required this.tracks}); - - int playerId; - - List?> tracks; - - Object encode() { - return [playerId, tracks]; - } - - static TrackMessage decode(Object result) { - result as List; - return TrackMessage( - playerId: result[0]! as int, - tracks: (result[1] as List?)!.cast?>(), - ); - } -} - -class TrackTypeMessage { - TrackTypeMessage({required this.playerId, required this.trackType}); - - int playerId; - - String trackType; - - Object encode() { - return [playerId, trackType]; - } - - static TrackTypeMessage decode(Object result) { - result as List; - return TrackTypeMessage( - playerId: result[0]! as int, - trackType: result[1]! as String, - ); - } -} - -class SelectedTracksMessage { - SelectedTracksMessage({ - required this.playerId, - required this.trackId, - required this.trackType, - }); - - int playerId; - - int trackId; - - String trackType; - - Object encode() { - return [playerId, trackId, trackType]; - } - - static SelectedTracksMessage decode(Object result) { - result as List; - return SelectedTracksMessage( - playerId: result[0]! as int, - trackId: result[1]! as int, - trackType: result[2]! as String, - ); - } -} - -class PositionMessage { - PositionMessage({required this.playerId, required this.position}); - - int playerId; - - int position; - - Object encode() { - return [playerId, position]; - } - - static PositionMessage decode(Object result) { - result as List; - return PositionMessage( - playerId: result[0]! as int, - position: result[1]! as int, - ); - } -} - -class CreateMessage { - CreateMessage({ - this.asset, - this.uri, - this.packageName, - this.formatHint, - this.httpHeaders, - this.drmConfigs, - this.playerOptions, - this.windowGeometry, - }); - - String? asset; - - String? uri; - - String? packageName; - - String? formatHint; - - Map? httpHeaders; - - Map? drmConfigs; - - Map? playerOptions; - - Map? windowGeometry; - - Object encode() { - return [ - asset, - uri, - packageName, - formatHint, - httpHeaders, - drmConfigs, - playerOptions, - windowGeometry, - ]; - } - - static CreateMessage decode(Object result) { - result as List; - return CreateMessage( - asset: result[0] as String?, - uri: result[1] as String?, - packageName: result[2] as String?, - formatHint: result[3] as String?, - httpHeaders: - (result[4] as Map?)?.cast(), - drmConfigs: - (result[5] as Map?)?.cast(), - playerOptions: - (result[6] as Map?)?.cast(), - windowGeometry: - (result[7] as Map?)?.cast(), - ); - } -} - -class MixWithOthersMessage { - MixWithOthersMessage({required this.mixWithOthers}); - - bool mixWithOthers; - - Object encode() { - return [mixWithOthers]; - } - - static MixWithOthersMessage decode(Object result) { - result as List; - return MixWithOthersMessage(mixWithOthers: result[0]! as bool); - } -} - -class GeometryMessage { - GeometryMessage({ - required this.playerId, - required this.x, - required this.y, - required this.width, - required this.height, - }); - - int playerId; - - int x; - - int y; - - int width; - - int height; - - Object encode() { - return [playerId, x, y, width, height]; - } - - static GeometryMessage decode(Object result) { - result as List; - return GeometryMessage( - playerId: result[0]! as int, - x: result[1]! as int, - y: result[2]! as int, - width: result[3]! as int, - height: result[4]! as int, - ); - } -} - -class DurationMessage { - DurationMessage({required this.playerId, this.durationRange}); - - int playerId; - - List? durationRange; - - Object encode() { - return [playerId, durationRange]; - } - - static DurationMessage decode(Object result) { - result as List; - return DurationMessage( - playerId: result[0]! as int, - durationRange: (result[1] as List?)?.cast(), - ); - } -} - -class RotationMessage { - RotationMessage({required this.playerId, required this.rotation}); - - int playerId; - - int rotation; - - Object encode() { - return [playerId, rotation]; - } - - static RotationMessage decode(Object result) { - result as List; - return RotationMessage( - playerId: result[0]! as int, - rotation: result[1]! as int, - ); - } -} - -class _VideoPlayerVideoholeApiCodec extends StandardMessageCodec { - const _VideoPlayerVideoholeApiCodec(); - @override - void writeValue(WriteBuffer buffer, Object? value) { - if (value is CreateMessage) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is CreateMessage) { - buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else if (value is DurationMessage) { - buffer.putUint8(130); - writeValue(buffer, value.encode()); - } else if (value is GeometryMessage) { - buffer.putUint8(131); - writeValue(buffer, value.encode()); - } else if (value is LoopingMessage) { - buffer.putUint8(132); - writeValue(buffer, value.encode()); - } else if (value is MixWithOthersMessage) { - buffer.putUint8(133); - writeValue(buffer, value.encode()); - } else if (value is PlaybackSpeedMessage) { - buffer.putUint8(134); - writeValue(buffer, value.encode()); - } else if (value is PlayerMessage) { - buffer.putUint8(135); - writeValue(buffer, value.encode()); - } else if (value is PositionMessage) { - buffer.putUint8(136); - writeValue(buffer, value.encode()); - } else if (value is RotationMessage) { - buffer.putUint8(137); - writeValue(buffer, value.encode()); - } else if (value is SelectedTracksMessage) { - buffer.putUint8(138); - writeValue(buffer, value.encode()); - } else if (value is TrackMessage) { - buffer.putUint8(139); - writeValue(buffer, value.encode()); - } else if (value is TrackTypeMessage) { - buffer.putUint8(140); - writeValue(buffer, value.encode()); - } else if (value is VolumeMessage) { - buffer.putUint8(141); - writeValue(buffer, value.encode()); - } else { - super.writeValue(buffer, value); - } - } - - @override - Object? readValueOfType(int type, ReadBuffer buffer) { - switch (type) { - case 128: - return CreateMessage.decode(readValue(buffer)!); - case 129: - return CreateMessage.decode(readValue(buffer)!); - case 130: - return DurationMessage.decode(readValue(buffer)!); - case 131: - return GeometryMessage.decode(readValue(buffer)!); - case 132: - return LoopingMessage.decode(readValue(buffer)!); - case 133: - return MixWithOthersMessage.decode(readValue(buffer)!); - case 134: - return PlaybackSpeedMessage.decode(readValue(buffer)!); - case 135: - return PlayerMessage.decode(readValue(buffer)!); - case 136: - return PositionMessage.decode(readValue(buffer)!); - case 137: - return RotationMessage.decode(readValue(buffer)!); - case 138: - return SelectedTracksMessage.decode(readValue(buffer)!); - case 139: - return TrackMessage.decode(readValue(buffer)!); - case 140: - return TrackTypeMessage.decode(readValue(buffer)!); - case 141: - return VolumeMessage.decode(readValue(buffer)!); - default: - return super.readValueOfType(type, buffer); - } - } -} - -class VideoPlayerVideoholeApi { - /// Constructor for [VideoPlayerVideoholeApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default - /// BinaryMessenger will be used which routes to the host platform. - VideoPlayerVideoholeApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = _VideoPlayerVideoholeApiCodec(); - - Future initialize() async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.initialize', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = await channel.send(null) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future create(CreateMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.create', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyList[0] as PlayerMessage?)!; - } - } - - Future dispose(PlayerMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.dispose', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future setLooping(LoopingMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.setLooping', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future setVolume(VolumeMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.setVolume', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future setPlaybackSpeed(PlaybackSpeedMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.setPlaybackSpeed', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future play(PlayerMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.play', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future setDeactivate(PlayerMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.setDeactivate', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyList[0] as bool?)!; - } - } - - Future setActivate(PlayerMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.setActivate', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyList[0] as bool?)!; - } - } - - Future track(TrackTypeMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.track', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyList[0] as TrackMessage?)!; - } - } - - Future setTrackSelection(SelectedTracksMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.setTrackSelection', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyList[0] as bool?)!; - } - } - - Future position(PlayerMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.position', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyList[0] as PositionMessage?)!; - } - } - - Future seekTo(PositionMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.seekTo', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future pause(PlayerMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.pause', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future setMixWithOthers(MixWithOthersMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.setMixWithOthers', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future setDisplayGeometry(GeometryMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.setDisplayGeometry', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future duration(PlayerMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.duration', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyList[0] as DurationMessage?)!; - } - } - - Future suspend(int arg_playerId) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.suspend', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_playerId]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future restore( - int arg_playerId, - CreateMessage? arg_msg, - int arg_resumeTime, - ) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.restore', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = await channel.send([ - arg_playerId, - arg_msg, - arg_resumeTime, - ]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return; - } - } - - Future setDisplayRotate(RotationMessage arg_msg) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi.setDisplayRotate', - codec, - binaryMessenger: _binaryMessenger, - ); - final List? replyList = - await channel.send([arg_msg]) as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else if (replyList[0] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyList[0] as bool?)!; - } - } -} diff --git a/packages/video_player_videohole/lib/src/video_player_tizen.dart b/packages/video_player_videohole/lib/src/video_player_tizen.dart index b7aa79b31..487d0febf 100644 --- a/packages/video_player_videohole/lib/src/video_player_tizen.dart +++ b/packages/video_player_videohole/lib/src/video_player_tizen.dart @@ -4,44 +4,65 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; +import 'dart:isolate' show RawReceivePort; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; -import 'package:tizen_window_manager/tizen_window_manager.dart'; import '../video_player_platform_interface.dart'; -import 'messages.g.dart'; +import 'ffi_messages.dart'; import 'tracks.dart'; -/// An implementation of [VideoPlayerPlatform] that uses the -/// Pigeon-generated [VideoPlayerVideoholeApi]. +class _SeekOperation { + _SeekOperation({required this.position, required this.completers}); + + Duration position; + final List> completers; +} + +/// An implementation of [VideoPlayerPlatform] that uses FFI for all methods. class VideoPlayerTizen extends VideoPlayerPlatform { - final VideoPlayerVideoholeApi _api = VideoPlayerVideoholeApi(); + /// Create a new VideoPlayerTizen instance. + VideoPlayerTizen() : super(); - /// Fetches the window geometry via the tizen_window_manager plugin. - /// - /// Returns null if the geometry is not available. - Future?> _getWindowGeometry() async { - try { - final Map geometry = await WindowManager.getGeometry(); - return Map.from(geometry); - } on Exception { - return null; - } - } + final VideoPlayerVideoholeFFIApi _ffiApi = VideoPlayerVideoholeFFIApi(); @override - Future init() { - return _api.initialize(); + Future init() async { + final int result = _ffiApi.initialize(); + if (result != 0) { + throw PlatformException( + code: 'FFI_INITIALIZE_FAILED', + message: 'FFI initialize failed with code: $result', + ); + } } @override - Future dispose(int playerId) { - return _api.dispose(PlayerMessage(playerId: playerId)); + Future dispose(int playerId) async { + _completeSeeksWithError( + playerId, + PlatformException( + code: 'FFI_SEEK_TO_CANCELLED', + message: 'seekTo was cancelled because player $playerId was disposed', + ), + ); + + final StreamController? controller = _eventControllers.remove( + playerId, + ); + if (controller != null && !controller.isClosed) { + await controller.close(); + } + + _ffiApi.dispose(playerId); } @override Future create(DataSource dataSource) async { + _ensureEventPortRegistered(); + final CreateMessage message = CreateMessage(); switch (dataSource.sourceType) { @@ -55,73 +76,199 @@ class VideoPlayerTizen extends VideoPlayerPlatform { message.drmConfigs = dataSource.drmConfigs?.toMap(); message.playerOptions = dataSource.playerOptions; case DataSourceType.file: - message.uri = dataSource.uri; case DataSourceType.contentUri: message.uri = dataSource.uri; } - message.windowGeometry = await _getWindowGeometry(); + final int playerId = _ffiApi.create(message); - final PlayerMessage response = await _api.create(message); - return response.playerId; + if (playerId < 0) { + throw PlatformException( + code: 'FFI_CREATE_FAILED', + message: 'FFI create failed with code: $playerId', + ); + } + + return playerId; } @override - Future setLooping(int playerId, bool looping) { - return _api.setLooping( - LoopingMessage(playerId: playerId, isLooping: looping), - ); + Future prepare(int playerId) async { + final int result = _ffiApi.prepare(playerId); + if (result < 0) { + throw PlatformException( + code: 'FFI_PREPARE_FAILED', + message: 'FFI prepare failed with code: $result', + ); + } + } + + void _ensureEventPortRegistered() { + if (_eventPort == null) { + ffiInitializeApiDL(); + + _eventPort = RawReceivePort(); + + _eventPort!.handler = (dynamic message) { + try { + if (message is List && message.length == 2) { + final int receivingPlayerId = message[0] as int; + final String eventJson = message[1] as String; + + final Map eventMap = + jsonDecode(eventJson) as Map; + + if (eventMap['event'] == 'seekCompleted') { + _handleSeekCompleted(receivingPlayerId); + return; + } + + final StreamController? controller = + _eventControllers[receivingPlayerId]; + + if (eventMap['event'] == 'error') { + final PlatformException exception = PlatformException( + code: eventMap['code'] as String? ?? 'unknown', + message: eventMap['message'] as String?, + ); + + _completeSeeksWithError(receivingPlayerId, exception); + + if (controller != null && !controller.isClosed) { + controller.addError(exception); + } + return; + } + + if (controller != null && !controller.isClosed) { + final VideoEvent videoEvent = _parseVideoEventFromMap(eventMap); + controller.add(videoEvent); + } + } + } catch (e, stackTrace) { + FlutterError.reportError( + FlutterErrorDetails( + exception: PlatformException( + code: 'FFI_EVENT_PROCESSING_FAILED', + message: 'Failed to process FFI event', + ), + stack: stackTrace, + ), + ); + } + }; + + ffiRegisterEventPort(_eventPort!.nativePort); + } } @override - Future play(int playerId) { - return _api.play(PlayerMessage(playerId: playerId)); + Future setLooping(int playerId, bool looping) async { + final int result = _ffiApi.setLooping(playerId, looping); + if (result != 0) { + throw PlatformException( + code: 'FFI_SET_LOOPING_FAILED', + message: 'FFI setLooping failed with code: $result', + ); + } } @override - Future setActivate(int playerId) { - return _api.setActivate(PlayerMessage(playerId: playerId)); + Future play(int playerId) async { + final int result = _ffiApi.play(playerId); + if (result != 0) { + throw PlatformException( + code: 'FFI_PLAY_FAILED', + message: 'FFI play failed with code: $result', + ); + } } @override - Future setDeactivate(int playerId) { - return _api.setDeactivate(PlayerMessage(playerId: playerId)); + Future setActivate(int playerId) async { + final int result = _ffiApi.setActivate(playerId); + if (result != 0) { + throw PlatformException( + code: 'FFI_SET_ACTIVATE_FAILED', + message: 'FFI setActivate failed with code: $result', + ); + } + return true; } @override - Future pause(int playerId) { - return _api.pause(PlayerMessage(playerId: playerId)); + Future setDeactivate(int playerId) async { + final int result = _ffiApi.setDeactivate(playerId); + if (result != 0) { + throw PlatformException( + code: 'FFI_SET_DEACTIVATE_FAILED', + message: 'FFI setDeactivate failed with code: $result', + ); + } + return true; } @override - Future setVolume(int playerId, double volume) { - return _api.setVolume(VolumeMessage(playerId: playerId, volume: volume)); + Future pause(int playerId) async { + final int result = _ffiApi.pause(playerId); + if (result != 0) { + throw PlatformException( + code: 'FFI_PAUSE_FAILED', + message: 'FFI pause failed with code: $result', + ); + } } @override - Future setPlaybackSpeed(int playerId, double speed) { - assert(speed > 0); + Future setVolume(int playerId, double volume) async { + final int result = _ffiApi.setVolume(playerId, volume); + if (result != 0) { + throw PlatformException( + code: 'FFI_SET_VOLUME_FAILED', + message: 'FFI setVolume failed with code: $result', + ); + } + } - return _api.setPlaybackSpeed( - PlaybackSpeedMessage(playerId: playerId, speed: speed), - ); + @override + Future setPlaybackSpeed(int playerId, double speed) async { + assert(speed > 0); + final int result = _ffiApi.setPlaybackSpeed(playerId, speed); + if (result != 0) { + throw PlatformException( + code: 'FFI_SET_PLAYBACK_SPEED_FAILED', + message: 'FFI setPlaybackSpeed failed with code: $result', + ); + } } @override - Future seekTo(int playerId, Duration position) { - return _api.seekTo( - PositionMessage(playerId: playerId, position: position.inMilliseconds), - ); + Future seekTo(int playerId, Duration position) async { + _ensureEventPortRegistered(); + + final Completer completer = Completer(); + + if (_activeSeeks.containsKey(playerId)) { + final _SeekOperation pendingSeek = _pendingSeeks.putIfAbsent( + playerId, + () => + _SeekOperation(position: position, completers: >[]), + ); + pendingSeek.position = position; + pendingSeek.completers.add(completer); + return completer.future; + } + + _startSeek(playerId, position, >[completer]); + return completer.future; } @override Future> getVideoTracks(int playerId) async { - final TrackMessage response = await _api.track( - TrackTypeMessage(playerId: playerId, trackType: TrackType.video.name), - ); + final TrackMessage message = _ffiApi.getTrackInfo(playerId, 'video'); final List videoTracks = []; - for (final Map? trackMap in response.tracks) { + for (final Map? trackMap in message.tracks) { final int trackId = trackMap!['trackId']! as int; final int bitrate = trackMap['bitrate']! as int; final int width = trackMap['width']! as int; @@ -142,12 +289,10 @@ class VideoPlayerTizen extends VideoPlayerPlatform { @override Future> getAudioTracks(int playerId) async { - final TrackMessage response = await _api.track( - TrackTypeMessage(playerId: playerId, trackType: TrackType.audio.name), - ); + final TrackMessage message = _ffiApi.getTrackInfo(playerId, 'audio'); final List audioTracks = []; - for (final Map? trackMap in response.tracks) { + for (final Map? trackMap in message.tracks) { final int trackId = trackMap!['trackId']! as int; final String language = trackMap['language']! as String; final int channel = trackMap['channel']! as int; @@ -168,12 +313,10 @@ class VideoPlayerTizen extends VideoPlayerPlatform { @override Future> getTextTracks(int playerId) async { - final TrackMessage response = await _api.track( - TrackTypeMessage(playerId: playerId, trackType: TrackType.text.name), - ); + final TrackMessage message = _ffiApi.getTrackInfo(playerId, 'text'); final List textTracks = []; - for (final Map? trackMap in response.tracks) { + for (final Map? trackMap in message.tracks) { final int trackId = trackMap!['trackId']! as int; final String language = trackMap['language']! as String; @@ -184,21 +327,24 @@ class VideoPlayerTizen extends VideoPlayerPlatform { } @override - Future setTrackSelection(int playerId, Track track) { - return _api.setTrackSelection( - SelectedTracksMessage( - playerId: playerId, - trackId: track.trackId, - trackType: track.trackType.name, - ), + Future setTrackSelection(int playerId, Track track) async { + final int result = _ffiApi.setTrackSelection( + playerId, + track.trackId, + track.trackType.name, ); + if (result != 0) { + throw PlatformException( + code: 'FFI_SET_TRACK_SELECTION_FAILED', + message: 'FFI setTrackSelection failed with code: $result', + ); + } + return true; } @override Future getDuration(int playerId) async { - final DurationMessage message = await _api.duration( - PlayerMessage(playerId: playerId), - ); + final DurationMessage message = _ffiApi.duration(playerId); return DurationRange( Duration(milliseconds: message.durationRange?[0] ?? 0), Duration(milliseconds: message.durationRange?[1] ?? 0), @@ -207,66 +353,80 @@ class VideoPlayerTizen extends VideoPlayerPlatform { @override Future getPosition(int playerId) async { - final PositionMessage response = await _api.position( - PlayerMessage(playerId: playerId), - ); - return Duration(milliseconds: response.position); + final int positionMs = _ffiApi.getPosition(playerId); + if (positionMs < 0) { + throw PlatformException( + code: 'FFI_GET_POSITION_FAILED', + message: 'FFI getPosition failed with code: $positionMs', + ); + } + return Duration(milliseconds: positionMs); } + RawReceivePort? _eventPort; + + final Map> _eventControllers = + >{}; + + final Map _activeSeeks = {}; + final Map _pendingSeeks = {}; + @override Stream videoEventsFor(int playerId) { - return _eventChannelFor(playerId).receiveBroadcastStream().map(( - dynamic event, - ) { - final Map map = event as Map; - switch (map['event']) { - case 'initialized': - case 'restored': - final List? durationVal = map['duration'] as List?; - VideoEventType videoEventType; - if (map['event'] == 'initialized') { - videoEventType = VideoEventType.initialized; - } else { - videoEventType = VideoEventType.restored; - } - return VideoEvent( - eventType: videoEventType, - duration: DurationRange( - Duration(milliseconds: durationVal?[0] as int), - Duration(milliseconds: durationVal?[1] as int), - ), - size: Size( - (map['width'] as num?)?.toDouble() ?? 0.0, - (map['height'] as num?)?.toDouble() ?? 0.0, - ), - ); - case 'completed': - return VideoEvent(eventType: VideoEventType.completed); - case 'bufferingUpdate': - final int value = map['value']! as int; - - return VideoEvent( - buffered: value, - eventType: VideoEventType.bufferingUpdate, - ); - case 'bufferingStart': - return VideoEvent(eventType: VideoEventType.bufferingStart); - case 'bufferingEnd': - return VideoEvent(eventType: VideoEventType.bufferingEnd); - case 'subtitleUpdate': - return VideoEvent( - eventType: VideoEventType.subtitleUpdate, - text: map['text']! as String, - ); - case 'isPlayingStateUpdate': - return VideoEvent( - eventType: VideoEventType.isPlayingStateUpdate, - isPlaying: map['isPlaying']! as bool, - ); - default: - return VideoEvent(eventType: VideoEventType.unknown); - } - }); + _ensureEventPortRegistered(); + + return _eventControllers + .putIfAbsent(playerId, () => StreamController.broadcast()) + .stream; + } + + VideoEvent _parseVideoEventFromMap(Map map) { + switch (map['event']) { + case 'initialized': + case 'restored': + final List? durationVal = map['duration'] as List?; + VideoEventType videoEventType; + if (map['event'] == 'initialized') { + videoEventType = VideoEventType.initialized; + } else { + videoEventType = VideoEventType.restored; + } + return VideoEvent( + eventType: videoEventType, + duration: DurationRange( + Duration(milliseconds: durationVal?[0] as int? ?? 0), + Duration(milliseconds: durationVal?[1] as int? ?? 0), + ), + size: Size( + (map['width'] as num?)?.toDouble() ?? 0.0, + (map['height'] as num?)?.toDouble() ?? 0.0, + ), + ); + case 'completed': + return VideoEvent(eventType: VideoEventType.completed); + case 'bufferingUpdate': + final int value = map['value']! as int; + return VideoEvent( + buffered: value, + eventType: VideoEventType.bufferingUpdate, + ); + case 'bufferingStart': + return VideoEvent(eventType: VideoEventType.bufferingStart); + case 'bufferingEnd': + return VideoEvent(eventType: VideoEventType.bufferingEnd); + case 'subtitleUpdate': + return VideoEvent( + eventType: VideoEventType.subtitleUpdate, + text: map['text']! as String, + ); + case 'isPlayingStateUpdate': + return VideoEvent( + eventType: VideoEventType.isPlayingStateUpdate, + isPlaying: map['isPlaying']! as bool, + ); + default: + return VideoEvent(eventType: VideoEventType.unknown); + } } @override @@ -275,10 +435,14 @@ class VideoPlayerTizen extends VideoPlayerPlatform { } @override - Future setMixWithOthers(bool mixWithOthers) { - return _api.setMixWithOthers( - MixWithOthersMessage(mixWithOthers: mixWithOthers), - ); + Future setMixWithOthers(bool mixWithOthers) async { + final int result = _ffiApi.setMixWithOthers(mixWithOthers); + if (result != 0) { + throw PlatformException( + code: 'FFI_SET_MIX_WITH_OTHERS_FAILED', + message: 'FFI setMixWithOthers failed with code: $result', + ); + } } @override @@ -288,21 +452,31 @@ class VideoPlayerTizen extends VideoPlayerPlatform { int y, int width, int height, - ) { - return _api.setDisplayGeometry( - GeometryMessage( - playerId: playerId, - x: x, - y: y, - width: width, - height: height, - ), + ) async { + final int result = _ffiApi.setDisplayGeometry( + playerId, + x, + y, + width, + height, ); + if (result != 0) { + throw PlatformException( + code: 'FFI_SET_DISPLAY_GEOMETRY_FAILED', + message: 'FFI setDisplayGeometry failed with code: $result', + ); + } } @override - Future suspend(int playerId) { - return _api.suspend(playerId); + Future suspend(int playerId) async { + final int result = _ffiApi.suspend(playerId); + if (result != 0) { + throw PlatformException( + code: 'FFI_SUSPEND_FAILED', + message: 'FFI suspend failed with code: $result', + ); + } } @override @@ -311,9 +485,10 @@ class VideoPlayerTizen extends VideoPlayerPlatform { DataSource? dataSource, int resumeTime = -1, }) async { - final CreateMessage message = CreateMessage(); - + CreateMessage? message; if (dataSource != null) { + message = CreateMessage(); + switch (dataSource.sourceType) { case DataSourceType.asset: message.asset = dataSource.asset; @@ -325,26 +500,138 @@ class VideoPlayerTizen extends VideoPlayerPlatform { message.drmConfigs = dataSource.drmConfigs?.toMap(); message.playerOptions = dataSource.playerOptions; case DataSourceType.file: - message.uri = dataSource.uri; case DataSourceType.contentUri: message.uri = dataSource.uri; } } - message.windowGeometry = await _getWindowGeometry(); - - return _api.restore(playerId, message, resumeTime); + final int result = _ffiApi.restore(playerId, message, resumeTime); + if (result != 0) { + throw PlatformException( + code: 'FFI_RESTORE_FAILED', + message: 'FFI restore failed with code: $result', + ); + } } @override - Future setDisplayRotate(int playerId, DisplayRotation rotation) { - return _api.setDisplayRotate( - RotationMessage(playerId: playerId, rotation: rotation.index), + Future setDisplayRotate(int playerId, DisplayRotation rotation) async { + final int result = _ffiApi.setDisplayRotate(playerId, rotation.index); + if (result != 0) { + throw PlatformException( + code: 'FFI_SET_DISPLAY_ROTATE_FAILED', + message: 'FFI setDisplayRotate failed with code: $result', + ); + } + return true; + } + + void _startSeek( + int playerId, + Duration position, + List> completers, + ) { + final _SeekOperation seek = _SeekOperation( + position: position, + completers: completers, ); + + _activeSeeks[playerId] = seek; + + try { + final int result = _ffiApi.seekTo(playerId, position.inMilliseconds); + if (result != 0) { + if (identical(_activeSeeks[playerId], seek)) { + _activeSeeks.remove(playerId); + } + + _completeSeekWithError( + seek, + PlatformException( + code: 'FFI_SEEK_TO_FAILED', + message: 'FFI seekTo failed with code: $result', + ), + ); + + _startPendingSeekIfAny(playerId); + return; + } + } catch (e, stackTrace) { + if (identical(_activeSeeks[playerId], seek)) { + _activeSeeks.remove(playerId); + } + + _completeSeekWithError( + seek, + e is PlatformException + ? e + : PlatformException( + code: 'FFI_SEEK_TO_FAILED', + message: 'FFI seekTo failed', + details: e.toString(), + ), + stackTrace, + ); + + _startPendingSeekIfAny(playerId); + } + } + + void _handleSeekCompleted(int playerId) { + final _SeekOperation? completedSeek = _activeSeeks.remove(playerId); + if (completedSeek == null) { + return; + } + + _completeSeek(completedSeek); + _startPendingSeekIfAny(playerId); } - EventChannel _eventChannelFor(int playerId) { - return EventChannel('tizen/video_player/video_events_$playerId'); + void _completeSeek(_SeekOperation seek) { + for (final Completer completer in seek.completers) { + if (!completer.isCompleted) { + completer.complete(); + } + } + } + + void _completeSeekWithError( + _SeekOperation seek, + Object error, [ + StackTrace? stackTrace, + ]) { + for (final Completer completer in seek.completers) { + if (!completer.isCompleted) { + completer.completeError(error, stackTrace); + } + } + } + + void _completeSeeksWithError( + int playerId, + Object error, [ + StackTrace? stackTrace, + ]) { + final _SeekOperation? activeSeek = _activeSeeks.remove(playerId); + if (activeSeek != null) { + _completeSeekWithError(activeSeek, error, stackTrace); + } + + final _SeekOperation? pendingSeek = _pendingSeeks.remove(playerId); + if (pendingSeek != null) { + _completeSeekWithError(pendingSeek, error, stackTrace); + } + } + + void _startPendingSeekIfAny(int playerId) { + if (_activeSeeks.containsKey(playerId)) { + return; + } + + final _SeekOperation? pendingSeek = _pendingSeeks.remove(playerId); + if (pendingSeek != null) { + _startSeek(playerId, pendingSeek.position, pendingSeek.completers); + } } static const Map _videoFormatStringMap = diff --git a/packages/video_player_videohole/lib/video_player.dart b/packages/video_player_videohole/lib/video_player.dart index 23c2a8aeb..19437a7d7 100644 --- a/packages/video_player_videohole/lib/video_player.dart +++ b/packages/video_player_videohole/lib/video_player.dart @@ -371,6 +371,9 @@ class VideoPlayerController extends ValueNotifier { RestoreDataSourceCallback? _onRestoreDataSource; RestoreTimeCallback? _onRestoreTime; + void Function(VideoEvent)? _eventListener; + void Function(Object)? _errorListener; + /// The id of a player that hasn't been initialized. @visibleForTesting static const int kUninitializedPlayerId = -1; @@ -435,7 +438,7 @@ class VideoPlayerController extends ValueNotifier { _creatingCompleter!.complete(null); final Completer initializingCompleter = Completer(); - void eventListener(VideoEvent event) { + _eventListener = (VideoEvent event) { if (_isDisposed) { return; } @@ -509,7 +512,7 @@ class VideoPlayerController extends ValueNotifier { case VideoEventType.unknown: break; } - } + }; if (closedCaptionFile != null) { _closedCaptionFile ??= await closedCaptionFile; @@ -529,7 +532,7 @@ class VideoPlayerController extends ValueNotifier { }); } - void errorListener(Object obj) { + _errorListener = (Object obj) { final PlatformException e = obj as PlatformException; value = VideoPlayerValue.erroneous(e.message!); if (!initializingCompleter.isCompleted) { @@ -537,14 +540,14 @@ class VideoPlayerController extends ValueNotifier { } _timer?.cancel(); _durationTimer?.cancel(); - if (!initializingCompleter.isCompleted) { - initializingCompleter.completeError(obj); - } - } + }; _eventSubscription = _videoPlayerPlatform .videoEventsFor(_playerId) - .listen(eventListener, onError: errorListener); + .listen(_eventListener, onError: _errorListener); + + await _videoPlayerPlatform.prepare(_playerId); + return initializingCompleter.future; } @@ -630,7 +633,7 @@ class VideoPlayerController extends ValueNotifier { return Timer.periodic(const Duration(milliseconds: 500), ( Timer timer, ) async { - if (_isDisposed) { + if (_isDisposed || _isDisposedOrNotInitialized) { return; } final Duration? newPosition = await position; diff --git a/packages/video_player_videohole/lib/video_player_platform_interface.dart b/packages/video_player_videohole/lib/video_player_platform_interface.dart index 9412ed433..0097a179a 100644 --- a/packages/video_player_videohole/lib/video_player_platform_interface.dart +++ b/packages/video_player_videohole/lib/video_player_platform_interface.dart @@ -53,10 +53,24 @@ abstract class VideoPlayerPlatform extends PlatformInterface { } /// Creates an instance of a video player and returns its playerId. + /// + /// For two-phase initialization, this method only creates the player + /// without starting playback preparation. Call [prepare()] separately + /// after setting up event listeners. Future create(DataSource dataSource) { throw UnimplementedError('create() has not been implemented.'); } + /// Prepares the player for playback (two-phase initialization). + /// + /// This method starts the asynchronous preparation for playback. + /// It must be called after [create()] and after setting up event listeners + /// to ensure the initialized event is not missed. + /// + /// For platforms that don't support two-phase initialization, + /// this method is a no-op. + Future prepare(int playerId) async {} + /// Returns a Stream of [VideoEventType]s. Stream videoEventsFor(int playerId) { throw UnimplementedError('videoEventsFor() has not been implemented.'); diff --git a/packages/video_player_videohole/pigeons/messages.dart b/packages/video_player_videohole/pigeons/messages.dart deleted file mode 100644 index 91a400c9f..000000000 --- a/packages/video_player_videohole/pigeons/messages.dart +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:pigeon/pigeon.dart'; - -@ConfigurePigeon( - PigeonOptions( - dartOut: 'lib/src/messages.g.dart', - cppOptions: CppOptions(namespace: 'video_player_videohole_tizen'), - cppHeaderOut: 'tizen/src/messages.h', - cppSourceOut: 'tizen/src/messages.cc', - ), -) -class PlayerMessage { - PlayerMessage(this.playerId); - int playerId; -} - -class LoopingMessage { - LoopingMessage(this.playerId, this.isLooping); - int playerId; - bool isLooping; -} - -class VolumeMessage { - VolumeMessage(this.playerId, this.volume); - int playerId; - double volume; -} - -class PlaybackSpeedMessage { - PlaybackSpeedMessage(this.playerId, this.speed); - int playerId; - double speed; -} - -class TrackMessage { - TrackMessage(this.playerId, this.tracks); - int playerId; - List?> tracks; -} - -class TrackTypeMessage { - TrackTypeMessage(this.playerId, this.trackType); - int playerId; - String trackType; -} - -class SelectedTracksMessage { - SelectedTracksMessage(this.playerId, this.trackId, this.trackType); - int playerId; - int trackId; - String trackType; -} - -class PositionMessage { - PositionMessage(this.playerId, this.position); - int playerId; - int position; -} - -class CreateMessage { - CreateMessage(); - String? asset; - String? uri; - String? packageName; - String? formatHint; - Map? httpHeaders; - Map? drmConfigs; - Map? playerOptions; - Map? windowGeometry; -} - -class MixWithOthersMessage { - MixWithOthersMessage(this.mixWithOthers); - bool mixWithOthers; -} - -class GeometryMessage { - GeometryMessage(this.playerId, this.x, this.y, this.width, this.height); - int playerId; - int x; - int y; - int width; - int height; -} - -class DurationMessage { - DurationMessage(this.playerId); - int playerId; - List? durationRange; -} - -class RotationMessage { - RotationMessage(this.playerId, this.rotation); - int playerId; - int rotation; -} - -@HostApi() -abstract class VideoPlayerVideoholeApi { - void initialize(); - PlayerMessage create(CreateMessage msg); - void dispose(PlayerMessage msg); - void setLooping(LoopingMessage msg); - void setVolume(VolumeMessage msg); - void setPlaybackSpeed(PlaybackSpeedMessage msg); - void play(PlayerMessage msg); - bool setDeactivate(PlayerMessage msg); - bool setActivate(PlayerMessage msg); - TrackMessage track(TrackTypeMessage msg); - bool setTrackSelection(SelectedTracksMessage msg); - PositionMessage position(PlayerMessage msg); - @async - void seekTo(PositionMessage msg); - void pause(PlayerMessage msg); - void setMixWithOthers(MixWithOthersMessage msg); - void setDisplayGeometry(GeometryMessage msg); - DurationMessage duration(PlayerMessage msg); - void suspend(int playerId); - void restore(int playerId, CreateMessage? msg, int resumeTime); - bool setDisplayRotate(RotationMessage msg); -} diff --git a/packages/video_player_videohole/pubspec.yaml b/packages/video_player_videohole/pubspec.yaml index c50810b28..a18807eb5 100644 --- a/packages/video_player_videohole/pubspec.yaml +++ b/packages/video_player_videohole/pubspec.yaml @@ -2,7 +2,7 @@ name: video_player_videohole description: Flutter plugin for displaying inline video on Tizen TV devices. homepage: https://github.com/flutter-tizen/plugins repository: https://github.com/flutter-tizen/plugins/tree/main/packages/video_player_videohole -version: 0.5.11 +version: 0.6.0 environment: sdk: ">=3.1.0 <4.0.0" @@ -16,13 +16,12 @@ flutter: fileName: video_player_tizen_plugin.h dependencies: + ffi: ^2.0.0 flutter: sdk: flutter html: ^0.15.0 plugin_platform_interface: ^2.1.0 - tizen_window_manager: ^0.2.0 dev_dependencies: flutter_test: sdk: flutter - pigeon: ^10.0.0 diff --git a/packages/video_player_videohole/tizen/src/drm_manager.cc b/packages/video_player_videohole/tizen/src/drm_manager.cc index 3547b6cbd..56af62eac 100644 --- a/packages/video_player_videohole/tizen/src/drm_manager.cc +++ b/packages/video_player_videohole/tizen/src/drm_manager.cc @@ -116,7 +116,7 @@ bool DrmManager::SetChallenge(const std::string &media_url, return DM_ERROR_NONE == SetChallenge(media_url); } -void DrmManager::ReleaseDrmSession() { +void DrmManager::StopDrmSession() { if (drm_session_ == nullptr) { LOG_ERROR("[DrmManager] Already released."); return; @@ -138,8 +138,15 @@ void DrmManager::ReleaseDrmSession() { LOG_ERROR("[DrmManager] Fail to set finalize to drm session: %s", get_error_message(ret)); } +} + +void DrmManager::ReleaseDrmSession() { + if (drm_session_ == nullptr) { + LOG_ERROR("[DrmManager] Already released."); + return; + } - ret = DMGRReleaseDRMSession(drm_session_); + int ret = DMGRReleaseDRMSession(drm_session_); if (ret != DM_ERROR_NONE) { LOG_ERROR("[DrmManager] Fail to release drm session: %s", get_error_message(ret)); diff --git a/packages/video_player_videohole/tizen/src/drm_manager.h b/packages/video_player_videohole/tizen/src/drm_manager.h index 3c820a0a0..5881e54b6 100644 --- a/packages/video_player_videohole/tizen/src/drm_manager.h +++ b/packages/video_player_videohole/tizen/src/drm_manager.h @@ -34,6 +34,7 @@ class DrmManager { unsigned char *pssh_data, void *user_data); int UpdatePsshData(const void *data, int length); void ReleaseDrmSession(); + void StopDrmSession(); private: struct DataForLicenseProcess { diff --git a/packages/video_player_videohole/tizen/src/ecore_wl2_window_proxy.cc b/packages/video_player_videohole/tizen/src/ecore_wl2_window_proxy.cc new file mode 100644 index 000000000..ea6f0ef98 --- /dev/null +++ b/packages/video_player_videohole/tizen/src/ecore_wl2_window_proxy.cc @@ -0,0 +1,44 @@ +// Copyright 2023 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ecore_wl2_window_proxy.h" + +#include + +#include "log.h" + +typedef void (*FuncEcoreWl2WindowGeometryGet)(void *window, int *x, int *y, + int *width, int *height); + +EcoreWl2WindowProxy::EcoreWl2WindowProxy() { + ecore_wl2_window_handle_ = dlopen("libecore_wl2.so.1", RTLD_LAZY); + if (ecore_wl2_window_handle_ == nullptr) { + LOG_ERROR("Failed to open ecore wl2."); + } +} + +void EcoreWl2WindowProxy::ecore_wl2_window_geometry_get(void *window, int *x, + int *y, int *width, + int *height) { + if (!ecore_wl2_window_handle_) { + LOG_ERROR("ecore_wl2_window_handle_ not valid"); + return; + } + + FuncEcoreWl2WindowGeometryGet ecore_wl2_window_geometry_get = + reinterpret_cast( + dlsym(ecore_wl2_window_handle_, "ecore_wl2_window_geometry_get")); + if (!ecore_wl2_window_geometry_get) { + LOG_ERROR("Fail to find ecore_wl2_window_geometry_get."); + return; + } + ecore_wl2_window_geometry_get(window, x, y, width, height); +} + +EcoreWl2WindowProxy::~EcoreWl2WindowProxy() { + if (ecore_wl2_window_handle_) { + dlclose(ecore_wl2_window_handle_); + ecore_wl2_window_handle_ = nullptr; + } +} diff --git a/packages/video_player_videohole/tizen/src/ecore_wl2_window_proxy.h b/packages/video_player_videohole/tizen/src/ecore_wl2_window_proxy.h new file mode 100644 index 000000000..f8545a457 --- /dev/null +++ b/packages/video_player_videohole/tizen/src/ecore_wl2_window_proxy.h @@ -0,0 +1,19 @@ +// Copyright 2022 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_PLUGIN_ECORE_WL2_WINDOW_PROXY_H_ +#define FLUTTER_PLUGIN_ECORE_WL2_WINDOW_PROXY_H_ + +class EcoreWl2WindowProxy { + public: + EcoreWl2WindowProxy(); + ~EcoreWl2WindowProxy(); + void ecore_wl2_window_geometry_get(void *window, int *x, int *y, int *width, + int *height); + + private: + void *ecore_wl2_window_handle_ = nullptr; +}; + +#endif // FLUTTER_PLUGIN_ECORE_WL2_WINDOW_PROXY_H_ diff --git a/packages/video_player_videohole/tizen/src/ffi_messages.cc b/packages/video_player_videohole/tizen/src/ffi_messages.cc new file mode 100644 index 000000000..f6242936e --- /dev/null +++ b/packages/video_player_videohole/tizen/src/ffi_messages.cc @@ -0,0 +1,444 @@ +// Copyright 2026 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ffi_messages.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../third_party/nlohmann_json/json.hpp" +#include "log.h" +#include "media_player.h" +#include "video_player.h" +#include "video_player_options.h" + +using nlohmann::json; + +namespace video_player_videohole_tizen { + +static std::map> g_players; +static std::shared_mutex g_players_mutex; +static FlutterDesktopPluginRegistrarRef g_registrar_ref = nullptr; +static flutter::PluginRegistrar* g_plugin_registrar = nullptr; +static VideoPlayerOptions g_options; +static bool g_dart_api_dl_initialized = false; + +static std::shared_ptr GetPlayer(int64_t player_id) { + std::shared_lock lock(g_players_mutex); + auto iter = g_players.find(player_id); + if (iter != g_players.end()) { + return iter->second; + } + return nullptr; +} + +static flutter::EncodableValue EncodableValueFromJson(const json& j) { + if (j.is_null()) { + return flutter::EncodableValue(); + } else if (j.is_boolean()) { + return flutter::EncodableValue(j.get()); + } else if (j.is_number_integer()) { + return flutter::EncodableValue(static_cast(j.get())); + } else if (j.is_number_float()) { + return flutter::EncodableValue(j.get()); + } else if (j.is_string()) { + return flutter::EncodableValue(j.get()); + } else if (j.is_array()) { + flutter::EncodableList list; + for (const auto& item : j) { + list.push_back(EncodableValueFromJson(item)); + } + return flutter::EncodableValue(list); + } else if (j.is_object()) { + flutter::EncodableMap map; + for (auto& [key, value] : j.items()) { + map[flutter::EncodableValue(key)] = EncodableValueFromJson(value); + } + return flutter::EncodableValue(map); + } + return flutter::EncodableValue(); +} + +static flutter::EncodableMap ParseJsonMap(const std::string& json_str) { + flutter::EncodableMap result; + if (json_str.empty() || json_str == "{}") { + return result; + } + try { + json j = json::parse(json_str); + if (j.is_object()) { + for (auto& [key, value] : j.items()) { + result[flutter::EncodableValue(key)] = EncodableValueFromJson(value); + } + } + } catch (const json::parse_error& e) { + LOG_ERROR("[ParseJsonMap] JSON parse error: %s", e.what()); + } + return result; +} + +CreateMessage ParseCreateMessage(const std::string& json_str) { + CreateMessage msg; + if (json_str.empty() || json_str == "{}") { + return msg; + } + try { + json j = json::parse(json_str); + if (j.contains("uri") && !j["uri"].is_null()) { + msg.set_uri(j["uri"].get()); + } + if (j.contains("asset") && !j["asset"].is_null()) { + msg.set_asset(j["asset"].get()); + } + if (j.contains("packageName") && !j["packageName"].is_null()) { + msg.set_package_name(j["packageName"].get()); + } + if (j.contains("formatHint") && !j["formatHint"].is_null()) { + msg.set_format_hint(j["formatHint"].get()); + } + if (j.contains("httpHeaders") && j["httpHeaders"].is_object()) { + msg.set_http_headers(ParseJsonMap(j["httpHeaders"].dump())); + } + if (j.contains("playerOptions") && j["playerOptions"].is_object()) { + msg.set_player_options(ParseJsonMap(j["playerOptions"].dump())); + } + if (j.contains("drmConfigs") && j["drmConfigs"].is_object()) { + msg.set_drm_configs(ParseJsonMap(j["drmConfigs"].dump())); + } + } catch (const json::parse_error& e) { + LOG_ERROR("[ParseCreateMessage] JSON parse error: %s", e.what()); + } + return msg; +} + +void ffi_set_plugin_registrar(FlutterDesktopPluginRegistrarRef registrar_ref, + flutter::PluginRegistrar* registrar) { + g_registrar_ref = registrar_ref; + g_plugin_registrar = registrar; +} + +} // namespace video_player_videohole_tizen + +using video_player_videohole_tizen::CreateMessage; +using video_player_videohole_tizen::VideoPlayer; + +extern "C" { + +int ffi_initialize() { + std::unique_lock lock( + video_player_videohole_tizen::g_players_mutex); + video_player_videohole_tizen::g_players.clear(); + return 0; +} + +void ffi_dispose_all_players() { + using namespace video_player_videohole_tizen; + + std::vector> players_to_dispose; + { + std::unique_lock lock(g_players_mutex); + for (auto& [id, player] : g_players) { + players_to_dispose.push_back(player); + } + g_players.clear(); + } + + for (auto& player : players_to_dispose) { + player->Dispose(); + } + + UnregisterDartPort(); + + g_registrar_ref = nullptr; + g_plugin_registrar = nullptr; + + LOG_INFO( + "[FFI] All players disposed, Dart port unregistered, registrar refs " + "cleared"); +} + +int64_t ffi_create(const char* create_message_json) { + using namespace video_player_videohole_tizen; + if (g_registrar_ref == nullptr || g_plugin_registrar == nullptr) { + return -1; + } + FlutterDesktopViewRef view = + FlutterDesktopPluginRegistrarGetView(g_registrar_ref); + if (!view) { + return -1; + } + CreateMessage msg; + if (create_message_json != nullptr && strlen(create_message_json) > 0) { + msg = ParseCreateMessage(std::string(create_message_json)); + } + std::string uri; + if (msg.asset() && !msg.asset()->empty()) { + char* res_path = app_get_resource_path(); + if (res_path) { + uri = uri + res_path + "flutter_assets/" + *msg.asset(); + free(res_path); + } else { + return -1; + } + } else if (msg.uri() && !msg.uri()->empty()) { + uri = *msg.uri(); + } else { + return -1; + } + auto player = std::make_unique( + g_plugin_registrar->messenger(), view); + int64_t player_id = player->Create(uri, msg); + if (player_id == -1) { + return -1; + } + std::unique_lock lock(g_players_mutex); + g_players[player_id] = std::move(player); + return player_id; +} + +int ffi_prepare(int64_t player_id) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player) { + return -1; + } + return player->Prepare(); +} + +int ffi_dispose(int64_t player_id) { + using namespace video_player_videohole_tizen; + std::shared_ptr player; + + { + std::unique_lock lock(g_players_mutex); + auto iter = g_players.find(player_id); + if (iter != g_players.end()) { + player = iter->second; + g_players.erase(iter); + } + } + + if (player) { + player->Dispose(); + } + + return 0; +} + +int ffi_play(int64_t player_id) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player) { + return -1; + } + return player->Play() ? 0 : -1; +} + +int ffi_pause(int64_t player_id) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player) { + return -1; + } + return player->Pause() ? 0 : -1; +} + +int ffi_seek_to(int64_t player_id, int64_t position_ms) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player) { + return -1; + } + return player->SeekTo( + position_ms, + video_player_videohole_tizen::VideoPlayer::SeekCompletedCallback()) + ? 0 + : -1; +} + +int64_t ffi_get_position(int64_t player_id) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player) { + return -1; + } + return player->GetPosition(); +} + +const char* ffi_get_duration(int64_t player_id) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player) { + return strdup("-1"); + } + auto duration_pair = player->GetDuration(); + std::string duration_json = "{\"playerId\":" + std::to_string(player_id) + + ",\"durationRange\":[" + + std::to_string(duration_pair.first) + "," + + std::to_string(duration_pair.second) + "]}"; + return strdup(duration_json.c_str()); +} + +int ffi_set_volume(int64_t player_id, double volume) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player) { + return -1; + } + return player->SetVolume(volume) ? 0 : -1; +} + +int ffi_set_playback_speed(int64_t player_id, double speed) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player) { + return -1; + } + return player->SetPlaybackSpeed(speed) ? 0 : -1; +} + +int ffi_set_looping(int64_t player_id, bool is_looping) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player) { + return -1; + } + return player->SetLooping(is_looping) ? 0 : -1; +} + +const char* ffi_get_track_info(int64_t player_id, const char* track_type) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player || track_type == nullptr) { + return nullptr; + } + auto tracks = player->GetTrackInfo(std::string(track_type)); + json j; + j["playerId"] = player_id; + j["tracks"] = json::array(); + for (const auto& track_value : tracks) { + const auto& track_map = std::get(track_value); + json track_j = json::object(); + for (const auto& [key, value] : track_map) { + const std::string* key_str = std::get_if(&key); + if (!key_str) continue; + if (std::holds_alternative(value)) { + track_j[*key_str] = std::get(value); + } else if (std::holds_alternative(value)) { + track_j[*key_str] = std::get(value); + } else if (std::holds_alternative(value)) { + track_j[*key_str] = std::get(value); + } else if (std::holds_alternative(value)) { + track_j[*key_str] = std::get(value); + } else if (std::holds_alternative(value)) { + track_j[*key_str] = std::get(value); + } + } + j["tracks"].push_back(track_j); + } + return strdup(j.dump().c_str()); +} + +int ffi_set_track_selection(int64_t player_id, int64_t track_id, + const char* track_type) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player || track_type == nullptr) { + return -1; + } + return player->SetTrackSelection(track_id, std::string(track_type)) ? 0 : -1; +} + +int ffi_set_display_geometry(int64_t player_id, int32_t x, int32_t y, + int32_t width, int32_t height) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player) { + return -1; + } + player->SetDisplayRoi(x, y, width, height); + return 0; +} + +int ffi_set_display_rotate(int64_t player_id, int32_t rotation) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player) { + return -1; + } + return player->SetDisplayRotate(rotation) ? 0 : -1; +} + +int ffi_suspend(int64_t player_id) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player) { + return -1; + } + return player->Suspend() ? 0 : -1; +} + +int ffi_restore(int64_t player_id, const char* create_message_json, + int64_t resume_time) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player) { + return -1; + } + CreateMessage msg; + if (create_message_json != nullptr && strlen(create_message_json) > 0) { + msg = video_player_videohole_tizen::ParseCreateMessage( + std::string(create_message_json)); + } + return player->Restore(&msg, resume_time) ? 0 : -1; +} + +int ffi_set_activate(int64_t player_id) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player) { + return -1; + } + return player->Activate() ? 0 : -1; +} + +int ffi_set_deactivate(int64_t player_id) { + auto player = video_player_videohole_tizen::GetPlayer(player_id); + if (!player) { + return -1; + } + return player->Deactivate() ? 0 : -1; +} + +int ffi_set_mix_with_others(bool mix_with_others) { + video_player_videohole_tizen::g_options.SetMixWithOthers(mix_with_others); + return 0; +} + +int ffi_initialize_api_dl(void* data) { + if (!video_player_videohole_tizen::g_dart_api_dl_initialized) { + if (Dart_InitializeApiDL(data) == 0) { + video_player_videohole_tizen::g_dart_api_dl_initialized = true; + return 0; + } + return -1; + } + return 0; +} + +void ffi_free_string(char* ptr) { + if (ptr != nullptr) { + free(ptr); + } +} + +void ffi_register_dart_port(int64_t port) { + video_player_videohole_tizen::RegisterDartPort(port); +} + +void ffi_unregister_dart_port() { + video_player_videohole_tizen::UnregisterDartPort(); +} + +} // extern "C" diff --git a/packages/video_player_videohole/tizen/src/ffi_messages.h b/packages/video_player_videohole/tizen/src/ffi_messages.h new file mode 100644 index 000000000..ad1a3e851 --- /dev/null +++ b/packages/video_player_videohole/tizen/src/ffi_messages.h @@ -0,0 +1,124 @@ +// Copyright 2026 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FFI_MESSAGES_H_ +#define FFI_MESSAGES_H_ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "video_player_options.h" +#include "video_player_tizen_plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FLUTTER_PLUGIN_EXPORT int ffi_initialize(); +FLUTTER_PLUGIN_EXPORT int64_t ffi_create(const char* create_message_json); +FLUTTER_PLUGIN_EXPORT int ffi_prepare(int64_t player_id); +FLUTTER_PLUGIN_EXPORT int ffi_dispose(int64_t player_id); +FLUTTER_PLUGIN_EXPORT int ffi_play(int64_t player_id); +FLUTTER_PLUGIN_EXPORT int ffi_pause(int64_t player_id); +FLUTTER_PLUGIN_EXPORT int ffi_seek_to(int64_t player_id, int64_t position_ms); +FLUTTER_PLUGIN_EXPORT int64_t ffi_get_position(int64_t player_id); +FLUTTER_PLUGIN_EXPORT const char* ffi_get_duration(int64_t player_id); +FLUTTER_PLUGIN_EXPORT int ffi_set_volume(int64_t player_id, double volume); +FLUTTER_PLUGIN_EXPORT int ffi_set_playback_speed(int64_t player_id, + double speed); +FLUTTER_PLUGIN_EXPORT int ffi_set_looping(int64_t player_id, bool is_looping); +FLUTTER_PLUGIN_EXPORT const char* ffi_get_track_info(int64_t player_id, + const char* track_type); +FLUTTER_PLUGIN_EXPORT int ffi_set_track_selection(int64_t player_id, + int64_t track_id, + const char* track_type); +FLUTTER_PLUGIN_EXPORT int ffi_set_display_geometry(int64_t player_id, int32_t x, + int32_t y, int32_t width, + int32_t height); +FLUTTER_PLUGIN_EXPORT int ffi_set_display_rotate(int64_t player_id, + int32_t rotation); +FLUTTER_PLUGIN_EXPORT int ffi_suspend(int64_t player_id); +FLUTTER_PLUGIN_EXPORT int ffi_restore(int64_t player_id, + const char* create_message_json, + int64_t resume_time); +FLUTTER_PLUGIN_EXPORT int ffi_set_activate(int64_t player_id); +FLUTTER_PLUGIN_EXPORT int ffi_set_deactivate(int64_t player_id); +FLUTTER_PLUGIN_EXPORT int ffi_set_mix_with_others(bool mix_with_others); + +void ffi_dispose_all_players(); + +FLUTTER_PLUGIN_EXPORT int ffi_initialize_api_dl(void* data); +FLUTTER_PLUGIN_EXPORT void ffi_register_dart_port(int64_t port); +FLUTTER_PLUGIN_EXPORT void ffi_unregister_dart_port(); + +FLUTTER_PLUGIN_EXPORT void ffi_free_string(char* ptr); + +#ifdef __cplusplus +} // extern "C" + +namespace video_player_videohole_tizen { + +class CreateMessage { + public: + CreateMessage() = default; + + const std::optional& asset() const { return asset_; } + void set_asset(const std::string& value) { asset_ = value; } + + const std::optional& uri() const { return uri_; } + void set_uri(const std::string& value) { uri_ = value; } + + const std::optional& package_name() const { + return package_name_; + } + void set_package_name(const std::string& value) { package_name_ = value; } + + const std::optional& format_hint() const { return format_hint_; } + void set_format_hint(const std::string& value) { format_hint_ = value; } + + const flutter::EncodableMap& http_headers() const { return http_headers_; } + void set_http_headers(const flutter::EncodableMap& value) { + http_headers_ = value; + } + + const flutter::EncodableMap& drm_configs() const { return drm_configs_; } + void set_drm_configs(const flutter::EncodableMap& value) { + drm_configs_ = value; + } + + const flutter::EncodableMap& player_options() const { + return player_options_; + } + void set_player_options(const flutter::EncodableMap& value) { + player_options_ = value; + } + + private: + std::optional asset_; + std::optional uri_; + std::optional package_name_; + std::optional format_hint_; + flutter::EncodableMap http_headers_; + flutter::EncodableMap drm_configs_; + flutter::EncodableMap player_options_; +}; + +void ffi_set_plugin_registrar(FlutterDesktopPluginRegistrarRef registrar_ref, + flutter::PluginRegistrar* registrar); + +} // namespace video_player_videohole_tizen +#endif // __cplusplus + +#endif // FFI_MESSAGES_H_ diff --git a/packages/video_player_videohole/tizen/src/media_player.cc b/packages/video_player_videohole/tizen/src/media_player.cc index 8c5a7d5bc..4a74c06b3 100644 --- a/packages/video_player_videohole/tizen/src/media_player.cc +++ b/packages/video_player_videohole/tizen/src/media_player.cc @@ -5,6 +5,7 @@ #include "media_player.h" #include +#include #include @@ -46,31 +47,30 @@ MediaPlayer::MediaPlayer(flutter::BinaryMessenger *messenger, device_proxy_ = std::make_unique(); } -MediaPlayer::~MediaPlayer() { - if (player_) { - player_stop(player_); - player_unprepare(player_); - player_unset_buffering_cb(player_); - player_unset_completed_cb(player_); - player_unset_interrupted_cb(player_); - player_unset_error_cb(player_); - player_unset_subtitle_updated_cb(player_); - player_destroy(player_); - player_ = nullptr; - } - if (drm_manager_) { - drm_manager_->ReleaseDrmSession(); - } -} +MediaPlayer::~MediaPlayer() { Dispose(); } + +static int64_t player_id_counter = 1; int64_t MediaPlayer::Create(const std::string &uri, - const CreateMessage &create_message) { - LOG_INFO("[MediaPlayer] uri: %s.", uri.c_str()); + const CreateMessage &create_message, + bool reuse_existing_id) { + LOG_INFO("[MediaPlayer] Create: uri=%s, reuse_existing_id=%d", uri.c_str(), + reuse_existing_id ? 1 : 0); if (uri.empty()) { LOG_ERROR("[MediaPlayer] The uri must not be empty."); return -1; } + + if (!reuse_existing_id || player_id_ <= 0) { + player_id_ = player_id_counter++; + LOG_INFO("[MediaPlayer] Allocated new player_id=%lld", + static_cast(player_id_)); + } else { + LOG_INFO("[MediaPlayer] Reusing existing player_id=%lld", + static_cast(player_id_)); + } + url_ = uri; create_message_ = create_message; @@ -81,7 +81,7 @@ int64_t MediaPlayer::Create(const std::string &uri, return -1; } - std::string cookie = flutter_common::GetValue(create_message.http_headers(), + std::string cookie = flutter_common::GetValue(&create_message.http_headers(), "Cookie", std::string()); if (!cookie.empty()) { int ret = @@ -92,7 +92,7 @@ int64_t MediaPlayer::Create(const std::string &uri, } } std::string user_agent = flutter_common::GetValue( - create_message.http_headers(), "User-Agent", std::string()); + &create_message.http_headers(), "User-Agent", std::string()); if (!user_agent.empty()) { int ret = player_set_streaming_user_agent(player_, user_agent.c_str(), user_agent.size()); @@ -102,10 +102,10 @@ int64_t MediaPlayer::Create(const std::string &uri, } } - int64_t drm_type = - flutter_common::GetValue(create_message.drm_configs(), "drmType", 0); + int64_t drm_type = flutter_common::GetValue(&create_message.drm_configs(), + "drmType", (int64_t)0); std::string license_server_url = flutter_common::GetValue( - create_message.drm_configs(), "licenseServerUrl", std::string()); + &create_message.drm_configs(), "licenseServerUrl", std::string()); if (drm_type != 0) { if (!SetDrm(uri, drm_type, license_server_url)) { LOG_ERROR("[MediaPlayer] Failed to set drm."); @@ -170,19 +170,43 @@ int64_t MediaPlayer::Create(const std::string &uri, return -1; } - ret = player_prepare_async(player_, OnPrepared, this); + return player_id_; +} + +int MediaPlayer::Prepare() { + LOG_INFO("[MediaPlayer] Prepare() called for player_id=%lld", + static_cast(player_id_)); + + if (!player_) { + LOG_ERROR("[MediaPlayer] Player not created."); + return -1; + } + + int ret = player_prepare_async(player_, OnPrepared, this); if (ret != PLAYER_ERROR_NONE) { LOG_ERROR("[MediaPlayer] player_prepare_async failed : %s.", get_error_message(ret)); return -1; } - return SetUpEventChannel(); + return 0; } void MediaPlayer::Dispose() { - LOG_INFO("[MediaPlayer] Disposing."); - ClearUpEventChannel(); + MarkDisposed(); + + if (!player_) { + return; + } + LOG_INFO("[MediaPlayer] Player disposing."); + + player_unset_buffering_cb(player_); + player_unset_completed_cb(player_); + player_unset_interrupted_cb(player_); + player_unset_error_cb(player_); + player_unset_subtitle_updated_cb(player_); + + StopAndDestroy(); } void MediaPlayer::SetDisplayRoi(int32_t x, int32_t y, int32_t width, @@ -204,7 +228,9 @@ bool MediaPlayer::Play() { player_state_e state = PLAYER_STATE_NONE; int ret = player_get_state(player_, &state); if (ret != PLAYER_ERROR_NONE) { - LOG_ERROR("[MediaPlayer] Unable to get player state."); + LOG_ERROR("[MediaPlayer] Unable to get player state: %s.", + get_error_message(ret)); + return false; } if (state == PLAYER_STATE_NONE || state == PLAYER_STATE_IDLE) { LOG_ERROR("[MediaPlayer] Player not ready."); @@ -212,13 +238,15 @@ bool MediaPlayer::Play() { } if (state == PLAYER_STATE_PLAYING) { LOG_INFO("[MediaPlayer] Player already playing."); - return false; + return true; } + ret = player_start(player_); if (ret != PLAYER_ERROR_NONE) { LOG_ERROR("[MediaPlayer] player_start failed: %s.", get_error_message(ret)); return false; } + SendIsPlayingState(true); return true; } @@ -236,8 +264,8 @@ bool MediaPlayer::Pause() { return false; } if (state != PLAYER_STATE_PLAYING) { - LOG_INFO("[MediaPlayer] Player not playing."); - return false; + LOG_INFO("[MediaPlayer] Player already not playing (state=%d).", state); + return true; } ret = player_pause(player_); if (ret != PLAYER_ERROR_NONE) { @@ -287,11 +315,19 @@ bool MediaPlayer::SetPlaybackSpeed(double speed) { bool MediaPlayer::SeekTo(int64_t position, SeekCompletedCallback callback) { LOG_INFO("[MediaPlayer] position: %lld.", position); + if (is_seeking_) { + LOG_ERROR("[MediaPlayer] Seek is already in progress."); + return false; + } + on_seek_completed_ = std::move(callback); + is_seeking_ = true; + int ret = player_set_play_position(player_, position, true, OnSeekCompleted, this); if (ret != PLAYER_ERROR_NONE) { on_seek_completed_ = nullptr; + is_seeking_ = false; LOG_ERROR("[MediaPlayer] player_set_play_position failed: %s.", get_error_message(ret)); return false; @@ -300,10 +336,15 @@ bool MediaPlayer::SeekTo(int64_t position, SeekCompletedCallback callback) { } int64_t MediaPlayer::GetPosition() { + if (!player_) { + LOG_ERROR("[MediaPlayer] player_ is null, cannot get position."); + return -1; + } + int position = 0; int ret = player_get_play_position(player_, &position); if (ret != PLAYER_ERROR_NONE) { - LOG_ERROR("[MediaPlayer] player_get_play_position failed: %s.", + LOG_DEBUG("[MediaPlayer] player_get_play_position failed: %s.", get_error_message(ret)); } LOG_DEBUG("[MediaPlayer] Video current position : %d.", position); @@ -371,26 +412,13 @@ bool MediaPlayer::SetDisplay() { return false; } - const flutter::EncodableMap *window_geometry = - create_message_.window_geometry(); - if (!window_geometry) { - LOG_ERROR("[MediaPlayer] Window geometry is missing."); - return false; - } - int32_t x = flutter_common::GetValue(window_geometry, "x", 0); - int32_t y = flutter_common::GetValue(window_geometry, "y", 0); - int32_t width = flutter_common::GetValue(window_geometry, "width", 0); - int32_t height = flutter_common::GetValue(window_geometry, "height", 0); - if (width <= 0 || height <= 0) { - LOG_ERROR( - "[MediaPlayer] Invalid window geometry size: width[%d], height[%d].", - width, height); - return false; - } - LOG_INFO( - "[MediaPlayer] Window geometry: x[%d], y[%d], width[%d], height[%d].", x, - y, width, height); - + int x = 0, y = 0, width = 0, height = 0; + // TODO(JYY): ecore_wl2 APIs are not thread-safe. After the FFI migration, + // this display setup path may run on the flutter UI thread instead of the + // previous platform main thread. Revisit this when migrating the display + // handling from ecore to Glib. + ecore_wl2_window_proxy_->ecore_wl2_window_geometry_get(native_window, &x, &y, + &width, &height); int ret = media_player_proxy_->player_set_ecore_wl_display( player_, PLAYER_DISPLAY_TYPE_OVERLAY, native_window, x, y, width, height); if (ret != PLAYER_ERROR_NONE) { @@ -434,6 +462,7 @@ std::pair MediaPlayer::GetLiveDuration() { std::string live_duration_str = ""; char *live_duration_buff = static_cast(malloc(sizeof(char) * 64)); memset(live_duration_buff, 0, sizeof(char) * 64); + int ret = media_player_proxy_->player_get_adaptive_streaming_info( player_, (void *)&live_duration_buff, PLAYER_ADAPTIVE_INFO_LIVE_DURATION); if (ret != PLAYER_ERROR_NONE) { @@ -475,7 +504,9 @@ flutter::EncodableList MediaPlayer::GetTrackInfo(std::string track_type) { get_error_message(ret)); return {}; } + if (track_count <= 0) { + LOG_INFO("[MediaPlayer] No tracks found for type=%d", type); return {}; } @@ -639,7 +670,7 @@ bool MediaPlayer::SetDrm(const std::string &uri, int drm_type, ret = media_player_proxy_->player_set_drm_init_data_cb( player_, OnDrmUpdatePsshData, this); if (ret != PLAYER_ERROR_NONE) { - LOG_ERROR("[MediaPlayer] player_set_drm_init_complete_cb failed : %s.", + LOG_ERROR("[MediaPlayer] player_set_drm_init_data_cb failed : %s.", get_error_message(ret)); return false; } @@ -666,29 +697,37 @@ bool MediaPlayer::StopAndDestroy() { return false; } + bool success = true; is_buffering_ = false; + on_seek_completed_ = nullptr; + is_seeking_ = false; + player_state_e player_state = PLAYER_STATE_NONE; int ret = player_get_state(player_, &player_state); if (ret != PLAYER_ERROR_NONE) { LOG_ERROR("[MediaPlayer] player_get_state failed: %s.", get_error_message(ret)); - return false; + success = false; } - if (player_state == PLAYER_STATE_NONE || player_state == PLAYER_STATE_IDLE) { - LOG_INFO("[MediaPlayer] Player already stop, nothing to do."); - return true; + + if (drm_manager_) { + drm_manager_->StopDrmSession(); } - if (player_stop(player_) != PLAYER_ERROR_NONE) { - LOG_ERROR("[MediaPlayer] Player fail to stop."); - return false; + if (player_state == PLAYER_STATE_PLAYING || + player_state == PLAYER_STATE_PAUSED) { + if (player_stop(player_) != PLAYER_ERROR_NONE) { + LOG_ERROR("[MediaPlayer] Player fail to stop."); + success = false; + } } - if (player_unprepare(player_) != PLAYER_ERROR_NONE) { - LOG_ERROR("[MediaPlayer] Player fail to unprepare."); - return false; + if (player_state != PLAYER_STATE_NONE && player_state != PLAYER_STATE_IDLE) { + if (player_unprepare(player_) != PLAYER_ERROR_NONE) { + LOG_ERROR("[MediaPlayer] Player fail to unprepare."); + success = false; + } } - player_get_state(player_, &player_state); if (drm_manager_) { drm_manager_->ReleaseDrmSession(); @@ -697,11 +736,11 @@ bool MediaPlayer::StopAndDestroy() { if (player_destroy(player_) != PLAYER_ERROR_NONE) { LOG_ERROR("[MediaPlayer] Player fail to destroy."); - return false; + success = false; } player_ = nullptr; - return true; + return success; } bool MediaPlayer::Suspend() { @@ -752,13 +791,13 @@ bool MediaPlayer::Suspend() { LOG_INFO("[MediaPlayer] Player state is not standby: %d, do nothing.", res); } - if (player_state == PLAYER_STATE_IDLE) { + if (player_state == PLAYER_STATE_IDLE || player_state == PLAYER_STATE_READY) { if (!StopAndDestroy()) { LOG_ERROR("[MediaPlayer] Player StopAndDestroy fail."); return false; } LOG_INFO("[MediaPlayer] Player called in IDLE state, so stop the player."); - } else if (player_state != PLAYER_STATE_PAUSED) { + } else if (player_state == PLAYER_STATE_PLAYING) { LOG_INFO("[MediaPlayer] Player calling pause from suspend."); if (!Pause()) { LOG_ERROR( @@ -777,70 +816,25 @@ bool MediaPlayer::Suspend() { bool MediaPlayer::Restore(const CreateMessage *restore_message, int64_t resume_time) { LOG_INFO("[MediaPlayer] Restore is called."); - - player_state_e player_state = PLAYER_STATE_NONE; - if (player_) { - int ret = player_get_state(player_, &player_state); - if (ret != PLAYER_ERROR_NONE || (player_state != PLAYER_STATE_PAUSED && - player_state != PLAYER_STATE_PLAYING)) { - LOG_ERROR( - "[MediaPlayer] Player get state failed or in invalid state[%d].", - player_state); - return false; - } - } - - if (restore_message->uri()) { - LOG_INFO( - "[MediaPlayer] Restore URL is not emptpy, close the existing " - "instance."); - if (player_ && !StopAndDestroy()) { - LOG_ERROR("[MediaPlayer] Player StopAndDestroy fail."); - return false; - } - return RestorePlayer(restore_message, resume_time); - } - - switch (player_state) { - case PLAYER_STATE_NONE: - return RestorePlayer(restore_message, resume_time); - break; - case PLAYER_STATE_PAUSED: - if (pre_state_ == PLAYER_STATE_PLAYING) { - if (!Play()) { - LOG_ERROR("[MediaPlayer] Player play failed."); - return false; - } - } - break; - case PLAYER_STATE_PLAYING: - // might be the case that widget has called - // restore more than once, just ignore. - break; - default: - LOG_INFO( - "[MediaPlayer] Unhandled state, dont know how to process, just " - "return " - "false."); - return false; - } - return true; + return RestorePlayer(restore_message, resume_time); } bool MediaPlayer::RestorePlayer(const CreateMessage *restore_message, int64_t resume_time) { LOG_INFO("[MediaPlayer] RestorePlayer is called."); + if (player_ && !StopAndDestroy()) { + LOG_ERROR("[MediaPlayer] RestorePlayer: StopAndDestroy failed."); + return false; + } + LOG_INFO("[MediaPlayer] RestorePlayer: old player cleaned up."); + if (restore_message->uri()) { LOG_INFO("[MediaPlayer] Player previous url: %s", url_.c_str()); LOG_INFO("[MediaPlayer] Player new url: %s", restore_message->uri()->c_str()); url_ = *restore_message->uri(); create_message_ = *restore_message; - } else { - if (restore_message->window_geometry()) { - create_message_.set_window_geometry(*restore_message->window_geometry()); - } } LOG_INFO("[MediaPlayer] Player previous playing time: %llu ms", @@ -852,12 +846,20 @@ bool MediaPlayer::RestorePlayer(const CreateMessage *restore_message, if (resume_time >= 0) pre_playing_time_ = static_cast(resume_time); is_restored_ = true; - if (Create(url_, create_message_) < 0) { + + if (Create(url_, create_message_, true) < 0) { LOG_ERROR("[MediaPlayer] Fail to create player."); is_restored_ = false; return false; } + LOG_INFO("[MediaPlayer] RestorePlayer: calling Prepare() after Create()."); + if (Prepare() < 0) { + LOG_ERROR("[MediaPlayer] RestorePlayer: Prepare() failed."); + is_restored_ = false; + return false; + } + return true; } @@ -874,8 +876,14 @@ bool MediaPlayer::SetDisplayRotate(int64_t rotation) { } void MediaPlayer::OnRestoreCompleted() { - if (pre_playing_time_ <= 0 || - !SeekTo(pre_playing_time_, [this]() { SendRestored(); })) { + if (pre_playing_time_ <= 0 || !SeekTo(pre_playing_time_, [this]() { + if (pre_state_ == PLAYER_STATE_PLAYING) { + LOG_INFO("[MediaPlayer] Restoring to PLAYING state after seek."); + Play(); + } + SendRestored(); + })) { + if (pre_state_ == PLAYER_STATE_PLAYING) Play(); SendRestored(); } } @@ -884,19 +892,32 @@ void MediaPlayer::OnPrepared(void *user_data) { LOG_INFO("[MediaPlayer] Player prepared."); MediaPlayer *self = static_cast(user_data); - if (!self->is_initialized_) { - self->SendInitialized(); + + if (self->IsDisposed()) { + LOG_DEBUG("[MediaPlayer] OnPrepared: player disposed, dropping callback"); + return; } if (self->is_restored_) { + self->ResetEventDispatchState(); + LOG_INFO("[MediaPlayer] Event dispatch state reset for restored player."); self->OnRestoreCompleted(); } + + if (!self->is_initialized_) { + self->SendInitialized(); + } } void MediaPlayer::OnBuffering(int percent, void *user_data) { LOG_INFO("[MediaPlayer] Buffering percent: %d.", percent); MediaPlayer *self = static_cast(user_data); + + if (self->IsDisposed()) { + return; + } + if (percent == 100) { self->SendBufferingEnd(); self->is_buffering_ = false; @@ -912,16 +933,35 @@ void MediaPlayer::OnSeekCompleted(void *user_data) { LOG_INFO("[MediaPlayer] Seek completed."); MediaPlayer *self = static_cast(user_data); - if (self->on_seek_completed_) { - self->on_seek_completed_(); - self->on_seek_completed_ = nullptr; + + if (self->IsDisposed()) { + LOG_DEBUG( + "[MediaPlayer] OnSeekCompleted: player disposed, dropping callback"); + return; } + + auto on_seek_completed = std::move(self->on_seek_completed_); + self->on_seek_completed_ = nullptr; + self->is_seeking_ = false; + + if (on_seek_completed) { + on_seek_completed(); + } + + self->SendSeekCompleted(); } void MediaPlayer::OnPlayCompleted(void *user_data) { LOG_INFO("[MediaPlayer] Play completed."); MediaPlayer *self = static_cast(user_data); + + if (self->IsDisposed()) { + LOG_DEBUG( + "[MediaPlayer] OnPlayCompleted: player disposed, dropping callback"); + return; + } + self->SendPlayCompleted(); self->Pause(); } @@ -929,6 +969,13 @@ void MediaPlayer::OnPlayCompleted(void *user_data) { void MediaPlayer::OnInterrupted(player_interrupted_code_e code, void *user_data) { MediaPlayer *self = static_cast(user_data); + + if (self->IsDisposed()) { + LOG_DEBUG( + "[MediaPlayer] OnInterrupted: player disposed, dropping callback"); + return; + } + self->SendIsPlayingState(false); LOG_ERROR("[MediaPlayer] Interrupt code: %d.", code); } @@ -938,6 +985,12 @@ void MediaPlayer::OnError(int error_code, void *user_data) { get_error_message(error_code)); MediaPlayer *self = static_cast(user_data); + + if (self->IsDisposed()) { + LOG_DEBUG("[MediaPlayer] OnError: player disposed, dropping callback"); + return; + } + self->SendError("Media Player error", get_error_message(error_code)); } @@ -947,6 +1000,13 @@ void MediaPlayer::OnSubtitleUpdated(unsigned long duration, char *text, text); MediaPlayer *self = static_cast(user_data); + + if (self->IsDisposed()) { + LOG_DEBUG( + "[MediaPlayer] OnSubtitleUpdated: player disposed, dropping callback"); + return; + } + self->SendSubtitleUpdate(duration, std::string(text)); } diff --git a/packages/video_player_videohole/tizen/src/media_player.h b/packages/video_player_videohole/tizen/src/media_player.h index 3a3506c2d..379592d0d 100644 --- a/packages/video_player_videohole/tizen/src/media_player.h +++ b/packages/video_player_videohole/tizen/src/media_player.h @@ -24,8 +24,9 @@ class MediaPlayer : public VideoPlayer { FlutterDesktopViewRef flutter_view); ~MediaPlayer(); - int64_t Create(const std::string &uri, - const CreateMessage &create_message) override; + int64_t Create(const std::string &uri, const CreateMessage &create_message, + bool reuse_existing_id = false) override; + int Prepare() override; void Dispose() override; void SetDisplayRoi(int32_t x, int32_t y, int32_t width, @@ -76,6 +77,7 @@ class MediaPlayer : public VideoPlayer { std::unique_ptr drm_manager_; bool is_buffering_ = false; SeekCompletedCallback on_seek_completed_; + bool is_seeking_ = false; std::unique_ptr device_proxy_ = nullptr; std::string url_; CreateMessage create_message_; diff --git a/packages/video_player_videohole/tizen/src/messages.cc b/packages/video_player_videohole/tizen/src/messages.cc deleted file mode 100644 index fa4c43667..000000000 --- a/packages/video_player_videohole/tizen/src/messages.cc +++ /dev/null @@ -1,1500 +0,0 @@ -// Autogenerated from Pigeon (v10.1.6), do not edit directly. -// See also: https://pub.dev/packages/pigeon - -#undef _HAS_EXCEPTIONS - -#include "messages.h" - -#include -#include -#include -#include - -#include -#include -#include - -namespace video_player_videohole_tizen { -using flutter::BasicMessageChannel; -using flutter::CustomEncodableValue; -using flutter::EncodableList; -using flutter::EncodableMap; -using flutter::EncodableValue; - -// PlayerMessage - -PlayerMessage::PlayerMessage(int64_t player_id) : player_id_(player_id) {} - -int64_t PlayerMessage::player_id() const { return player_id_; } - -void PlayerMessage::set_player_id(int64_t value_arg) { player_id_ = value_arg; } - -EncodableList PlayerMessage::ToEncodableList() const { - EncodableList list; - list.reserve(1); - list.push_back(EncodableValue(player_id_)); - return list; -} - -PlayerMessage PlayerMessage::FromEncodableList(const EncodableList& list) { - PlayerMessage decoded(list[0].LongValue()); - return decoded; -} - -// LoopingMessage - -LoopingMessage::LoopingMessage(int64_t player_id, bool is_looping) - : player_id_(player_id), is_looping_(is_looping) {} - -int64_t LoopingMessage::player_id() const { return player_id_; } - -void LoopingMessage::set_player_id(int64_t value_arg) { - player_id_ = value_arg; -} - -bool LoopingMessage::is_looping() const { return is_looping_; } - -void LoopingMessage::set_is_looping(bool value_arg) { is_looping_ = value_arg; } - -EncodableList LoopingMessage::ToEncodableList() const { - EncodableList list; - list.reserve(2); - list.push_back(EncodableValue(player_id_)); - list.push_back(EncodableValue(is_looping_)); - return list; -} - -LoopingMessage LoopingMessage::FromEncodableList(const EncodableList& list) { - LoopingMessage decoded(list[0].LongValue(), std::get(list[1])); - return decoded; -} - -// VolumeMessage - -VolumeMessage::VolumeMessage(int64_t player_id, double volume) - : player_id_(player_id), volume_(volume) {} - -int64_t VolumeMessage::player_id() const { return player_id_; } - -void VolumeMessage::set_player_id(int64_t value_arg) { player_id_ = value_arg; } - -double VolumeMessage::volume() const { return volume_; } - -void VolumeMessage::set_volume(double value_arg) { volume_ = value_arg; } - -EncodableList VolumeMessage::ToEncodableList() const { - EncodableList list; - list.reserve(2); - list.push_back(EncodableValue(player_id_)); - list.push_back(EncodableValue(volume_)); - return list; -} - -VolumeMessage VolumeMessage::FromEncodableList(const EncodableList& list) { - VolumeMessage decoded(list[0].LongValue(), std::get(list[1])); - return decoded; -} - -// PlaybackSpeedMessage - -PlaybackSpeedMessage::PlaybackSpeedMessage(int64_t player_id, double speed) - : player_id_(player_id), speed_(speed) {} - -int64_t PlaybackSpeedMessage::player_id() const { return player_id_; } - -void PlaybackSpeedMessage::set_player_id(int64_t value_arg) { - player_id_ = value_arg; -} - -double PlaybackSpeedMessage::speed() const { return speed_; } - -void PlaybackSpeedMessage::set_speed(double value_arg) { speed_ = value_arg; } - -EncodableList PlaybackSpeedMessage::ToEncodableList() const { - EncodableList list; - list.reserve(2); - list.push_back(EncodableValue(player_id_)); - list.push_back(EncodableValue(speed_)); - return list; -} - -PlaybackSpeedMessage PlaybackSpeedMessage::FromEncodableList( - const EncodableList& list) { - PlaybackSpeedMessage decoded(list[0].LongValue(), std::get(list[1])); - return decoded; -} - -// TrackMessage - -TrackMessage::TrackMessage(int64_t player_id, const EncodableList& tracks) - : player_id_(player_id), tracks_(tracks) {} - -int64_t TrackMessage::player_id() const { return player_id_; } - -void TrackMessage::set_player_id(int64_t value_arg) { player_id_ = value_arg; } - -const EncodableList& TrackMessage::tracks() const { return tracks_; } - -void TrackMessage::set_tracks(const EncodableList& value_arg) { - tracks_ = value_arg; -} - -EncodableList TrackMessage::ToEncodableList() const { - EncodableList list; - list.reserve(2); - list.push_back(EncodableValue(player_id_)); - list.push_back(EncodableValue(tracks_)); - return list; -} - -TrackMessage TrackMessage::FromEncodableList(const EncodableList& list) { - TrackMessage decoded(list[0].LongValue(), std::get(list[1])); - return decoded; -} - -// TrackTypeMessage - -TrackTypeMessage::TrackTypeMessage(int64_t player_id, - const std::string& track_type) - : player_id_(player_id), track_type_(track_type) {} - -int64_t TrackTypeMessage::player_id() const { return player_id_; } - -void TrackTypeMessage::set_player_id(int64_t value_arg) { - player_id_ = value_arg; -} - -const std::string& TrackTypeMessage::track_type() const { return track_type_; } - -void TrackTypeMessage::set_track_type(std::string_view value_arg) { - track_type_ = value_arg; -} - -EncodableList TrackTypeMessage::ToEncodableList() const { - EncodableList list; - list.reserve(2); - list.push_back(EncodableValue(player_id_)); - list.push_back(EncodableValue(track_type_)); - return list; -} - -TrackTypeMessage TrackTypeMessage::FromEncodableList( - const EncodableList& list) { - TrackTypeMessage decoded(list[0].LongValue(), std::get(list[1])); - return decoded; -} - -// SelectedTracksMessage - -SelectedTracksMessage::SelectedTracksMessage(int64_t player_id, - int64_t track_id, - const std::string& track_type) - : player_id_(player_id), track_id_(track_id), track_type_(track_type) {} - -int64_t SelectedTracksMessage::player_id() const { return player_id_; } - -void SelectedTracksMessage::set_player_id(int64_t value_arg) { - player_id_ = value_arg; -} - -int64_t SelectedTracksMessage::track_id() const { return track_id_; } - -void SelectedTracksMessage::set_track_id(int64_t value_arg) { - track_id_ = value_arg; -} - -const std::string& SelectedTracksMessage::track_type() const { - return track_type_; -} - -void SelectedTracksMessage::set_track_type(std::string_view value_arg) { - track_type_ = value_arg; -} - -EncodableList SelectedTracksMessage::ToEncodableList() const { - EncodableList list; - list.reserve(3); - list.push_back(EncodableValue(player_id_)); - list.push_back(EncodableValue(track_id_)); - list.push_back(EncodableValue(track_type_)); - return list; -} - -SelectedTracksMessage SelectedTracksMessage::FromEncodableList( - const EncodableList& list) { - SelectedTracksMessage decoded(list[0].LongValue(), list[1].LongValue(), - std::get(list[2])); - return decoded; -} - -// PositionMessage - -PositionMessage::PositionMessage(int64_t player_id, int64_t position) - : player_id_(player_id), position_(position) {} - -int64_t PositionMessage::player_id() const { return player_id_; } - -void PositionMessage::set_player_id(int64_t value_arg) { - player_id_ = value_arg; -} - -int64_t PositionMessage::position() const { return position_; } - -void PositionMessage::set_position(int64_t value_arg) { position_ = value_arg; } - -EncodableList PositionMessage::ToEncodableList() const { - EncodableList list; - list.reserve(2); - list.push_back(EncodableValue(player_id_)); - list.push_back(EncodableValue(position_)); - return list; -} - -PositionMessage PositionMessage::FromEncodableList(const EncodableList& list) { - PositionMessage decoded(list[0].LongValue(), list[1].LongValue()); - return decoded; -} - -// CreateMessage - -CreateMessage::CreateMessage() {} - -CreateMessage::CreateMessage(const std::string* asset, const std::string* uri, - const std::string* package_name, - const std::string* format_hint, - const EncodableMap* http_headers, - const EncodableMap* drm_configs, - const EncodableMap* player_options, - const EncodableMap* window_geometry) - : asset_(asset ? std::optional(*asset) : std::nullopt), - uri_(uri ? std::optional(*uri) : std::nullopt), - package_name_(package_name ? std::optional(*package_name) - : std::nullopt), - format_hint_(format_hint ? std::optional(*format_hint) - : std::nullopt), - http_headers_(http_headers ? std::optional(*http_headers) - : std::nullopt), - drm_configs_(drm_configs ? std::optional(*drm_configs) - : std::nullopt), - player_options_(player_options - ? std::optional(*player_options) - : std::nullopt), - window_geometry_(window_geometry - ? std::optional(*window_geometry) - : std::nullopt) {} - -const std::string* CreateMessage::asset() const { - return asset_ ? &(*asset_) : nullptr; -} - -void CreateMessage::set_asset(const std::string_view* value_arg) { - asset_ = value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void CreateMessage::set_asset(std::string_view value_arg) { - asset_ = value_arg; -} - -const std::string* CreateMessage::uri() const { - return uri_ ? &(*uri_) : nullptr; -} - -void CreateMessage::set_uri(const std::string_view* value_arg) { - uri_ = value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void CreateMessage::set_uri(std::string_view value_arg) { uri_ = value_arg; } - -const std::string* CreateMessage::package_name() const { - return package_name_ ? &(*package_name_) : nullptr; -} - -void CreateMessage::set_package_name(const std::string_view* value_arg) { - package_name_ = - value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void CreateMessage::set_package_name(std::string_view value_arg) { - package_name_ = value_arg; -} - -const std::string* CreateMessage::format_hint() const { - return format_hint_ ? &(*format_hint_) : nullptr; -} - -void CreateMessage::set_format_hint(const std::string_view* value_arg) { - format_hint_ = - value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void CreateMessage::set_format_hint(std::string_view value_arg) { - format_hint_ = value_arg; -} - -const EncodableMap* CreateMessage::http_headers() const { - return http_headers_ ? &(*http_headers_) : nullptr; -} - -void CreateMessage::set_http_headers(const EncodableMap* value_arg) { - http_headers_ = - value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void CreateMessage::set_http_headers(const EncodableMap& value_arg) { - http_headers_ = value_arg; -} - -const EncodableMap* CreateMessage::drm_configs() const { - return drm_configs_ ? &(*drm_configs_) : nullptr; -} - -void CreateMessage::set_drm_configs(const EncodableMap* value_arg) { - drm_configs_ = - value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void CreateMessage::set_drm_configs(const EncodableMap& value_arg) { - drm_configs_ = value_arg; -} - -const EncodableMap* CreateMessage::player_options() const { - return player_options_ ? &(*player_options_) : nullptr; -} - -void CreateMessage::set_player_options(const EncodableMap* value_arg) { - player_options_ = - value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void CreateMessage::set_player_options(const EncodableMap& value_arg) { - player_options_ = value_arg; -} - -const EncodableMap* CreateMessage::window_geometry() const { - return window_geometry_ ? &(*window_geometry_) : nullptr; -} - -void CreateMessage::set_window_geometry(const EncodableMap* value_arg) { - window_geometry_ = - value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void CreateMessage::set_window_geometry(const EncodableMap& value_arg) { - window_geometry_ = value_arg; -} - -EncodableList CreateMessage::ToEncodableList() const { - EncodableList list; - list.reserve(8); - list.push_back(asset_ ? EncodableValue(*asset_) : EncodableValue()); - list.push_back(uri_ ? EncodableValue(*uri_) : EncodableValue()); - list.push_back(package_name_ ? EncodableValue(*package_name_) - : EncodableValue()); - list.push_back(format_hint_ ? EncodableValue(*format_hint_) - : EncodableValue()); - list.push_back(http_headers_ ? EncodableValue(*http_headers_) - : EncodableValue()); - list.push_back(drm_configs_ ? EncodableValue(*drm_configs_) - : EncodableValue()); - list.push_back(player_options_ ? EncodableValue(*player_options_) - : EncodableValue()); - list.push_back(window_geometry_ ? EncodableValue(*window_geometry_) - : EncodableValue()); - return list; -} - -CreateMessage CreateMessage::FromEncodableList(const EncodableList& list) { - CreateMessage decoded; - auto& encodable_asset = list[0]; - if (!encodable_asset.IsNull()) { - decoded.set_asset(std::get(encodable_asset)); - } - auto& encodable_uri = list[1]; - if (!encodable_uri.IsNull()) { - decoded.set_uri(std::get(encodable_uri)); - } - auto& encodable_package_name = list[2]; - if (!encodable_package_name.IsNull()) { - decoded.set_package_name(std::get(encodable_package_name)); - } - auto& encodable_format_hint = list[3]; - if (!encodable_format_hint.IsNull()) { - decoded.set_format_hint(std::get(encodable_format_hint)); - } - auto& encodable_http_headers = list[4]; - if (!encodable_http_headers.IsNull()) { - decoded.set_http_headers(std::get(encodable_http_headers)); - } - auto& encodable_drm_configs = list[5]; - if (!encodable_drm_configs.IsNull()) { - decoded.set_drm_configs(std::get(encodable_drm_configs)); - } - auto& encodable_player_options = list[6]; - if (!encodable_player_options.IsNull()) { - decoded.set_player_options( - std::get(encodable_player_options)); - } - auto& encodable_window_geometry = list[7]; - if (!encodable_window_geometry.IsNull()) { - decoded.set_window_geometry( - std::get(encodable_window_geometry)); - } - return decoded; -} - -// MixWithOthersMessage - -MixWithOthersMessage::MixWithOthersMessage(bool mix_with_others) - : mix_with_others_(mix_with_others) {} - -bool MixWithOthersMessage::mix_with_others() const { return mix_with_others_; } - -void MixWithOthersMessage::set_mix_with_others(bool value_arg) { - mix_with_others_ = value_arg; -} - -EncodableList MixWithOthersMessage::ToEncodableList() const { - EncodableList list; - list.reserve(1); - list.push_back(EncodableValue(mix_with_others_)); - return list; -} - -MixWithOthersMessage MixWithOthersMessage::FromEncodableList( - const EncodableList& list) { - MixWithOthersMessage decoded(std::get(list[0])); - return decoded; -} - -// GeometryMessage - -GeometryMessage::GeometryMessage(int64_t player_id, int64_t x, int64_t y, - int64_t width, int64_t height) - : player_id_(player_id), x_(x), y_(y), width_(width), height_(height) {} - -int64_t GeometryMessage::player_id() const { return player_id_; } - -void GeometryMessage::set_player_id(int64_t value_arg) { - player_id_ = value_arg; -} - -int64_t GeometryMessage::x() const { return x_; } - -void GeometryMessage::set_x(int64_t value_arg) { x_ = value_arg; } - -int64_t GeometryMessage::y() const { return y_; } - -void GeometryMessage::set_y(int64_t value_arg) { y_ = value_arg; } - -int64_t GeometryMessage::width() const { return width_; } - -void GeometryMessage::set_width(int64_t value_arg) { width_ = value_arg; } - -int64_t GeometryMessage::height() const { return height_; } - -void GeometryMessage::set_height(int64_t value_arg) { height_ = value_arg; } - -EncodableList GeometryMessage::ToEncodableList() const { - EncodableList list; - list.reserve(5); - list.push_back(EncodableValue(player_id_)); - list.push_back(EncodableValue(x_)); - list.push_back(EncodableValue(y_)); - list.push_back(EncodableValue(width_)); - list.push_back(EncodableValue(height_)); - return list; -} - -GeometryMessage GeometryMessage::FromEncodableList(const EncodableList& list) { - GeometryMessage decoded(list[0].LongValue(), list[1].LongValue(), - list[2].LongValue(), list[3].LongValue(), - list[4].LongValue()); - return decoded; -} - -// DurationMessage - -DurationMessage::DurationMessage(int64_t player_id) : player_id_(player_id) {} - -DurationMessage::DurationMessage(int64_t player_id, - const EncodableList* duration_range) - : player_id_(player_id), - duration_range_(duration_range - ? std::optional(*duration_range) - : std::nullopt) {} - -int64_t DurationMessage::player_id() const { return player_id_; } - -void DurationMessage::set_player_id(int64_t value_arg) { - player_id_ = value_arg; -} - -const EncodableList* DurationMessage::duration_range() const { - return duration_range_ ? &(*duration_range_) : nullptr; -} - -void DurationMessage::set_duration_range(const EncodableList* value_arg) { - duration_range_ = - value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void DurationMessage::set_duration_range(const EncodableList& value_arg) { - duration_range_ = value_arg; -} - -EncodableList DurationMessage::ToEncodableList() const { - EncodableList list; - list.reserve(2); - list.push_back(EncodableValue(player_id_)); - list.push_back(duration_range_ ? EncodableValue(*duration_range_) - : EncodableValue()); - return list; -} - -DurationMessage DurationMessage::FromEncodableList(const EncodableList& list) { - DurationMessage decoded(list[0].LongValue()); - auto& encodable_duration_range = list[1]; - if (!encodable_duration_range.IsNull()) { - decoded.set_duration_range( - std::get(encodable_duration_range)); - } - return decoded; -} - -// RotationMessage - -RotationMessage::RotationMessage(int64_t player_id, int64_t rotation) - : player_id_(player_id), rotation_(rotation) {} - -int64_t RotationMessage::player_id() const { return player_id_; } - -void RotationMessage::set_player_id(int64_t value_arg) { - player_id_ = value_arg; -} - -int64_t RotationMessage::rotation() const { return rotation_; } - -void RotationMessage::set_rotation(int64_t value_arg) { rotation_ = value_arg; } - -EncodableList RotationMessage::ToEncodableList() const { - EncodableList list; - list.reserve(2); - list.push_back(EncodableValue(player_id_)); - list.push_back(EncodableValue(rotation_)); - return list; -} - -RotationMessage RotationMessage::FromEncodableList(const EncodableList& list) { - RotationMessage decoded(list[0].LongValue(), list[1].LongValue()); - return decoded; -} - -VideoPlayerVideoholeApiCodecSerializer:: - VideoPlayerVideoholeApiCodecSerializer() {} - -EncodableValue VideoPlayerVideoholeApiCodecSerializer::ReadValueOfType( - uint8_t type, flutter::ByteStreamReader* stream) const { - switch (type) { - case 128: - return CustomEncodableValue(CreateMessage::FromEncodableList( - std::get(ReadValue(stream)))); - case 129: - return CustomEncodableValue(CreateMessage::FromEncodableList( - std::get(ReadValue(stream)))); - case 130: - return CustomEncodableValue(DurationMessage::FromEncodableList( - std::get(ReadValue(stream)))); - case 131: - return CustomEncodableValue(GeometryMessage::FromEncodableList( - std::get(ReadValue(stream)))); - case 132: - return CustomEncodableValue(LoopingMessage::FromEncodableList( - std::get(ReadValue(stream)))); - case 133: - return CustomEncodableValue(MixWithOthersMessage::FromEncodableList( - std::get(ReadValue(stream)))); - case 134: - return CustomEncodableValue(PlaybackSpeedMessage::FromEncodableList( - std::get(ReadValue(stream)))); - case 135: - return CustomEncodableValue(PlayerMessage::FromEncodableList( - std::get(ReadValue(stream)))); - case 136: - return CustomEncodableValue(PositionMessage::FromEncodableList( - std::get(ReadValue(stream)))); - case 137: - return CustomEncodableValue(RotationMessage::FromEncodableList( - std::get(ReadValue(stream)))); - case 138: - return CustomEncodableValue(SelectedTracksMessage::FromEncodableList( - std::get(ReadValue(stream)))); - case 139: - return CustomEncodableValue(TrackMessage::FromEncodableList( - std::get(ReadValue(stream)))); - case 140: - return CustomEncodableValue(TrackTypeMessage::FromEncodableList( - std::get(ReadValue(stream)))); - case 141: - return CustomEncodableValue(VolumeMessage::FromEncodableList( - std::get(ReadValue(stream)))); - default: - return flutter::StandardCodecSerializer::ReadValueOfType(type, stream); - } -} - -void VideoPlayerVideoholeApiCodecSerializer::WriteValue( - const EncodableValue& value, flutter::ByteStreamWriter* stream) const { - if (const CustomEncodableValue* custom_value = - std::get_if(&value)) { - if (custom_value->type() == typeid(CreateMessage)) { - stream->WriteByte(128); - WriteValue( - EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), - stream); - return; - } - if (custom_value->type() == typeid(CreateMessage)) { - stream->WriteByte(129); - WriteValue( - EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), - stream); - return; - } - if (custom_value->type() == typeid(DurationMessage)) { - stream->WriteByte(130); - WriteValue( - EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), - stream); - return; - } - if (custom_value->type() == typeid(GeometryMessage)) { - stream->WriteByte(131); - WriteValue( - EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), - stream); - return; - } - if (custom_value->type() == typeid(LoopingMessage)) { - stream->WriteByte(132); - WriteValue( - EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), - stream); - return; - } - if (custom_value->type() == typeid(MixWithOthersMessage)) { - stream->WriteByte(133); - WriteValue( - EncodableValue(std::any_cast(*custom_value) - .ToEncodableList()), - stream); - return; - } - if (custom_value->type() == typeid(PlaybackSpeedMessage)) { - stream->WriteByte(134); - WriteValue( - EncodableValue(std::any_cast(*custom_value) - .ToEncodableList()), - stream); - return; - } - if (custom_value->type() == typeid(PlayerMessage)) { - stream->WriteByte(135); - WriteValue( - EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), - stream); - return; - } - if (custom_value->type() == typeid(PositionMessage)) { - stream->WriteByte(136); - WriteValue( - EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), - stream); - return; - } - if (custom_value->type() == typeid(RotationMessage)) { - stream->WriteByte(137); - WriteValue( - EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), - stream); - return; - } - if (custom_value->type() == typeid(SelectedTracksMessage)) { - stream->WriteByte(138); - WriteValue( - EncodableValue(std::any_cast(*custom_value) - .ToEncodableList()), - stream); - return; - } - if (custom_value->type() == typeid(TrackMessage)) { - stream->WriteByte(139); - WriteValue( - EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), - stream); - return; - } - if (custom_value->type() == typeid(TrackTypeMessage)) { - stream->WriteByte(140); - WriteValue( - EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), - stream); - return; - } - if (custom_value->type() == typeid(VolumeMessage)) { - stream->WriteByte(141); - WriteValue( - EncodableValue( - std::any_cast(*custom_value).ToEncodableList()), - stream); - return; - } - } - flutter::StandardCodecSerializer::WriteValue(value, stream); -} - -/// The codec used by VideoPlayerVideoholeApi. -const flutter::StandardMessageCodec& VideoPlayerVideoholeApi::GetCodec() { - return flutter::StandardMessageCodec::GetInstance( - &VideoPlayerVideoholeApiCodecSerializer::GetInstance()); -} - -// Sets up an instance of `VideoPlayerVideoholeApi` to handle messages through -// the `binary_messenger`. -void VideoPlayerVideoholeApi::SetUp(flutter::BinaryMessenger* binary_messenger, - VideoPlayerVideoholeApi* api) { - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "initialize", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - std::optional output = api->Initialize(); - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "create", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - ErrorOr output = api->Create(msg_arg); - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back( - CustomEncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "dispose", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - std::optional output = api->Dispose(msg_arg); - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "setLooping", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - std::optional output = api->SetLooping(msg_arg); - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "setVolume", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - std::optional output = api->SetVolume(msg_arg); - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "setPlaybackSpeed", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - std::optional output = - api->SetPlaybackSpeed(msg_arg); - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "play", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - std::optional output = api->Play(msg_arg); - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "setDeactivate", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - ErrorOr output = api->SetDeactivate(msg_arg); - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "setActivate", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - ErrorOr output = api->SetActivate(msg_arg); - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "track", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - ErrorOr output = api->Track(msg_arg); - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back( - CustomEncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "setTrackSelection", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - ErrorOr output = api->SetTrackSelection(msg_arg); - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "position", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - ErrorOr output = api->Position(msg_arg); - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back( - CustomEncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "seekTo", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - api->SeekTo(msg_arg, - [reply](std::optional&& output) { - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - }); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "pause", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - std::optional output = api->Pause(msg_arg); - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "setMixWithOthers", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - std::optional output = - api->SetMixWithOthers(msg_arg); - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "setDisplayGeometry", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - std::optional output = - api->SetDisplayGeometry(msg_arg); - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "duration", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - ErrorOr output = api->Duration(msg_arg); - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back( - CustomEncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "suspend", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_player_id_arg = args.at(0); - if (encodable_player_id_arg.IsNull()) { - reply(WrapError("player_id_arg unexpectedly null.")); - return; - } - const int64_t player_id_arg = encodable_player_id_arg.LongValue(); - std::optional output = api->Suspend(player_id_arg); - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "restore", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_player_id_arg = args.at(0); - if (encodable_player_id_arg.IsNull()) { - reply(WrapError("player_id_arg unexpectedly null.")); - return; - } - const int64_t player_id_arg = encodable_player_id_arg.LongValue(); - const auto& encodable_msg_arg = args.at(1); - const auto* msg_arg = &(std::any_cast( - std::get(encodable_msg_arg))); - const auto& encodable_resume_time_arg = args.at(2); - if (encodable_resume_time_arg.IsNull()) { - reply(WrapError("resume_time_arg unexpectedly null.")); - return; - } - const int64_t resume_time_arg = - encodable_resume_time_arg.LongValue(); - std::optional output = - api->Restore(player_id_arg, msg_arg, resume_time_arg); - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } - { - auto channel = std::make_unique>( - binary_messenger, - "dev.flutter.pigeon.video_player_videohole.VideoPlayerVideoholeApi." - "setDisplayRotate", - &GetCodec()); - if (api != nullptr) { - channel->SetMessageHandler( - [api](const EncodableValue& message, - const flutter::MessageReply& reply) { - try { - const auto& args = std::get(message); - const auto& encodable_msg_arg = args.at(0); - if (encodable_msg_arg.IsNull()) { - reply(WrapError("msg_arg unexpectedly null.")); - return; - } - const auto& msg_arg = std::any_cast( - std::get(encodable_msg_arg)); - ErrorOr output = api->SetDisplayRotate(msg_arg); - if (output.has_error()) { - reply(WrapError(output.error())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue(std::move(output).TakeValue())); - reply(EncodableValue(std::move(wrapped))); - } catch (const std::exception& exception) { - reply(WrapError(exception.what())); - } - }); - } else { - channel->SetMessageHandler(nullptr); - } - } -} - -EncodableValue VideoPlayerVideoholeApi::WrapError( - std::string_view error_message) { - return EncodableValue( - EncodableList{EncodableValue(std::string(error_message)), - EncodableValue("Error"), EncodableValue()}); -} - -EncodableValue VideoPlayerVideoholeApi::WrapError(const FlutterError& error) { - return EncodableValue(EncodableList{EncodableValue(error.code()), - EncodableValue(error.message()), - error.details()}); -} - -} // namespace video_player_videohole_tizen diff --git a/packages/video_player_videohole/tizen/src/messages.h b/packages/video_player_videohole/tizen/src/messages.h deleted file mode 100644 index ebba1c465..000000000 --- a/packages/video_player_videohole/tizen/src/messages.h +++ /dev/null @@ -1,456 +0,0 @@ -// Autogenerated from Pigeon (v10.1.6), do not edit directly. -// See also: https://pub.dev/packages/pigeon - -#ifndef PIGEON_MESSAGES_H_ -#define PIGEON_MESSAGES_H_ -#include -#include -#include -#include - -#include -#include -#include - -namespace video_player_videohole_tizen { - -// Generated class from Pigeon. - -class FlutterError { - public: - explicit FlutterError(const std::string& code) : code_(code) {} - explicit FlutterError(const std::string& code, const std::string& message) - : code_(code), message_(message) {} - explicit FlutterError(const std::string& code, const std::string& message, - const flutter::EncodableValue& details) - : code_(code), message_(message), details_(details) {} - - const std::string& code() const { return code_; } - const std::string& message() const { return message_; } - const flutter::EncodableValue& details() const { return details_; } - - private: - std::string code_; - std::string message_; - flutter::EncodableValue details_; -}; - -template -class ErrorOr { - public: - ErrorOr(const T& rhs) : v_(rhs) {} - ErrorOr(const T&& rhs) : v_(std::move(rhs)) {} - ErrorOr(const FlutterError& rhs) : v_(rhs) {} - ErrorOr(const FlutterError&& rhs) : v_(std::move(rhs)) {} - - bool has_error() const { return std::holds_alternative(v_); } - const T& value() const { return std::get(v_); }; - const FlutterError& error() const { return std::get(v_); }; - - private: - friend class VideoPlayerVideoholeApi; - ErrorOr() = default; - T TakeValue() && { return std::get(std::move(v_)); } - - std::variant v_; -}; - -// Generated class from Pigeon that represents data sent in messages. -class PlayerMessage { - public: - // Constructs an object setting all fields. - explicit PlayerMessage(int64_t player_id); - - int64_t player_id() const; - void set_player_id(int64_t value_arg); - - private: - static PlayerMessage FromEncodableList(const flutter::EncodableList& list); - flutter::EncodableList ToEncodableList() const; - friend class VideoPlayerVideoholeApi; - friend class VideoPlayerVideoholeApiCodecSerializer; - int64_t player_id_; -}; - -// Generated class from Pigeon that represents data sent in messages. -class LoopingMessage { - public: - // Constructs an object setting all fields. - explicit LoopingMessage(int64_t player_id, bool is_looping); - - int64_t player_id() const; - void set_player_id(int64_t value_arg); - - bool is_looping() const; - void set_is_looping(bool value_arg); - - private: - static LoopingMessage FromEncodableList(const flutter::EncodableList& list); - flutter::EncodableList ToEncodableList() const; - friend class VideoPlayerVideoholeApi; - friend class VideoPlayerVideoholeApiCodecSerializer; - int64_t player_id_; - bool is_looping_; -}; - -// Generated class from Pigeon that represents data sent in messages. -class VolumeMessage { - public: - // Constructs an object setting all fields. - explicit VolumeMessage(int64_t player_id, double volume); - - int64_t player_id() const; - void set_player_id(int64_t value_arg); - - double volume() const; - void set_volume(double value_arg); - - private: - static VolumeMessage FromEncodableList(const flutter::EncodableList& list); - flutter::EncodableList ToEncodableList() const; - friend class VideoPlayerVideoholeApi; - friend class VideoPlayerVideoholeApiCodecSerializer; - int64_t player_id_; - double volume_; -}; - -// Generated class from Pigeon that represents data sent in messages. -class PlaybackSpeedMessage { - public: - // Constructs an object setting all fields. - explicit PlaybackSpeedMessage(int64_t player_id, double speed); - - int64_t player_id() const; - void set_player_id(int64_t value_arg); - - double speed() const; - void set_speed(double value_arg); - - private: - static PlaybackSpeedMessage FromEncodableList( - const flutter::EncodableList& list); - flutter::EncodableList ToEncodableList() const; - friend class VideoPlayerVideoholeApi; - friend class VideoPlayerVideoholeApiCodecSerializer; - int64_t player_id_; - double speed_; -}; - -// Generated class from Pigeon that represents data sent in messages. -class TrackMessage { - public: - // Constructs an object setting all fields. - explicit TrackMessage(int64_t player_id, - const flutter::EncodableList& tracks); - - int64_t player_id() const; - void set_player_id(int64_t value_arg); - - const flutter::EncodableList& tracks() const; - void set_tracks(const flutter::EncodableList& value_arg); - - private: - static TrackMessage FromEncodableList(const flutter::EncodableList& list); - flutter::EncodableList ToEncodableList() const; - friend class VideoPlayerVideoholeApi; - friend class VideoPlayerVideoholeApiCodecSerializer; - int64_t player_id_; - flutter::EncodableList tracks_; -}; - -// Generated class from Pigeon that represents data sent in messages. -class TrackTypeMessage { - public: - // Constructs an object setting all fields. - explicit TrackTypeMessage(int64_t player_id, const std::string& track_type); - - int64_t player_id() const; - void set_player_id(int64_t value_arg); - - const std::string& track_type() const; - void set_track_type(std::string_view value_arg); - - private: - static TrackTypeMessage FromEncodableList(const flutter::EncodableList& list); - flutter::EncodableList ToEncodableList() const; - friend class VideoPlayerVideoholeApi; - friend class VideoPlayerVideoholeApiCodecSerializer; - int64_t player_id_; - std::string track_type_; -}; - -// Generated class from Pigeon that represents data sent in messages. -class SelectedTracksMessage { - public: - // Constructs an object setting all fields. - explicit SelectedTracksMessage(int64_t player_id, int64_t track_id, - const std::string& track_type); - - int64_t player_id() const; - void set_player_id(int64_t value_arg); - - int64_t track_id() const; - void set_track_id(int64_t value_arg); - - const std::string& track_type() const; - void set_track_type(std::string_view value_arg); - - private: - static SelectedTracksMessage FromEncodableList( - const flutter::EncodableList& list); - flutter::EncodableList ToEncodableList() const; - friend class VideoPlayerVideoholeApi; - friend class VideoPlayerVideoholeApiCodecSerializer; - int64_t player_id_; - int64_t track_id_; - std::string track_type_; -}; - -// Generated class from Pigeon that represents data sent in messages. -class PositionMessage { - public: - // Constructs an object setting all fields. - explicit PositionMessage(int64_t player_id, int64_t position); - - int64_t player_id() const; - void set_player_id(int64_t value_arg); - - int64_t position() const; - void set_position(int64_t value_arg); - - private: - static PositionMessage FromEncodableList(const flutter::EncodableList& list); - flutter::EncodableList ToEncodableList() const; - friend class VideoPlayerVideoholeApi; - friend class VideoPlayerVideoholeApiCodecSerializer; - int64_t player_id_; - int64_t position_; -}; - -// Generated class from Pigeon that represents data sent in messages. -class CreateMessage { - public: - // Constructs an object setting all non-nullable fields. - CreateMessage(); - - // Constructs an object setting all fields. - explicit CreateMessage(const std::string* asset, const std::string* uri, - const std::string* package_name, - const std::string* format_hint, - const flutter::EncodableMap* http_headers, - const flutter::EncodableMap* drm_configs, - const flutter::EncodableMap* player_options, - const flutter::EncodableMap* window_geometry); - - const std::string* asset() const; - void set_asset(const std::string_view* value_arg); - void set_asset(std::string_view value_arg); - - const std::string* uri() const; - void set_uri(const std::string_view* value_arg); - void set_uri(std::string_view value_arg); - - const std::string* package_name() const; - void set_package_name(const std::string_view* value_arg); - void set_package_name(std::string_view value_arg); - - const std::string* format_hint() const; - void set_format_hint(const std::string_view* value_arg); - void set_format_hint(std::string_view value_arg); - - const flutter::EncodableMap* http_headers() const; - void set_http_headers(const flutter::EncodableMap* value_arg); - void set_http_headers(const flutter::EncodableMap& value_arg); - - const flutter::EncodableMap* drm_configs() const; - void set_drm_configs(const flutter::EncodableMap* value_arg); - void set_drm_configs(const flutter::EncodableMap& value_arg); - - const flutter::EncodableMap* player_options() const; - void set_player_options(const flutter::EncodableMap* value_arg); - void set_player_options(const flutter::EncodableMap& value_arg); - - const flutter::EncodableMap* window_geometry() const; - void set_window_geometry(const flutter::EncodableMap* value_arg); - void set_window_geometry(const flutter::EncodableMap& value_arg); - - private: - static CreateMessage FromEncodableList(const flutter::EncodableList& list); - flutter::EncodableList ToEncodableList() const; - friend class VideoPlayerVideoholeApi; - friend class VideoPlayerVideoholeApiCodecSerializer; - std::optional asset_; - std::optional uri_; - std::optional package_name_; - std::optional format_hint_; - std::optional http_headers_; - std::optional drm_configs_; - std::optional player_options_; - std::optional window_geometry_; -}; - -// Generated class from Pigeon that represents data sent in messages. -class MixWithOthersMessage { - public: - // Constructs an object setting all fields. - explicit MixWithOthersMessage(bool mix_with_others); - - bool mix_with_others() const; - void set_mix_with_others(bool value_arg); - - private: - static MixWithOthersMessage FromEncodableList( - const flutter::EncodableList& list); - flutter::EncodableList ToEncodableList() const; - friend class VideoPlayerVideoholeApi; - friend class VideoPlayerVideoholeApiCodecSerializer; - bool mix_with_others_; -}; - -// Generated class from Pigeon that represents data sent in messages. -class GeometryMessage { - public: - // Constructs an object setting all fields. - explicit GeometryMessage(int64_t player_id, int64_t x, int64_t y, - int64_t width, int64_t height); - - int64_t player_id() const; - void set_player_id(int64_t value_arg); - - int64_t x() const; - void set_x(int64_t value_arg); - - int64_t y() const; - void set_y(int64_t value_arg); - - int64_t width() const; - void set_width(int64_t value_arg); - - int64_t height() const; - void set_height(int64_t value_arg); - - private: - static GeometryMessage FromEncodableList(const flutter::EncodableList& list); - flutter::EncodableList ToEncodableList() const; - friend class VideoPlayerVideoholeApi; - friend class VideoPlayerVideoholeApiCodecSerializer; - int64_t player_id_; - int64_t x_; - int64_t y_; - int64_t width_; - int64_t height_; -}; - -// Generated class from Pigeon that represents data sent in messages. -class DurationMessage { - public: - // Constructs an object setting all non-nullable fields. - explicit DurationMessage(int64_t player_id); - - // Constructs an object setting all fields. - explicit DurationMessage(int64_t player_id, - const flutter::EncodableList* duration_range); - - int64_t player_id() const; - void set_player_id(int64_t value_arg); - - const flutter::EncodableList* duration_range() const; - void set_duration_range(const flutter::EncodableList* value_arg); - void set_duration_range(const flutter::EncodableList& value_arg); - - private: - static DurationMessage FromEncodableList(const flutter::EncodableList& list); - flutter::EncodableList ToEncodableList() const; - friend class VideoPlayerVideoholeApi; - friend class VideoPlayerVideoholeApiCodecSerializer; - int64_t player_id_; - std::optional duration_range_; -}; - -// Generated class from Pigeon that represents data sent in messages. -class RotationMessage { - public: - // Constructs an object setting all fields. - explicit RotationMessage(int64_t player_id, int64_t rotation); - - int64_t player_id() const; - void set_player_id(int64_t value_arg); - - int64_t rotation() const; - void set_rotation(int64_t value_arg); - - private: - static RotationMessage FromEncodableList(const flutter::EncodableList& list); - flutter::EncodableList ToEncodableList() const; - friend class VideoPlayerVideoholeApi; - friend class VideoPlayerVideoholeApiCodecSerializer; - int64_t player_id_; - int64_t rotation_; -}; - -class VideoPlayerVideoholeApiCodecSerializer - : public flutter::StandardCodecSerializer { - public: - VideoPlayerVideoholeApiCodecSerializer(); - inline static VideoPlayerVideoholeApiCodecSerializer& GetInstance() { - static VideoPlayerVideoholeApiCodecSerializer sInstance; - return sInstance; - } - - void WriteValue(const flutter::EncodableValue& value, - flutter::ByteStreamWriter* stream) const override; - - protected: - flutter::EncodableValue ReadValueOfType( - uint8_t type, flutter::ByteStreamReader* stream) const override; -}; - -// Generated interface from Pigeon that represents a handler of messages from -// Flutter. -class VideoPlayerVideoholeApi { - public: - VideoPlayerVideoholeApi(const VideoPlayerVideoholeApi&) = delete; - VideoPlayerVideoholeApi& operator=(const VideoPlayerVideoholeApi&) = delete; - virtual ~VideoPlayerVideoholeApi() {} - virtual std::optional Initialize() = 0; - virtual ErrorOr Create(const CreateMessage& msg) = 0; - virtual std::optional Dispose(const PlayerMessage& msg) = 0; - virtual std::optional SetLooping(const LoopingMessage& msg) = 0; - virtual std::optional SetVolume(const VolumeMessage& msg) = 0; - virtual std::optional SetPlaybackSpeed( - const PlaybackSpeedMessage& msg) = 0; - virtual std::optional Play(const PlayerMessage& msg) = 0; - virtual ErrorOr SetDeactivate(const PlayerMessage& msg) = 0; - virtual ErrorOr SetActivate(const PlayerMessage& msg) = 0; - virtual ErrorOr Track(const TrackTypeMessage& msg) = 0; - virtual ErrorOr SetTrackSelection(const SelectedTracksMessage& msg) = 0; - virtual ErrorOr Position(const PlayerMessage& msg) = 0; - virtual void SeekTo( - const PositionMessage& msg, - std::function reply)> result) = 0; - virtual std::optional Pause(const PlayerMessage& msg) = 0; - virtual std::optional SetMixWithOthers( - const MixWithOthersMessage& msg) = 0; - virtual std::optional SetDisplayGeometry( - const GeometryMessage& msg) = 0; - virtual ErrorOr Duration(const PlayerMessage& msg) = 0; - virtual std::optional Suspend(int64_t player_id) = 0; - virtual std::optional Restore(int64_t player_id, - const CreateMessage* msg, - int64_t resume_time) = 0; - virtual ErrorOr SetDisplayRotate(const RotationMessage& msg) = 0; - - // The codec used by VideoPlayerVideoholeApi. - static const flutter::StandardMessageCodec& GetCodec(); - // Sets up an instance of `VideoPlayerVideoholeApi` to handle messages through - // the `binary_messenger`. - static void SetUp(flutter::BinaryMessenger* binary_messenger, - VideoPlayerVideoholeApi* api); - static flutter::EncodableValue WrapError(std::string_view error_message); - static flutter::EncodableValue WrapError(const FlutterError& error); - - protected: - VideoPlayerVideoholeApi() = default; -}; -} // namespace video_player_videohole_tizen -#endif // PIGEON_MESSAGES_H_ diff --git a/packages/video_player_videohole/tizen/src/video_player.cc b/packages/video_player_videohole/tizen/src/video_player.cc index 6e5a677c9..d0926fa9e 100644 --- a/packages/video_player_videohole/tizen/src/video_player.cc +++ b/packages/video_player_videohole/tizen/src/video_player.cc @@ -4,19 +4,142 @@ #include "video_player.h" -#include -#include +#include +#include + +#include "../third_party/nlohmann_json/json.hpp" #include "log.h" +using nlohmann::json; + namespace video_player_videohole_tizen { -static int64_t player_index = 1; +static int64_t g_dart_port = -1; +static std::mutex g_dart_port_mutex; + +void RegisterDartPort(int64_t dart_port) { + std::lock_guard lock(g_dart_port_mutex); + g_dart_port = dart_port; + LOG_INFO("[VideoPlayer] Registered global port %lld", + static_cast(dart_port)); +} + +void UnregisterDartPort() { + std::lock_guard lock(g_dart_port_mutex); + g_dart_port = -1; + LOG_INFO("[VideoPlayer] Unregistered global port"); +} + +void PostEventToDart(int64_t player_id, const std::string& event_json) { + int64_t port; + { + std::lock_guard lock(g_dart_port_mutex); + if (g_dart_port < 0) { + LOG_ERROR("[VideoPlayer] Global port not registered, dropping event"); + return; + } + port = g_dart_port; + } + + Dart_CObject player_id_obj; + player_id_obj.type = Dart_CObject_kInt64; + player_id_obj.value.as_int64 = player_id; + + char* json_copy = strdup(event_json.c_str()); + + Dart_CObject event_json_obj; + event_json_obj.type = Dart_CObject_kString; + event_json_obj.value.as_string = json_copy; + + Dart_CObject* array_elements[2]; + array_elements[0] = &player_id_obj; + array_elements[1] = &event_json_obj; + + Dart_CObject message; + message.type = Dart_CObject_kArray; + message.value.as_array.length = 2; + message.value.as_array.values = array_elements; + + bool result = Dart_PostCObject_DL(port, &message); + free(json_copy); + + if (!result) { + LOG_ERROR( + "[VideoPlayer] Failed to post event to Dart for player %lld. Freeing " + "json_copy.", + static_cast(player_id)); + } +} + +static json EncodableValueToJson(const flutter::EncodableValue& value); + +static json EncodableMapToJson(const flutter::EncodableMap& map) { + json j = json::object(); + for (const auto& [key, val] : map) { + std::string key_str; + if (std::holds_alternative(key)) { + key_str = std::get(key); + } else if (std::holds_alternative(key)) { + key_str = std::to_string(std::get(key)); + } else if (std::holds_alternative(key)) { + key_str = std::to_string(std::get(key)); + } + j[key_str] = EncodableValueToJson(val); + } + return j; +} + +static json EncodableListToJson(const flutter::EncodableList& list) { + json j = json::array(); + for (const auto& item : list) { + j.push_back(EncodableValueToJson(item)); + } + return j; +} + +static json EncodableValueToJson(const flutter::EncodableValue& value) { + try { + if (std::holds_alternative(value)) { + return json(std::get(value)); + } + if (std::holds_alternative(value)) { + return json(std::get(value)); + } + if (std::holds_alternative(value)) { + return json(std::get(value)); + } + if (std::holds_alternative(value)) { + return json(std::get(value)); + } + if (std::holds_alternative(value)) { + return json(std::get(value)); + } + if (std::holds_alternative>(value) || + std::holds_alternative>(value) || + std::holds_alternative>(value) || + std::holds_alternative>(value) || + std::holds_alternative>(value)) { + return json::array(); + } + if (std::holds_alternative(value)) { + return EncodableListToJson(std::get(value)); + } + if (std::holds_alternative(value)) { + return EncodableMapToJson(std::get(value)); + } + return json(nullptr); + } catch (const std::bad_variant_access& e) { + return json(nullptr); + } +} -VideoPlayer::VideoPlayer(flutter::BinaryMessenger *messenger, +VideoPlayer::VideoPlayer(flutter::BinaryMessenger* messenger, FlutterDesktopViewRef flutter_view) - : binary_messenger_(messenger), flutter_view_(flutter_view) { - // Initialize GMainContext and event dispatch state + : player_id_(-1), + ecore_wl2_window_proxy_(std::make_unique()), + binary_messenger_(messenger), + flutter_view_(flutter_view) { main_context_ = std::unique_ptr( g_main_context_ref_thread_default()); event_dispatch_state_ = std::make_shared(); @@ -24,99 +147,137 @@ VideoPlayer::VideoPlayer(flutter::BinaryMessenger *messenger, } VideoPlayer::~VideoPlayer() { - // Mark event dispatch state as disposed and cancel pending event source - if (event_dispatch_state_) { + MarkDisposed(); + main_context_.reset(); +} + +void VideoPlayer::MarkDisposed() { + if (!event_dispatch_state_) { + return; + } + + guint pending_source_id = 0; + { std::lock_guard lock(event_dispatch_state_->mutex); event_dispatch_state_->disposed = true; event_dispatch_state_->player = nullptr; - - if (event_dispatch_state_->pending_source_id != 0) { - g_source_remove(event_dispatch_state_->pending_source_id); - event_dispatch_state_->pending_source_id = 0; - } + pending_source_id = event_dispatch_state_->pending_source_id; + event_dispatch_state_->pending_source_id = 0; } - main_context_.reset(); + if (pending_source_id != 0) { + g_source_remove(pending_source_id); + } } -void VideoPlayer::ClearUpEventChannel() { - is_initialized_ = false; - { - std::lock_guard lock(queue_mutex_); - event_sink_ = nullptr; - } - if (event_channel_) { - event_channel_->SetStreamHandler(nullptr); +void VideoPlayer::ResetEventDispatchState() { + if (event_dispatch_state_) { + std::lock_guard lock(event_dispatch_state_->mutex); + event_dispatch_state_->disposed = false; + event_dispatch_state_->player = this; + event_dispatch_state_->pending_source_id = 0; + LOG_INFO("[VideoPlayer] ResetEventDispatchState: player=%p, this=%p", + event_dispatch_state_->player, this); } } -int64_t VideoPlayer::SetUpEventChannel() { - int64_t player_id = player_index++; - std::string channel_name = - "tizen/video_player/video_events_" + std::to_string(player_id); - auto channel = - std::make_unique>( - binary_messenger_, channel_name, - &flutter::StandardMethodCodec::GetInstance()); - auto handler = std::make_unique< - flutter::StreamHandlerFunctions>( - [&](const flutter::EncodableValue *arguments, - std::unique_ptr> &&events) - -> std::unique_ptr> { - event_sink_ = std::move(events); - if (IsReady()) { - SendInitialized(); - } else { - LOG_INFO("[VideoPlayer] Player is not ready."); - } - return nullptr; - }, - [&](const flutter::EncodableValue *arguments) - -> std::unique_ptr> { - event_sink_ = nullptr; - return nullptr; - }); - channel->SetStreamHandler(std::move(handler)); - event_channel_ = std::move(channel); - return player_id; +bool VideoPlayer::IsDisposed() const { + if (event_dispatch_state_) { + std::lock_guard lock(event_dispatch_state_->mutex); + return event_dispatch_state_->disposed; + } + return true; } void VideoPlayer::ExecuteSinkEvents() { - std::lock_guard lock(queue_mutex_); - while (!encodable_event_queue_.empty()) { - if (event_sink_) { - event_sink_->Success(encodable_event_queue_.front()); + if (event_dispatch_state_) { + std::lock_guard state_lock(event_dispatch_state_->mutex); + if (event_dispatch_state_->disposed) { + LOG_ERROR("[VideoPlayer] ExecuteSinkEvents: disposed, dropping events"); + return; + } + } + + std::vector regular_events; + { + std::lock_guard lock(queue_mutex_); + while (!encodable_event_queue_.empty()) { + regular_events.push_back(encodable_event_queue_.front()); + encodable_event_queue_.pop(); + } + } + + int event_count = 0; + for (const auto& event : regular_events) { + std::string event_json = EncodableValueToJson(event).dump(); + + std::string event_type = "unknown"; + if (event_json.find("\"event\":\"initialized\"") != std::string::npos) { + event_type = "initialized"; + } else if (event_json.find("\"event\":\"bufferingStart\"") != + std::string::npos) { + event_type = "bufferingStart"; + } else if (event_json.find("\"event\":\"bufferingUpdate\"") != + std::string::npos) { + event_type = "bufferingUpdate"; + } else if (event_json.find("\"event\":\"bufferingEnd\"") != + std::string::npos) { + event_type = "bufferingEnd"; + } else if (event_json.find("\"event\":\"completed\"") != + std::string::npos) { + event_type = "completed"; } - encodable_event_queue_.pop(); + + LOG_DEBUG( + "[VideoPlayer] Sending event #%d: type=%s, player_id=%lld, " + "json_len=%zu", + event_count, event_type.c_str(), static_cast(player_id_), + event_json.length()); + + PostEventToDart(player_id_, event_json); + event_count++; } - while (!error_event_queue_.empty()) { - if (event_sink_) { - event_sink_->Error(error_event_queue_.front().first, - error_event_queue_.front().second); + std::vector> error_events; + { + std::lock_guard lock(queue_mutex_); + while (!error_event_queue_.empty()) { + error_events.push_back(error_event_queue_.front()); + error_event_queue_.pop(); } - error_event_queue_.pop(); + } + + for (const auto& error : error_events) { + flutter::EncodableMap error_map = { + {flutter::EncodableValue("event"), flutter::EncodableValue("error")}, + {flutter::EncodableValue("code"), flutter::EncodableValue(error.first)}, + {flutter::EncodableValue("message"), + flutter::EncodableValue(error.second)}, + }; + std::string error_json = + EncodableValueToJson(flutter::EncodableValue(error_map)).dump(); + PostEventToDart(player_id_, error_json); } } void VideoPlayer::ScheduleSendPendingEvents() { std::lock_guard lock(event_dispatch_state_->mutex); - // Check conditions and deduplicate if (!main_context_ || !event_dispatch_state_ || event_dispatch_state_->disposed || event_dispatch_state_->pending_source_id != 0) { return; } - auto *state = new std::shared_ptr(event_dispatch_state_); + auto* state = new std::shared_ptr(event_dispatch_state_); + + GSource* source = g_idle_source_new(); - GSource *source = g_idle_source_new(); g_source_set_callback( source, [](gpointer data) -> gboolean { - auto state = static_cast *>(data); - VideoPlayer *player = nullptr; + auto state = static_cast*>(data); + VideoPlayer* player = nullptr; { std::lock_guard lock((*state)->mutex); if (!(*state)->disposed && (*state)->player) { @@ -131,7 +292,7 @@ void VideoPlayer::ScheduleSendPendingEvents() { }, state, [](gpointer data) { - delete static_cast *>(data); + delete static_cast*>(data); }); event_dispatch_state_->pending_source_id = @@ -142,17 +303,13 @@ void VideoPlayer::ScheduleSendPendingEvents() { void VideoPlayer::PushEvent(flutter::EncodableValue encodable_value) { { std::lock_guard lock(queue_mutex_); - if (!event_sink_) { - LOG_ERROR("[VideoPlayer] event sink is nullptr."); - return; - } encodable_event_queue_.push(encodable_value); } ScheduleSendPendingEvents(); } void VideoPlayer::SendInitialized() { - if (!is_initialized_ && event_sink_) { + if (!is_initialized_) { int32_t width = 0, height = 0; GetVideoSize(&width, &height); is_initialized_ = true; @@ -197,8 +354,16 @@ void VideoPlayer::SendBufferingEnd() { PushEvent(flutter::EncodableValue(result)); } +void VideoPlayer::SendSeekCompleted() { + flutter::EncodableMap result = { + {flutter::EncodableValue("event"), + flutter::EncodableValue("seekCompleted")}, + }; + PushEvent(flutter::EncodableValue(result)); +} + void VideoPlayer::SendSubtitleUpdate(int32_t duration, - const std::string &text) { + const std::string& text) { flutter::EncodableMap result = { {flutter::EncodableValue("event"), flutter::EncodableValue("subtitleUpdate")}, @@ -226,7 +391,7 @@ void VideoPlayer::SendIsPlayingState(bool is_playing) { } void VideoPlayer::SendRestored() { - if (is_restored_ && event_sink_) { + if (is_restored_) { is_restored_ = false; int32_t width = 0, height = 0; GetVideoSize(&width, &height); @@ -246,20 +411,14 @@ void VideoPlayer::SendRestored() { } } -void VideoPlayer::SendError(const std::string &error_code, - const std::string &error_message) { - { - std::lock_guard lock(queue_mutex_); - if (!event_sink_) { - LOG_ERROR("[VideoPlayer] event sink is nullptr."); - return; - } - error_event_queue_.push(std::make_pair(error_code, error_message)); - } +void VideoPlayer::SendError(const std::string& error_code, + const std::string& error_message) { + std::lock_guard lock(queue_mutex_); + error_event_queue_.push(std::make_pair(error_code, error_message)); ScheduleSendPendingEvents(); } -void *VideoPlayer::GetWindowHandle() { +void* VideoPlayer::GetWindowHandle() { return FlutterDesktopViewGetNativeHandle(flutter_view_); } diff --git a/packages/video_player_videohole/tizen/src/video_player.h b/packages/video_player_videohole/tizen/src/video_player.h index 353077559..3af7c79dd 100644 --- a/packages/video_player_videohole/tizen/src/video_player.h +++ b/packages/video_player_videohole/tizen/src/video_player.h @@ -5,21 +5,29 @@ #ifndef FLUTTER_PLUGIN_VIDEO_PLAYER_H_ #define FLUTTER_PLUGIN_VIDEO_PLAYER_H_ +#include #include -#include #include #include +#include +#include #include #include #include #include #include -#include "messages.h" +#include "ecore_wl2_window_proxy.h" +#include "ffi_messages.h" namespace video_player_videohole_tizen { +void RegisterDartPort(int64_t dart_port); +void UnregisterDartPort(); + +void PostEventToDart(int64_t player_id, const std::string &event_json); + class VideoPlayer { public: using SeekCompletedCallback = std::function; @@ -31,7 +39,9 @@ class VideoPlayer { virtual ~VideoPlayer(); virtual int64_t Create(const std::string &uri, - const CreateMessage &create_message) = 0; + const CreateMessage &create_message, + bool reuse_existing_id = false) = 0; + virtual int Prepare() = 0; virtual void Dispose() = 0; virtual void SetDisplayRoi(int32_t x, int32_t y, int32_t width, @@ -46,6 +56,7 @@ class VideoPlayer { virtual bool SeekTo(int64_t position, SeekCompletedCallback callback) = 0; virtual int64_t GetPosition() = 0; virtual std::pair GetDuration() = 0; + virtual bool IsLive() = 0; virtual bool IsReady() = 0; virtual flutter::EncodableList GetTrackInfo(std::string track_type) = 0; virtual bool SetTrackSelection(int32_t track_id, std::string track_type) = 0; @@ -57,20 +68,24 @@ class VideoPlayer { protected: virtual void GetVideoSize(int32_t *width, int32_t *height) = 0; void *GetWindowHandle(); - int64_t SetUpEventChannel(); - void ClearUpEventChannel(); void SendInitialized(); void SendBufferingStart(); void SendBufferingUpdate(int32_t value); void SendBufferingEnd(); + void SendSeekCompleted(); void SendSubtitleUpdate(int32_t duration, const std::string &text); void SendPlayCompleted(); void SendIsPlayingState(bool is_playing); void SendRestored(); void SendError(const std::string &error_code, const std::string &error_message); + void ResetEventDispatchState(); + bool IsDisposed() const; + void MarkDisposed(); + int64_t player_id_; std::mutex queue_mutex_; + std::unique_ptr ecore_wl2_window_proxy_ = nullptr; flutter::BinaryMessenger *binary_messenger_; bool is_initialized_ = false; FlutterDesktopViewRef flutter_view_; @@ -83,7 +98,6 @@ class VideoPlayer { } }; - // Event dispatch state structure for lifecycle management struct EventDispatchState { std::mutex mutex; VideoPlayer *player = nullptr; @@ -100,9 +114,6 @@ class VideoPlayer { std::queue encodable_event_queue_; std::queue> error_event_queue_; - std::unique_ptr> - event_channel_; - std::unique_ptr> event_sink_; }; } // namespace video_player_videohole_tizen diff --git a/packages/video_player_videohole/tizen/src/video_player_tizen_plugin.cc b/packages/video_player_videohole/tizen/src/video_player_tizen_plugin.cc index 50c3c076b..249838752 100644 --- a/packages/video_player_videohole/tizen/src/video_player_tizen_plugin.cc +++ b/packages/video_player_videohole/tizen/src/video_player_tizen_plugin.cc @@ -4,347 +4,61 @@ #include "video_player_tizen_plugin.h" -#include -#include #include #include -#include -#include -#include -#include -#include +#include -#include "media_player.h" -#include "messages.h" -#include "video_player.h" -#include "video_player_options.h" +#include "ffi_messages.h" +#include "log.h" namespace video_player_videohole_tizen { -class VideoPlayerTizenPlugin : public flutter::Plugin, - public VideoPlayerVideoholeApi { +class VideoPlayerTizenPlugin : public flutter::Plugin { public: static void RegisterWithRegistrar( FlutterDesktopPluginRegistrarRef registrar_ref, - flutter::PluginRegistrar *plugin_registrar); - - VideoPlayerTizenPlugin(FlutterDesktopPluginRegistrarRef registrar_ref, - flutter::PluginRegistrar *plugin_registrar); - virtual ~VideoPlayerTizenPlugin(); - - std::optional Initialize() override; - ErrorOr Create(const CreateMessage &msg) override; - std::optional Dispose(const PlayerMessage &msg) override; - ErrorOr Duration(const PlayerMessage &msg) override; - std::optional SetLooping(const LoopingMessage &msg) override; - std::optional SetVolume(const VolumeMessage &msg) override; - std::optional SetPlaybackSpeed( - const PlaybackSpeedMessage &msg) override; - ErrorOr Track(const TrackTypeMessage &msg) override; - ErrorOr SetTrackSelection(const SelectedTracksMessage &msg) override; - std::optional Play(const PlayerMessage &msg) override; - ErrorOr SetDeactivate(const PlayerMessage &msg) override; - ErrorOr SetActivate(const PlayerMessage &msg) override; - ErrorOr Position(const PlayerMessage &msg) override; - void SeekTo( - const PositionMessage &msg, - std::function reply)> result) override; - std::optional Pause(const PlayerMessage &msg) override; - std::optional SetMixWithOthers( - const MixWithOthersMessage &msg) override; - std::optional SetDisplayGeometry( - const GeometryMessage &msg) override; - std::optional Suspend(int64_t player_id) override; - std::optional Restore(int64_t palyer_id, - const CreateMessage *msg, - int64_t resume_time) override; - ErrorOr SetDisplayRotate(const RotationMessage &msg) override; - - static VideoPlayer *FindPlayerById(int64_t player_id) { - auto iter = players_.find(player_id); - if (iter != players_.end()) { - return iter->second.get(); - } - return nullptr; - } - - private: - void DisposeAllPlayers(); - void ParseFromCreateMessage(const CreateMessage &msg, std::string &uri, - int64_t &drm_type, - std::string &license_server_url, - bool &prebuffer_mode, - flutter::EncodableMap &http_headers); - - FlutterDesktopPluginRegistrarRef registrar_ref_; - flutter::PluginRegistrar *plugin_registrar_; - VideoPlayerOptions options_; - - static inline std::map> players_; -}; - -void VideoPlayerTizenPlugin::RegisterWithRegistrar( - FlutterDesktopPluginRegistrarRef registrar_ref, - flutter::PluginRegistrar *plugin_registrar) { - auto plugin = - std::make_unique(registrar_ref, plugin_registrar); - plugin_registrar->AddPlugin(std::move(plugin)); -} - -VideoPlayerTizenPlugin::VideoPlayerTizenPlugin( - FlutterDesktopPluginRegistrarRef registrar_ref, - flutter::PluginRegistrar *plugin_registrar) - : registrar_ref_(registrar_ref), plugin_registrar_(plugin_registrar) { - VideoPlayerVideoholeApi::SetUp(plugin_registrar->messenger(), this); -} - -VideoPlayerTizenPlugin::~VideoPlayerTizenPlugin() { DisposeAllPlayers(); } - -void VideoPlayerTizenPlugin::DisposeAllPlayers() { - for (const auto &[id, player] : players_) { - player->Dispose(); - } - players_.clear(); -} - -std::optional VideoPlayerTizenPlugin::Initialize() { - DisposeAllPlayers(); - return std::nullopt; -} - -ErrorOr VideoPlayerTizenPlugin::Create( - const CreateMessage &msg) { - if (!FlutterDesktopPluginRegistrarGetView(registrar_ref_)) { - return FlutterError("Operation failed", "Could not get a Flutter view."); - } - std::string uri; - - if (msg.asset() && !msg.asset()->empty()) { - char *res_path = app_get_resource_path(); - if (res_path) { - uri = uri + res_path + "flutter_assets/" + *msg.asset(); - free(res_path); - } else { - return FlutterError("Internal error", "Failed to get resource path."); - } - } else if (msg.uri() && !msg.uri()->empty()) { - uri = *msg.uri(); - } else { - return FlutterError("Invalid argument", "Either asset or uri must be set."); - } - - auto player = std::make_unique( - plugin_registrar_->messenger(), - FlutterDesktopPluginRegistrarGetView(registrar_ref_)); - int64_t player_id = player->Create(uri, msg); - if (player_id == -1) { - return FlutterError("Operation failed", "Failed to create a player."); - } - players_[player_id] = std::move(player); - PlayerMessage result(player_id); - return result; -} - -ErrorOr VideoPlayerTizenPlugin::Duration( - const PlayerMessage &msg) { - VideoPlayer *player = FindPlayerById(msg.player_id()); - if (!player) { - return FlutterError("Invalid argument", "Player not found."); - } - DurationMessage result(msg.player_id()); - auto duration_pair = player->GetDuration(); - flutter::EncodableList duration_range{ - flutter::EncodableValue(duration_pair.first), - flutter::EncodableValue(duration_pair.second)}; - result.set_duration_range(duration_range); - return result; -} - -std::optional VideoPlayerTizenPlugin::Dispose( - const PlayerMessage &msg) { - auto iter = players_.find(msg.player_id()); - if (iter != players_.end()) { - iter->second->Dispose(); - players_.erase(iter); - } - return std::nullopt; -} - -std::optional VideoPlayerTizenPlugin::SetLooping( - const LoopingMessage &msg) { - VideoPlayer *player = FindPlayerById(msg.player_id()); - if (!player) { - return FlutterError("Invalid argument", "Player not found"); - } - if (!player->SetLooping(msg.is_looping())) { - return FlutterError("SetLooping", "Player set looping failed"); - } - return std::nullopt; -} - -std::optional VideoPlayerTizenPlugin::SetVolume( - const VolumeMessage &msg) { - VideoPlayer *player = FindPlayerById(msg.player_id()); - if (!player) { - return FlutterError("Invalid argument", "Player not found"); - } - if (!player->SetVolume(msg.volume())) { - return FlutterError("SetVolume", "Player set volume failed"); - } - return std::nullopt; -} - -std::optional VideoPlayerTizenPlugin::SetPlaybackSpeed( - const PlaybackSpeedMessage &msg) { - VideoPlayer *player = FindPlayerById(msg.player_id()); - if (!player) { - return FlutterError("Invalid argument", "Player not found"); + flutter::PluginRegistrar* plugin_registrar) { + auto plugin = std::make_unique(registrar_ref); + plugin_registrar->AddPlugin(std::move(plugin)); } - if (!player->SetPlaybackSpeed(msg.speed())) { - return FlutterError("SetPlaybackSpeed", "Player set playback speed failed"); - } - return std::nullopt; -} - -ErrorOr VideoPlayerTizenPlugin::Track( - const TrackTypeMessage &msg) { - VideoPlayer *player = FindPlayerById(msg.player_id()); - if (!player) { - return FlutterError("Invalid argument", "Player not found"); - } - - TrackMessage result(msg.player_id(), player->GetTrackInfo(msg.track_type())); - return result; -} + explicit VideoPlayerTizenPlugin( + FlutterDesktopPluginRegistrarRef registrar_ref) + : registrar_ref_(registrar_ref) { + auto* plugin_registrar = + flutter::PluginRegistrarManager::GetInstance() + ->GetRegistrar(registrar_ref); + ffi_set_plugin_registrar(registrar_ref, plugin_registrar); -ErrorOr VideoPlayerTizenPlugin::SetTrackSelection( - const SelectedTracksMessage &msg) { - VideoPlayer *player = FindPlayerById(msg.player_id()); - if (!player) { - return FlutterError("Invalid argument", "Player not found"); + LOG_INFO("[VideoPlayerTizenPlugin] Registered with registrar"); } - return player->SetTrackSelection(msg.track_id(), msg.track_type()); -} - -std::optional VideoPlayerTizenPlugin::Play( - const PlayerMessage &msg) { - VideoPlayer *player = FindPlayerById(msg.player_id()); - if (!player) { - return FlutterError("Invalid argument", "Player not found"); - } - if (!player->Play()) { - return FlutterError("Play", "Player play failed"); - } - return std::nullopt; -} - -ErrorOr VideoPlayerTizenPlugin::SetDeactivate(const PlayerMessage &msg) { - VideoPlayer *player = FindPlayerById(msg.player_id()); - if (!player) { - return FlutterError("Invalid argument", "Player not found"); - } - return player->Deactivate(); -} - -ErrorOr VideoPlayerTizenPlugin::SetActivate(const PlayerMessage &msg) { - VideoPlayer *player = FindPlayerById(msg.player_id()); - if (!player) { - return FlutterError("Invalid argument", "Player not found"); - } - return player->Activate(); -} - -std::optional VideoPlayerTizenPlugin::Pause( - const PlayerMessage &msg) { - VideoPlayer *player = FindPlayerById(msg.player_id()); - if (!player) { - return FlutterError("Invalid argument", "Player not found"); - } - if (!player->Pause()) { - return FlutterError("Pause", "Player pause failed"); - } - return std::nullopt; -} -ErrorOr VideoPlayerTizenPlugin::Position( - const PlayerMessage &msg) { - VideoPlayer *player = FindPlayerById(msg.player_id()); - if (!player) { - return FlutterError("Invalid argument", "Player not found"); + ~VideoPlayerTizenPlugin() override { + LOG_INFO( + "[VideoPlayerTizenPlugin] Destroying plugin, cleaning up resources"); + ffi_dispose_all_players(); } - PositionMessage result(msg.player_id(), player->GetPosition()); - return result; -} -void VideoPlayerTizenPlugin::SeekTo( - const PositionMessage &msg, - std::function reply)> result) { - VideoPlayer *player = FindPlayerById(msg.player_id()); - if (!player) { - result(FlutterError("Invalid argument", "Player not found")); - return; - } - if (!player->SeekTo(msg.position(), - [result]() -> void { result(std::nullopt); })) { - result(FlutterError("SeekTo", "Player seek to failed")); - } -} + VideoPlayerTizenPlugin(const VideoPlayerTizenPlugin&) = delete; + VideoPlayerTizenPlugin& operator=(const VideoPlayerTizenPlugin&) = delete; -std::optional VideoPlayerTizenPlugin::SetDisplayGeometry( - const GeometryMessage &msg) { - VideoPlayer *player = FindPlayerById(msg.player_id()); - if (!player) { - return FlutterError("Invalid argument", "Player not found"); - } - player->SetDisplayRoi(msg.x(), msg.y(), msg.width(), msg.height()); - return std::nullopt; -} + private: + FlutterDesktopPluginRegistrarRef registrar_ref_; +}; -std::optional VideoPlayerTizenPlugin::SetMixWithOthers( - const MixWithOthersMessage &msg) { - options_.SetMixWithOthers(msg.mix_with_others()); - return std::nullopt; -} +extern "C" { -std::optional VideoPlayerTizenPlugin::Suspend(int64_t player_id) { - VideoPlayer *player = FindPlayerById(player_id); - if (!player) { - return FlutterError("Invalid argument", "Player not found"); - } - if (!player->Suspend()) { - return FlutterError("Operation failed", "Player suspend error"); - } - return std::nullopt; -} -std::optional VideoPlayerTizenPlugin::Restore( - int64_t player_id, const CreateMessage *msg, int64_t resume_time) { - VideoPlayer *player = FindPlayerById(player_id); - if (!player) { - return FlutterError("Invalid argument", "Player not found"); - } +void VideoPlayerTizenPluginRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar_ref) { + auto* plugin_registrar = + flutter::PluginRegistrarManager::GetInstance() + ->GetRegistrar(registrar_ref); - if (!player->Restore(msg, resume_time)) { - return FlutterError("Operation failed", "Player restore error"); - } - return std::nullopt; + VideoPlayerTizenPlugin::RegisterWithRegistrar(registrar_ref, + plugin_registrar); } -ErrorOr VideoPlayerTizenPlugin::SetDisplayRotate( - const RotationMessage &msg) { - VideoPlayer *player = FindPlayerById(msg.player_id()); - if (!player) { - return FlutterError("Invalid argument", "Player not found"); - } - return player->SetDisplayRotate(msg.rotation()); -} +} // extern "C" } // namespace video_player_videohole_tizen - -void VideoPlayerTizenPluginRegisterWithRegistrar( - FlutterDesktopPluginRegistrarRef registrar) { - video_player_videohole_tizen::VideoPlayerTizenPlugin::RegisterWithRegistrar( - registrar, flutter::PluginRegistrarManager::GetInstance() - ->GetRegistrar(registrar)); -} diff --git a/packages/video_player_videohole/tizen/third_party/nlohmann_json/LICENSE b/packages/video_player_videohole/tizen/third_party/nlohmann_json/LICENSE new file mode 100644 index 000000000..2fd5ad781 --- /dev/null +++ b/packages/video_player_videohole/tizen/third_party/nlohmann_json/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013-2022 Niels Lohmann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/packages/video_player_videohole/tizen/third_party/nlohmann_json/LICENSES/Apache-2.0.txt b/packages/video_player_videohole/tizen/third_party/nlohmann_json/LICENSES/Apache-2.0.txt new file mode 100644 index 000000000..33666dddf --- /dev/null +++ b/packages/video_player_videohole/tizen/third_party/nlohmann_json/LICENSES/Apache-2.0.txt @@ -0,0 +1,73 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/packages/video_player_videohole/tizen/third_party/nlohmann_json/NOTICE b/packages/video_player_videohole/tizen/third_party/nlohmann_json/NOTICE new file mode 100644 index 000000000..efbc55ee1 --- /dev/null +++ b/packages/video_player_videohole/tizen/third_party/nlohmann_json/NOTICE @@ -0,0 +1,10 @@ +nlohmann/json + +This directory contains a vendored copy of nlohmann/json v3.11.2. +Source: https://github.com/nlohmann/json + +The nlohmann/json library is licensed under the MIT License. See LICENSE. + +The bundled json.hpp header also contains code derived from Google Abseil +(absl/utility/utility.h), which is licensed under the Apache License 2.0. +See LICENSES/Apache-2.0.txt. \ No newline at end of file diff --git a/packages/video_player_videohole/tizen/third_party/nlohmann_json/json.hpp b/packages/video_player_videohole/tizen/third_party/nlohmann_json/json.hpp new file mode 100644 index 000000000..4d1a37ad7 --- /dev/null +++ b/packages/video_player_videohole/tizen/third_party/nlohmann_json/json.hpp @@ -0,0 +1,24596 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +/****************************************************************************\ + * Note on documentation: The source files contain links to the online * + * documentation of the public API at https://json.nlohmann.me. This URL * + * contains the most recent documentation and should also be applicable to * + * previous versions; documentation for deprecated functions is not * + * removed, but marked deprecated. See "Generate documentation" section in * + * file docs/README.md. * +\****************************************************************************/ + +#ifndef INCLUDE_NLOHMANN_JSON_HPP_ +#define INCLUDE_NLOHMANN_JSON_HPP_ + +#include // all_of, find, for_each +#include // nullptr_t, ptrdiff_t, size_t +#include // hash, less +#include // initializer_list +#ifndef JSON_NO_IO + #include // istream, ostream +#endif // JSON_NO_IO +#include // random_access_iterator_tag +#include // unique_ptr +#include // accumulate +#include // string, stoi, to_string +#include // declval, forward, move, pair, swap +#include // vector + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// This file contains all macro definitions affecting or depending on the ABI + +#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK + #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) + #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 2 + #warning "Already included a different version of the library!" + #endif + #endif +#endif + +#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_PATCH 2 // NOLINT(modernize-macro-to-enum) + +#ifndef JSON_DIAGNOSTICS + #define JSON_DIAGNOSTICS 0 +#endif + +#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 +#endif + +#if JSON_DIAGNOSTICS + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag +#else + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS +#endif + +#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp +#else + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION + #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 +#endif + +// Construct the namespace ABI tags component +#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b +#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \ + NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) + +#define NLOHMANN_JSON_ABI_TAGS \ + NLOHMANN_JSON_ABI_TAGS_CONCAT( \ + NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ + NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON) + +// Construct the namespace version component +#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ + _v ## major ## _ ## minor ## _ ## patch +#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) + +#if NLOHMANN_JSON_NAMESPACE_NO_VERSION +#define NLOHMANN_JSON_NAMESPACE_VERSION +#else +#define NLOHMANN_JSON_NAMESPACE_VERSION \ + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ + NLOHMANN_JSON_VERSION_MINOR, \ + NLOHMANN_JSON_VERSION_PATCH) +#endif + +// Combine namespace components +#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b +#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ + NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) + +#ifndef NLOHMANN_JSON_NAMESPACE +#define NLOHMANN_JSON_NAMESPACE \ + nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ + NLOHMANN_JSON_ABI_TAGS, \ + NLOHMANN_JSON_NAMESPACE_VERSION) +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN +#define NLOHMANN_JSON_NAMESPACE_BEGIN \ + namespace nlohmann \ + { \ + inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ + NLOHMANN_JSON_ABI_TAGS, \ + NLOHMANN_JSON_NAMESPACE_VERSION) \ + { +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_END +#define NLOHMANN_JSON_NAMESPACE_END \ + } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ + } // namespace nlohmann +#endif + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // transform +#include // array +#include // forward_list +#include // inserter, front_inserter, end +#include // map +#include // string +#include // tuple, make_tuple +#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible +#include // unordered_map +#include // pair, declval +#include // valarray + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // nullptr_t +#include // exception +#include // runtime_error +#include // to_string +#include // vector + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // array +#include // size_t +#include // uint8_t +#include // string + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // declval, pair +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template struct make_void +{ + using type = void; +}; +template using void_t = typename make_void::type; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +// https://en.cppreference.com/w/cpp/experimental/is_detected +struct nonesuch +{ + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const&) = delete; + nonesuch(nonesuch const&&) = delete; + void operator=(nonesuch const&) = delete; + void operator=(nonesuch&&) = delete; +}; + +template class Op, + class... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +template class Op, class... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +template class Op, class... Args> +using is_detected = typename detector::value_t; + +template class Op, class... Args> +struct is_detected_lazy : is_detected { }; + +template class Op, class... Args> +using detected_t = typename detector::type; + +template class Op, class... Args> +using detected_or = detector; + +template class Op, class... Args> +using detected_or_t = typename detected_or::type; + +template class Op, class... Args> +using is_detected_exact = std::is_same>; + +template class Op, class... Args> +using is_detected_convertible = + std::is_convertible, To>; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include + + +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-FileCopyrightText: 2016-2021 Evan Nemerson +// SPDX-License-Identifier: MIT + +/* Hedley - https://nemequ.github.io/hedley + * Created by Evan Nemerson + */ + +#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15) +#if defined(JSON_HEDLEY_VERSION) + #undef JSON_HEDLEY_VERSION +#endif +#define JSON_HEDLEY_VERSION 15 + +#if defined(JSON_HEDLEY_STRINGIFY_EX) + #undef JSON_HEDLEY_STRINGIFY_EX +#endif +#define JSON_HEDLEY_STRINGIFY_EX(x) #x + +#if defined(JSON_HEDLEY_STRINGIFY) + #undef JSON_HEDLEY_STRINGIFY +#endif +#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x) + +#if defined(JSON_HEDLEY_CONCAT_EX) + #undef JSON_HEDLEY_CONCAT_EX +#endif +#define JSON_HEDLEY_CONCAT_EX(a,b) a##b + +#if defined(JSON_HEDLEY_CONCAT) + #undef JSON_HEDLEY_CONCAT +#endif +#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) + +#if defined(JSON_HEDLEY_CONCAT3_EX) + #undef JSON_HEDLEY_CONCAT3_EX +#endif +#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c + +#if defined(JSON_HEDLEY_CONCAT3) + #undef JSON_HEDLEY_CONCAT3 +#endif +#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c) + +#if defined(JSON_HEDLEY_VERSION_ENCODE) + #undef JSON_HEDLEY_VERSION_ENCODE +#endif +#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) + +#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR) + #undef JSON_HEDLEY_VERSION_DECODE_MAJOR +#endif +#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) + +#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR) + #undef JSON_HEDLEY_VERSION_DECODE_MINOR +#endif +#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) + +#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION) + #undef JSON_HEDLEY_VERSION_DECODE_REVISION +#endif +#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) + +#if defined(JSON_HEDLEY_GNUC_VERSION) + #undef JSON_HEDLEY_GNUC_VERSION +#endif +#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) + #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) +#elif defined(__GNUC__) + #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) +#endif + +#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK) + #undef JSON_HEDLEY_GNUC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_GNUC_VERSION) + #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_MSVC_VERSION) + #undef JSON_HEDLEY_MSVC_VERSION +#endif +#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL) + #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) +#elif defined(_MSC_FULL_VER) && !defined(__ICL) + #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) +#elif defined(_MSC_VER) && !defined(__ICL) + #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) +#endif + +#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) + #undef JSON_HEDLEY_MSVC_VERSION_CHECK +#endif +#if !defined(JSON_HEDLEY_MSVC_VERSION) + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) +#elif defined(_MSC_VER) && (_MSC_VER >= 1200) + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) +#else + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) +#endif + +#if defined(JSON_HEDLEY_INTEL_VERSION) + #undef JSON_HEDLEY_INTEL_VERSION +#endif +#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL) + #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) +#elif defined(__INTEL_COMPILER) && !defined(__ICL) + #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) +#endif + +#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK) + #undef JSON_HEDLEY_INTEL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_INTEL_VERSION) + #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_INTEL_CL_VERSION) + #undef JSON_HEDLEY_INTEL_CL_VERSION +#endif +#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL) + #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0) +#endif + +#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK) + #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_INTEL_CL_VERSION) + #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_PGI_VERSION) + #undef JSON_HEDLEY_PGI_VERSION +#endif +#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) + #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) +#endif + +#if defined(JSON_HEDLEY_PGI_VERSION_CHECK) + #undef JSON_HEDLEY_PGI_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_PGI_VERSION) + #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_SUNPRO_VERSION) + #undef JSON_HEDLEY_SUNPRO_VERSION +#endif +#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10) +#elif defined(__SUNPRO_C) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) +#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10) +#elif defined(__SUNPRO_CC) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) +#endif + +#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK) + #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_SUNPRO_VERSION) + #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) + #undef JSON_HEDLEY_EMSCRIPTEN_VERSION +#endif +#if defined(__EMSCRIPTEN__) + #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) +#endif + +#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK) + #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) + #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_ARM_VERSION) + #undef JSON_HEDLEY_ARM_VERSION +#endif +#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) + #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) +#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) + #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) +#endif + +#if defined(JSON_HEDLEY_ARM_VERSION_CHECK) + #undef JSON_HEDLEY_ARM_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_ARM_VERSION) + #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_IBM_VERSION) + #undef JSON_HEDLEY_IBM_VERSION +#endif +#if defined(__ibmxl__) + #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) +#elif defined(__xlC__) && defined(__xlC_ver__) + #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) +#elif defined(__xlC__) + #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) +#endif + +#if defined(JSON_HEDLEY_IBM_VERSION_CHECK) + #undef JSON_HEDLEY_IBM_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_IBM_VERSION) + #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_VERSION) + #undef JSON_HEDLEY_TI_VERSION +#endif +#if \ + defined(__TI_COMPILER_VERSION__) && \ + ( \ + defined(__TMS470__) || defined(__TI_ARM__) || \ + defined(__MSP430__) || \ + defined(__TMS320C2000__) \ + ) +#if (__TI_COMPILER_VERSION__ >= 16000000) + #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif +#endif + +#if defined(JSON_HEDLEY_TI_VERSION_CHECK) + #undef JSON_HEDLEY_TI_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_VERSION) + #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL2000_VERSION) + #undef JSON_HEDLEY_TI_CL2000_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__) + #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL2000_VERSION) + #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL430_VERSION) + #undef JSON_HEDLEY_TI_CL430_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) + #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL430_VERSION) + #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) + #undef JSON_HEDLEY_TI_ARMCL_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__)) + #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK) + #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) + #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL6X_VERSION) + #undef JSON_HEDLEY_TI_CL6X_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__) + #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL6X_VERSION) + #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL7X_VERSION) + #undef JSON_HEDLEY_TI_CL7X_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__) + #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL7X_VERSION) + #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) + #undef JSON_HEDLEY_TI_CLPRU_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__) + #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) + #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_CRAY_VERSION) + #undef JSON_HEDLEY_CRAY_VERSION +#endif +#if defined(_CRAYC) + #if defined(_RELEASE_PATCHLEVEL) + #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) + #else + #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) + #endif +#endif + +#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK) + #undef JSON_HEDLEY_CRAY_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_CRAY_VERSION) + #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_IAR_VERSION) + #undef JSON_HEDLEY_IAR_VERSION +#endif +#if defined(__IAR_SYSTEMS_ICC__) + #if __VER__ > 1000 + #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) + #else + #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0) + #endif +#endif + +#if defined(JSON_HEDLEY_IAR_VERSION_CHECK) + #undef JSON_HEDLEY_IAR_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_IAR_VERSION) + #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TINYC_VERSION) + #undef JSON_HEDLEY_TINYC_VERSION +#endif +#if defined(__TINYC__) + #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) +#endif + +#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK) + #undef JSON_HEDLEY_TINYC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TINYC_VERSION) + #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_DMC_VERSION) + #undef JSON_HEDLEY_DMC_VERSION +#endif +#if defined(__DMC__) + #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) +#endif + +#if defined(JSON_HEDLEY_DMC_VERSION_CHECK) + #undef JSON_HEDLEY_DMC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_DMC_VERSION) + #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_COMPCERT_VERSION) + #undef JSON_HEDLEY_COMPCERT_VERSION +#endif +#if defined(__COMPCERT_VERSION__) + #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) +#endif + +#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK) + #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_COMPCERT_VERSION) + #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_PELLES_VERSION) + #undef JSON_HEDLEY_PELLES_VERSION +#endif +#if defined(__POCC__) + #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) +#endif + +#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK) + #undef JSON_HEDLEY_PELLES_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_PELLES_VERSION) + #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_MCST_LCC_VERSION) + #undef JSON_HEDLEY_MCST_LCC_VERSION +#endif +#if defined(__LCC__) && defined(__LCC_MINOR__) + #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__) +#endif + +#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK) + #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_MCST_LCC_VERSION) + #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_GCC_VERSION) + #undef JSON_HEDLEY_GCC_VERSION +#endif +#if \ + defined(JSON_HEDLEY_GNUC_VERSION) && \ + !defined(__clang__) && \ + !defined(JSON_HEDLEY_INTEL_VERSION) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_ARM_VERSION) && \ + !defined(JSON_HEDLEY_CRAY_VERSION) && \ + !defined(JSON_HEDLEY_TI_VERSION) && \ + !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL430_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ + !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ + !defined(__COMPCERT__) && \ + !defined(JSON_HEDLEY_MCST_LCC_VERSION) + #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION +#endif + +#if defined(JSON_HEDLEY_GCC_VERSION_CHECK) + #undef JSON_HEDLEY_GCC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_GCC_VERSION) + #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_HAS_ATTRIBUTE +#endif +#if \ + defined(__has_attribute) && \ + ( \ + (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \ + ) +# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) +#else +# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE +#endif +#if defined(__has_attribute) + #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) +#else + #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE +#endif +#if defined(__has_attribute) + #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) +#else + #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE +#endif +#if \ + defined(__has_cpp_attribute) && \ + defined(__cplusplus) && \ + (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) +#else + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) +#endif + +#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS) + #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS +#endif +#if !defined(__cplusplus) || !defined(__has_cpp_attribute) + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) +#elif \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_IAR_VERSION) && \ + (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ + (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) +#else + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE +#endif +#if defined(__has_cpp_attribute) && defined(__cplusplus) + #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) +#else + #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE +#endif +#if defined(__has_cpp_attribute) && defined(__cplusplus) + #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) +#else + #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_BUILTIN) + #undef JSON_HEDLEY_HAS_BUILTIN +#endif +#if defined(__has_builtin) + #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) +#else + #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN) + #undef JSON_HEDLEY_GNUC_HAS_BUILTIN +#endif +#if defined(__has_builtin) + #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) +#else + #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN) + #undef JSON_HEDLEY_GCC_HAS_BUILTIN +#endif +#if defined(__has_builtin) + #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) +#else + #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_FEATURE) + #undef JSON_HEDLEY_HAS_FEATURE +#endif +#if defined(__has_feature) + #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature) +#else + #define JSON_HEDLEY_HAS_FEATURE(feature) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE) + #undef JSON_HEDLEY_GNUC_HAS_FEATURE +#endif +#if defined(__has_feature) + #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) +#else + #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_FEATURE) + #undef JSON_HEDLEY_GCC_HAS_FEATURE +#endif +#if defined(__has_feature) + #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) +#else + #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_EXTENSION) + #undef JSON_HEDLEY_HAS_EXTENSION +#endif +#if defined(__has_extension) + #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) +#else + #define JSON_HEDLEY_HAS_EXTENSION(extension) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION) + #undef JSON_HEDLEY_GNUC_HAS_EXTENSION +#endif +#if defined(__has_extension) + #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) +#else + #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION) + #undef JSON_HEDLEY_GCC_HAS_EXTENSION +#endif +#if defined(__has_extension) + #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) +#else + #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE +#endif +#if defined(__has_declspec_attribute) + #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) +#else + #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE +#endif +#if defined(__has_declspec_attribute) + #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) +#else + #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE +#endif +#if defined(__has_declspec_attribute) + #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) +#else + #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_WARNING) + #undef JSON_HEDLEY_HAS_WARNING +#endif +#if defined(__has_warning) + #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning) +#else + #define JSON_HEDLEY_HAS_WARNING(warning) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_WARNING) + #undef JSON_HEDLEY_GNUC_HAS_WARNING +#endif +#if defined(__has_warning) + #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) +#else + #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_WARNING) + #undef JSON_HEDLEY_GCC_HAS_WARNING +#endif +#if defined(__has_warning) + #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) +#else + #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ + defined(__clang__) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ + (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) + #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value) +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) + #define JSON_HEDLEY_PRAGMA(value) __pragma(value) +#else + #define JSON_HEDLEY_PRAGMA(value) +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH) + #undef JSON_HEDLEY_DIAGNOSTIC_PUSH +#endif +#if defined(JSON_HEDLEY_DIAGNOSTIC_POP) + #undef JSON_HEDLEY_DIAGNOSTIC_POP +#endif +#if defined(__clang__) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) + #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) +#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") +#else + #define JSON_HEDLEY_DIAGNOSTIC_PUSH + #define JSON_HEDLEY_DIAGNOSTIC_POP +#endif + +/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for + HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ +#endif +#if defined(__cplusplus) +# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") +# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") +# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions") +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ + _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# endif +# else +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# endif +# endif +#endif +#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x +#endif + +#if defined(JSON_HEDLEY_CONST_CAST) + #undef JSON_HEDLEY_CONST_CAST +#endif +#if defined(__cplusplus) +# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) +#elif \ + JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ + ((T) (expr)); \ + JSON_HEDLEY_DIAGNOSTIC_POP \ + })) +#else +# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_REINTERPRET_CAST) + #undef JSON_HEDLEY_REINTERPRET_CAST +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) +#else + #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_STATIC_CAST) + #undef JSON_HEDLEY_STATIC_CAST +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) +#else + #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_CPP_CAST) + #undef JSON_HEDLEY_CPP_CAST +#endif +#if defined(__cplusplus) +# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast") +# define JSON_HEDLEY_CPP_CAST(T, expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ + ((T) (expr)) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0) +# define JSON_HEDLEY_CPP_CAST(T, expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("diag_suppress=Pe137") \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) +# endif +#else +# define JSON_HEDLEY_CPP_CAST(T, expr) (expr) +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445") +#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292)) +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098") +#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097") +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunused-function") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505)) +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION +#endif + +#if defined(JSON_HEDLEY_DEPRECATED) + #undef JSON_HEDLEY_DEPRECATED +#endif +#if defined(JSON_HEDLEY_DEPRECATED_FOR) + #undef JSON_HEDLEY_DEPRECATED_FOR +#endif +#if \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) +#elif \ + (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) +#elif defined(__cplusplus) && (__cplusplus >= 201402L) + #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) +#elif \ + JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) + #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated") + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") +#else + #define JSON_HEDLEY_DEPRECATED(since) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) +#endif + +#if defined(JSON_HEDLEY_UNAVAILABLE) + #undef JSON_HEDLEY_UNAVAILABLE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) +#else + #define JSON_HEDLEY_UNAVAILABLE(available_since) +#endif + +#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) + #undef JSON_HEDLEY_WARN_UNUSED_RESULT +#endif +#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) + #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__)) +#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L) + #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]]) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) + #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) +#elif defined(_Check_return_) /* SAL */ + #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_ +#else + #define JSON_HEDLEY_WARN_UNUSED_RESULT + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) +#endif + +#if defined(JSON_HEDLEY_SENTINEL) + #undef JSON_HEDLEY_SENTINEL +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) +#else + #define JSON_HEDLEY_SENTINEL(position) +#endif + +#if defined(JSON_HEDLEY_NO_RETURN) + #undef JSON_HEDLEY_NO_RETURN +#endif +#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_NO_RETURN __noreturn +#elif \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L + #define JSON_HEDLEY_NO_RETURN _Noreturn +#elif defined(__cplusplus) && (__cplusplus >= 201103L) + #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]]) +#elif \ + JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) + #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) + #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) + #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") +#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) + #define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) + #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) +#else + #define JSON_HEDLEY_NO_RETURN +#endif + +#if defined(JSON_HEDLEY_NO_ESCAPE) + #undef JSON_HEDLEY_NO_ESCAPE +#endif +#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape) + #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__)) +#else + #define JSON_HEDLEY_NO_ESCAPE +#endif + +#if defined(JSON_HEDLEY_UNREACHABLE) + #undef JSON_HEDLEY_UNREACHABLE +#endif +#if defined(JSON_HEDLEY_UNREACHABLE_RETURN) + #undef JSON_HEDLEY_UNREACHABLE_RETURN +#endif +#if defined(JSON_HEDLEY_ASSUME) + #undef JSON_HEDLEY_ASSUME +#endif +#if \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_ASSUME(expr) __assume(expr) +#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) + #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) +#elif \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) + #if defined(__cplusplus) + #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) + #else + #define JSON_HEDLEY_ASSUME(expr) _nassert(expr) + #endif +#endif +#if \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() +#elif defined(JSON_HEDLEY_ASSUME) + #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) +#endif +#if !defined(JSON_HEDLEY_ASSUME) + #if defined(JSON_HEDLEY_UNREACHABLE) + #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1))) + #else + #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr) + #endif +#endif +#if defined(JSON_HEDLEY_UNREACHABLE) + #if \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value)) + #else + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() + #endif +#else + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value) +#endif +#if !defined(JSON_HEDLEY_UNREACHABLE) + #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) +#endif + +JSON_HEDLEY_DIAGNOSTIC_PUSH +#if JSON_HEDLEY_HAS_WARNING("-Wpedantic") + #pragma clang diagnostic ignored "-Wpedantic" +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus) + #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" +#endif +#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0) + #if defined(__clang__) + #pragma clang diagnostic ignored "-Wvariadic-macros" + #elif defined(JSON_HEDLEY_GCC_VERSION) + #pragma GCC diagnostic ignored "-Wvariadic-macros" + #endif +#endif +#if defined(JSON_HEDLEY_NON_NULL) + #undef JSON_HEDLEY_NON_NULL +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) + #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) +#else + #define JSON_HEDLEY_NON_NULL(...) +#endif +JSON_HEDLEY_DIAGNOSTIC_POP + +#if defined(JSON_HEDLEY_PRINTF_FORMAT) + #undef JSON_HEDLEY_PRINTF_FORMAT +#endif +#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) +#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) +#elif \ + JSON_HEDLEY_HAS_ATTRIBUTE(format) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) +#else + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) +#endif + +#if defined(JSON_HEDLEY_CONSTEXPR) + #undef JSON_HEDLEY_CONSTEXPR +#endif +#if defined(__cplusplus) + #if __cplusplus >= 201103L + #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr) + #endif +#endif +#if !defined(JSON_HEDLEY_CONSTEXPR) + #define JSON_HEDLEY_CONSTEXPR +#endif + +#if defined(JSON_HEDLEY_PREDICT) + #undef JSON_HEDLEY_PREDICT +#endif +#if defined(JSON_HEDLEY_LIKELY) + #undef JSON_HEDLEY_LIKELY +#endif +#if defined(JSON_HEDLEY_UNLIKELY) + #undef JSON_HEDLEY_UNLIKELY +#endif +#if defined(JSON_HEDLEY_UNPREDICTABLE) + #undef JSON_HEDLEY_UNPREDICTABLE +#endif +#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) + #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) +#endif +#if \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability)) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability)) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability)) +# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 ) +# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 ) +#elif \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PREDICT(expr, expected, probability) \ + (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ + (__extension__ ({ \ + double hedley_probability_ = (probability); \ + ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ + })) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ + (__extension__ ({ \ + double hedley_probability_ = (probability); \ + ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ + })) +# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) +# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) +#else +# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) +# define JSON_HEDLEY_LIKELY(expr) (!!(expr)) +# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr)) +#endif +#if !defined(JSON_HEDLEY_UNPREDICTABLE) + #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5) +#endif + +#if defined(JSON_HEDLEY_MALLOC) + #undef JSON_HEDLEY_MALLOC +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) + #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_MALLOC __declspec(restrict) +#else + #define JSON_HEDLEY_MALLOC +#endif + +#if defined(JSON_HEDLEY_PURE) + #undef JSON_HEDLEY_PURE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PURE __attribute__((__pure__)) +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) +# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") +#elif defined(__cplusplus) && \ + ( \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \ + ) +# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") +#else +# define JSON_HEDLEY_PURE +#endif + +#if defined(JSON_HEDLEY_CONST) + #undef JSON_HEDLEY_CONST +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(const) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_CONST __attribute__((__const__)) +#elif \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) + #define JSON_HEDLEY_CONST _Pragma("no_side_effect") +#else + #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE +#endif + +#if defined(JSON_HEDLEY_RESTRICT) + #undef JSON_HEDLEY_RESTRICT +#endif +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) + #define JSON_HEDLEY_RESTRICT restrict +#elif \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ + defined(__clang__) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_RESTRICT __restrict +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) + #define JSON_HEDLEY_RESTRICT _Restrict +#else + #define JSON_HEDLEY_RESTRICT +#endif + +#if defined(JSON_HEDLEY_INLINE) + #undef JSON_HEDLEY_INLINE +#endif +#if \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ + (defined(__cplusplus) && (__cplusplus >= 199711L)) + #define JSON_HEDLEY_INLINE inline +#elif \ + defined(JSON_HEDLEY_GCC_VERSION) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0) + #define JSON_HEDLEY_INLINE __inline__ +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_INLINE __inline +#else + #define JSON_HEDLEY_INLINE +#endif + +#if defined(JSON_HEDLEY_ALWAYS_INLINE) + #undef JSON_HEDLEY_ALWAYS_INLINE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) +# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_ALWAYS_INLINE __forceinline +#elif defined(__cplusplus) && \ + ( \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \ + ) +# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) +# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") +#else +# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE +#endif + +#if defined(JSON_HEDLEY_NEVER_INLINE) + #undef JSON_HEDLEY_NEVER_INLINE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) + #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) + #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) + #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") +#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) + #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline)) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) + #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) +#else + #define JSON_HEDLEY_NEVER_INLINE +#endif + +#if defined(JSON_HEDLEY_PRIVATE) + #undef JSON_HEDLEY_PRIVATE +#endif +#if defined(JSON_HEDLEY_PUBLIC) + #undef JSON_HEDLEY_PUBLIC +#endif +#if defined(JSON_HEDLEY_IMPORT) + #undef JSON_HEDLEY_IMPORT +#endif +#if defined(_WIN32) || defined(__CYGWIN__) +# define JSON_HEDLEY_PRIVATE +# define JSON_HEDLEY_PUBLIC __declspec(dllexport) +# define JSON_HEDLEY_IMPORT __declspec(dllimport) +#else +# if \ + JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + ( \ + defined(__TI_EABI__) && \ + ( \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \ + ) \ + ) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) +# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) +# else +# define JSON_HEDLEY_PRIVATE +# define JSON_HEDLEY_PUBLIC +# endif +# define JSON_HEDLEY_IMPORT extern +#endif + +#if defined(JSON_HEDLEY_NO_THROW) + #undef JSON_HEDLEY_NO_THROW +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) + #define JSON_HEDLEY_NO_THROW __declspec(nothrow) +#else + #define JSON_HEDLEY_NO_THROW +#endif + +#if defined(JSON_HEDLEY_FALL_THROUGH) + #undef JSON_HEDLEY_FALL_THROUGH +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) + #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough) + #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]]) +#elif defined(__fallthrough) /* SAL */ + #define JSON_HEDLEY_FALL_THROUGH __fallthrough +#else + #define JSON_HEDLEY_FALL_THROUGH +#endif + +#if defined(JSON_HEDLEY_RETURNS_NON_NULL) + #undef JSON_HEDLEY_RETURNS_NON_NULL +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) +#elif defined(_Ret_notnull_) /* SAL */ + #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ +#else + #define JSON_HEDLEY_RETURNS_NON_NULL +#endif + +#if defined(JSON_HEDLEY_ARRAY_PARAM) + #undef JSON_HEDLEY_ARRAY_PARAM +#endif +#if \ + defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ + !defined(__STDC_NO_VLA__) && \ + !defined(__cplusplus) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_TINYC_VERSION) + #define JSON_HEDLEY_ARRAY_PARAM(name) (name) +#else + #define JSON_HEDLEY_ARRAY_PARAM(name) +#endif + +#if defined(JSON_HEDLEY_IS_CONSTANT) + #undef JSON_HEDLEY_IS_CONSTANT +#endif +#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR) + #undef JSON_HEDLEY_REQUIRE_CONSTEXPR +#endif +/* JSON_HEDLEY_IS_CONSTEXPR_ is for + HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ +#if defined(JSON_HEDLEY_IS_CONSTEXPR_) + #undef JSON_HEDLEY_IS_CONSTEXPR_ +#endif +#if \ + JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) +#endif +#if !defined(__cplusplus) +# if \ + JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24) +#if defined(__INTPTR_TYPE__) + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) +#else + #include + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) +#endif +# elif \ + ( \ + defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ + !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_IAR_VERSION)) || \ + (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0) +#if defined(__INTPTR_TYPE__) + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) +#else + #include + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) +#endif +# elif \ + defined(JSON_HEDLEY_GCC_VERSION) || \ + defined(JSON_HEDLEY_INTEL_VERSION) || \ + defined(JSON_HEDLEY_TINYC_VERSION) || \ + defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \ + defined(JSON_HEDLEY_TI_CL2000_VERSION) || \ + defined(JSON_HEDLEY_TI_CL6X_VERSION) || \ + defined(JSON_HEDLEY_TI_CL7X_VERSION) || \ + defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \ + defined(__clang__) +# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ + sizeof(void) != \ + sizeof(*( \ + 1 ? \ + ((void*) ((expr) * 0L) ) : \ +((struct { char v[sizeof(void) * 2]; } *) 1) \ + ) \ + ) \ + ) +# endif +#endif +#if defined(JSON_HEDLEY_IS_CONSTEXPR_) + #if !defined(JSON_HEDLEY_IS_CONSTANT) + #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr) + #endif + #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1)) +#else + #if !defined(JSON_HEDLEY_IS_CONSTANT) + #define JSON_HEDLEY_IS_CONSTANT(expr) (0) + #endif + #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) +#endif + +#if defined(JSON_HEDLEY_BEGIN_C_DECLS) + #undef JSON_HEDLEY_BEGIN_C_DECLS +#endif +#if defined(JSON_HEDLEY_END_C_DECLS) + #undef JSON_HEDLEY_END_C_DECLS +#endif +#if defined(JSON_HEDLEY_C_DECL) + #undef JSON_HEDLEY_C_DECL +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" { + #define JSON_HEDLEY_END_C_DECLS } + #define JSON_HEDLEY_C_DECL extern "C" +#else + #define JSON_HEDLEY_BEGIN_C_DECLS + #define JSON_HEDLEY_END_C_DECLS + #define JSON_HEDLEY_C_DECL +#endif + +#if defined(JSON_HEDLEY_STATIC_ASSERT) + #undef JSON_HEDLEY_STATIC_ASSERT +#endif +#if \ + !defined(__cplusplus) && ( \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ + (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + defined(_Static_assert) \ + ) +# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) +#elif \ + (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ + JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) +#else +# define JSON_HEDLEY_STATIC_ASSERT(expr, message) +#endif + +#if defined(JSON_HEDLEY_NULL) + #undef JSON_HEDLEY_NULL +#endif +#if defined(__cplusplus) + #if __cplusplus >= 201103L + #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr) + #elif defined(NULL) + #define JSON_HEDLEY_NULL NULL + #else + #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0) + #endif +#elif defined(NULL) + #define JSON_HEDLEY_NULL NULL +#else + #define JSON_HEDLEY_NULL ((void*) 0) +#endif + +#if defined(JSON_HEDLEY_MESSAGE) + #undef JSON_HEDLEY_MESSAGE +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") +# define JSON_HEDLEY_MESSAGE(msg) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ + JSON_HEDLEY_PRAGMA(message msg) \ + JSON_HEDLEY_DIAGNOSTIC_POP +#elif \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg) +#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg) +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) +#else +# define JSON_HEDLEY_MESSAGE(msg) +#endif + +#if defined(JSON_HEDLEY_WARNING) + #undef JSON_HEDLEY_WARNING +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") +# define JSON_HEDLEY_WARNING(msg) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ + JSON_HEDLEY_PRAGMA(clang warning msg) \ + JSON_HEDLEY_DIAGNOSTIC_POP +#elif \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) +#else +# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) +#endif + +#if defined(JSON_HEDLEY_REQUIRE) + #undef JSON_HEDLEY_REQUIRE +#endif +#if defined(JSON_HEDLEY_REQUIRE_MSG) + #undef JSON_HEDLEY_REQUIRE_MSG +#endif +#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if) +# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat") +# define JSON_HEDLEY_REQUIRE(expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ + __attribute__((diagnose_if(!(expr), #expr, "error"))) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ + __attribute__((diagnose_if(!(expr), msg, "error"))) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error"))) +# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error"))) +# endif +#else +# define JSON_HEDLEY_REQUIRE(expr) +# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) +#endif + +#if defined(JSON_HEDLEY_FLAGS) + #undef JSON_HEDLEY_FLAGS +#endif +#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion")) + #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) +#else + #define JSON_HEDLEY_FLAGS +#endif + +#if defined(JSON_HEDLEY_FLAGS_CAST) + #undef JSON_HEDLEY_FLAGS_CAST +#endif +#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0) +# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("warning(disable:188)") \ + ((T) (expr)); \ + JSON_HEDLEY_DIAGNOSTIC_POP \ + })) +#else +# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr) +#endif + +#if defined(JSON_HEDLEY_EMPTY_BASES) + #undef JSON_HEDLEY_EMPTY_BASES +#endif +#if \ + (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) +#else + #define JSON_HEDLEY_EMPTY_BASES +#endif + +/* Remaining macros are deprecated. */ + +#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) + #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK +#endif +#if defined(__clang__) + #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) +#else + #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE +#endif +#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) + +#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE +#endif +#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) + +#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN) + #undef JSON_HEDLEY_CLANG_HAS_BUILTIN +#endif +#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin) + +#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE) + #undef JSON_HEDLEY_CLANG_HAS_FEATURE +#endif +#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature) + +#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION) + #undef JSON_HEDLEY_CLANG_HAS_EXTENSION +#endif +#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension) + +#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE +#endif +#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) + +#if defined(JSON_HEDLEY_CLANG_HAS_WARNING) + #undef JSON_HEDLEY_CLANG_HAS_WARNING +#endif +#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning) + +#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ + + +// This file contains all internal macro definitions (except those affecting ABI) +// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them + +// #include + + +// exclude unsupported compilers +#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) + #if defined(__clang__) + #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 + #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) + #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 + #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #endif +#endif + +// C++ language standard detection +// if the user manually specified the used c++ version this is skipped +#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) + #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) + #define JSON_HAS_CPP_20 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) + #define JSON_HAS_CPP_14 + #endif + // the cpp 11 flag is always specified because it is the minimal required version + #define JSON_HAS_CPP_11 +#endif + +#ifdef __has_include + #if __has_include() + #include + #endif +#endif + +#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) + #ifdef JSON_HAS_CPP_17 + #if defined(__cpp_lib_filesystem) + #define JSON_HAS_FILESYSTEM 1 + #elif defined(__cpp_lib_experimental_filesystem) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif !defined(__has_include) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #endif + + // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/ + #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__clang_major__) && __clang_major__ < 7 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support + #if defined(_MSC_VER) && _MSC_VER < 1914 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before iOS 13 + #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before macOS Catalina + #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + #endif +#endif + +#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 +#endif + +#ifndef JSON_HAS_FILESYSTEM + #define JSON_HAS_FILESYSTEM 0 +#endif + +#ifndef JSON_HAS_THREE_WAY_COMPARISON + #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \ + && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L + #define JSON_HAS_THREE_WAY_COMPARISON 1 + #else + #define JSON_HAS_THREE_WAY_COMPARISON 0 + #endif +#endif + +#ifndef JSON_HAS_RANGES + // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error + #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427 + #define JSON_HAS_RANGES 0 + #elif defined(__cpp_lib_ranges) + #define JSON_HAS_RANGES 1 + #else + #define JSON_HAS_RANGES 0 + #endif +#endif + +#ifdef JSON_HAS_CPP_17 + #define JSON_INLINE_VARIABLE inline +#else + #define JSON_INLINE_VARIABLE +#endif + +#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address) + #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]] +#else + #define JSON_NO_UNIQUE_ADDRESS +#endif + +// disable documentation warnings on clang +#if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdocumentation" + #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" +#endif + +// allow disabling exceptions +#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) + #define JSON_THROW(exception) throw exception + #define JSON_TRY try + #define JSON_CATCH(exception) catch(exception) + #define JSON_INTERNAL_CATCH(exception) catch(exception) +#else + #include + #define JSON_THROW(exception) std::abort() + #define JSON_TRY if(true) + #define JSON_CATCH(exception) if(false) + #define JSON_INTERNAL_CATCH(exception) if(false) +#endif + +// override exception macros +#if defined(JSON_THROW_USER) + #undef JSON_THROW + #define JSON_THROW JSON_THROW_USER +#endif +#if defined(JSON_TRY_USER) + #undef JSON_TRY + #define JSON_TRY JSON_TRY_USER +#endif +#if defined(JSON_CATCH_USER) + #undef JSON_CATCH + #define JSON_CATCH JSON_CATCH_USER + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_CATCH_USER +#endif +#if defined(JSON_INTERNAL_CATCH_USER) + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER +#endif + +// allow overriding assert +#if !defined(JSON_ASSERT) + #include // assert + #define JSON_ASSERT(x) assert(x) +#endif + +// allow to access some private functions (needed by the test suite) +#if defined(JSON_TESTS_PRIVATE) + #define JSON_PRIVATE_UNLESS_TESTED public +#else + #define JSON_PRIVATE_UNLESS_TESTED private +#endif + +/*! +@brief macro to briefly define a mapping between an enum and JSON +@def NLOHMANN_JSON_SERIALIZE_ENUM +@since version 3.4.0 +*/ +#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ + template \ + inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [e](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.first == e; \ + }); \ + j = ((it != std::end(m)) ? it : std::begin(m))->second; \ + } \ + template \ + inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [&j](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.second == j; \ + }); \ + e = ((it != std::end(m)) ? it : std::begin(m))->first; \ + } + +// Ugly macros to avoid uglier copy-paste when specializing basic_json. They +// may be removed in the future once the class is split. + +#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ + template class ObjectType, \ + template class ArrayType, \ + class StringType, class BooleanType, class NumberIntegerType, \ + class NumberUnsignedType, class NumberFloatType, \ + template class AllocatorType, \ + template class JSONSerializer, \ + class BinaryType> + +#define NLOHMANN_BASIC_JSON_TPL \ + basic_json + +// Macros to simplify conversion from/to types + +#define NLOHMANN_JSON_EXPAND( x ) x +#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME +#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ + NLOHMANN_JSON_PASTE64, \ + NLOHMANN_JSON_PASTE63, \ + NLOHMANN_JSON_PASTE62, \ + NLOHMANN_JSON_PASTE61, \ + NLOHMANN_JSON_PASTE60, \ + NLOHMANN_JSON_PASTE59, \ + NLOHMANN_JSON_PASTE58, \ + NLOHMANN_JSON_PASTE57, \ + NLOHMANN_JSON_PASTE56, \ + NLOHMANN_JSON_PASTE55, \ + NLOHMANN_JSON_PASTE54, \ + NLOHMANN_JSON_PASTE53, \ + NLOHMANN_JSON_PASTE52, \ + NLOHMANN_JSON_PASTE51, \ + NLOHMANN_JSON_PASTE50, \ + NLOHMANN_JSON_PASTE49, \ + NLOHMANN_JSON_PASTE48, \ + NLOHMANN_JSON_PASTE47, \ + NLOHMANN_JSON_PASTE46, \ + NLOHMANN_JSON_PASTE45, \ + NLOHMANN_JSON_PASTE44, \ + NLOHMANN_JSON_PASTE43, \ + NLOHMANN_JSON_PASTE42, \ + NLOHMANN_JSON_PASTE41, \ + NLOHMANN_JSON_PASTE40, \ + NLOHMANN_JSON_PASTE39, \ + NLOHMANN_JSON_PASTE38, \ + NLOHMANN_JSON_PASTE37, \ + NLOHMANN_JSON_PASTE36, \ + NLOHMANN_JSON_PASTE35, \ + NLOHMANN_JSON_PASTE34, \ + NLOHMANN_JSON_PASTE33, \ + NLOHMANN_JSON_PASTE32, \ + NLOHMANN_JSON_PASTE31, \ + NLOHMANN_JSON_PASTE30, \ + NLOHMANN_JSON_PASTE29, \ + NLOHMANN_JSON_PASTE28, \ + NLOHMANN_JSON_PASTE27, \ + NLOHMANN_JSON_PASTE26, \ + NLOHMANN_JSON_PASTE25, \ + NLOHMANN_JSON_PASTE24, \ + NLOHMANN_JSON_PASTE23, \ + NLOHMANN_JSON_PASTE22, \ + NLOHMANN_JSON_PASTE21, \ + NLOHMANN_JSON_PASTE20, \ + NLOHMANN_JSON_PASTE19, \ + NLOHMANN_JSON_PASTE18, \ + NLOHMANN_JSON_PASTE17, \ + NLOHMANN_JSON_PASTE16, \ + NLOHMANN_JSON_PASTE15, \ + NLOHMANN_JSON_PASTE14, \ + NLOHMANN_JSON_PASTE13, \ + NLOHMANN_JSON_PASTE12, \ + NLOHMANN_JSON_PASTE11, \ + NLOHMANN_JSON_PASTE10, \ + NLOHMANN_JSON_PASTE9, \ + NLOHMANN_JSON_PASTE8, \ + NLOHMANN_JSON_PASTE7, \ + NLOHMANN_JSON_PASTE6, \ + NLOHMANN_JSON_PASTE5, \ + NLOHMANN_JSON_PASTE4, \ + NLOHMANN_JSON_PASTE3, \ + NLOHMANN_JSON_PASTE2, \ + NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) +#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) +#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) +#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) +#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) +#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) +#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) +#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) +#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) +#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) +#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) +#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) +#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) +#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) +#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) +#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) +#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) +#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) +#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) +#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) +#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) +#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) +#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) +#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) +#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) +#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) +#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) +#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) +#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) +#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) +#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) +#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) +#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) +#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) +#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) +#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) +#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) +#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) +#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) +#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) +#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) +#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) +#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) +#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) +#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) +#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) +#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) +#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) +#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) +#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) +#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) +#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) +#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) +#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) +#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) +#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) +#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) +#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) +#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) +#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) +#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) +#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) +#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) +#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) + +#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; +#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); +#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1); + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_INTRUSIVE +@since version 3.9.0 +*/ +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE +@since version 3.9.0 +*/ +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + + +// inspired from https://stackoverflow.com/a/26745591 +// allows to call any std function as if (e.g. with begin): +// using std::begin; begin(x); +// +// it allows using the detected idiom to retrieve the return type +// of such an expression +#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ + namespace detail { \ + using std::std_name; \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + } \ + \ + namespace detail2 { \ + struct std_name##_tag \ + { \ + }; \ + \ + template \ + std_name##_tag std_name(T&&...); \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + \ + template \ + struct would_call_std_##std_name \ + { \ + static constexpr auto const value = ::nlohmann::detail:: \ + is_detected_exact::value; \ + }; \ + } /* namespace detail2 */ \ + \ + template \ + struct would_call_std_##std_name : detail2::would_call_std_##std_name \ + { \ + } + +#ifndef JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_USE_IMPLICIT_CONVERSIONS 1 +#endif + +#if JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_EXPLICIT +#else + #define JSON_EXPLICIT explicit +#endif + +#ifndef JSON_DISABLE_ENUM_SERIALIZATION + #define JSON_DISABLE_ENUM_SERIALIZATION 0 +#endif + +#ifndef JSON_USE_GLOBAL_UDLS + #define JSON_USE_GLOBAL_UDLS 1 +#endif + +#if JSON_HAS_THREE_WAY_COMPARISON + #include // partial_ordering +#endif + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/////////////////////////// +// JSON type enumeration // +/////////////////////////// + +/*! +@brief the JSON type enumeration + +This enumeration collects the different JSON types. It is internally used to +distinguish the stored values, and the functions @ref basic_json::is_null(), +@ref basic_json::is_object(), @ref basic_json::is_array(), +@ref basic_json::is_string(), @ref basic_json::is_boolean(), +@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), +@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), +@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and +@ref basic_json::is_structured() rely on it. + +@note There are three enumeration entries (number_integer, number_unsigned, and +number_float), because the library distinguishes these three types for numbers: +@ref basic_json::number_unsigned_t is used for unsigned integers, +@ref basic_json::number_integer_t is used for signed integers, and +@ref basic_json::number_float_t is used for floating-point numbers or to +approximate integers which do not fit in the limits of their respective type. + +@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON +value with the default value for a given type + +@since version 1.0.0 +*/ +enum class value_t : std::uint8_t +{ + null, ///< null value + object, ///< object (unordered set of name/value pairs) + array, ///< array (ordered collection of values) + string, ///< string value + boolean, ///< boolean value + number_integer, ///< number value (signed integer) + number_unsigned, ///< number value (unsigned integer) + number_float, ///< number value (floating-point) + binary, ///< binary array (ordered collection of bytes) + discarded ///< discarded by the parser callback function +}; + +/*! +@brief comparison operator for JSON types + +Returns an ordering that is similar to Python: +- order: null < boolean < number < object < array < string < binary +- furthermore, each type is not smaller than itself +- discarded values are not comparable +- binary is represented as a b"" string in python and directly comparable to a + string; however, making a binary array directly comparable with a string would + be surprising behavior in a JSON file. + +@since version 1.0.0 +*/ +#if JSON_HAS_THREE_WAY_COMPARISON + inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD* +#else + inline bool operator<(const value_t lhs, const value_t rhs) noexcept +#endif +{ + static constexpr std::array order = {{ + 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, + 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, + 6 /* binary */ + } + }; + + const auto l_index = static_cast(lhs); + const auto r_index = static_cast(rhs); +#if JSON_HAS_THREE_WAY_COMPARISON + if (l_index < order.size() && r_index < order.size()) + { + return order[l_index] <=> order[r_index]; // *NOPAD* + } + return std::partial_ordering::unordered; +#else + return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; +#endif +} + +// GCC selects the built-in operator< over an operator rewritten from +// a user-defined spaceship operator +// Clang, MSVC, and ICC select the rewritten candidate +// (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200) +#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__) +inline bool operator<(const value_t lhs, const value_t rhs) noexcept +{ + return std::is_lt(lhs <=> rhs); // *NOPAD* +} +#endif + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/*! +@brief replace all occurrences of a substring by another string + +@param[in,out] s the string to manipulate; changed so that all + occurrences of @a f are replaced with @a t +@param[in] f the substring to replace with @a t +@param[in] t the string to replace @a f + +@pre The search string @a f must not be empty. **This precondition is +enforced with an assertion.** + +@since version 2.0.0 +*/ +template +inline void replace_substring(StringType& s, const StringType& f, + const StringType& t) +{ + JSON_ASSERT(!f.empty()); + for (auto pos = s.find(f); // find first occurrence of f + pos != StringType::npos; // make sure f was found + s.replace(pos, f.size(), t), // replace with t, and + pos = s.find(f, pos + t.size())) // find next occurrence of f + {} +} + +/*! + * @brief string escaping as described in RFC 6901 (Sect. 4) + * @param[in] s string to escape + * @return escaped string + * + * Note the order of escaping "~" to "~0" and "/" to "~1" is important. + */ +template +inline StringType escape(StringType s) +{ + replace_substring(s, StringType{"~"}, StringType{"~0"}); + replace_substring(s, StringType{"/"}, StringType{"~1"}); + return s; +} + +/*! + * @brief string unescaping as described in RFC 6901 (Sect. 4) + * @param[in] s string to unescape + * @return unescaped string + * + * Note the order of escaping "~1" to "/" and "~0" to "~" is important. + */ +template +static void unescape(StringType& s) +{ + replace_substring(s, StringType{"~1"}, StringType{"/"}); + replace_substring(s, StringType{"~0"}, StringType{"~"}); +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // size_t + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/// struct to capture the start position of the current token +struct position_t +{ + /// the total number of characters read + std::size_t chars_read_total = 0; + /// the number of characters read in the current line + std::size_t chars_read_current_line = 0; + /// the number of lines read + std::size_t lines_read = 0; + + /// conversion to size_t to preserve SAX interface + constexpr operator size_t() const + { + return chars_read_total; + } +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-FileCopyrightText: 2018 The Abseil Authors +// SPDX-License-Identifier: MIT + + + +#include // array +#include // size_t +#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type +#include // index_sequence, make_index_sequence, index_sequence_for + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +using uncvref_t = typename std::remove_cv::type>::type; + +#ifdef JSON_HAS_CPP_14 + +// the following utilities are natively available in C++14 +using std::enable_if_t; +using std::index_sequence; +using std::make_index_sequence; +using std::index_sequence_for; + +#else + +// alias templates to reduce boilerplate +template +using enable_if_t = typename std::enable_if::type; + +// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h +// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. + +//// START OF CODE FROM GOOGLE ABSEIL + +// integer_sequence +// +// Class template representing a compile-time integer sequence. An instantiation +// of `integer_sequence` has a sequence of integers encoded in its +// type through its template arguments (which is a common need when +// working with C++11 variadic templates). `absl::integer_sequence` is designed +// to be a drop-in replacement for C++14's `std::integer_sequence`. +// +// Example: +// +// template< class T, T... Ints > +// void user_function(integer_sequence); +// +// int main() +// { +// // user_function's `T` will be deduced to `int` and `Ints...` +// // will be deduced to `0, 1, 2, 3, 4`. +// user_function(make_integer_sequence()); +// } +template +struct integer_sequence +{ + using value_type = T; + static constexpr std::size_t size() noexcept + { + return sizeof...(Ints); + } +}; + +// index_sequence +// +// A helper template for an `integer_sequence` of `size_t`, +// `absl::index_sequence` is designed to be a drop-in replacement for C++14's +// `std::index_sequence`. +template +using index_sequence = integer_sequence; + +namespace utility_internal +{ + +template +struct Extend; + +// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. +template +struct Extend, SeqSize, 0> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; +}; + +template +struct Extend, SeqSize, 1> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; +}; + +// Recursion helper for 'make_integer_sequence'. +// 'Gen::type' is an alias for 'integer_sequence'. +template +struct Gen +{ + using type = + typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; +}; + +template +struct Gen +{ + using type = integer_sequence; +}; + +} // namespace utility_internal + +// Compile-time sequences of integers + +// make_integer_sequence +// +// This template alias is equivalent to +// `integer_sequence`, and is designed to be a drop-in +// replacement for C++14's `std::make_integer_sequence`. +template +using make_integer_sequence = typename utility_internal::Gen::type; + +// make_index_sequence +// +// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, +// and is designed to be a drop-in replacement for C++14's +// `std::make_index_sequence`. +template +using make_index_sequence = make_integer_sequence; + +// index_sequence_for +// +// Converts a typename pack into an index sequence of the same length, and +// is designed to be a drop-in replacement for C++14's +// `std::index_sequence_for()` +template +using index_sequence_for = make_index_sequence; + +//// END OF CODE FROM GOOGLE ABSEIL + +#endif + +// dispatch utility (taken from ranges-v3) +template struct priority_tag : priority_tag < N - 1 > {}; +template<> struct priority_tag<0> {}; + +// taken from ranges-v3 +template +struct static_const +{ + static JSON_INLINE_VARIABLE constexpr T value{}; +}; + +#ifndef JSON_HAS_CPP_17 + template + constexpr T static_const::value; +#endif + +template +inline constexpr std::array make_array(Args&& ... args) +{ + return std::array {{static_cast(std::forward(args))...}}; +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // numeric_limits +#include // false_type, is_constructible, is_integral, is_same, true_type +#include // declval +#include // tuple + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // random_access_iterator_tag + +// #include + +// #include + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +struct iterator_types {}; + +template +struct iterator_types < + It, + void_t> +{ + using difference_type = typename It::difference_type; + using value_type = typename It::value_type; + using pointer = typename It::pointer; + using reference = typename It::reference; + using iterator_category = typename It::iterator_category; +}; + +// This is required as some compilers implement std::iterator_traits in a way that +// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. +template +struct iterator_traits +{ +}; + +template +struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> + : iterator_types +{ +}; + +template +struct iterator_traits::value>> +{ + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = T*; + using reference = T&; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN + +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); + +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN + +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); + +NLOHMANN_JSON_NAMESPACE_END + +// #include + +// #include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.2 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann +// SPDX-License-Identifier: MIT + +#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ + #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ + + #include // int64_t, uint64_t + #include // map + #include // allocator + #include // string + #include // vector + + // #include + + + /*! + @brief namespace for Niels Lohmann + @see https://github.com/nlohmann + @since version 1.0.0 + */ + NLOHMANN_JSON_NAMESPACE_BEGIN + + /*! + @brief default JSONSerializer template argument + + This serializer ignores the template arguments and uses ADL + ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) + for serialization. + */ + template + struct adl_serializer; + + /// a class to store JSON values + /// @sa https://json.nlohmann.me/api/basic_json/ + template class ObjectType = + std::map, + template class ArrayType = std::vector, + class StringType = std::string, class BooleanType = bool, + class NumberIntegerType = std::int64_t, + class NumberUnsignedType = std::uint64_t, + class NumberFloatType = double, + template class AllocatorType = std::allocator, + template class JSONSerializer = + adl_serializer, + class BinaryType = std::vector> + class basic_json; + + /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document + /// @sa https://json.nlohmann.me/api/json_pointer/ + template + class json_pointer; + + /*! + @brief default specialization + @sa https://json.nlohmann.me/api/json/ + */ + using json = basic_json<>; + + /// @brief a minimal map-like container that preserves insertion order + /// @sa https://json.nlohmann.me/api/ordered_map/ + template + struct ordered_map; + + /// @brief specialization that maintains the insertion order of object keys + /// @sa https://json.nlohmann.me/api/ordered_json/ + using ordered_json = basic_json; + + NLOHMANN_JSON_NAMESPACE_END + +#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ + + +NLOHMANN_JSON_NAMESPACE_BEGIN +/*! +@brief detail namespace with internal helper functions + +This namespace collects functions that should not be exposed, +implementations of some @ref basic_json methods, and meta-programming helpers. + +@since version 2.1.0 +*/ +namespace detail +{ + +///////////// +// helpers // +///////////// + +// Note to maintainers: +// +// Every trait in this file expects a non CV-qualified type. +// The only exceptions are in the 'aliases for detected' section +// (i.e. those of the form: decltype(T::member_function(std::declval()))) +// +// In this case, T has to be properly CV-qualified to constraint the function arguments +// (e.g. to_json(BasicJsonType&, const T&)) + +template struct is_basic_json : std::false_type {}; + +NLOHMANN_BASIC_JSON_TPL_DECLARATION +struct is_basic_json : std::true_type {}; + +// used by exceptions create() member functions +// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t +// false_type otherwise +template +struct is_basic_json_context : + std::integral_constant < bool, + is_basic_json::type>::type>::value + || std::is_same::value > +{}; + +////////////////////// +// json_ref helpers // +////////////////////// + +template +class json_ref; + +template +struct is_json_ref : std::false_type {}; + +template +struct is_json_ref> : std::true_type {}; + +////////////////////////// +// aliases for detected // +////////////////////////// + +template +using mapped_type_t = typename T::mapped_type; + +template +using key_type_t = typename T::key_type; + +template +using value_type_t = typename T::value_type; + +template +using difference_type_t = typename T::difference_type; + +template +using pointer_t = typename T::pointer; + +template +using reference_t = typename T::reference; + +template +using iterator_category_t = typename T::iterator_category; + +template +using to_json_function = decltype(T::to_json(std::declval()...)); + +template +using from_json_function = decltype(T::from_json(std::declval()...)); + +template +using get_template_function = decltype(std::declval().template get()); + +// trait checking if JSONSerializer::from_json(json const&, udt&) exists +template +struct has_from_json : std::false_type {}; + +// trait checking if j.get is valid +// use this trait instead of std::is_constructible or std::is_convertible, +// both rely on, or make use of implicit conversions, and thus fail when T +// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) +template +struct is_getable +{ + static constexpr bool value = is_detected::value; +}; + +template +struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +// This trait checks if JSONSerializer::from_json(json const&) exists +// this overload is used for non-default-constructible user-defined-types +template +struct has_non_default_from_json : std::false_type {}; + +template +struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +// This trait checks if BasicJsonType::json_serializer::to_json exists +// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. +template +struct has_to_json : std::false_type {}; + +template +struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +template +using detect_key_compare = typename T::key_compare; + +template +struct has_key_compare : std::integral_constant::value> {}; + +// obtains the actual object key comparator +template +struct actual_object_comparator +{ + using object_t = typename BasicJsonType::object_t; + using object_comparator_t = typename BasicJsonType::default_object_comparator_t; + using type = typename std::conditional < has_key_compare::value, + typename object_t::key_compare, object_comparator_t>::type; +}; + +template +using actual_object_comparator_t = typename actual_object_comparator::type; + +/////////////////// +// is_ functions // +/////////////////// + +// https://en.cppreference.com/w/cpp/types/conjunction +template struct conjunction : std::true_type { }; +template struct conjunction : B { }; +template +struct conjunction +: std::conditional(B::value), conjunction, B>::type {}; + +// https://en.cppreference.com/w/cpp/types/negation +template struct negation : std::integral_constant < bool, !B::value > { }; + +// Reimplementation of is_constructible and is_default_constructible, due to them being broken for +// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). +// This causes compile errors in e.g. clang 3.5 or gcc 4.9. +template +struct is_default_constructible : std::is_default_constructible {}; + +template +struct is_default_constructible> + : conjunction, is_default_constructible> {}; + +template +struct is_default_constructible> + : conjunction, is_default_constructible> {}; + +template +struct is_default_constructible> + : conjunction...> {}; + +template +struct is_default_constructible> + : conjunction...> {}; + + +template +struct is_constructible : std::is_constructible {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + + +template +struct is_iterator_traits : std::false_type {}; + +template +struct is_iterator_traits> +{ + private: + using traits = iterator_traits; + + public: + static constexpr auto value = + is_detected::value && + is_detected::value && + is_detected::value && + is_detected::value && + is_detected::value; +}; + +template +struct is_range +{ + private: + using t_ref = typename std::add_lvalue_reference::type; + + using iterator = detected_t; + using sentinel = detected_t; + + // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator + // and https://en.cppreference.com/w/cpp/iterator/sentinel_for + // but reimplementing these would be too much work, as a lot of other concepts are used underneath + static constexpr auto is_iterator_begin = + is_iterator_traits>::value; + + public: + static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; +}; + +template +using iterator_t = enable_if_t::value, result_of_begin())>>; + +template +using range_value_t = value_type_t>>; + +// The following implementation of is_complete_type is taken from +// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ +// and is written by Xiang Fan who agreed to using it in this library. + +template +struct is_complete_type : std::false_type {}; + +template +struct is_complete_type : std::true_type {}; + +template +struct is_compatible_object_type_impl : std::false_type {}; + +template +struct is_compatible_object_type_impl < + BasicJsonType, CompatibleObjectType, + enable_if_t < is_detected::value&& + is_detected::value >> +{ + using object_t = typename BasicJsonType::object_t; + + // macOS's is_constructible does not play well with nonesuch... + static constexpr bool value = + is_constructible::value && + is_constructible::value; +}; + +template +struct is_compatible_object_type + : is_compatible_object_type_impl {}; + +template +struct is_constructible_object_type_impl : std::false_type {}; + +template +struct is_constructible_object_type_impl < + BasicJsonType, ConstructibleObjectType, + enable_if_t < is_detected::value&& + is_detected::value >> +{ + using object_t = typename BasicJsonType::object_t; + + static constexpr bool value = + (is_default_constructible::value && + (std::is_move_assignable::value || + std::is_copy_assignable::value) && + (is_constructible::value && + std::is_same < + typename object_t::mapped_type, + typename ConstructibleObjectType::mapped_type >::value)) || + (has_from_json::value || + has_non_default_from_json < + BasicJsonType, + typename ConstructibleObjectType::mapped_type >::value); +}; + +template +struct is_constructible_object_type + : is_constructible_object_type_impl {}; + +template +struct is_compatible_string_type +{ + static constexpr auto value = + is_constructible::value; +}; + +template +struct is_constructible_string_type +{ + // launder type through decltype() to fix compilation failure on ICPC +#ifdef __INTEL_COMPILER + using laundered_type = decltype(std::declval()); +#else + using laundered_type = ConstructibleStringType; +#endif + + static constexpr auto value = + conjunction < + is_constructible, + is_detected_exact>::value; +}; + +template +struct is_compatible_array_type_impl : std::false_type {}; + +template +struct is_compatible_array_type_impl < + BasicJsonType, CompatibleArrayType, + enable_if_t < + is_detected::value&& + is_iterator_traits>>::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 + !std::is_same>::value >> +{ + static constexpr bool value = + is_constructible>::value; +}; + +template +struct is_compatible_array_type + : is_compatible_array_type_impl {}; + +template +struct is_constructible_array_type_impl : std::false_type {}; + +template +struct is_constructible_array_type_impl < + BasicJsonType, ConstructibleArrayType, + enable_if_t::value >> + : std::true_type {}; + +template +struct is_constructible_array_type_impl < + BasicJsonType, ConstructibleArrayType, + enable_if_t < !std::is_same::value&& + !is_compatible_string_type::value&& + is_default_constructible::value&& +(std::is_move_assignable::value || + std::is_copy_assignable::value)&& +is_detected::value&& +is_iterator_traits>>::value&& +is_detected::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 +!std::is_same>::value&& + is_complete_type < + detected_t>::value >> +{ + using value_type = range_value_t; + + static constexpr bool value = + std::is_same::value || + has_from_json::value || + has_non_default_from_json < + BasicJsonType, + value_type >::value; +}; + +template +struct is_constructible_array_type + : is_constructible_array_type_impl {}; + +template +struct is_compatible_integer_type_impl : std::false_type {}; + +template +struct is_compatible_integer_type_impl < + RealIntegerType, CompatibleNumberIntegerType, + enable_if_t < std::is_integral::value&& + std::is_integral::value&& + !std::is_same::value >> +{ + // is there an assert somewhere on overflows? + using RealLimits = std::numeric_limits; + using CompatibleLimits = std::numeric_limits; + + static constexpr auto value = + is_constructible::value && + CompatibleLimits::is_integer && + RealLimits::is_signed == CompatibleLimits::is_signed; +}; + +template +struct is_compatible_integer_type + : is_compatible_integer_type_impl {}; + +template +struct is_compatible_type_impl: std::false_type {}; + +template +struct is_compatible_type_impl < + BasicJsonType, CompatibleType, + enable_if_t::value >> +{ + static constexpr bool value = + has_to_json::value; +}; + +template +struct is_compatible_type + : is_compatible_type_impl {}; + +template +struct is_constructible_tuple : std::false_type {}; + +template +struct is_constructible_tuple> : conjunction...> {}; + +template +struct is_json_iterator_of : std::false_type {}; + +template +struct is_json_iterator_of : std::true_type {}; + +template +struct is_json_iterator_of : std::true_type +{}; + +// checks if a given type T is a template specialization of Primary +template