From 27404765978ec92744192ac96d79b59e9e10b4ef Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Fri, 13 Sep 2024 19:36:06 +0200 Subject: [PATCH 01/51] WIP --- RDMSharp/Metadata/JSONDefinesResources.cs | 11 + RDMSharp/Metadata/MetadataDefineVersion.cs | 55 ++ RDMSharp/Metadata/MetadataFactory.cs | 27 + RDMSharp/Metadata/MetadataSchemaVersion.cs | 41 ++ RDMSharp/RDMSharp.csproj | 3 + .../e1.20/BOOT_SOFTWARE_VERSION_ID.json | 14 + .../e1.20/BOOT_SOFTWARE_VERSION_LABEL.json | 16 + .../1.0.0/Defines/e1.20/CAPTURE_PRESET.json | 35 ++ .../1.0.0/Defines/e1.20/CLEAR_STATUS_ID.json | 9 + .../1.0.0/Defines/e1.20/COMMS_STATUS.json | 16 + .../e1.20/CONTROLLER_FLAG_SUPPORT.json | 19 + .../Defines/e1.20/DEFAULT_SLOT_VALUE.json | 21 + .../1.0.0/Defines/e1.20/DEVICE_HOURS.json | 14 + .../1.0.0/Defines/e1.20/DEVICE_INFO.json | 109 ++++ .../1.0.0/Defines/e1.20/DEVICE_LABEL.json | 19 + .../e1.20/DEVICE_MODEL_DESCRIPTION.json | 16 + .../Defines/e1.20/DEVICE_POWER_CYCLES.json | 14 + .../1.0.0/Defines/e1.20/DISPLAY_INVERT.json | 23 + .../1.0.0/Defines/e1.20/DISPLAY_LEVEL.json | 21 + .../1.0.0/Defines/e1.20/DMX_PERSONALITY.json | 23 + .../e1.20/DMX_PERSONALITY_DESCRIPTION.json | 32 + .../Defines/e1.20/DMX_START_ADDRESS.json | 32 + .../1.0.0/Defines/e1.20/FACTORY_DEFAULTS.json | 17 + .../1.0.0/Defines/e1.20/IDENTIFY_DEVICE.json | 21 + .../1.0.0/Defines/e1.20/LAMP_HOURS.json | 14 + .../1.0.0/Defines/e1.20/LAMP_ON_MODE.json | 23 + .../1.0.0/Defines/e1.20/LAMP_STATE.json | 25 + .../1.0.0/Defines/e1.20/LAMP_STRIKES.json | 14 + .../1.0.0/Defines/e1.20/LANGUAGE.json | 21 + .../Defines/e1.20/LANGUAGE_CAPABILITIES.json | 22 + .../Defines/e1.20/MANUFACTURER_LABEL.json | 16 + .../1.0.0/Defines/e1.20/NACK_DESCRIPTION.json | 18 + .../1.0.0/Defines/e1.20/PACKED_PID_INDEX.json | 35 ++ .../1.0.0/Defines/e1.20/PACKED_PID_SUB.json | 57 ++ .../1.0.0/Defines/e1.20/PAN_INVERT.json | 21 + .../1.0.0/Defines/e1.20/PAN_TILT_SWAP.json | 21 + .../Defines/e1.20/PARAMETER_DESCRIPTION.json | 101 +++ .../Defines/e1.20/PERFORM_SELF_TEST.json | 23 + .../1.0.0/Defines/e1.20/POWER_STATE.json | 24 + .../1.0.0/Defines/e1.20/PRESET_PLAYBACK.json | 22 + .../Defines/e1.20/PRODUCT_DETAIL_ID_LIST.json | 99 +++ .../1.0.0/Defines/e1.20/PROXIED_DEVICES.json | 19 + .../Defines/e1.20/PROXIED_DEVICE_COUNT.json | 12 + .../1.0.0/Defines/e1.20/QUEUED_MESSAGE.json | 22 + .../e1.20/QUEUED_MESSAGE_PID_SUBSCRIBE.json | 9 + .../QUEUED_MESSAGE_SENSOR_SUBSCRIBE.json | 18 + .../1.0.0/Defines/e1.20/REAL_TIME_CLOCK.json | 55 ++ .../1.0.0/Defines/e1.20/RECORD_SENSORS.json | 11 + .../1.0.0/Defines/e1.20/RESET_DEVICE.json | 19 + .../Defines/e1.20/SELF_TEST_DESCRIPTION.json | 19 + .../Defines/e1.20/SENSOR_DEFINITION.json | 145 +++++ .../1.0.0/Defines/e1.20/SENSOR_VALUE.json | 20 + .../1.0.0/Defines/e1.20/SLOT_DESCRIPTION.json | 19 + .../1.0.0/Defines/e1.20/SLOT_INFO.json | 22 + .../Defines/e1.20/SOFTWARE_VERSION_LABEL.json | 16 + .../Defines/e1.20/STATUS_ID_DESCRIPTION.json | 18 + .../1.0.0/Defines/e1.20/STATUS_MESSAGES.json | 49 ++ .../SUB_DEVICE_STATUS_REPORT_THRESHOLD.json | 24 + .../Defines/e1.20/SUPPORTED_PARAMETERS.json | 18 + .../e1.20/SUPPORTED_PARAMETERS_ENHANCED.json | 33 + .../1.0.0/Defines/e1.20/TILT_INVERT.json | 21 + .../1.0.0/Defines/e1.37-1/BURN_IN.json | 23 + .../1.0.0/Defines/e1.37-1/CURVE.json | 18 + .../Defines/e1.37-1/CURVE_DESCRIPTION.json | 20 + .../1.0.0/Defines/e1.37-1/DIMMER_INFO.json | 55 ++ .../Defines/e1.37-1/DMX_BLOCK_ADDRESS.json | 40 ++ .../1.0.0/Defines/e1.37-1/DMX_FAIL_MODE.json | 47 ++ .../Defines/e1.37-1/DMX_STARTUP_MODE.json | 44 ++ .../1.0.0/Defines/e1.37-1/IDENTIFY_MODE.json | 22 + .../1.0.0/Defines/e1.37-1/LOCK_PIN.json | 36 ++ .../1.0.0/Defines/e1.37-1/LOCK_STATE.json | 37 ++ .../e1.37-1/LOCK_STATE_DESCRIPTION.json | 32 + .../1.0.0/Defines/e1.37-1/MAXIMUM_LEVEL.json | 15 + .../1.0.0/Defines/e1.37-1/MINIMUM_LEVEL.json | 17 + .../Defines/e1.37-1/MODULATION_FREQUENCY.json | 30 + .../MODULATION_FREQUENCY_DESCRIPTION.json | 42 ++ .../Defines/e1.37-1/OUTPUT_RESPONSE_TIME.json | 30 + .../OUTPUT_RESPONSE_TIME_DESCRIPTION.json | 34 + .../Defines/e1.37-1/POWER_ON_SELF_TEST.json | 22 + .../1.0.0/Defines/e1.37-1/PRESET_INFO.json | 114 ++++ .../Defines/e1.37-1/PRESET_MERGE_MODE.json | 26 + .../1.0.0/Defines/e1.37-1/PRESET_STATUS.json | 91 +++ .../Defines/e1.37-2/DNS_DOMAIN_NAME.json | 28 + .../1.0.0/Defines/e1.37-2/DNS_HOSTNAME.json | 29 + .../Defines/e1.37-2/DNS_IPV4_NAME_SERVER.json | 35 ++ .../INTERFACE_APPLY_CONFIGURATION.json | 18 + .../INTERFACE_HARDWARE_ADDRESS_TYPE1.json | 32 + .../Defines/e1.37-2/INTERFACE_LABEL.json | 32 + .../e1.37-2/INTERFACE_RELEASE_DHCP.json | 18 + .../Defines/e1.37-2/INTERFACE_RENEW_DHCP.json | 18 + .../Defines/e1.37-2/IPV4_CURRENT_ADDRESS.json | 49 ++ .../Defines/e1.37-2/IPV4_DEFAULT_ROUTE.json | 27 + .../1.0.0/Defines/e1.37-2/IPV4_DHCP_MODE.json | 37 ++ .../Defines/e1.37-2/IPV4_STATIC_ADDRESS.json | 41 ++ .../Defines/e1.37-2/IPV4_ZEROCONF_MODE.json | 37 ++ .../Defines/e1.37-2/LIST_INTERFACES.json | 32 + .../1.0.0/Defines/e1.37-5/ADD_TAG.json | 16 + .../1.0.0/Defines/e1.37-5/CHECK_TAG.json | 25 + .../1.0.0/Defines/e1.37-5/CLEAR_TAGS.json | 10 + .../Defines/e1.37-5/COMMS_STATUS_NSC.json | 63 ++ .../Defines/e1.37-5/DEVICE_INFO_OFFSTAGE.json | 135 ++++ .../Defines/e1.37-5/DEVICE_UNIT_NUMBER.json | 21 + .../Defines/e1.37-5/DMX_PERSONALITY_ID.json | 22 + .../1.0.0/Defines/e1.37-5/FIRMWARE_URL.json | 17 + .../Defines/e1.37-5/IDENTIFY_TIMEOUT.json | 23 + .../1.0.0/Defines/e1.37-5/LIST_TAGS.json | 16 + .../Defines/e1.37-5/MANUFACTURER_URL.json | 17 + .../1.0.0/Defines/e1.37-5/METADATA_JSON.json | 19 + .../Defines/e1.37-5/METADATA_JSON_URL.json | 16 + .../e1.37-5/METADATA_PARAMETER_VERSION.json | 18 + .../Defines/e1.37-5/POWER_OFF_READY.json | 19 + .../1.0.0/Defines/e1.37-5/PRODUCT_URL.json | 17 + .../1.0.0/Defines/e1.37-5/REMOVE_TAG.json | 16 + .../Defines/e1.37-5/SENSOR_TYPE_CUSTOM.json | 25 + .../Defines/e1.37-5/SENSOR_UNIT_CUSTOM.json | 25 + .../1.0.0/Defines/e1.37-5/SERIAL_NUMBER.json | 16 + .../1.0.0/Defines/e1.37-5/SHIPPING_LOCK.json | 35 ++ .../1.0.0/Defines/e1.37-5/TEST_DATA.json | 33 + .../Defines/e1.37-7/BACKGROUND_DISCOVERY.json | 39 ++ .../BACKGROUND_QUEUED_STATUS_POLICY.json | 32 + ...OUND_QUEUED_STATUS_POLICY_DESCRIPTION.json | 29 + .../e1.37-7/BINDING_CONTROL_FIELDS.json | 37 ++ .../Defines/e1.37-7/DISCOVERY_STATE.json | 74 +++ .../1.0.0/Defines/e1.37-7/ENDPOINT_LABEL.json | 44 ++ .../1.0.0/Defines/e1.37-7/ENDPOINT_LIST.json | 37 ++ .../Defines/e1.37-7/ENDPOINT_LIST_CHANGE.json | 12 + .../1.0.0/Defines/e1.37-7/ENDPOINT_MODE.json | 48 ++ .../Defines/e1.37-7/ENDPOINT_RESPONDERS.json | 30 + .../ENDPOINT_RESPONDER_LIST_CHANGE.json | 21 + .../Defines/e1.37-7/ENDPOINT_TIMING.json | 46 ++ .../e1.37-7/ENDPOINT_TIMING_DESCRIPTION.json | 26 + .../Defines/e1.37-7/ENDPOINT_TO_UNIVERSE.json | 59 ++ .../Defines/e1.37-7/IDENTIFY_ENDPOINT.json | 46 ++ .../Defines/e1.37-7/RDM_TRAFFIC_ENABLE.json | 39 ++ .../Resources/JSON-Defines/1.0.0/schema.json | 582 ++++++++++++++++++ RDMSharpTests/TestJSONDefines.cs | 36 ++ 136 files changed, 4802 insertions(+) create mode 100644 RDMSharp/Metadata/JSONDefinesResources.cs create mode 100644 RDMSharp/Metadata/MetadataDefineVersion.cs create mode 100644 RDMSharp/Metadata/MetadataFactory.cs create mode 100644 RDMSharp/Metadata/MetadataSchemaVersion.cs create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/BOOT_SOFTWARE_VERSION_ID.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/BOOT_SOFTWARE_VERSION_LABEL.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CAPTURE_PRESET.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CLEAR_STATUS_ID.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/COMMS_STATUS.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CONTROLLER_FLAG_SUPPORT.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEFAULT_SLOT_VALUE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_HOURS.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_INFO.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_LABEL.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_MODEL_DESCRIPTION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_POWER_CYCLES.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DISPLAY_INVERT.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DISPLAY_LEVEL.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DMX_PERSONALITY.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DMX_PERSONALITY_DESCRIPTION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DMX_START_ADDRESS.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/FACTORY_DEFAULTS.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/IDENTIFY_DEVICE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_HOURS.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_ON_MODE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_STATE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_STRIKES.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LANGUAGE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LANGUAGE_CAPABILITIES.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/MANUFACTURER_LABEL.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/NACK_DESCRIPTION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_INDEX.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_SUB.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PAN_INVERT.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PAN_TILT_SWAP.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PARAMETER_DESCRIPTION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PERFORM_SELF_TEST.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/POWER_STATE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PRESET_PLAYBACK.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PRODUCT_DETAIL_ID_LIST.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PROXIED_DEVICES.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PROXIED_DEVICE_COUNT.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_PID_SUBSCRIBE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_SENSOR_SUBSCRIBE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/REAL_TIME_CLOCK.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/RECORD_SENSORS.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/RESET_DEVICE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SELF_TEST_DESCRIPTION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SENSOR_DEFINITION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SENSOR_VALUE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SLOT_DESCRIPTION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SLOT_INFO.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SOFTWARE_VERSION_LABEL.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/STATUS_ID_DESCRIPTION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/STATUS_MESSAGES.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUB_DEVICE_STATUS_REPORT_THRESHOLD.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUPPORTED_PARAMETERS.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUPPORTED_PARAMETERS_ENHANCED.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/TILT_INVERT.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/BURN_IN.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/CURVE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/CURVE_DESCRIPTION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DIMMER_INFO.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DMX_BLOCK_ADDRESS.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DMX_FAIL_MODE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DMX_STARTUP_MODE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/IDENTIFY_MODE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/LOCK_PIN.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/LOCK_STATE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/LOCK_STATE_DESCRIPTION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MAXIMUM_LEVEL.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MINIMUM_LEVEL.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MODULATION_FREQUENCY.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MODULATION_FREQUENCY_DESCRIPTION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/OUTPUT_RESPONSE_TIME.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/OUTPUT_RESPONSE_TIME_DESCRIPTION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/POWER_ON_SELF_TEST.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/PRESET_INFO.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/PRESET_MERGE_MODE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/PRESET_STATUS.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/DNS_DOMAIN_NAME.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/DNS_HOSTNAME.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/DNS_IPV4_NAME_SERVER.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_APPLY_CONFIGURATION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_HARDWARE_ADDRESS_TYPE1.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_LABEL.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_RELEASE_DHCP.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_RENEW_DHCP.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_CURRENT_ADDRESS.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_DEFAULT_ROUTE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_DHCP_MODE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_STATIC_ADDRESS.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_ZEROCONF_MODE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/LIST_INTERFACES.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/ADD_TAG.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/CHECK_TAG.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/CLEAR_TAGS.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/COMMS_STATUS_NSC.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/DEVICE_INFO_OFFSTAGE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/DEVICE_UNIT_NUMBER.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/DMX_PERSONALITY_ID.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/FIRMWARE_URL.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/IDENTIFY_TIMEOUT.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/LIST_TAGS.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/MANUFACTURER_URL.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/METADATA_JSON.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/METADATA_JSON_URL.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/METADATA_PARAMETER_VERSION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/POWER_OFF_READY.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/PRODUCT_URL.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/REMOVE_TAG.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SENSOR_TYPE_CUSTOM.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SENSOR_UNIT_CUSTOM.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SERIAL_NUMBER.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SHIPPING_LOCK.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/TEST_DATA.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BACKGROUND_DISCOVERY.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BACKGROUND_QUEUED_STATUS_POLICY.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BINDING_CONTROL_FIELDS.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/DISCOVERY_STATE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_LABEL.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_LIST.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_LIST_CHANGE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_MODE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_RESPONDERS.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_RESPONDER_LIST_CHANGE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_TIMING.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_TIMING_DESCRIPTION.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_TO_UNIVERSE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/IDENTIFY_ENDPOINT.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/RDM_TRAFFIC_ENABLE.json create mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/schema.json create mode 100644 RDMSharpTests/TestJSONDefines.cs diff --git a/RDMSharp/Metadata/JSONDefinesResources.cs b/RDMSharp/Metadata/JSONDefinesResources.cs new file mode 100644 index 0000000..ad88f51 --- /dev/null +++ b/RDMSharp/Metadata/JSONDefinesResources.cs @@ -0,0 +1,11 @@ +namespace RDMSharp +{ + public static class JSONDefinesResources + { + public static string[] GetResources() + { + var assembly = typeof(JSONDefinesResources).Assembly; + return assembly.GetManifestResourceNames(); + } + } +} diff --git a/RDMSharp/Metadata/MetadataDefineVersion.cs b/RDMSharp/Metadata/MetadataDefineVersion.cs new file mode 100644 index 0000000..9a7ce32 --- /dev/null +++ b/RDMSharp/Metadata/MetadataDefineVersion.cs @@ -0,0 +1,55 @@ +using System; +using System.IO; +using System.Text.RegularExpressions; + +namespace RDMSharp.Metadata +{ + public readonly struct MetadataDefineVersion + { + public readonly string Version; + public readonly string Define; + public readonly string Path; + public readonly string Name; + public MetadataDefineVersion(string path) : this(getVersion(path), getDefine(path), path) + { + } + public MetadataDefineVersion(string version, string define, string path) + { + Version = version; + Define = define; + Path = path; + string pattern = @"[^\.]+\.[json]+$"; + var match = Regex.Match(Path, pattern); + + if (match.Success) + { + Name = match.Value; + } + else + throw new Exception($"Can't extract Name from Path: {path}"); + } + private static string getVersion(string path) + { + string pattern = @"_(\d+)\._(\d+)\._(\d+)"; + var match = Regex.Match(path, pattern); + + if (match.Success) + { + return match.Value.Replace("_", ""); + } + else + throw new Exception($"Can't extract Version from Path: {path}"); + } + private static string getDefine(string path) + { + var assembly = typeof(MetadataFactory).Assembly; + using Stream stream = assembly.GetManifestResourceStream(path); + using StreamReader reader = new StreamReader(stream); + return reader.ReadToEnd(); + } + public override string ToString() + { + return $"{Name} [{Version}]"; + } + } +} diff --git a/RDMSharp/Metadata/MetadataFactory.cs b/RDMSharp/Metadata/MetadataFactory.cs new file mode 100644 index 0000000..ef018c1 --- /dev/null +++ b/RDMSharp/Metadata/MetadataFactory.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using System.Linq; + +namespace RDMSharp.Metadata +{ + public static class MetadataFactory + { + private const string SCHEMA_FILE_NAME = "schema.json"; + private const string JSON_ENDING = ".json"; + public static string[] GetResources() + { + var assembly = typeof(MetadataFactory).Assembly; + return assembly.GetManifestResourceNames(); + } + + public static IList GetMetadataSchemaVersions() + { + var list = GetResources().Where(r => r.EndsWith(SCHEMA_FILE_NAME)); + return list.Select(r=>new MetadataSchemaVersion(r)).ToList(); + } + public static IList GetMetadataDefineVersions() + { + var list = GetResources().Where(r => r.EndsWith(JSON_ENDING) && !r.EndsWith(SCHEMA_FILE_NAME)); + return list.Select(r => new MetadataDefineVersion(r)).ToList(); + } + } +} diff --git a/RDMSharp/Metadata/MetadataSchemaVersion.cs b/RDMSharp/Metadata/MetadataSchemaVersion.cs new file mode 100644 index 0000000..7b14d97 --- /dev/null +++ b/RDMSharp/Metadata/MetadataSchemaVersion.cs @@ -0,0 +1,41 @@ +using System; +using System.IO; +using System.Text.RegularExpressions; + +namespace RDMSharp.Metadata +{ + public readonly struct MetadataSchemaVersion + { + public readonly string Version; + public readonly string Schema; + public readonly string Path; + public MetadataSchemaVersion(string path) : this(getVersion(path), getSchema(path), path) + { + } + public MetadataSchemaVersion(string version, string schema, string path) + { + Version = version; + Schema = schema; + Path = path; + } + private static string getVersion(string path) + { + string pattern = @"_(\d+)\._(\d+)\._(\d+)"; + var match = Regex.Match(path, pattern); + + if (match.Success) + { + return match.Value.Replace("_", ""); + } + else + throw new Exception($"Can't extract Version from Path: {path}"); + } + private static string getSchema(string path) + { + var assembly = typeof(MetadataFactory).Assembly; + using Stream stream = assembly.GetManifestResourceStream(path); + using StreamReader reader = new StreamReader(stream); + return reader.ReadToEnd(); + } + } +} diff --git a/RDMSharp/RDMSharp.csproj b/RDMSharp/RDMSharp.csproj index 14b7403..f7c3d67 100644 --- a/RDMSharp/RDMSharp.csproj +++ b/RDMSharp/RDMSharp.csproj @@ -34,4 +34,7 @@ + + + diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/BOOT_SOFTWARE_VERSION_ID.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/BOOT_SOFTWARE_VERSION_ID.json new file mode 100644 index 0000000..9d08e03 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/BOOT_SOFTWARE_VERSION_ID.json @@ -0,0 +1,14 @@ +{ + "name": "BOOT_SOFTWARE_VERSION_ID", + "manufacturer_id": 0, + "pid": 193, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "boot_software_version_id", + "type": "uint32" + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/BOOT_SOFTWARE_VERSION_LABEL.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/BOOT_SOFTWARE_VERSION_LABEL.json new file mode 100644 index 0000000..74a51c2 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/BOOT_SOFTWARE_VERSION_LABEL.json @@ -0,0 +1,16 @@ +{ + "name": "BOOT_SOFTWARE_VERSION_LABEL", + "manufacturer_id": 0, + "pid": 194, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "boot_software_version_label", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CAPTURE_PRESET.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CAPTURE_PRESET.json new file mode 100644 index 0000000..5054209 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CAPTURE_PRESET.json @@ -0,0 +1,35 @@ +{ + "name": "CAPTURE_PRESET", + "notes": "Either the first field or all four fields can be given.", + "manufacturer_id": 0, + "pid": 4144, + "version": 1, + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { + "name": "scene_num", + "type": "uint16", + "units": 21, + "prefixPower": -1 + }, + { + "name": "up_fade_time", + "type": "uint16", + "units": 21, + "prefixPower": -1 + }, + { + "name": "down_fade_time", + "type": "uint16", + "units": 21, + "prefixPower": -1 + }, + { + "name": "wait_time", + "type": "uint16", + "units": 21, + "prefixPower": -1 + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CLEAR_STATUS_ID.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CLEAR_STATUS_ID.json new file mode 100644 index 0000000..56c00b8 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CLEAR_STATUS_ID.json @@ -0,0 +1,9 @@ +{ + "name": "CLEAR_STATUS_ID", + "manufacturer_id": 0, + "pid": 50, + "version": 1, + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/COMMS_STATUS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/COMMS_STATUS.json new file mode 100644 index 0000000..bdf738d --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/COMMS_STATUS.json @@ -0,0 +1,16 @@ +{ + "name": "COMMS_STATUS", + "manufacturer_id": 0, + "pid": 21, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [], + "get_response": [ + { "name": "short_message", "type": "uint16" }, + { "name": "length_mismatch", "type": "uint16" }, + { "name": "checksum_fail", "type": "uint16" } + ], + "set_request_subdevice_range": [ "root" ], + "set_request": [], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CONTROLLER_FLAG_SUPPORT.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CONTROLLER_FLAG_SUPPORT.json new file mode 100644 index 0000000..4705fd3 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CONTROLLER_FLAG_SUPPORT.json @@ -0,0 +1,19 @@ +{ + "name": "CONTROLLER_FLAG_SUPPORT", + "manufacturer_id": 0, + "pid": -1, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [], + "get_response": [ + { + "name": "controller_flags", + "type": "bitField", + "size": 8, + "bits": [ + { "name": "unicode", "index": 0 }, + { "name": "hi_res_ack_timer_support", "index": 1 } + ] + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEFAULT_SLOT_VALUE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEFAULT_SLOT_VALUE.json new file mode 100644 index 0000000..9a85a1a --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEFAULT_SLOT_VALUE.json @@ -0,0 +1,21 @@ +{ + "name": "DEFAULT_SLOT_VALUE", + "manufacturer_id": 0, + "pid": 290, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "slots", + "type": "list", + "itemType": { + "type": "compound", + "subtypes": [ + { "name": "id", "type": "uint16" }, + { "name": "default_value", "type": "uint8" } + ] + } + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_HOURS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_HOURS.json new file mode 100644 index 0000000..c4af096 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_HOURS.json @@ -0,0 +1,14 @@ +{ + "name": "DEVICE_HOURS", + "manufacturer_id": 0, + "pid": 1024, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { "name": "hours", "type": "uint32" } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_INFO.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_INFO.json new file mode 100644 index 0000000..70dc7c3 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_INFO.json @@ -0,0 +1,109 @@ +{ + "name": "DEVICE_INFO", + "manufacturer_id": 0, + "pid": 96, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { "name": "protocol_major", "type": "uint8" }, + { "name": "protocol_minor", "type": "uint8" }, + { "name": "device_model_id", "type": "uint16" }, + { + "name": "product_category", + "type": "uint16", + "labels": [ + { "name": "NOT_DECLARED", "value": 0 }, + { "name": "FIXTURE", "value": 256 }, + { "name": "FIXTURE_FIXED", "value": 257 }, + { "name": "FIXTURE_MOVING_YOKE", "value": 258 }, + { "name": "FIXTURE_MOVING_MIRROR", "value": 259 }, + { "name": "FIXTURE_OTHER", "value": 511 }, + { "name": "FIXTURE_ACCESSORY", "value": 512 }, + { "name": "FIXTURE_ACCESSORY_COLOR", "value": 513 }, + { "name": "FIXTURE_ACCESSORY_YOKE", "value": 514 }, + { "name": "FIXTURE_ACCESSORY_MIRROR", "value": 515 }, + { "name": "FIXTURE_ACCESSORY_EFFECT", "value": 516 }, + { "name": "FIXTURE_ACCESSORY_BEAM", "value": 517 }, + { "name": "FIXTURE_ACCESSORY_OTHER", "value": 767 }, + { "name": "PROJECTOR", "value": 768 }, + { "name": "PROJECTOR_FIXED", "value": 769 }, + { "name": "PROJECTOR_MOVING_YOKE", "value": 770 }, + { "name": "PROJECTOR_MOVING_MIRROR", "value": 771 }, + { "name": "PROJECTOR_OTHER", "value": 1023 }, + { "name": "ATMOSPHERIC", "value": 1024 }, + { "name": "ATMOSPHERIC_EFFECT", "value": 1025 }, + { "name": "ATMOSPHERIC_PYRO", "value": 1026 }, + { "name": "ATMOSPHERIC_OTHER", "value": 1279 }, + { "name": "DIMMER", "value": 1280 }, + { "name": "DIMMER_AC_INCANDESCENT", "value": 1281 }, + { "name": "DIMMER_AC_FLUORESCENT", "value": 1282 }, + { "name": "DIMMER_AC_COLD_CATHODE", "value": 1283 }, + { "name": "DIMMER_AC_NONDIM", "value": 1284 }, + { "name": "DIMMER_AC_ELV", "value": 1285 }, + { "name": "DIMMER_AC_OTHER", "value": 1286 }, + { "name": "DIMMER_DC_LEVEL", "value": 1287 }, + { "name": "DIMMER_DC_PWM", "value": 1288 }, + { "name": "DIMMER_CS_LED", "value": 1289 }, + { "name": "DIMMER_OTHER", "value": 1535 }, + { "name": "POWER", "value": 1536 }, + { "name": "POWER_CONTROL", "value": 1537 }, + { "name": "POWER_SOURCE", "value": 1538 }, + { "name": "POWER_OTHER", "value": 1791 }, + { "name": "SCENIC", "value": 1792 }, + { "name": "SCENIC_DRIVE", "value": 1793 }, + { "name": "SCENIC_OTHER", "value": 2047 }, + { "name": "DATA", "value": 2048 }, + { "name": "DATA_DISTRIBUTION", "value": 2049 }, + { "name": "DATA_CONVERSION", "value": 2050 }, + { "name": "DATA_OTHER", "value": 2303 }, + { "name": "AV", "value": 2304 }, + { "name": "AV_AUDIO", "value": 2305 }, + { "name": "AV_VIDEO", "value": 2306 }, + { "name": "AV_OTHER", "value": 2559 }, + { "name": "MONITOR", "value": 2560 }, + { "name": "MONITOR_AC_LINE_POWER", "value": 2561 }, + { "name": "MONITOR_DC_POWER", "value": 2562 }, + { "name": "MONITOR_ENVIRONMENTAL", "value": 2563 }, + { "name": "MONITOR_OTHER", "value": 2815 }, + { "name": "CONTROL", "value": 28672 }, + { "name": "CONTROL_CONTROLLER", "value": 28673 }, + { "name": "CONTROL_BACKUP_DEVICE", "value": 28674 }, + { "name": "CONTROL_OTHER", "value": 28927 }, + { "name": "TEST", "value": 28928 }, + { "name": "TEST_EQUIPMENT", "value": 28929 }, + { "name": "TEST_OTHER", "value": 29183 }, + { "name": "OTHER", "value": 32767 } + ] + }, + { "name": "software_version_id", "type": "uint32" }, + { + "name": "dmx_footprint", + "type": "uint16", + "ranges": [ + { "minimum": 0, "maximum": 512 } + ] + }, + { + "name": "current_personality", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + }, + { "name": "personality_count", "type": "uint8" }, + { + "name": "dmx_start_address", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 512 }, + { "minimum": 65535, "maximum": 65535 } + ], + "labels": [ + { "name": "No Footprint", "value": 65535 } + ] + }, + { "name": "sub_device_count", "type": "uint16" }, + { "name": "sensor_count", "type": "uint8" } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_LABEL.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_LABEL.json new file mode 100644 index 0000000..37a523e --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_LABEL.json @@ -0,0 +1,19 @@ +{ + "name": "DEVICE_LABEL", + "manufacturer_id": 0, + "pid": 130, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "label", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_MODEL_DESCRIPTION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_MODEL_DESCRIPTION.json new file mode 100644 index 0000000..ffee24b --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_MODEL_DESCRIPTION.json @@ -0,0 +1,16 @@ +{ + "name": "DEVICE_MODEL_DESCRIPTION", + "manufacturer_id": 0, + "pid": 128, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "description", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_POWER_CYCLES.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_POWER_CYCLES.json new file mode 100644 index 0000000..d100b5f --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DEVICE_POWER_CYCLES.json @@ -0,0 +1,14 @@ +{ + "name": "DEVICE_POWER_CYCLES", + "manufacturer_id": 0, + "pid": 1029, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { "name": "power_cycle_count", "type": "uint32" } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DISPLAY_INVERT.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DISPLAY_INVERT.json new file mode 100644 index 0000000..8941c00 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DISPLAY_INVERT.json @@ -0,0 +1,23 @@ +{ + "name": "DISPLAY_INVERT", + "manufacturer_id": 0, + "pid": 1280, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "setting", + "type": "uint8", + "labels": [ + { "name": "Off", "value": 0 }, + { "name": "On", "value": 1 }, + { "name": "Auto", "value": 2 } + ], + "restrictToLabeled": true + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DISPLAY_LEVEL.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DISPLAY_LEVEL.json new file mode 100644 index 0000000..7369a06 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DISPLAY_LEVEL.json @@ -0,0 +1,21 @@ +{ + "name": "DISPLAY_LEVEL", + "manufacturer_id": 0, + "pid": 1281, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "level", + "type": "uint8", + "labels": [ + { "name": "Off", "value": 0 }, + { "name": "Full", "value": 255 } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DMX_PERSONALITY.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DMX_PERSONALITY.json new file mode 100644 index 0000000..3e90e6e --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DMX_PERSONALITY.json @@ -0,0 +1,23 @@ +{ + "name": "DMX_PERSONALITY", + "manufacturer_id": 0, + "pid": 224, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "personality", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + }, + { "name": "personality_count", "type": "uint8" } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { "$ref": "#/get_response/0" } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DMX_PERSONALITY_DESCRIPTION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DMX_PERSONALITY_DESCRIPTION.json new file mode 100644 index 0000000..d4c953a --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DMX_PERSONALITY_DESCRIPTION.json @@ -0,0 +1,32 @@ +{ + "name": "DMX_PERSONALITY_DESCRIPTION", + "manufacturer_id": 0, + "pid": 225, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "personality", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + } + ], + "get_response": [ + { "name": "personality", "type": "uint8" }, + { + "name": "dmx_slots_required", + "type": "uint16", + "ranges": [ + { "minimum": 0, "maximum": 512 } + ] + }, + { + "name": "description", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DMX_START_ADDRESS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DMX_START_ADDRESS.json new file mode 100644 index 0000000..9ec7246 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/DMX_START_ADDRESS.json @@ -0,0 +1,32 @@ +{ + "name": "DMX_START_ADDRESS", + "manufacturer_id": 0, + "pid": 240, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "dmx_address", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 512 }, + { "minimum": 65535, "maximum": 65535 } + ], + "labels": [ + { "name": "No Footprint", "value": 65535 } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { + "name": "dmx_address", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 512 } + ] + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/FACTORY_DEFAULTS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/FACTORY_DEFAULTS.json new file mode 100644 index 0000000..59c01ae --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/FACTORY_DEFAULTS.json @@ -0,0 +1,17 @@ +{ + "name": "FACTORY_DEFAULTS", + "manufacturer_id": 0, + "pid": 144, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "status", + "type": "boolean" + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/IDENTIFY_DEVICE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/IDENTIFY_DEVICE.json new file mode 100644 index 0000000..550c141 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/IDENTIFY_DEVICE.json @@ -0,0 +1,21 @@ +{ + "name": "IDENTIFY_DEVICE", + "manufacturer_id": 0, + "pid": 4096, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "state", + "type": "boolean", + "labels": [ + { "name": "Off", "value": false }, + { "name": "On", "value": true } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_HOURS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_HOURS.json new file mode 100644 index 0000000..468e8d4 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_HOURS.json @@ -0,0 +1,14 @@ +{ + "name": "LAMP_HOURS", + "manufacturer_id": 0, + "pid": 1025, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { "name": "hours", "type": "uint32" } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_ON_MODE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_ON_MODE.json new file mode 100644 index 0000000..25c47b4 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_ON_MODE.json @@ -0,0 +1,23 @@ +{ + "name": "LAMP_ON_MODE", + "manufacturer_id": 0, + "pid": 1028, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "mode", + "type": "uint8", + "labels": [ + { "name": "OFF", "value": 0 }, + { "name": "DMX", "value": 1 }, + { "name": "ON", "value": 2 }, + { "name": "AFTER_CAL", "value": 3 } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_STATE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_STATE.json new file mode 100644 index 0000000..5bc6fdf --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_STATE.json @@ -0,0 +1,25 @@ +{ + "name": "LAMP_STATE", + "manufacturer_id": 0, + "pid": 1027, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "state", + "type": "uint8", + "labels": [ + { "name": "LAMP_OFF", "value": 0 }, + { "name": "LAMP_ON", "value": 1 }, + { "name": "LAMP_STRIKE", "value": 2 }, + { "name": "LAMP_STANDBY", "value": 3 }, + { "name": "LAMP_NOT_PRESENT", "value": 4 }, + { "name": "LAMP_ERROR", "value": 127 } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_STRIKES.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_STRIKES.json new file mode 100644 index 0000000..0e4e4fa --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LAMP_STRIKES.json @@ -0,0 +1,14 @@ +{ + "name": "LAMP_STRIKES", + "manufacturer_id": 0, + "pid": 1026, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { "name": "strikes", "type": "uint32" } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LANGUAGE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LANGUAGE.json new file mode 100644 index 0000000..f77b87a --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LANGUAGE.json @@ -0,0 +1,21 @@ +{ + "name": "LANGUAGE", + "manufacturer_id": 0, + "pid": 176, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "language_code", + "type": "string", + "pattern": "^[a-zA-Z]{2}$", + "resources": [ "https://en.wikipedia.org/wiki/ISO_639-1" ], + "minLength": 2, + "maxLength": 2 + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LANGUAGE_CAPABILITIES.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LANGUAGE_CAPABILITIES.json new file mode 100644 index 0000000..6cb7027 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/LANGUAGE_CAPABILITIES.json @@ -0,0 +1,22 @@ +{ + "name": "LANGUAGE_CAPABILITIES", + "manufacturer_id": 0, + "pid": 160, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "language_codes", + "type": "list", + "itemType": { + "name": "language_code", + "type": "string", + "pattern": "^[a-zA-Z]{2}$", + "resources": [ "https://en.wikipedia.org/wiki/ISO_639-1" ], + "minLength": 2, + "maxLength": 2 + } + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/MANUFACTURER_LABEL.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/MANUFACTURER_LABEL.json new file mode 100644 index 0000000..516f466 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/MANUFACTURER_LABEL.json @@ -0,0 +1,16 @@ +{ + "name": "MANUFACTURER_LABEL", + "manufacturer_id": 0, + "pid": 129, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "description", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/NACK_DESCRIPTION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/NACK_DESCRIPTION.json new file mode 100644 index 0000000..8680eae --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/NACK_DESCRIPTION.json @@ -0,0 +1,18 @@ +{ + "name": "NACK_DESCRIPTION", + "manufacturer_id": 0, + "pid": -1, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { "name": "nack_reason_number", "type": "uint16" } + ], + "get_response": [ + { "name": "nack_reason_number", "type": "uint16" }, + { + "name": "description", + "type": "string", + "maxLength": 32 + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_INDEX.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_INDEX.json new file mode 100644 index 0000000..672aeed --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_INDEX.json @@ -0,0 +1,35 @@ +{ + "name": "PACKED_PID_INDEX", + "manufacturer_id": 0, + "pid": -1, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "pid", + "type": "uint16", + "notes": "Some PIDs are disallowed from being packed. See \"Table A-3: RDM Categories/Parameter ID Defines\" of the ANSI E1.20-202x specification." + }, + { "name": "first_item", "type": "uint16" }, + { + "name": "item_count", + "type": "uint16", + "labels": [ + { "name": "All Data", "value": 65535 } + ] + } + ], + "get_response": [ + { "name": "pid", "type": "uint16" }, + { "name": "first_item", "type": "uint16" }, + { "name": "entry_count", "type": "uint8" }, + { + "name": "entries", + "type": "list", + "itemType": { "type": "pdEnvelope" } + } + ], + "set_request_subdevice_range": [ "root", "subdevices" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_SUB.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_SUB.json new file mode 100644 index 0000000..fdd3aa9 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_SUB.json @@ -0,0 +1,57 @@ +{ + "name": "PACKED_PID_SUB", + "manufacturer_id": 0, + "pid": -1, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "pid", + "type": "uint16", + "notes": "Some PIDs are disallowed from being packed. See \"Table A-3: RDM Categories/Parameter ID Defines\" of the ANSI E1.20-202x specification." + }, + { "name": "index", "type": "uint16" }, + { + "name": "first_subdevice", + "type": "uint16", + "ranges": [ + { "minimum": 0, "maximum": 65520 } + ] + }, + { + "name": "subdevice_count", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 65520 }, + { "minimum": 65535, "maximum": 65535 } + ], + "labels": [ + { "name": "All Subdevices", "value": 65535 } + ] + } + ], + "get_response": [ + { "name": "pid", "type": "uint16" }, + { "name": "index", "type": "uint16" }, + { + "name": "entries", + "type": "list", + "itemType": { + "type": "compound", + "subtypes": [ + { + "name": "subdevice", + "type": "uint16", + "ranges": [ + { "minimum": 0, "maximum": 65520 } + ] + }, + { "name": "subdevice_entry", "type": "pdEnvelope" } + ] + } + } + ], + "set_request_subdevice_range": [ "root" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PAN_INVERT.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PAN_INVERT.json new file mode 100644 index 0000000..127211c --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PAN_INVERT.json @@ -0,0 +1,21 @@ +{ + "name": "PAN_INVERT", + "manufacturer_id": 0, + "pid": 1536, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "setting", + "type": "boolean", + "labels": [ + { "name": "Off", "value": false }, + { "name": "On", "value": true } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PAN_TILT_SWAP.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PAN_TILT_SWAP.json new file mode 100644 index 0000000..e54cfec --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PAN_TILT_SWAP.json @@ -0,0 +1,21 @@ +{ + "name": "PAN_TILT_SWAP", + "manufacturer_id": 0, + "pid": 1538, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "setting", + "type": "boolean", + "labels": [ + { "name": "Off", "value": false }, + { "name": "On", "value": true } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PARAMETER_DESCRIPTION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PARAMETER_DESCRIPTION.json new file mode 100644 index 0000000..1dcc40c --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PARAMETER_DESCRIPTION.json @@ -0,0 +1,101 @@ +{ + "name": "PARAMETER_DESCRIPTION", + "manufacturer_id": 0, + "pid": 81, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { "name": "pid", "type": "uint16" } + ], + "get_response": [ + { "name": "pid", "type": "uint16" }, + { "name": "pdl", "type": "uint8" }, + { "name": "data_type", "type": "uint8" }, + { + "name": "command_class", + "type": "uint8", + "labels": [ + { "name": "GET", "value": 1 }, + { "name": "SET", "value": 2 }, + { "name": "GET_SET", "value": 3 } + ], + "restrictToLabeled": true + }, + { "name": "type", "type": "uint8" }, + { + "name": "unit", + "type": "uint8", + "labels": [ + { "name": "NONE", "value": 0 }, + { "name": "CENTIGRADE", "value": 1 }, + { "name": "VOLTS_DC", "value": 2 }, + { "name": "VOLTS_AC_PEAK", "value": 3 }, + { "name": "VOLTS_AC_RMS", "value": 4 }, + { "name": "AMPERE_DC", "value": 5 }, + { "name": "AMPERE_AC_PEAK", "value": 6 }, + { "name": "AMPERE_AC_RMS", "value": 7 }, + { "name": "HERTZ", "value": 8 }, + { "name": "OHM", "value": 9 }, + { "name": "WATT", "value": 10 }, + { "name": "KILOGRAM", "value": 11 }, + { "name": "METERS", "value": 12 }, + { "name": "METERS_SQUARED", "value": 13 }, + { "name": "METERS_CUBED", "value": 14 }, + { "name": "KILOGRAMS_PER_METERS_CUBED", "value": 15 }, + { "name": "METERS_PER_SECOND", "value": 16 }, + { "name": "METERS_PER_SECOND_SQUARED", "value": 17 }, + { "name": "NEWTON", "value": 18 }, + { "name": "JOULE", "value": 19 }, + { "name": "PASCAL", "value": 20 }, + { "name": "SECOND", "value": 21 }, + { "name": "DEGREE", "value": 22 }, + { "name": "STERADIAN", "value": 23 }, + { "name": "CANDELA", "value": 24 }, + { "name": "LUMEN", "value": 25 }, + { "name": "LUX", "value": 26 }, + { "name": "IRE", "value": 27 }, + { "name": "BYTE", "value": 28 }, + { "name": "DECIBEL", "value": 29 }, + { "name": "DECIBEL_VOLT", "value": 30 }, + { "name": "DECIBEL_WATT", "value": 31 }, + { "name": "DECIBEL_METER", "value": 32 }, + { "name": "PERCENT", "value": 33 } + ] + }, + { + "name": "unit_prefix", + "type": "uint8", + "labels": [ + { "name": "NONE", "value": 0 }, + { "name": "DECI", "value": 1 }, + { "name": "CENTI", "value": 2 }, + { "name": "MILLI", "value": 3 }, + { "name": "MICRO", "value": 4 }, + { "name": "NANO", "value": 5 }, + { "name": "PICO", "value": 6 }, + { "name": "FEMTO", "value": 7 }, + { "name": "ATTO", "value": 8 }, + { "name": "ZEPTO", "value": 9 }, + { "name": "YOCTO", "value": 10 }, + { "name": "DECA", "value": 17 }, + { "name": "HEPTO", "value": 18 }, + { "name": "KILO", "value": 19 }, + { "name": "MEGA", "value": 20 }, + { "name": "GIGA", "value": 21 }, + { "name": "TERA", "value": 22 }, + { "name": "PETA", "value": 23 }, + { "name": "EXA", "value": 24 }, + { "name": "ZETTA", "value": 25 }, + { "name": "YOTTA", "value": 26 } + ] + }, + { "name": "min_valid_value", "type": "uint32" }, + { "name": "max_valid_value", "type": "uint32" }, + { "name": "default_value", "type": "uint32" }, + { + "name": "description", + "type": "string", + "maxLength": 32 + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PERFORM_SELF_TEST.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PERFORM_SELF_TEST.json new file mode 100644 index 0000000..95e7b24 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PERFORM_SELF_TEST.json @@ -0,0 +1,23 @@ +{ + "name": "PERFORM_SELF_TEST", + "manufacturer_id": 0, + "pid": 4128, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { "name": "self_tests_active", "type": "boolean" } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { + "name": "self_test_num", + "type": "uint8", + "labels": [ + { "name": "SELF_TEST_OFF", "value": 0 }, + { "name": "SELF_TEST_ALL", "value": 255 } + ] + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/POWER_STATE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/POWER_STATE.json new file mode 100644 index 0000000..c379f26 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/POWER_STATE.json @@ -0,0 +1,24 @@ +{ + "name": "POWER_STATE", + "manufacturer_id": 0, + "pid": 4112, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "state", + "type": "uint8", + "labels": [ + { "name": "FULL_OFF", "value": 0 }, + { "name": "SHUTDOWN", "value": 1 }, + { "name": "STANDBY", "value": 2 }, + { "name": "NORMAL", "value": 255 } + ], + "restrictToLabeled": true + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PRESET_PLAYBACK.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PRESET_PLAYBACK.json new file mode 100644 index 0000000..5ba91ee --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PRESET_PLAYBACK.json @@ -0,0 +1,22 @@ +{ + "name": "PRESET_PLAYBACK", + "manufacturer_id": 0, + "pid": 4145, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "mode", + "type": "uint16", + "labels": [ + { "name": "OFF", "value": 0 }, + { "name": "ALL", "value": 65535 } + ] + }, + { "name": "level", "type": "uint8" } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PRODUCT_DETAIL_ID_LIST.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PRODUCT_DETAIL_ID_LIST.json new file mode 100644 index 0000000..188c4e9 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PRODUCT_DETAIL_ID_LIST.json @@ -0,0 +1,99 @@ +{ + "name": "PRODUCT_DETAIL_ID_LIST", + "manufacturer_id": 0, + "pid": 112, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "product_detail_ids", + "type": "list", + "itemType": { + "name": "product_detail_id", + "type": "uint16", + "labels": [ + { "name": "NOT_DECLARED", "value": 0 }, + { "name": "ARC", "value": 1 }, + { "name": "METAL_HALIDE", "value": 2 }, + { "name": "INCANDESCENT", "value": 3 }, + { "name": "LED", "value": 4 }, + { "name": "FLUORESCENT", "value": 5 }, + { "name": "COLD_CATHODE", "value": 6 }, + { "name": "ELECTROLUMINESCENT", "value": 7 }, + { "name": "LASER", "value": 8 }, + { "name": "FLASHTUBE", "value": 9 }, + { "name": "COLOR_SCROLLER", "value": 256 }, + { "name": "COLOR_WHEEL", "value": 257 }, + { "name": "COLOR_CHANGE", "value": 258 }, + { "name": "IRIS_DOUSER", "value": 259 }, + { "name": "DIMMING_SHUTTER", "value": 260 }, + { "name": "PROFILE_SHUTTER", "value": 261 }, + { "name": "BARNDOOR_SHUTTER", "value": 262 }, + { "name": "EFFECTS_DISC", "value": 263 }, + { "name": "GOBO_ROTATOR", "value": 264 }, + { "name": "VIDEO", "value": 512 }, + { "name": "SLIDE", "value": 513 }, + { "name": "FILM", "value": 514 }, + { "name": "OIL_WHEEL", "value": 515 }, + { "name": "LCD_GATE", "value": 516 }, + { "name": "FOGGER_GLYCOL", "value": 768 }, + { "name": "FOGGER_MINERAL_OIL", "value": 769 }, + { "name": "FOGGER_WATER", "value": 770 }, + { "name": "CO2", "value": 771 }, + { "name": "LN2", "value": 772 }, + { "name": "BUBBLE", "value": 773 }, + { "name": "FLAME_PROPANE", "value": 774 }, + { "name": "FLAME_OTHER", "value": 775 }, + { "name": "OLFACTORY_STIMULATOR", "value": 776 }, + { "name": "SNOW", "value": 777 }, + { "name": "WATER_JET", "value": 778 }, + { "name": "WIND", "value": 779 }, + { "name": "CONFETTI", "value": 780 }, + { "name": "HAZARD", "value": 781 }, + { "name": "PHASE_CONTROL", "value": 1024 }, + { "name": "REVERSE_PHASE_CONTROL", "value": 1025 }, + { "name": "SINE", "value": 1026 }, + { "name": "PWM", "value": 1027 }, + { "name": "DC", "value": 1028 }, + { "name": "HF_BALLAST", "value": 1029 }, + { "name": "HFHV_NEON_BALLAST", "value": 1030 }, + { "name": "HFHV_EL", "value": 1031 }, + { "name": "MHR_BALLAST", "value": 1032 }, + { "name": "BIT_ANGLE_MODULATION", "value": 1033 }, + { "name": "HIGH_FREQUENCY_12V", "value": 1034 }, + { "name": "RELAY_MECHANICAL", "value": 1035 }, + { "name": "RELAY_ELECTRONIC", "value": 1036 }, + { "name": "SWITCH_ELECTRONIC", "value": 1037 }, + { "name": "CONTACTOR", "value": 1037 }, + { "name": "MIRROR_BALL_ROTATOR", "value": 1280 }, + { "name": "OTHER_ROTATOR", "value": 1281 }, + { "name": "KABUKI_DROP", "value": 1282 }, + { "name": "CURTAIN", "value": 1283 }, + { "name": "LINESET", "value": 1284 }, + { "name": "MOTOR_CONTROL", "value": 1285 }, + { "name": "DAMPER_CONTROL", "value": 1286 }, + { "name": "SPLITTER", "value": 1536 }, + { "name": "ETHERNET_NODE", "value": 1537 }, + { "name": "MERGE", "value": 1538 }, + { "name": "DATAPATCH", "value": 1539 }, + { "name": "WIRELESS_LINK", "value": 1540 }, + { "name": "PROTOCOL_CONVERTER", "value": 1793 }, + { "name": "ANALOG_DEMULTIPLEX", "value": 1794 }, + { "name": "ANALOG_MULTIPLEX", "value": 1795 }, + { "name": "SWITCH_PANEL", "value": 1796 }, + { "name": "ROUTER", "value": 2048 }, + { "name": "FADER", "value": 2049 }, + { "name": "MIXER", "value": 2050 }, + { "name": "CHANGEOVER_MANUAL", "value": 2304 }, + { "name": "CHANGEOVER_AUTO", "value": 2305 }, + { "name": "TEST", "value": 2036 }, + { "name": "GFI_RCD", "value": 2560 }, + { "name": "BATTERY", "value": 2561 }, + { "name": "CONTROLLABLE_BREAKER", "value": 2562 }, + { "name": "OTHER", "value": 32767 } + ] + } + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PROXIED_DEVICES.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PROXIED_DEVICES.json new file mode 100644 index 0000000..01ffafd --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PROXIED_DEVICES.json @@ -0,0 +1,19 @@ +{ + "name": "PROXIED_DEVICES", + "manufacturer_id": 0, + "pid": 16, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [], + "get_response": [ + { + "name": "device_uids", + "type": "list", + "itemType": { + "name": "device_uid", + "type": "bytes", + "format": "uid" + } + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PROXIED_DEVICE_COUNT.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PROXIED_DEVICE_COUNT.json new file mode 100644 index 0000000..348fc8f --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PROXIED_DEVICE_COUNT.json @@ -0,0 +1,12 @@ +{ + "name": "PROXIED_DEVICE_COUNT", + "manufacturer_id": 0, + "pid": 17, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [], + "get_response": [ + { "name": "device_count", "type": "uint16" }, + { "name": "list_change", "type": "boolean" } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE.json new file mode 100644 index 0000000..eed499b --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE.json @@ -0,0 +1,22 @@ +{ + "name": "QUEUED_MESSAGE", + "manufacturer_id": 0, + "pid": 32, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "status_type", + "type": "uint8", + "labels": [ + { "name": "STATUS_NONE", "value": 0 }, + { "name": "STATUS_GET_LAST_MESSAGE", "value": 1 }, + { "name": "STATUS_ADVISORY", "value": 2 }, + { "name": "STATUS_WARNING", "value": 3 }, + { "name": "STATUS_ERROR", "value": 4 } + ], + "restrictToLabeled": true + } + ], + "get_response": "different_pid" +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_PID_SUBSCRIBE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_PID_SUBSCRIBE.json new file mode 100644 index 0000000..23c5113 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_PID_SUBSCRIBE.json @@ -0,0 +1,9 @@ +{ + "name": "QUEUED_MESSAGE_PID_SUBSCRIBE WHERE IS THIS IN THE SPEC?", + "manufacturer_id": 0, + "pid": -1, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_SENSOR_SUBSCRIBE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_SENSOR_SUBSCRIBE.json new file mode 100644 index 0000000..c1b3359 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_SENSOR_SUBSCRIBE.json @@ -0,0 +1,18 @@ +{ + "name": "QUEUED_MESSAGE_SENSOR_SUBSCRIBE", + "manufacturer_id": 0, + "pid": -1, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "sensor_numbers", + "type": "list", + "itemType": { + "name": "sensor_number", + "type": "uint8" + } + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/REAL_TIME_CLOCK.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/REAL_TIME_CLOCK.json new file mode 100644 index 0000000..260937a --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/REAL_TIME_CLOCK.json @@ -0,0 +1,55 @@ +{ + "name": "REAL_TIME_CLOCK", + "manufacturer_id": 0, + "pid": 1539, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "year", + "type": "uint16", + "ranges": [ + { "minimum": 2003, "maximum": 65535 } + ] + }, + { + "name": "month", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 12 } + ] + }, + { + "name": "day", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 31 } + ] + }, + { + "name": "hour", + "type": "uint8", + "ranges": [ + { "minimum": 0, "maximum": 24 } + ] + }, + { + "name": "minute", + "type": "uint8", + "ranges": [ + { "minimum": 0, "maximum": 59 } + ] + }, + { + "name": "second", + "type": "uint8", + "ranges": [ + { "minimum": 0, "maximum": 60 } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/RECORD_SENSORS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/RECORD_SENSORS.json new file mode 100644 index 0000000..636941e --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/RECORD_SENSORS.json @@ -0,0 +1,11 @@ +{ + "name": "RECORD_SENSORS", + "manufacturer_id": 0, + "pid": 514, + "version": 1, + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { "name": "sensor", "type": "uint8" } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/RESET_DEVICE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/RESET_DEVICE.json new file mode 100644 index 0000000..5ca68fa --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/RESET_DEVICE.json @@ -0,0 +1,19 @@ +{ + "name": "RESET_DEVICE", + "manufacturer_id": 0, + "pid": 4097, + "version": 1, + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { + "name": "state", + "type": "uint8", + "labels": [ + { "name": "Warm Reset", "value": 1 }, + { "name": "Cold Reset", "value": 255 } + ], + "restrictToLabeled": true + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SELF_TEST_DESCRIPTION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SELF_TEST_DESCRIPTION.json new file mode 100644 index 0000000..918bf5c --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SELF_TEST_DESCRIPTION.json @@ -0,0 +1,19 @@ +{ + "name": "SELF_TEST_DESCRIPTION", + "manufacturer_id": 0, + "pid": 4129, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { "name": "self_test_num", "type": "uint8" } + ], + "get_response": [ + { "name": "self_test_num", "type": "uint8" }, + { + "name": "label", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SENSOR_DEFINITION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SENSOR_DEFINITION.json new file mode 100644 index 0000000..b53cb79 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SENSOR_DEFINITION.json @@ -0,0 +1,145 @@ +{ + "name": "SENSOR_DEFINITION", + "manufacturer_id": 0, + "pid": 512, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { "name": "sensor", "type": "uint8" } + ], + "get_response": [ + { "name": "sensor", "type": "uint8" }, + { + "name": "type", + "type": "uint8", + "labels": [ + { "name": "TEMPERATURE", "value": 0 }, + { "name": "VOLTAGE", "value": 1 }, + { "name": "CURRENT", "value": 2 }, + { "name": "FREQUENCY", "value": 3 }, + { "name": "RESISTANCE", "value": 4 }, + { "name": "POWER", "value": 5 }, + { "name": "MASS", "value": 6 }, + { "name": "LENGTH", "value": 7 }, + { "name": "AREA", "value": 8 }, + { "name": "VOLUME", "value": 9 }, + { "name": "DENSITY", "value": 10 }, + { "name": "VELOCITY", "value": 11 }, + { "name": "ACCELERATION", "value": 12 }, + { "name": "FORCE", "value": 13 }, + { "name": "ENERGY", "value": 14 }, + { "name": "PRESSURE", "value": 15 }, + { "name": "TIME", "value": 16 }, + { "name": "ANGLE", "value": 17 }, + { "name": "POSITION_X", "value": 18 }, + { "name": "POSITION_Y", "value": 19 }, + { "name": "POSITION_Z", "value": 20 }, + { "name": "ANGULAR_VELOCTY", "value": 21 }, + { "name": "LUMINOUS_INTENSITY", "value": 22 }, + { "name": "LUMINOUS_FLUX", "value": 23 }, + { "name": "ILLUMINANCE", "value": 24 }, + { "name": "CHROMINANCE_RED", "value": 25 }, + { "name": "CHROMINANCE_GREEN", "value": 26 }, + { "name": "CHROMINANCE_BLUE", "value": 27 }, + { "name": "CONTACTS", "value": 28 }, + { "name": "MEMORY", "value": 29 }, + { "name": "ITEMS", "value": 30 }, + { "name": "HUMIDITY", "value": 31 }, + { "name": "COUNTER_16BIT", "value": 32 }, + { "name": "RPM", "value": 33 }, + { "name": "CPU_LOAD", "value": 34 }, + { "name": "BANDWIDTH_TOTAL", "value": 35 }, + { "name": "BANDWIDTH_USED", "value": 36 }, + { "name": "GAS_CONCENTRATION", "value": 37 }, + { "name": "CO2_LEVEL", "value": 38 }, + { "name": "SOUND_PRESSURE_LEVEL", "value": 39 }, + { "name": "OTHER", "value": 127 } + ] + }, + { + "name": "unit", + "type": "uint8", + "labels": [ + { "name": "NONE", "value": 0 }, + { "name": "CENTIGRADE", "value": 1 }, + { "name": "VOLTS_DC", "value": 2 }, + { "name": "VOLTS_AC_PEAK", "value": 3 }, + { "name": "VOLTS_AC_RMS", "value": 4 }, + { "name": "AMPERE_DC", "value": 5 }, + { "name": "AMPERE_AC_PEAK", "value": 6 }, + { "name": "AMPERE_AC_RMS", "value": 7 }, + { "name": "HERTZ", "value": 8 }, + { "name": "OHM", "value": 9 }, + { "name": "WATT", "value": 10 }, + { "name": "KILOGRAM", "value": 11 }, + { "name": "METERS", "value": 12 }, + { "name": "METERS_SQUARED", "value": 13 }, + { "name": "METERS_CUBED", "value": 14 }, + { "name": "KILOGRAMS_PER_METERS_CUBED", "value": 15 }, + { "name": "METERS_PER_SECOND", "value": 16 }, + { "name": "METERS_PER_SECOND_SQUARED", "value": 17 }, + { "name": "NEWTON", "value": 18 }, + { "name": "JOULE", "value": 19 }, + { "name": "PASCAL", "value": 20 }, + { "name": "SECOND", "value": 21 }, + { "name": "DEGREE", "value": 22 }, + { "name": "STERADIAN", "value": 23 }, + { "name": "CANDELA", "value": 24 }, + { "name": "LUMEN", "value": 25 }, + { "name": "LUX", "value": 26 }, + { "name": "IRE", "value": 27 }, + { "name": "BYTE", "value": 28 }, + { "name": "DECIBEL", "value": 29 }, + { "name": "DECIBEL_VOLT", "value": 30 }, + { "name": "DECIBEL_WATT", "value": 31 }, + { "name": "DECIBEL_METER", "value": 32 }, + { "name": "PERCENT", "value": 33 } + ] + }, + { + "name": "unit_prefix", + "type": "uint8", + "labels": [ + { "name": "NONE", "value": 0 }, + { "name": "DECI", "value": 1 }, + { "name": "CENTI", "value": 2 }, + { "name": "MILLI", "value": 3 }, + { "name": "MICRO", "value": 4 }, + { "name": "NANO", "value": 5 }, + { "name": "PICO", "value": 6 }, + { "name": "FEMTO", "value": 7 }, + { "name": "ATTO", "value": 8 }, + { "name": "ZEPTO", "value": 9 }, + { "name": "YOCTO", "value": 10 }, + { "name": "DECA", "value": 17 }, + { "name": "HEPTO", "value": 18 }, + { "name": "KILO", "value": 19 }, + { "name": "MEGA", "value": 20 }, + { "name": "GIGA", "value": 21 }, + { "name": "TERA", "value": 22 }, + { "name": "PETA", "value": 23 }, + { "name": "EXA", "value": 24 }, + { "name": "ZETTA", "value": 25 }, + { "name": "YOTTA", "value": 26 } + ] + }, + { "name": "range_min_value", "type": "int16" }, + { "name": "range_max_value", "type": "int16" }, + { "name": "normal_min_value", "type": "int16" }, + { "name": "normal_max_value", "type": "int16" }, + { + "name": "recorded_value_support", + "type": "bitField", + "size": 8, + "bits": [ + { "name": "recorded_value_supported", "index": 0 }, + { "name": "low_high_detected_values_supported", "index": 1 } + ] + }, + { + "name": "description", + "type": "string", + "maxLength": 32 + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SENSOR_VALUE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SENSOR_VALUE.json new file mode 100644 index 0000000..6ad3ba6 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SENSOR_VALUE.json @@ -0,0 +1,20 @@ +{ + "name": "SENSOR_VALUE", + "manufacturer_id": 0, + "pid": 513, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { "name": "sensor", "type": "uint8" } + ], + "get_response": [ + { "name": "sensor", "type": "uint8" }, + { "name": "value", "type": "int16" }, + { "name": "lowest_detected", "type": "int16" }, + { "name": "highest_detected", "type": "int16" }, + { "name": "recorded_value", "type": "int16" } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_request", + "set_response": "get_response" +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SLOT_DESCRIPTION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SLOT_DESCRIPTION.json new file mode 100644 index 0000000..7d3fbee --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SLOT_DESCRIPTION.json @@ -0,0 +1,19 @@ +{ + "name": "SLOT_DESCRIPTION", + "manufacturer_id": 0, + "pid": 289, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { "name": "slot", "type": "uint16" } + ], + "get_response": [ + { "name": "slot", "type": "uint16" }, + { + "name": "description", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SLOT_INFO.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SLOT_INFO.json new file mode 100644 index 0000000..a25aaba --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SLOT_INFO.json @@ -0,0 +1,22 @@ +{ + "name": "SLOT_INFO", + "manufacturer_id": 0, + "pid": 288, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "slots", + "type": "list", + "itemType": { + "type": "compound", + "subtypes": [ + { "name": "id", "type": "uint16" }, + { "name": "type", "type": "uint8" }, + { "name": "label_id", "type": "uint16" } + ] + } + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SOFTWARE_VERSION_LABEL.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SOFTWARE_VERSION_LABEL.json new file mode 100644 index 0000000..0eb607d --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SOFTWARE_VERSION_LABEL.json @@ -0,0 +1,16 @@ +{ + "name": "SOFTWARE_VERSION_LABEL", + "manufacturer_id": 0, + "pid": 192, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "software_version_label", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/STATUS_ID_DESCRIPTION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/STATUS_ID_DESCRIPTION.json new file mode 100644 index 0000000..8428a76 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/STATUS_ID_DESCRIPTION.json @@ -0,0 +1,18 @@ +{ + "name": "STATUS_ID_DESCRIPTION", + "manufacturer_id": 0, + "pid": 49, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { "name": "status_id", "type": "uint16" } + ], + "get_response": [ + { + "name": "description", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/STATUS_MESSAGES.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/STATUS_MESSAGES.json new file mode 100644 index 0000000..3876d53 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/STATUS_MESSAGES.json @@ -0,0 +1,49 @@ +{ + "name": "STATUS_MESSAGES", + "manufacturer_id": 0, + "pid": 48, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "status_type", + "type": "uint8", + "notes": "The requested Status Type isn't restricted in the spec.", + "labels": [ + { "name": "STATUS_NONE", "value": 0 }, + { "name": "STATUS_GET_LAST_MESSAGE", "value": 1 }, + { "name": "STATUS_ADVISORY", "value": 2 }, + { "name": "STATUS_WARNING", "value": 3 }, + { "name": "STATUS_ERROR", "value": 4 } + ] + } + ], + "get_response": [ + { + "name": "slots", + "type": "list", + "itemType": { + "type": "compound", + "subtypes": [ + { "name": "subdevice_id", "type": "uint16" }, + { + "name": "status_type", + "type": "uint8", + "labels": [ + { "name": "STATUS_ADVISORY", "value": 2 }, + { "name": "STATUS_WARNING", "value": 3 }, + { "name": "STATUS_ERROR", "value": 4 }, + { "name": "STATUS_ADVISORY_CLEARED", "value": 18 }, + { "name": "STATUS_WARNING_CLEARED", "value": 19 }, + { "name": "STATUS_ERROR_CLEARED", "value": 20 } + ], + "restrictToLabeled": true + }, + { "name": "status_message_id", "type": "uint16" }, + { "name": "data_value_1", "type": "int16" }, + { "name": "data_value_2", "type": "int16" } + ] + } + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUB_DEVICE_STATUS_REPORT_THRESHOLD.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUB_DEVICE_STATUS_REPORT_THRESHOLD.json new file mode 100644 index 0000000..66f35fb --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUB_DEVICE_STATUS_REPORT_THRESHOLD.json @@ -0,0 +1,24 @@ +{ + "name": "SUB_DEVICE_STATUS_REPORT_THRESHOLD", + "manufacturer_id": 0, + "pid": 51, + "version": 1, + "get_request_subdevice_range": [ "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "status_type", + "type": "uint8", + "notes": "The Status Type value is not restricted in the spec.", + "labels": [ + { "name": "STATUS_NONE", "value": 0 }, + { "name": "STATUS_ADVISORY", "value": 2 }, + { "name": "STATUS_WARNING", "value": 3 }, + { "name": "STATUS_ERROR", "value": 4 } + ] + } + ], + "set_request_subdevice_range": [ "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUPPORTED_PARAMETERS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUPPORTED_PARAMETERS.json new file mode 100644 index 0000000..dd2143e --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUPPORTED_PARAMETERS.json @@ -0,0 +1,18 @@ +{ + "name": "SUPPORTED_PARAMETERS", + "manufacturer_id": 0, + "pid": 80, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "pids", + "type": "list", + "itemType": { + "name": "pid", + "type": "uint16" + } + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUPPORTED_PARAMETERS_ENHANCED.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUPPORTED_PARAMETERS_ENHANCED.json new file mode 100644 index 0000000..78c382c --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUPPORTED_PARAMETERS_ENHANCED.json @@ -0,0 +1,33 @@ +{ + "name": "SUPPORTED_PARAMETERS_ENHANCED", + "manufacturer_id": 0, + "pid": -1, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "pids", + "type": "list", + "itemType": { + "type": "compound", + "subtypes": [ + { "name": "pid", "type": "uint16" }, + { + "name": "pid_support", + "type": "bitField", + "size": 16, + "bits": [ + { "name": "get_supported", "index": 0 }, + { "name": "set_supported", "index": 1 }, + { "name": "packed_pid_sub_get_supported", "index": 2 }, + { "name": "packed_pid_sub_set_supported", "index": 3 }, + { "name": "packed_pid_index_get_supported", "index": 4 }, + { "name": "packed_pid_index_set_supported", "index": 5 } + ] + } + ] + } + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/TILT_INVERT.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/TILT_INVERT.json new file mode 100644 index 0000000..75eb34e --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/TILT_INVERT.json @@ -0,0 +1,21 @@ +{ + "name": "TILT_INVERT", + "manufacturer_id": 0, + "pid": 1537, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "setting", + "type": "boolean", + "labels": [ + { "name": "Off", "value": false }, + { "name": "On", "value": true } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/BURN_IN.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/BURN_IN.json new file mode 100644 index 0000000..f608075 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/BURN_IN.json @@ -0,0 +1,23 @@ +{ + "name": "BURN_IN", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 1088, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { "name": "hours_remaining", "type": "uint8" } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { + "name": "hours", + "type": "uint8", + "labels": [ + { "name": "Abort", "value": 0 } + ] + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/CURVE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/CURVE.json new file mode 100644 index 0000000..fbec7d5 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/CURVE.json @@ -0,0 +1,18 @@ +{ + "name": "CURVE", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 835, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { "name": "curve", "type": "uint8" }, + { "name": "curve_count", "type": "uint8" } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { "name": "curve", "type": "uint8" } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/CURVE_DESCRIPTION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/CURVE_DESCRIPTION.json new file mode 100644 index 0000000..abc6992 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/CURVE_DESCRIPTION.json @@ -0,0 +1,20 @@ +{ + "name": "CURVE_DESCRIPTION", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 836, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { "name": "curve", "type": "uint8" } + ], + "get_response": [ + { "name": "curve", "type": "uint8" }, + { + "name": "description", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DIMMER_INFO.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DIMMER_INFO.json new file mode 100644 index 0000000..896d4c8 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DIMMER_INFO.json @@ -0,0 +1,55 @@ +{ + "name": "DIMMER_INFO", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 832, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "min_level_lower_limit", + "type": "uint16", + "labels": [ + { "name": "Not Implemented", "value": 0 } + ] + }, + { + "name": "min_level_upper_limit", + "type": "uint16", + "labels": [ + { "name": "Not Implemented", "value": 0 } + ] + }, + { + "name": "max_level_lower_limit", + "type": "uint16", + "labels": [ + { "name": "Not Implemented", "value": 65535 } + ] + }, + { + "name": "max_level_upper_limit", + "type": "uint16", + "labels": [ + { "name": "Not Implemented", "value": 65535 } + ] + }, + { "name": "curve_count", "type": "uint8" }, + { + "name": "levels_resolution_bits", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 16 } + ] + }, + { + "name": "min_level_split_levels_supported", + "type": "boolean", + "labels": [ + { "name": "Not Supported", "value": false }, + { "name": "Supported", "value": true } + ] + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DMX_BLOCK_ADDRESS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DMX_BLOCK_ADDRESS.json new file mode 100644 index 0000000..34799d3 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DMX_BLOCK_ADDRESS.json @@ -0,0 +1,40 @@ +{ + "name": "DMX_BLOCK_ADDRESS", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 320, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [], + "get_response": [ + { + "name": "total_subdevice_footprint", + "type": "uint16", + "ranges": [ + { "minimum": 0, "maximum": 512 } + ] + }, + { + "name": "base_dmx_address", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 512 }, + { "minimum": 65535, "maximum": 65535 } + ], + "labels": [ + { "name": "No Footprint", "value": 65535 } + ] + } + ], + "set_request_subdevice_range": [ "root" ], + "set_request": [ + { + "name": "base_dmx_address", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 512 } + ] + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DMX_FAIL_MODE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DMX_FAIL_MODE.json new file mode 100644 index 0000000..593c822 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DMX_FAIL_MODE.json @@ -0,0 +1,47 @@ +{ + "name": "DMX_FAIL_MODE", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 321, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "scene_num", + "type": "uint16", + "labels": [ + { "name": "PRESET_PLAYBACK_OFF", "value": 0 }, + { "name": "PRESET_PLAYBACK_ALL", "value": 65535 } + ] + }, + { + "name": "loss_of_signal_delay_time", + "type": "uint16", + "units": 21, + "prefixPower": -1, + "labels": [ + { "name": "Infinite", "value": 65535 } + ] + }, + { + "name": "hold_time", + "type": "uint16", + "units": 21, + "prefixPower": -1, + "labels": [ + { "name": "Infinite", "value": 65535 } + ] + }, + { + "name": "level", + "type": "uint8", + "labels": [ + { "name": "Full", "value": 255 } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DMX_STARTUP_MODE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DMX_STARTUP_MODE.json new file mode 100644 index 0000000..f568ba9 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/DMX_STARTUP_MODE.json @@ -0,0 +1,44 @@ +{ + "name": "DMX_STARTUP_MODE", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 322, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "scene_num", + "type": "uint16", + "labels": [ + { "name": "PRESET_PLAYBACK_OFF", "value": 0 }, + { "name": "PRESET_PLAYBACK_ALL", "value": 65535 } + ] + }, + { + "name": "startup_delay_time", + "type": "uint16", + "units": 21, + "prefixPower": -1 + }, + { + "name": "hold_time", + "type": "uint16", + "units": 21, + "prefixPower": -1, + "labels": [ + { "name": "Infinite", "value": 65535 } + ] + }, + { + "name": "level", + "type": "uint8", + "labels": [ + { "name": "Full", "value": 255 } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/IDENTIFY_MODE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/IDENTIFY_MODE.json new file mode 100644 index 0000000..7eaec5e --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/IDENTIFY_MODE.json @@ -0,0 +1,22 @@ +{ + "name": "IDENTIFY_MODE", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 4160, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "mode", + "type": "uint8", + "labels": [ + { "name": "Quiet Identify", "value": 0 }, + { "name": "Loud Identify", "value": 255 } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/LOCK_PIN.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/LOCK_PIN.json new file mode 100644 index 0000000..4d934b1 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/LOCK_PIN.json @@ -0,0 +1,36 @@ +{ + "name": "LOCK_PIN", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 1600, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "current_pin_code", + "type": "uint16", + "ranges": [ + { "minimum": 0, "maximum": 9999 } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { + "name": "new_pin_code", + "type": "uint16", + "ranges": [ + { "minimum": 0, "maximum": 9999 } + ] + }, + { + "name": "current_pin_code", + "type": "uint16", + "ranges": [ + { "minimum": 0, "maximum": 9999 } + ] + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/LOCK_STATE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/LOCK_STATE.json new file mode 100644 index 0000000..a82df8d --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/LOCK_STATE.json @@ -0,0 +1,37 @@ +{ + "name": "LOCK_STATE", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 1601, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "state", + "type": "uint8", + "labels": [ + { "name": "Unlocked", "value": 0 } + ] + }, + { "name": "state_count", "type": "uint8" } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { + "name": "pin_code", + "type": "uint16", + "ranges": [ + { "minimum": 0, "maximum": 9999 } + ] + }, + { + "name": "state", + "type": "uint8", + "labels": [ + { "name": "Unlocked", "value": 0 } + ] + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/LOCK_STATE_DESCRIPTION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/LOCK_STATE_DESCRIPTION.json new file mode 100644 index 0000000..36cecf6 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/LOCK_STATE_DESCRIPTION.json @@ -0,0 +1,32 @@ +{ + "name": "LOCK_STATE_DESCRIPTION", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 1602, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "state", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + } + ], + "get_response": [ + { + "name": "state", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + }, + { + "name": "description", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MAXIMUM_LEVEL.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MAXIMUM_LEVEL.json new file mode 100644 index 0000000..4227ddc --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MAXIMUM_LEVEL.json @@ -0,0 +1,15 @@ +{ + "name": "MAXIMUM_LEVEL", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 834, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { "name": "max_level", "type": "uint16" } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MINIMUM_LEVEL.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MINIMUM_LEVEL.json new file mode 100644 index 0000000..fe4ea10 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MINIMUM_LEVEL.json @@ -0,0 +1,17 @@ +{ + "name": "MINIMUM_LEVEL", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 833, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { "name": "min_level_increasing", "type": "uint16" }, + { "name": "min_level_decreasing", "type": "uint16" }, + { "name": "on_below_min", "type": "boolean" } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MODULATION_FREQUENCY.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MODULATION_FREQUENCY.json new file mode 100644 index 0000000..aa66cd4 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MODULATION_FREQUENCY.json @@ -0,0 +1,30 @@ +{ + "name": "MODULATION_FREQUENCY", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 839, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "setting", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + }, + { "name": "setting_count", "type": "uint8" } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { + "name": "setting", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MODULATION_FREQUENCY_DESCRIPTION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MODULATION_FREQUENCY_DESCRIPTION.json new file mode 100644 index 0000000..2dcf584 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/MODULATION_FREQUENCY_DESCRIPTION.json @@ -0,0 +1,42 @@ +{ + "name": "MODULATION_FREQUENCY_DESCRIPTION", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 840, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "setting", + "type": "uint8", + "notes": "The value isn't restricted in the spec, but MODULATION_FREQUENCY restricts this.", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + } + ], + "get_response": [ + { + "name": "setting", + "type": "uint8", + "notes": "The value isn't restricted in the spec, but MODULATION_FREQUENCY restricts this.", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + }, + { + "name": "frequency", + "type": "uint32", + "units": 8, + "labels": [ + { "name": "Not Declared", "value": 4294967295 } + ] + }, + { + "name": "description", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/OUTPUT_RESPONSE_TIME.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/OUTPUT_RESPONSE_TIME.json new file mode 100644 index 0000000..6910308 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/OUTPUT_RESPONSE_TIME.json @@ -0,0 +1,30 @@ +{ + "name": "OUTPUT_RESPONSE_TIME", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 837, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "setting", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + }, + { "name": "setting_count", "type": "uint8" } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { + "name": "setting", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/OUTPUT_RESPONSE_TIME_DESCRIPTION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/OUTPUT_RESPONSE_TIME_DESCRIPTION.json new file mode 100644 index 0000000..2c96662 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/OUTPUT_RESPONSE_TIME_DESCRIPTION.json @@ -0,0 +1,34 @@ +{ + "name": "OUTPUT_RESPONSE_TIME_DESCRIPTION", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 838, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "setting", + "type": "uint8", + "notes": "The value isn't restricted in the spec, but OUTPUT_RESPONSE_TIME restricts this.", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + } + ], + "get_response": [ + { + "name": "setting", + "type": "uint8", + "notes": "The value isn't restricted in the spec, but OUTPUT_RESPONSE_TIME restricts this.", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + }, + { + "name": "description", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/POWER_ON_SELF_TEST.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/POWER_ON_SELF_TEST.json new file mode 100644 index 0000000..f3101d7 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/POWER_ON_SELF_TEST.json @@ -0,0 +1,22 @@ +{ + "name": "POWER_ON_SELF_TEST", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 4164, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "parameter", + "type": "uint8", + "labels": [ + { "name": "Disabled", "value": 0 }, + { "name": "Enabled", "value": 1 } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/PRESET_INFO.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/PRESET_INFO.json new file mode 100644 index 0000000..80ea0de --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/PRESET_INFO.json @@ -0,0 +1,114 @@ +{ + "name": "PRESET_INFO", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 4161, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { "name": "level_field_supported", "type": "boolean" }, + { "name": "preset_sequence_supported", "type": "boolean" }, + { "name": "split_times_supported", "type": "boolean" }, + { "name": "dmx_fail_infinite_delay_time_supported", "type": "boolean" }, + { "name": "dmx_fail_infinite_hold_time_supported", "type": "boolean" }, + { "name": "startup_infinite_hold_time_supported", "type": "boolean" }, + { "name": "max_scene_number", "type": "uint16" }, + { + "name": "preset_min_fade_time", + "type": "uint16", + "units": 21, + "prefixPower": -1 + }, + { + "name": "preset_max_fade_time", + "type": "uint16", + "units": 21, + "prefixPower": -1 + }, + { + "name": "preset_min_wait_time", + "type": "uint16", + "units": 21, + "prefixPower": -1 + }, + { + "name": "preset_max_wait_time", + "type": "uint16", + "units": 21, + "prefixPower": -1 + }, + { + "name": "dmx_fail_min_delay_time", + "type": "uint16", + "units": 21, + "prefixPower": -1, + "labels": [ + { "name": "Not Supported", "value": 65535 } + ] + }, + { + "name": "dmx_fail_max_delay_time", + "type": "uint16", + "units": 21, + "prefixPower": -1, + "labels": [ + { "name": "Not Supported", "value": 65535 } + ] + }, + { + "name": "dmx_fail_min_hold_time", + "type": "uint16", + "units": 21, + "prefixPower": -1, + "labels": [ + { "name": "Not Supported", "value": 65535 } + ] + }, + { + "name": "dmx_fail_max_hold_time", + "type": "uint16", + "units": 21, + "prefixPower": -1, + "labels": [ + { "name": "Not Supported", "value": 65535 } + ] + }, + { + "name": "startup_min_delay_time", + "type": "uint16", + "units": 21, + "prefixPower": -1, + "labels": [ + { "name": "Not Supported", "value": 65535 } + ] + }, + { + "name": "startup_max_delay_time", + "type": "uint16", + "units": 21, + "prefixPower": -1, + "labels": [ + { "name": "Not Supported", "value": 65535 } + ] + }, + { + "name": "startup_min_hold_time", + "type": "uint16", + "units": 21, + "prefixPower": -1, + "labels": [ + { "name": "Not Supported", "value": 65535 } + ] + }, + { + "name": "startup_max_hold_time", + "type": "uint16", + "units": 21, + "prefixPower": -1, + "labels": [ + { "name": "Not Supported", "value": 65535 } + ] + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/PRESET_MERGE_MODE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/PRESET_MERGE_MODE.json new file mode 100644 index 0000000..465f69a --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/PRESET_MERGE_MODE.json @@ -0,0 +1,26 @@ +{ + "name": "PRESET_MERGE_MODE", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 4163, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "mode", + "type": "uint8", + "labels": [ + { "name": "DEFAULT", "value": 0 }, + { "name": "HTP", "value": 1 }, + { "name": "LTP", "value": 2 }, + { "name": "DMX_ONLY", "value": 3 }, + { "name": "OTHER", "value": 255 } + ], + "restrictToLabeled": true + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/PRESET_STATUS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/PRESET_STATUS.json new file mode 100644 index 0000000..f7df384 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-1/PRESET_STATUS.json @@ -0,0 +1,91 @@ +{ + "name": "PRESET_STATUS", + "notes": "E1.37-1", + "manufacturer_id": 0, + "pid": 4162, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "scene_num", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 65534 } + ] + } + ], + "get_response": [ + { + "name": "scene_num", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 65534 } + ] + }, + { + "name": "up_fade_time", + "type": "uint16", + "units": 21, + "prefixPower": -1 + }, + { + "name": "down_fade_time", + "type": "uint16", + "units": 21, + "prefixPower": -1 + }, + { + "name": "wait_time", + "type": "uint16", + "units": 21, + "prefixPower": -1 + }, + { + "name": "programmed", + "type": "uint8", + "labels": [ + { "name": "NOT_PROGRAMMED", "value": 0 }, + { "name": "PROGRAMMED", "value": 1 }, + { "name": "PROGRAMMED_READ_ONLY", "value": 2 } + ], + "restrictToLabeled": true + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { + "name": "scene_num", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 65534 } + ] + }, + { + "name": "up_fade_time", + "type": "uint16", + "units": 21, + "prefixPower": -1 + }, + { + "name": "down_fade_time", + "type": "uint16", + "units": 21, + "prefixPower": -1 + }, + { + "name": "wait_time", + "type": "uint16", + "units": 21, + "prefixPower": -1 + }, + { + "name": "clear_preset", + "type": "boolean", + "labels": [ + { "name": "Don't Clear", "value": false }, + { "name": "Clear", "value": true } + ] + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/DNS_DOMAIN_NAME.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/DNS_DOMAIN_NAME.json new file mode 100644 index 0000000..2fdb9c2 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/DNS_DOMAIN_NAME.json @@ -0,0 +1,28 @@ +{ + "name": "DNS_DOMAIN_NAME", + "notes": "E1.37-2. This the domain of an internet host; it is appended to the hostname using a dot ('.') to create a fully qualified domain name (FQDN).", + "manufacturer_id": 0, + "pid": 1805, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "domain_name", + "type": "string", + "resources": [ + "https://www.rfc-editor.org/rfc/rfc1123.html#section-2", + "https://www.rfc-editor.org/rfc/rfc1912.html#section-2.1", + "https://www.rfc-editor.org/rfc/rfc1035.html#section-2.3.1", + "https://www.rfc-editor.org/rfc/rfc3696.html#section-2", + "https://stackoverflow.com/a/14622263" + ], + "format": "hostname", + "maxLength": 231, + "restrictToASCII": true + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/DNS_HOSTNAME.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/DNS_HOSTNAME.json new file mode 100644 index 0000000..a96c6f7 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/DNS_HOSTNAME.json @@ -0,0 +1,29 @@ +{ + "name": "DNS_HOSTNAME", + "notes": "E1.37-2. This the host-specific part (or \"label\") of an internet host; it is prepended to the domain name using a dot ('.') to create a fully qualified domain name (FQDN).", + "manufacturer_id": 0, + "pid": 1804, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "hostname", + "type": "string", + "resources": [ + "https://www.rfc-editor.org/rfc/rfc1123.html#section-2", + "https://www.rfc-editor.org/rfc/rfc1912.html#section-2.1", + "https://www.rfc-editor.org/rfc/rfc3696.html#section-2", + "https://stackoverflow.com/a/14622263" + ], + "pattern": "^(?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]$", + "notes": "Some implementations don't support negative lookbehind in patterns. Alternative patterns without negative lookahead: \"^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])$\", \"^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$\".", + "minLength": 1, + "maxLength": 63, + "restrictToASCII": true + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/DNS_IPV4_NAME_SERVER.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/DNS_IPV4_NAME_SERVER.json new file mode 100644 index 0000000..d4e0245 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/DNS_IPV4_NAME_SERVER.json @@ -0,0 +1,35 @@ +{ + "name": "DNS_IPV4_NAME_SERVER", + "notes": "E1.37-2", + "manufacturer_id": 0, + "pid": 1803, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "index", + "type": "uint8", + "ranges": [ + { "minimum": 0, "maximum": 2 } + ] + } + ], + "get_response": [ + { + "name": "index", + "type": "uint8", + "ranges": [ + { "minimum": 0, "maximum": 2 } + ] + }, + { + "name": "address", + "type": "bytes", + "notes": "All zeros means IPV4_UNCONFIGURED.", + "format": "ipv4" + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_APPLY_CONFIGURATION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_APPLY_CONFIGURATION.json new file mode 100644 index 0000000..46df8c9 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_APPLY_CONFIGURATION.json @@ -0,0 +1,18 @@ +{ + "name": "INTERFACE_APPLY_CONFIGURATION", + "notes": "E1.37-2", + "manufacturer_id": 0, + "pid": 1781, + "version": 1, + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_HARDWARE_ADDRESS_TYPE1.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_HARDWARE_ADDRESS_TYPE1.json new file mode 100644 index 0000000..5c2d03d --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_HARDWARE_ADDRESS_TYPE1.json @@ -0,0 +1,32 @@ +{ + "name": "INTERFACE_HARDWARE_ADDRESS_TYPE1", + "notes": "E1.37-2", + "manufacturer_id": 0, + "pid": 1794, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + } + ], + "get_response": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + }, + { + "name": "address", + "type": "bytes", + "resources": [ "https://www.rfc-editor.org/rfc/rfc7042.html#section-2.1" ], + "format": "mac-address" + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_LABEL.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_LABEL.json new file mode 100644 index 0000000..460c72e --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_LABEL.json @@ -0,0 +1,32 @@ +{ + "name": "INTERFACE_LABEL", + "notes": "E1.37-2", + "manufacturer_id": 0, + "pid": 1793, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + } + ], + "get_response": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + }, + { + "name": "label", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_RELEASE_DHCP.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_RELEASE_DHCP.json new file mode 100644 index 0000000..0cb4539 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_RELEASE_DHCP.json @@ -0,0 +1,18 @@ +{ + "name": "INTERFACE_RELEASE_DHCP", + "notes": "E1.37-2", + "manufacturer_id": 0, + "pid": 1780, + "version": 1, + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_RENEW_DHCP.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_RENEW_DHCP.json new file mode 100644 index 0000000..7251fa8 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/INTERFACE_RENEW_DHCP.json @@ -0,0 +1,18 @@ +{ + "name": "INTERFACE_RENEW_DHCP", + "notes": "E1.37-2", + "manufacturer_id": 0, + "pid": 1799, + "version": 1, + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_CURRENT_ADDRESS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_CURRENT_ADDRESS.json new file mode 100644 index 0000000..a6148e0 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_CURRENT_ADDRESS.json @@ -0,0 +1,49 @@ +{ + "name": "IPV4_CURRENT_ADDRESS", + "notes": "E1.37-2", + "manufacturer_id": 0, + "pid": 1797, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + } + ], + "get_response": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + }, + { + "name": "address", + "type": "bytes", + "notes": "All zeros means IPV4_UNCONFIGURED.", + "format": "ipv4" + }, + { + "name": "netmask", + "type": "uint8", + "ranges": [ + { "minimum": 0, "maximum": 32 } + ] + }, + { + "name": "dhcp_status", + "type": "uint8", + "labels": [ + { "name": "INACTIVE", "value": 0 }, + { "name": "ACTIVE", "value": 1 }, + { "name": "UNKNOWN", "value": 2 } + ], + "restrictToLabeled": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_DEFAULT_ROUTE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_DEFAULT_ROUTE.json new file mode 100644 index 0000000..586392e --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_DEFAULT_ROUTE.json @@ -0,0 +1,27 @@ +{ + "name": "IPV4_DEFAULT_ROUTE", + "notes": "E1.37-2", + "manufacturer_id": 0, + "pid": 1802, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + }, + { + "name": "default_route", + "type": "bytes", + "notes": "All zeros means NO_DEFAULT_ROUTE.", + "format": "ipv4" + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_DHCP_MODE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_DHCP_MODE.json new file mode 100644 index 0000000..eb5685f --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_DHCP_MODE.json @@ -0,0 +1,37 @@ +{ + "name": "IPV4_DHCP_MODE", + "notes": "E1.37-2", + "manufacturer_id": 0, + "pid": 1795, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + } + ], + "get_response": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + }, + { + "name": "mode", + "type": "boolean", + "labels": [ + { "name": "Disabled", "value": false }, + { "name": "Enabled", "value": true } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_STATIC_ADDRESS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_STATIC_ADDRESS.json new file mode 100644 index 0000000..c2f9be4 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_STATIC_ADDRESS.json @@ -0,0 +1,41 @@ +{ + "name": "IPV4_STATIC_ADDRESS", + "notes": "E1.37-2", + "manufacturer_id": 0, + "pid": 1798, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + } + ], + "get_response": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + }, + { + "name": "address", + "type": "bytes", + "format": "ipv4" + }, + { + "name": "netmask", + "type": "uint8", + "ranges": [ + { "minimum": 0, "maximum": 32 } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_ZEROCONF_MODE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_ZEROCONF_MODE.json new file mode 100644 index 0000000..e1ba671 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/IPV4_ZEROCONF_MODE.json @@ -0,0 +1,37 @@ +{ + "name": "IPV4_ZEROCONF_MODE", + "notes": "E1.37-2", + "manufacturer_id": 0, + "pid": 1796, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + } + ], + "get_response": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + }, + { + "name": "mode", + "type": "boolean", + "labels": [ + { "name": "Disabled", "value": false }, + { "name": "Enabled", "value": true } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/LIST_INTERFACES.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/LIST_INTERFACES.json new file mode 100644 index 0000000..bb8ad38 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-2/LIST_INTERFACES.json @@ -0,0 +1,32 @@ +{ + "name": "LIST_INTERFACES", + "notes": "E1.37-2", + "manufacturer_id": 0, + "pid": 1792, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "interfaces", + "type": "list", + "itemType": { + "type": "compound", + "subtypes": [ + { + "name": "id", + "type": "uint32", + "ranges": [ + { "minimum": 1, "maximum": 4294967040 } + ] + }, + { + "name": "hardware_type", + "type": "uint16", + "resources": [ "https://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml" ] + } + ] + } + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/ADD_TAG.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/ADD_TAG.json new file mode 100644 index 0000000..521f496 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/ADD_TAG.json @@ -0,0 +1,16 @@ +{ + "name": "ADD_TAG", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 1618, + "version": 1, + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { + "name": "tag", + "type": "string", + "maxLength": 32 + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/CHECK_TAG.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/CHECK_TAG.json new file mode 100644 index 0000000..cb1e97a --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/CHECK_TAG.json @@ -0,0 +1,25 @@ +{ + "name": "CHECK_TAG", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 1620, + "version": 1, + "set_request_subdevice_range": [ "root", "subdevices" ], + "set_request": [ + { + "name": "tag", + "type": "string", + "maxLength": 32 + } + ], + "set_response": [ + { + "name": "status", + "type": "boolean", + "labels": [ + { "name": "Not Present", "value": false }, + { "name": "Present", "value": true } + ] + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/CLEAR_TAGS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/CLEAR_TAGS.json new file mode 100644 index 0000000..487f4f3 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/CLEAR_TAGS.json @@ -0,0 +1,10 @@ +{ + "name": "CLEAR_TAGS", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 1621, + "version": 1, + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/COMMS_STATUS_NSC.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/COMMS_STATUS_NSC.json new file mode 100644 index 0000000..a0831f4 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/COMMS_STATUS_NSC.json @@ -0,0 +1,63 @@ +{ + "name": "COMMS_STATUS_NSC", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 23, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [], + "get_response": [ + { + "name": "supported", + "type": "bitField", + "size": 8, + "bits": [ + { "name": "additive_checksum", "index": 0 }, + { "name": "packet_count", "index": 1 }, + { "name": "most_recent_slot_count", "index": 2 }, + { "name": "min_slot_count", "index": 3 }, + { "name": "max_slot_count", "index": 4 }, + { "name": "error_count", "index": 5 } + ] + }, + { "name": "additive_checksum", "type": "uint32" }, + { + "name": "packet_count", + "type": "uint32", + "labels": [ + { "name": "Not Supported", "value": 4294967295 } + ] + }, + { + "name": "most_recent_slot_count", + "type": "uint16", + "labels": [ + { "name": "Not Supported", "value": 65535 } + ] + }, + { + "name": "min_slot_count", + "type": "uint16", + "labels": [ + { "name": "Not Supported", "value": 65535 } + ] + }, + { + "name": "max_slot_count", + "type": "uint16", + "labels": [ + { "name": "Not Supported", "value": 65535 } + ] + }, + { + "name": "error_count", + "type": "uint32", + "labels": [ + { "name": "Not Supported", "value": 4294967295 } + ] + } + ], + "set_request_subdevice_range": [ "root" ], + "set_request": [], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/DEVICE_INFO_OFFSTAGE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/DEVICE_INFO_OFFSTAGE.json new file mode 100644 index 0000000..be8442d --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/DEVICE_INFO_OFFSTAGE.json @@ -0,0 +1,135 @@ +{ + "name": "DEVICE_INFO_OFFSTAGE", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 212, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "root_personality", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + }, + { + "name": "subdevice", + "type": "uint16", + "labels": [ + { "name": "root", "value": 0 } + ] + }, + { + "name": "subdevice_personality", + "type": "uint8", + "labels": [ + { "name": "root", "value": 0 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { "$ref": "#/get_request/1" }, + { "$ref": "#/get_request/2" }, + { "name": "protocol_major", "type": "uint8" }, + { "name": "protocol_minor", "type": "uint8" }, + { "name": "device_model_id", "type": "uint16" }, + { + "name": "product_category", + "type": "uint16", + "labels": [ + { "name": "NOT_DECLARED", "value": 0 }, + { "name": "FIXTURE", "value": 256 }, + { "name": "FIXTURE_FIXED", "value": 257 }, + { "name": "FIXTURE_MOVING_YOKE", "value": 258 }, + { "name": "FIXTURE_MOVING_MIRROR", "value": 259 }, + { "name": "FIXTURE_OTHER", "value": 511 }, + { "name": "FIXTURE_ACCESSORY", "value": 512 }, + { "name": "FIXTURE_ACCESSORY_COLOR", "value": 513 }, + { "name": "FIXTURE_ACCESSORY_YOKE", "value": 514 }, + { "name": "FIXTURE_ACCESSORY_MIRROR", "value": 515 }, + { "name": "FIXTURE_ACCESSORY_EFFECT", "value": 516 }, + { "name": "FIXTURE_ACCESSORY_BEAM", "value": 517 }, + { "name": "FIXTURE_ACCESSORY_OTHER", "value": 767 }, + { "name": "PROJECTOR", "value": 768 }, + { "name": "PROJECTOR_FIXED", "value": 769 }, + { "name": "PROJECTOR_MOVING_YOKE", "value": 770 }, + { "name": "PROJECTOR_MOVING_MIRROR", "value": 771 }, + { "name": "PROJECTOR_OTHER", "value": 1023 }, + { "name": "ATMOSPHERIC", "value": 1024 }, + { "name": "ATMOSPHERIC_EFFECT", "value": 1025 }, + { "name": "ATMOSPHERIC_PYRO", "value": 1026 }, + { "name": "ATMOSPHERIC_OTHER", "value": 1279 }, + { "name": "DIMMER", "value": 1280 }, + { "name": "DIMMER_AC_INCANDESCENT", "value": 1281 }, + { "name": "DIMMER_AC_FLUORESCENT", "value": 1282 }, + { "name": "DIMMER_AC_COLD_CATHODE", "value": 1283 }, + { "name": "DIMMER_AC_NONDIM", "value": 1284 }, + { "name": "DIMMER_AC_ELV", "value": 1285 }, + { "name": "DIMMER_AC_OTHER", "value": 1286 }, + { "name": "DIMMER_DC_LEVEL", "value": 1287 }, + { "name": "DIMMER_DC_PWM", "value": 1288 }, + { "name": "DIMMER_CS_LED", "value": 1289 }, + { "name": "DIMMER_OTHER", "value": 1535 }, + { "name": "POWER", "value": 1536 }, + { "name": "POWER_CONTROL", "value": 1537 }, + { "name": "POWER_SOURCE", "value": 1538 }, + { "name": "POWER_OTHER", "value": 1791 }, + { "name": "SCENIC", "value": 1792 }, + { "name": "SCENIC_DRIVE", "value": 1793 }, + { "name": "SCENIC_OTHER", "value": 2047 }, + { "name": "DATA", "value": 2048 }, + { "name": "DATA_DISTRIBUTION", "value": 2049 }, + { "name": "DATA_CONVERSION", "value": 2050 }, + { "name": "DATA_OTHER", "value": 2303 }, + { "name": "AV", "value": 2304 }, + { "name": "AV_AUDIO", "value": 2305 }, + { "name": "AV_VIDEO", "value": 2306 }, + { "name": "AV_OTHER", "value": 2559 }, + { "name": "MONITOR", "value": 2560 }, + { "name": "MONITOR_AC_LINE_POWER", "value": 2561 }, + { "name": "MONITOR_DC_POWER", "value": 2562 }, + { "name": "MONITOR_ENVIRONMENTAL", "value": 2563 }, + { "name": "MONITOR_OTHER", "value": 2815 }, + { "name": "CONTROL", "value": 28672 }, + { "name": "CONTROL_CONTROLLER", "value": 28673 }, + { "name": "CONTROL_BACKUP_DEVICE", "value": 28674 }, + { "name": "CONTROL_OTHER", "value": 28927 }, + { "name": "TEST", "value": 28928 }, + { "name": "TEST_EQUIPMENT", "value": 28929 }, + { "name": "TEST_OTHER", "value": 29183 }, + { "name": "OTHER", "value": 32767 } + ] + }, + { "name": "software_version_id", "type": "uint32" }, + { + "name": "dmx_footprint", + "type": "uint16", + "ranges": [ + { "minimum": 0, "maximum": 512 } + ] + }, + { + "name": "current_personality", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + }, + { "name": "personality_count", "type": "uint8" }, + { + "name": "dmx_start_address", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 512 }, + { "minimum": 65535, "maximum": 65535 } + ], + "labels": [ + { "name": "No Footprint", "value": 65535 } + ] + }, + { "name": "sub_device_count", "type": "uint16" }, + { "name": "sensor_count", "type": "uint8" } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/DEVICE_UNIT_NUMBER.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/DEVICE_UNIT_NUMBER.json new file mode 100644 index 0000000..342e046 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/DEVICE_UNIT_NUMBER.json @@ -0,0 +1,21 @@ +{ + "name": "DEVICE_UNIT_NUMBER", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 1622, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "unit_number", + "type": "uint32", + "labels": [ + { "name": "Unset", "value": 0 } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/DMX_PERSONALITY_ID.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/DMX_PERSONALITY_ID.json new file mode 100644 index 0000000..d5d0dc6 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/DMX_PERSONALITY_ID.json @@ -0,0 +1,22 @@ +{ + "name": "DMX_PERSONALITY_ID", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 226, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "personality", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { "name": "major_id", "type": "uint32" }, + { "name": "minor_id", "type": "uint32" } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/FIRMWARE_URL.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/FIRMWARE_URL.json new file mode 100644 index 0000000..0cb65e8 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/FIRMWARE_URL.json @@ -0,0 +1,17 @@ +{ + "name": "FIRMWARE_URL", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 210, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "url", + "type": "string", + "notes": "The spec says that the minimum length is 5, but we shouldn't restrict because that would imply we know what the URL scheme is.", + "format": "url" + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/IDENTIFY_TIMEOUT.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/IDENTIFY_TIMEOUT.json new file mode 100644 index 0000000..7462e6e --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/IDENTIFY_TIMEOUT.json @@ -0,0 +1,23 @@ +{ + "name": "IDENTIFY_TIMEOUT", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 4176, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "timeout", + "type": "uint16", + "units": 21, + "prefixPower": 0, + "labels": [ + { "name": "Disabled", "value": 0 } + ] + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": "get_response", + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/LIST_TAGS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/LIST_TAGS.json new file mode 100644 index 0000000..9f718d2 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/LIST_TAGS.json @@ -0,0 +1,16 @@ +{ + "name": "LIST_TAGS", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 1617, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "tags", + "type": "bytes", + "notes": "NUL-delimited." + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/MANUFACTURER_URL.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/MANUFACTURER_URL.json new file mode 100644 index 0000000..05aae77 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/MANUFACTURER_URL.json @@ -0,0 +1,17 @@ +{ + "name": "MANUFACTURER_URL", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 208, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "url", + "type": "string", + "notes": "The spec says that the minimum length is 5, but we shouldn't restrict because that would imply we know what the URL scheme is.", + "format": "url" + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/METADATA_JSON.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/METADATA_JSON.json new file mode 100644 index 0000000..771db13 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/METADATA_JSON.json @@ -0,0 +1,19 @@ +{ + "name": "METADATA_JSON", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 83, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { "name": "pid", "type": "uint16" } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { + "name": "json", + "type": "string", + "format": "json" + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/METADATA_JSON_URL.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/METADATA_JSON_URL.json new file mode 100644 index 0000000..4b49ace --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/METADATA_JSON_URL.json @@ -0,0 +1,16 @@ +{ + "name": "METADATA_JSON_URL", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 84, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "url", + "type": "string", + "format": "url" + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/METADATA_PARAMETER_VERSION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/METADATA_PARAMETER_VERSION.json new file mode 100644 index 0000000..923e84b --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/METADATA_PARAMETER_VERSION.json @@ -0,0 +1,18 @@ +{ + "name": "METADATA_PARAMETER_VERSION", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 82, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { "name": "pid", "type": "uint16" } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { + "name": "version", + "type": "uint16" + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/POWER_OFF_READY.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/POWER_OFF_READY.json new file mode 100644 index 0000000..ad3e34a --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/POWER_OFF_READY.json @@ -0,0 +1,19 @@ +{ + "name": "POWER_OFF_READY", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 4177, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "state", + "type": "boolean", + "labels": [ + { "name": "Not Ready", "value": false }, + { "name": "Ready", "value": true } + ] + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/PRODUCT_URL.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/PRODUCT_URL.json new file mode 100644 index 0000000..0415439 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/PRODUCT_URL.json @@ -0,0 +1,17 @@ +{ + "name": "PRODUCT_URL", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 209, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "url", + "type": "string", + "notes": "The spec says that the minimum length is 5, but we shouldn't restrict because that would imply we know what the URL scheme is.", + "format": "url" + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/REMOVE_TAG.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/REMOVE_TAG.json new file mode 100644 index 0000000..bec5482 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/REMOVE_TAG.json @@ -0,0 +1,16 @@ +{ + "name": "REMOVE_TAG", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 1619, + "version": 1, + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { + "name": "tag", + "type": "string", + "maxLength": 32 + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SENSOR_TYPE_CUSTOM.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SENSOR_TYPE_CUSTOM.json new file mode 100644 index 0000000..3f0fd0d --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SENSOR_TYPE_CUSTOM.json @@ -0,0 +1,25 @@ +{ + "name": "SENSOR_TYPE_CUSTOM", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 528, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "sensor_type", + "type": "uint8", + "ranges": [ + { "minimum": 128, "maximum": 255 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { + "name": "label", + "type": "string", + "maxLength": 32 + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SENSOR_UNIT_CUSTOM.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SENSOR_UNIT_CUSTOM.json new file mode 100644 index 0000000..1db4c71 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SENSOR_UNIT_CUSTOM.json @@ -0,0 +1,25 @@ +{ + "name": "SENSOR_UNIT_CUSTOM", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 529, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "sensor_unit", + "type": "uint8", + "ranges": [ + { "minimum": 128, "maximum": 255 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { + "name": "label", + "type": "string", + "maxLength": 32 + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SERIAL_NUMBER.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SERIAL_NUMBER.json new file mode 100644 index 0000000..2873a47 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SERIAL_NUMBER.json @@ -0,0 +1,16 @@ +{ + "name": "SERIAL_NUMBER", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 211, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "serial_number", + "type": "string", + "maxLength": 231 + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SHIPPING_LOCK.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SHIPPING_LOCK.json new file mode 100644 index 0000000..79f7003 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/SHIPPING_LOCK.json @@ -0,0 +1,35 @@ +{ + "name": "SHIPPING_LOCK", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 1616, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [], + "get_response": [ + { + "name": "lock_state", + "type": "uint8", + "labels": [ + { "name": "UNLOCKED", "value": 0 }, + { "name": "LOCKED", "value": 1 }, + { "name": "PARTIALLY_LOCKED", "value": 2 } + ], + "restrictToLabeled": true + } + ], + "set_request_subdevice_range": [ "root" ], + "set_request": [ + { + "name": "lock_state", + "type": "uint8", + "notes": "The list here is more restrictive than for getting the lock state. Do we want to add states and maybe descriptions?", + "labels": [ + { "name": "Unlocked", "value": 0 }, + { "name": "Locked", "value": 1 } + ], + "restrictToLabeled": true + } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/TEST_DATA.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/TEST_DATA.json new file mode 100644 index 0000000..71d2a4a --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-5/TEST_DATA.json @@ -0,0 +1,33 @@ +{ + "name": "TEST_DATA", + "notes": "E1.37-5", + "manufacturer_id": 0, + "pid": 22, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "pattern_length", + "type": "uint16", + "ranges": [ + { "minimum": 0, "maximum": 4096 } + ] + } + ], + "get_response": [ + { + "name": "pattern_data", + "type": "bytes", + "maxLength": 4096 + } + ], + "set_request_subdevice_range": [ "root", "subdevices" ], + "set_request": [ + { + "name": "loopback_data", + "type": "bytes", + "maxLength": 231 + } + ], + "set_response": "set_request" +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BACKGROUND_DISCOVERY.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BACKGROUND_DISCOVERY.json new file mode 100644 index 0000000..c762a78 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BACKGROUND_DISCOVERY.json @@ -0,0 +1,39 @@ +{ + "name": "BACKGROUND_DISCOVERY", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2312, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { "name": "enabled", "type": "boolean" } + ], + "set_request_subdevice_range": [ "root" ], + "set_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 }, + { "minimum": 65535, "maximum": 65535 } + ], + "labels": [ + { "name": "BROADCAST", "value": 65535 } + ] + }, + { "$ref": "#/get_response/1" } + ], + "set_response": [ + { "$ref": "#/set_request/0" } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BACKGROUND_QUEUED_STATUS_POLICY.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BACKGROUND_QUEUED_STATUS_POLICY.json new file mode 100644 index 0000000..4baa465 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BACKGROUND_QUEUED_STATUS_POLICY.json @@ -0,0 +1,32 @@ +{ + "name": "BACKGROUND_QUEUED_STATUS_POLICY", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2318, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { + "name": "policy_setting", + "type": "uint8", + "notes": "See \"Table 7-3: Control Field\" in ANSI E1.20-202x. The labeled values are just informative, but this contradicts with the spec (E1.37-7) saying \"must support this minimum set\".", + "labels": [ + { "name": "STATUS_NONE", "value": 0 }, + { "name": "STATUS_ADVISORY", "value": 1 }, + { "name": "STATUS_WARNING", "value": 2 }, + { "name": "STATUS_ERROR", "value": 3 } + ] + }, + { + "name": "policy_setting_count", + "type": "uint8", + "notes": "Breaking with other message definitions (and this is not mentioned in the spec), the policy setting value starts at 0, unlike others which start at 1. This means that the maximum value is 254 since the count can be at most 255." + } + ], + "set_request_subdevice_range": [ "root", "subdevices", "broadcast" ], + "set_request": [ + { "$ref": "#/get_response/0" } + ], + "set_response": [] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION.json new file mode 100644 index 0000000..92e17a9 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION.json @@ -0,0 +1,29 @@ +{ + "name": "BACKGROUND_QUEUED_STATUS_POLICY_DESCRIPTION", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2319, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "policy", + "type": "uint8", + "labels": [ + { "name": "Status Type None", "value": 0 }, + { "name": "Status Type Advisory and higher", "value": 1 }, + { "name": "Status Type Warning and higher", "value": 2 }, + { "name": "Status Type Error", "value": 3 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { + "name": "description", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BINDING_CONTROL_FIELDS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BINDING_CONTROL_FIELDS.json new file mode 100644 index 0000000..d5634a4 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/BINDING_CONTROL_FIELDS.json @@ -0,0 +1,37 @@ +{ + "name": "BINDING_CONTROL_FIELDS", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2317, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 } + ] + }, + { + "name": "uid", + "type": "bytes", + "format": "uid" + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { "$ref": "#/get_request/1" }, + { + "name": "control", + "type": "uint16", + "notes": "See \"Table 7-3: Control Field\" in ANSI E1.20-202x." + }, + { + "name": "binding_uid", + "type": "bytes", + "notes": "All zeros means no Binding UID present in the DISC_MUTE response.", + "format": "uid" + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/DISCOVERY_STATE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/DISCOVERY_STATE.json new file mode 100644 index 0000000..b2037c1 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/DISCOVERY_STATE.json @@ -0,0 +1,74 @@ +{ + "name": "DISCOVERY_STATE", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2311, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { + "name": "device_count", + "type": "uint16", + "ranges": [ + { "minimum": 0, "maximum": 63999 }, + { "minimum": 65535, "maximum": 65535 } + ], + "labels": [ + { "name": "DISCOVERY_COUNT_INCOMPLETE", "value": 0 }, + { "name": "DISCOVERY_COUNT_UNKNOWN", "value": 65535 } + ] + }, + { + "name": "state", + "type": "uint8", + "ranges": [ + { "minimum": 0, "maximum": 223 } + ], + "labels": [ + { "name": "INCOMPLETE", "value": 0 }, + { "name": "INCREMENTAL", "value": 1 }, + { "name": "FULL", "value": 2 }, + { "name": "NOT_ACTIVE", "value": 3 } + ] + } + ], + "set_request_subdevice_range": [ "root" ], + "set_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 }, + { "minimum": 65535, "maximum": 65535 } + ], + "labels": [ + { "name": "BROADCAST", "value": 65535 } + ] + }, + { + "name": "state", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 223 } + ], + "labels": [ + { "name": "INCREMENTAL", "value": 1 }, + { "name": "FULL", "value": 2 }, + { "name": "NOT_ACTIVE", "value": 3 } + ] + } + ], + "set_response": [ + { "$ref": "#/set_request/0" } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_LABEL.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_LABEL.json new file mode 100644 index 0000000..0f49f88 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_LABEL.json @@ -0,0 +1,44 @@ +{ + "name": "ENDPOINT_LABEL", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2309, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { + "name": "label", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ], + "set_request_subdevice_range": [ "root" ], + "set_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 }, + { "minimum": 65535, "maximum": 65535 } + ], + "labels": [ + { "name": "BROADCAST", "value": 65535 } + ] + }, + { "$ref": "#/get_response/1" } + ], + "set_response": [ + { "$ref": "#/set_request/0" } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_LIST.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_LIST.json new file mode 100644 index 0000000..6c34502 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_LIST.json @@ -0,0 +1,37 @@ +{ + "name": "ENDPOINT_LIST", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2304, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [], + "get_response": [ + { "name": "list_change_number", "type": "uint32" }, + { + "name": "endpoints", + "type": "list", + "itemType": { + "type": "compound", + "subtypes": [ + { + "name": "id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 } + ] + }, + { + "name": "type", + "type": "uint8", + "labels": [ + { "name": "VIRTUAL", "value": 0 }, + { "name": "PHYSICAL", "value": 1 } + ], + "restrictToLabeled": true + } + ] + } + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_LIST_CHANGE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_LIST_CHANGE.json new file mode 100644 index 0000000..8f6720e --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_LIST_CHANGE.json @@ -0,0 +1,12 @@ +{ + "name": "ENDPOINT_LIST_CHANGE", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2305, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [], + "get_response": [ + { "name": "list_change_number", "type": "uint32" } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_MODE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_MODE.json new file mode 100644 index 0000000..9c83db9 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_MODE.json @@ -0,0 +1,48 @@ +{ + "name": "ENDPOINT_MODE", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2308, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { + "name": "mode", + "type": "uint8", + "labels": [ + { "name": "Disabled", "value": 0 }, + { "name": "Input", "value": 1 }, + { "name": "Output", "value": 2 } + ], + "restrictToLabeled": true + } + ], + "set_request_subdevice_range": [ "root" ], + "set_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 }, + { "minimum": 65535, "maximum": 65535 } + ], + "labels": [ + { "name": "BROADCAST", "value": 65535 } + ] + }, + { "$ref": "#/get_response/1" } + ], + "set_response": [ + { "$ref": "#/set_request/0" } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_RESPONDERS.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_RESPONDERS.json new file mode 100644 index 0000000..0437b36 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_RESPONDERS.json @@ -0,0 +1,30 @@ +{ + "name": "ENDPOINT_RESPONDERS", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2315, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { "name": "list_change_number", "type": "uint32" }, + { + "name": "uids", + "type": "list", + "itemType": { + "name": "uid", + "type": "bytes", + "format": "uid" + } + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_RESPONDER_LIST_CHANGE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_RESPONDER_LIST_CHANGE.json new file mode 100644 index 0000000..c7cee97 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_RESPONDER_LIST_CHANGE.json @@ -0,0 +1,21 @@ +{ + "name": "ENDPOINT_RESPONDER_LIST_CHANGE", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2316, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { "name": "list_change_number", "type": "uint32" } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_TIMING.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_TIMING.json new file mode 100644 index 0000000..2f8c9c0 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_TIMING.json @@ -0,0 +1,46 @@ +{ + "name": "ENDPOINT_TIMING", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2313, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { + "name": "setting", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + }, + { "name": "setting_count", "type": "uint8" } + ], + "set_request_subdevice_range": [ "root" ], + "set_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 }, + { "minimum": 65535, "maximum": 65535 } + ], + "labels": [ + { "name": "BROADCAST", "value": 65535 } + ] + }, + { "$ref": "#/get_response/1" } + ], + "set_response": [ + { "$ref": "#/set_request/0" } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_TIMING_DESCRIPTION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_TIMING_DESCRIPTION.json new file mode 100644 index 0000000..e1cbb6b --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_TIMING_DESCRIPTION.json @@ -0,0 +1,26 @@ +{ + "name": "ENDPOINT_TIMING_DESCRIPTION", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2314, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "setting", + "type": "uint8", + "ranges": [ + { "minimum": 1, "maximum": 255 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { + "name": "description", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_TO_UNIVERSE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_TO_UNIVERSE.json new file mode 100644 index 0000000..e8db959 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/ENDPOINT_TO_UNIVERSE.json @@ -0,0 +1,59 @@ +{ + "name": "ENDPOINT_TO_UNIVERSE", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2307, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { + "name": "universe", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 }, + { "minimum": 65535, "maximum": 65535 } + ], + "labels": [ + { "name": "Unpatched", "value": 0 }, + { "name": "Composite", "value": 65535 } + ] + } + ], + "set_request_subdevice_range": [ "root" ], + "set_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 }, + { "minimum": 65535, "maximum": 65535 } + ], + "labels": [ + { "name": "BROADCAST", "value": 65535 } + ] + }, + { + "name": "universe", + "type": "uint16", + "ranges": [ + { "minimum": 0, "maximum": 63999 } + ], + "labels": [ + { "name": "Unpatched", "value": 0 } + ] + } + ], + "set_response": [ + { "$ref": "#/set_request/0" } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/IDENTIFY_ENDPOINT.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/IDENTIFY_ENDPOINT.json new file mode 100644 index 0000000..16eed74 --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/IDENTIFY_ENDPOINT.json @@ -0,0 +1,46 @@ +{ + "name": "IDENTIFY_ENDPOINT", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2306, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { + "name": "identify_state", + "type": "boolean", + "labels": [ + { "name": "Off", "value": false }, + { "name": "On", "value": true } + ] + } + ], + "set_request_subdevice_range": [ "root" ], + "set_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 }, + { "minimum": 65535, "maximum": 65535 } + ], + "labels": [ + { "name": "BROADCAST", "value": 65535 } + ] + }, + { "$ref": "#/get_response/1" } + ], + "set_response": [ + { "$ref": "#/set_request/0" } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/RDM_TRAFFIC_ENABLE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/RDM_TRAFFIC_ENABLE.json new file mode 100644 index 0000000..6b091dd --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.37-7/RDM_TRAFFIC_ENABLE.json @@ -0,0 +1,39 @@ +{ + "name": "RDM_TRAFFIC_ENABLE", + "notes": "E1.37-7", + "manufacturer_id": 0, + "pid": 2310, + "version": 1, + "get_request_subdevice_range": [ "root" ], + "get_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 } + ] + } + ], + "get_response": [ + { "$ref": "#/get_request/0" }, + { "name": "rdm_enabled", "type": "boolean" } + ], + "set_request_subdevice_range": [ "root" ], + "set_request": [ + { + "name": "endpoint_id", + "type": "uint16", + "ranges": [ + { "minimum": 1, "maximum": 63999 }, + { "minimum": 65535, "maximum": 65535 } + ], + "labels": [ + { "name": "BROADCAST", "value": 65535 } + ] + }, + { "$ref": "#/get_response/1" } + ], + "set_response": [ + { "$ref": "#/set_request/0" } + ] +} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/schema.json b/RDMSharp/Resources/JSON-Defines/1.0.0/schema.json new file mode 100644 index 0000000..c877fdd --- /dev/null +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/schema.json @@ -0,0 +1,582 @@ +{ + "$id": "https://www.esta.org/e1.37-5/schemas/1.0.0/schema.json", + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "Parameter Message", + "description": "The schema for the Parameter Metadata Language from Section 5 of E1.37-5. This schema is subject to change.", + "type": "object", + "$ref": "#/$defs/commonPropertiesForNamed", + "properties": { + "manufacturer_id": { + "$comment": "Manufacturer IDs are assigned by ESTA and are commonly expressed in hexadecimal. Users may expect to see these values in the UI as hexadecimal.", + "title": "Manufacturer ID", + "description": "The Manufacturer ID.", + "type": "integer", + "minimum": 0, + "maximum": 65535 + }, + "pid": { + "title": "PID", + "description": "The parameter ID.", + "type": "integer", + "minimum": 0, + "maximum": 65535 + }, + "version": { + "title": "Version", + "description": "The parameter descriptor version.", + "type": "integer", + "minimum": 0, + "maximum": 65535 + }, + "get_request_subdevice_range": { + "$comment": "'subdevicesForRequests' already contains a title and description", + "description": "Absence implies a default value of [\"root\"].", + "$ref": "#/$defs/subdevicesForRequests", + "default": [ "root" ] + }, + "get_request": { + "$comment": "'command' already contains a description", + "title": "GET Command", + "$ref": "#/$defs/command" + }, + "get_response_subdevice_range": { + "$comment": "'subdevicesForResponses' already contains a title and description", + "description": "Absence implies a default value of [\"match\"].", + "$ref": "#/$defs/subdevicesForResponses", + "default": [ "match" ] + }, + "get_response": { + "$comment": "'command' already contains a description", + "title": "GET Command Response", + "$ref": "#/$defs/command" + }, + "set_request_subdevice_range": { + "$comment": "'subdevicesForRequests' already contains a title and description", + "description": "Absence implies a default value of [\"root\"].", + "$ref": "#/$defs/subdevicesForRequests", + "default": [ "root" ] + }, + "set_request": { + "$comment": "'command' already contains a description", + "title": "SET Command", + "$ref": "#/$defs/command" + }, + "set_response_subdevice_range": { + "$comment": "'subdevicesForResponses' already contains a title and description", + "description": "Absence implies a default value of [\"match\"].", + "$ref": "#/$defs/subdevicesForResponses", + "default": [ "match" ] + }, + "set_response": { + "$comment": "'command' already contains a description", + "title": "SET Command Response", + "$ref": "#/$defs/command" + } + }, + "unevaluatedProperties": false, + "required": [ "manufacturer_id", "pid", "version" ], + "dependentRequired": { + "get_request": [ "get_response" ], + "get_response": [ "get_request" ], + "set_request": [ "set_response" ], + "set_response": [ "set_request" ] + }, + "$defs": { + "bit": { + "title": "Bit", + "description": "One bit in a bit field.", + "type": "object", + "$ref": "#/$defs/commonPropertiesForNamed", + "properties": { + "index": { + "title": "Index", + "description": "Zero-based index of this bit.", + "type": "integer", + "minimum": 0 + }, + "reserved": { + "title": "Reserved", + "description": "Indicates that this bit is unused or reserved. Note that this value does not need to be specified for absent bits; they are already assumed to be reserved.", + "type": "boolean" + }, + "valueIfReserved": { + "title": "Value If Reserved", + "description": "The assumed value when the bit is marked as reserved. Absence implies a default value of false.", + "type": "boolean", + "default": false + } + }, + "unevaluatedProperties": false, + "required": [ "index" ] + }, + "bitFieldType": { + "title": "Bit Field Type", + "description": "A bit field, a collection of 'bit' items. The \"size\" field is used to specify the number of bits in this bit field, a multiple of 8. It is an error if the size is less than the number of defined bits. Bits that are not specified are assumed to be reserved, having a value equal to the \"valueForUnspecified\" value.", + "type": "object", + "$ref": "#/$defs/commonPropertiesForNamed", + "properties": { + "type": { "const": "bitField" }, + "bits": { + "title": "Bits", + "description": "A list of the bits in the bit field.", + "type": "array", + "items": { "$ref": "#/$defs/bit" }, + "uniqueItems": true + }, + "size": { + "title": "Size", + "description": "The size, in multiples-of-8 bits, of this bit field. It is an error if the size is less than the number of defined bits.", + "type": "integer", + "minimum": 0, + "multipleOf": 8 + }, + "valueForUnspecified": { + "title": "Value for Unspecified", + "description": "The default value to use for any unspecified bits. Absence implies a default value of false.", + "type": "boolean", + "default": false + } + }, + "required": [ "type", "size", "bits" ] + }, + "booleanType": { + "title": "Boolean Type", + "description": "A Boolean value. This corresponds to the intent of DS_BOOLEAN in \"Table A-15: Data Type Defines\" of the E1.20-2010 specification, a 1-byte zero-or-one value.", + "type": "object", + "$ref": "#/$defs/commonPropertiesForNamed", + "properties": { + "type": { "const": "boolean" }, + "labels": { + "title": "Labels", + "description": "A list of labels that name special values.", + "type": "array", + "items": { "$ref": "#/$defs/labeledBoolean" }, + "uniqueItems": true, + "maxItems": 2 + } + }, + "required": [ "type" ] + }, + "bytesType": { + "title": "Bytes Type", + "description": "An array of bytes. The minimum and maximum length properties are not required, but it is a good idea to specify their values for unknown bytes types. This corresponds to the intent of DS_UNSIGNED_BYTE in \"Table A-15: Data Type Defines\" of the E1.20-2010 specification.", + "type": "object", + "$ref": "#/$defs/commonPropertiesForNamed", + "properties": { + "type": { "const": "bytes" }, + "format": { + "title": "Interpretation Format", + "description": "This field describes how to interpret the value. It can be one of the bytes types defined in \"Table A-15: Data Type Defines\" of the E1.20-2010 specification (or other add-on specifications), or it can be something manufacturer-specific. Be aware, however, that anything not defined here may not be understood by a controller or UI. The known bytes types include: ipv4 (4 bytes), ipv6 (16 bytes), mac-address (6 bytes), uid (6 bytes), and uuid (16 bytes).", + "type": "string" + }, + "minLength": { + "title": "Minimum Length", + "description": "The minimum bytes length. Care must be taken to make sure this doesn't contradict any \"maxLength\" value. It is an error if there is a contradiction.", + "type": "integer", + "minimum": 0 + }, + "maxLength": { + "title": "Maximum Length", + "description": "The maximum bytes length. Care must be taken to make sure this doesn't contradict any \"minLength\" value. It is an error if there is a contradiction. If a responder requires a controller to limit the number of bytes sent, then this value should be set.", + "type": "integer", + "minimum": 0 + } + }, + "required": [ "type" ] + }, + "command": { + "$comment": "The title is specific to where this used, and so no title is defined here", + "description": "The contents of an RDM command: 1. a collection of 'field' items, each a simple or compound type, 2. a single 'field' item, or 3. a duplicate command.", + "oneOf": [ + { + "title": "List of Fields", + "description": "The command consists of zero or more fields.", + "type": "array", + "items": { + "$ref": "#/$defs/oneOfTypes", + "unevaluatedProperties": false + }, + "uniqueItems": true + }, + { + "title": "Single Field", + "description": "The command consists of a single field.", + "$ref": "#/$defs/oneOfTypes", + "unevaluatedProperties": false + }, + { + "title": "Command Duplicate", + "description": "Indicates that a command is a duplicate of one of the other commands. Using this feature can potentially save space. It is an error if the command refers to itself.", + "enum": [ + "get_request", + "get_response", + "set_request", + "set_response" + ] + } + ] + }, + "commonPropertiesForNamed": { + "$comment": "Defines a set of properties common to everything having a name", + "properties": { + "name": { + "title": "Name", + "description": "The object name. If this is not intended for UI display, then a displayable name can be added with \"displayName\". This property can, for example, be used as the key for lookup into a table of localized display names.", + "type": "string", + "minLength": 1 + }, + "displayName": { + "title": "Display Name", + "description": "An optional name for UI display. This might be used, for example, as the fallback or default display name if, say, a localized name isn't specified or found via the \"name\" property.", + "type": "string", + "minLength": 1 + }, + "notes": { + "title": "Notes", + "description": "Contains any notes about this object.", + "type": "string" + }, + "resources": { + "title": "List of Resources", + "description": "Informative URLs pointing to a specification or more information for this field type.", + "type": "array", + "items": { + "type": "string", + "format": "uri-reference" + } + } + } + }, + "compoundType": { + "title": "Compound Type", + "description": "Defines a compound type, a type used to combine other types. This is useful for including in lists. This corresponds to the intent of DS_GROUP in \"Table A-15: Data Type Defines\" of the E1.20-2010 specification.", + "type": "object", + "$ref": "#/$defs/commonPropertiesForNamed", + "properties": { + "type": { "const": "compound" }, + "subtypes": { + "title": "Subtypes", + "description": "A list of types composing this compound type.", + "type": "array", + "items": { + "$ref": "#/$defs/oneOfTypes", + "unevaluatedProperties": false + } + } + }, + "required": [ "type", "subtypes" ] + }, + "integerType": { + "title": "Integer Type", + "description": "A signed or unsigned integer, can have an optional prefix, unit, and range. This corresponds to the intent of any of the integer types in \"Table A-15: Data Type Defines\" of the E1.20-2010 specification.", + "type": "object", + "$ref": "#/$defs/commonPropertiesForNamed", + "properties": { + "type": { + "enum": [ + "int8", + "int16", + "int32", + "int64", + "int128", + "uint8", + "uint16", + "uint32", + "uint64", + "uint128" + ] + }, + "labels": { + "title": "Labels", + "description": "A list of labels that name special values.", + "type": "array", + "items": { "$ref": "#/$defs/labeledInteger" }, + "uniqueItems": true + }, + "restrictToLabeled": { + "title": "Restrict to Labeled", + "description": "Whether to restrict the allowed values to those that have labels. This is useful to not have to additionally specify a set of ranges. If this is set to \"true\" then \"ranges\" should not be specified.", + "type": "boolean" + }, + "ranges": { + "title": "Ranges", + "description": "A list of possible ranges for the value. The complete range is the union of all the ranges. This should not be specified if \"restrictToLabeled\" is set to 'true'.", + "type": "array", + "items": { "$ref": "#/$defs/range" }, + "uniqueItems": true + }, + "units": { + "title": "Units", + "description": "The units type, defined in Table A-13 of E1.20-2010.", + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "prefixPower": { + "title": "Prefix Power", + "description": "The power of 10 to be used as the prefix for the value. For example, -2 is used to represent 10^(-2) or the prefix centi-. Absence implies a default value of 0.", + "type": "integer", + "default": 0 + }, + "prefixBase": { + "title": "Prefix Base", + "description": "The base of the prefix. For example, to express \"kilo\", specify prefixBase=10 and prefixPower=3, and to express \"kibi\", specify prefixBase=2 and prefixPower=10 or prefixBase=1024 and prefixPower=1. Absence implies a default value of 10.", + "type": "integer", + "default": 10 + } + }, + "required": [ "type" ] + }, + "labeledBoolean": { + "title": "Labeled Boolean", + "description": "Associates a name to a Boolean value.", + "type": "object", + "$ref": "#/$defs/commonPropertiesForNamed", + "properties": { + "value": { + "title": "Value", + "description": "The labeled value", + "type": "boolean" + } + }, + "unevaluatedProperties": false, + "required": [ "name", "value" ] + }, + "labeledInteger": { + "title": "Labeled Integer", + "description": "Associates a name to an integer value.", + "type": "object", + "$ref": "#/$defs/commonPropertiesForNamed", + "properties": { + "value": { + "title": "Value", + "description": "The labeled value", + "type": "integer" + } + }, + "unevaluatedProperties": false, + "required": [ "name", "value" ] + }, + "listType": { + "title": "List Type", + "description": "A list of objects all having the same type.", + "$comment": "The names \"minItems\" and \"maxItems\" were chosen because those match the validation keywords for arrays in the JSON schema spec", + "type": "object", + "$ref": "#/$defs/commonPropertiesForNamed", + "properties": { + "type": { "const": "list" }, + "itemType": { + "title": "Item Type", + "description": "The type of each item in the list.", + "$ref": "#/$defs/oneOfTypes", + "unevaluatedProperties": false + }, + "minItems": { + "title": "Minimum List Size", + "description": "The minimum list size.", + "type": "integer", + "minimum": 0 + }, + "maxItems": { + "title": "Maximum List Size", + "description": "The maximum list size.", + "type": "integer", + "minimum": 0 + } + }, + "required": [ "type", "itemType" ] + }, + "oneOfTypes": { + "$comment": "One of any of the types. This provides a single location to keep the list. None of the types here specify \"unevaluatedProperties\", so if extra properties are to be disallowed, then that must be specified by the referencer of this schema. This will make sorting through any errors easier", + "oneOf": [ + { "$ref": "#/$defs/bitFieldType" }, + { "$ref": "#/$defs/booleanType" }, + { "$ref": "#/$defs/bytesType" }, + { "$ref": "#/$defs/compoundType" }, + { "$ref": "#/$defs/integerType" }, + { "$ref": "#/$defs/listType" }, + { "$ref": "#/$defs/pdEnvelopeType" }, + { "$ref": "#/$defs/refType" }, + { "$ref": "#/$defs/stringType" } + ] + }, + "pdEnvelopeType": { + "title": "PD Envelope Type", + "description": "Contains a length/data pair for one Parameter Data item, where the length is an unsigned 8-bit value and the data has 'length' bytes. This exists to provide a schema definition for the 'envelope' of a PDL/PD pair.", + "type": "object", + "$ref": "#/$defs/commonPropertiesForNamed", + "properties": { + "type": { "const": "pdEnvelope" }, + "length": { + "title": "Data Length", + "description": "The data length can be optionally specified.", + "type": "integer", + "minimum": 0, + "maximum": 255 + } + }, + "required": [ "type" ] + }, + "range": { + "title": "Range", + "description": "Defines an inclusive range of numbers. If one of the bounds is undefined then it is assumed to be the bound appropriate for the type.", + "type": "object", + "properties": { + "minimum": { + "title": "Minimum", + "description": "The lower bound, inclusive.", + "type": "integer" + }, + "maximum": { + "title": "Maximum", + "description": "The upper bound, inclusive.", + "type": "integer" + } + }, + "additionalProperties": false + }, + "refType": { + "title": "Reference Type", + "description": "Specifies a reference to another value, a URI whose fragment part, if present, is a JSON Pointer. See [URI Syntax](https://www.rfc-editor.org/rfc/rfc3986.html) and [JSON Pointer](https://www.rfc-editor.org/rfc/rfc6901.html). It is an error if this does not point to an object having one of the types in \"#/$defs/oneOfTypes\", or if there is a circular reference. Any common properties defined in this field will override any defined by the referenced field.", + "type": "object", + "$ref": "#/$defs/commonPropertiesForNamed", + "properties": { + "$ref": { + "title": "Reference", + "description": "Points to a resource, a URI.", + "type": "string", + "format": "uri-reference" + } + }, + "additionalProperties": false, + "required": [ "$ref" ] + }, + "stringType": { + "title": "String Type", + "description": "A UTF-8-encoded string having a possibly bounded size. Implementations may need to use either a NUL terminator or another \"length\" field for multi-field messages where a string is followed by another field, so that its boundary can be determined. This corresponds to the intent of DS_STRING in \"Table A-15: Data Type Defines\" of the E1.20-2010 specification. Characters are defined by the [JSON specification](https://www.rfc-editor.org/rfc/rfc8259.html) (see [Section 7: Strings](https://www.rfc-editor.org/rfc/rfc8259.html#section-7) and [Section 8: String and Character Issues](https://www.rfc-editor.org/rfc/rfc8259.html#section-8)). Note that characters are either encoded directly in UTF-8 or escaped using the scheme described by the specification.", + "type": "object", + "$ref": "#/$defs/commonPropertiesForNamed", + "properties": { + "type": { "const": "string" }, + "format": { + "title": "Interpretation Format", + "description": "This field describes how to interpret the string value. It can be one of the string types defined in \"Table A-15: Data Type Defines\" of the E1.20-2010 specification (or other add-on specifications), one of the defined formats from the [JSON Schema Validation specification](https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.7.3), or it can be something manufacturer-specific. It is suggested that a URI or other unique naming convention be used to uniquely identify these. Be aware, however, that anything not defined here may not be understood by a controller or UI. The known string types from E1.20-2010 (and add-ons) include: \"hostname\" (https://www.rfc-editor.org/rfc/rfc1123.html#section-2, https://www.rfc-editor.org/rfc/rfc3696.html#section-2, https://www.rfc-editor.org/rfc/rfc5890.html), \"json\" (https://www.rfc-editor.org/rfc/rfc8259.html), \"string\", and \"url\" (the intent of DS_URL in \"Table A-15\") (https://www.rfc-editor.org/rfc/rfc3986.html, https://www.rfc-editor.org/rfc/rfc1738.html).", + "type": "string" + }, + "pattern": { + "title": "Pattern", + "description": "An [ECMA-262 regular expression](https://www.ecma-international.org/publications/standards/Ecma-262.htm) that can be used to validate the contents of this field. They're helpful for assisting a controller or UI do message validation. It's not necessary to provide a pattern for known \"format\" types. Note that care must be taken to make sure that patterns don't contradict any \"minLength\" and \"maxLength\" values. It is an error if there is a contradiction. As well, if there are maximum or minimum sizes, it is suggested that an instance makes use of the \"minLength\" and \"maxLength\" sizes in order to support those UIs that don't support regexes.", + "type": "string", + "format": "regex" + }, + "minLength": { + "title": "Minimum Length", + "description": "The minimum string length, in characters as defined by [JSON](https://www.rfc-editor.org/rfc/rfc8259.html). Care must be taken to make sure this doesn't contradict any \"pattern\" or \"maxLength\" values. It is an error if there is a contradiction. If there are maximum or minimum sizes, it is suggested that an instance makes use of the \"minLength\" and \"maxLength\" sizes in order to support those UIs that don't support regexes.", + "type": "integer", + "minimum": 0 + }, + "maxLength": { + "title": "Maximum Length", + "description": "The maximum string length, in characters as defined by [JSON](https://www.rfc-editor.org/rfc/rfc8259.html). Care must be taken to make sure this doesn't contradict any \"pattern\" or \"minLength\" values. It is an error if there is a contradiction. If there are maximum or minimum sizes, it is suggested that an instance makes use of the \"minLength\" and \"maxLength\" sizes in order to support those UIs that don't support regexes.", + "type": "integer", + "minimum": 0 + }, + "minBytes": { + "title": "Minimum Length in Bytes", + "description": "The minimum UTF-8-encoded length in bytes. In the case that the number of characters in the string is different from the number of bytes after UTF-8 encoding, we may need to specify a minimum encoded length.", + "type": "integer", + "minimum": 0 + }, + "maxBytes": { + "title": "Maximum Length in Bytes", + "description": "The maximum UTF-8-encoded length in bytes. In the case that the number of characters in the string is different from the number of bytes after UTF-8 encoding, we may need to specify a maximum encoded length. If a responder requires a controller to limit the number of bytes sent, then this value should be set.", + "type": "integer", + "minimum": 0 + }, + "restrictToASCII": { + "title": "Restrict to ASCII", + "description": "Indicates whether the string contents should be restricted to US-ASCII.", + "type": "boolean" + } + }, + "required": [ "type" ] + }, + "subdeviceType": { + "title": "Subdevice Type", + "description": "A subdevice value. It is a 16-bit integral type and its range includes the values specified by the E1.20-2010 specification (0x0001-0x0200). It does not include the root value (0) or special all-call value (65535).", + "type": "integer", + "minimum": 1, + "maximum": 512 + }, + "subdeviceRange": { + "title": "Subdevice Range", + "description": "Defines a range of subdevices, not including the root or the special all-call value. The complete range is the union of all the ranges in the subdevice array.", + "type": "object", + "properties": { + "minimum": { + "$comment": "'subdeviceType' already contains a title and description", + "title": "Minimum", + "description": "The lower bound, inclusive.", + "$ref": "#/$defs/subdeviceType" + }, + "maximum": { + "$comment": "'subdeviceType' already contains a title and description", + "title": "Maximum", + "description": "The upper bound, inclusive.", + "$ref": "#/$defs/subdeviceType" + } + }, + "required": [ "minimum", "maximum" ], + "additionalProperties": false + }, + "subdeviceValue": { + "title": "Subdevice Value", + "description": "Defines a single subdevice or range of subdevices. Note that a \"subdevice\" here means any valid subdevice that isn't \"root\" or \"broadcast\".", + "anyOf": [ + { "$ref": "#/$defs/subdeviceRange" }, + { "$ref": "#/$defs/subdeviceType" } + ] + }, + "subdevicesForRequests": { + "title": "Subdevices in a Request", + "description": "Acceptable values for the subdevice in a GET or SET command. An empty list means allow nothing.", + "type": "array", + "items": { + "anyOf": [ + { + "enum": [ + "root", + "subdevices", + "broadcast" + ] + }, + { + "$ref": "#/$defs/subdeviceValue" + } + ] + }, + "uniqueItems": true + }, + "subdevicesForResponses": { + "title": "Subdevices in a Response", + "description": "Acceptable values for the subdevice in a GET_RESPONSE or SET_RESPONSE. An empty list means allow nothing.", + "type": "array", + "items": { + "anyOf": [ + { + "enum": [ + "root", + "subdevices", + "broadcast", + "match" + ] + }, + { + "$ref": "#/$defs/subdeviceValue" + } + ] + }, + "uniqueItems": true + } + } +} diff --git a/RDMSharpTests/TestJSONDefines.cs b/RDMSharpTests/TestJSONDefines.cs new file mode 100644 index 0000000..e076d91 --- /dev/null +++ b/RDMSharpTests/TestJSONDefines.cs @@ -0,0 +1,36 @@ +using RDMSharp.Metadata; + +namespace RDMSharpTests +{ + public class TestJSONMetadataDefines + { + [SetUp] + public void Setup() + { + Console.OutputEncoding = System.Text.Encoding.Unicode; + } + [TearDown] + public void Teardown() + { + Console.OutputEncoding = System.Text.Encoding.Default; + } + + [Test] + public void TestJSONDefinesResources() + { + string[] resources = JSONDefinesResources.GetResources(); + Assert.That(resources, Is.Not.Empty); + Assert.That(resources, Has.Length.EqualTo(130)); + string[] schemas = resources.Where(r => r.EndsWith("schema.json")).ToArray(); + Assert.That(schemas, Has.Length.EqualTo(1)); + } + [Test] + public void TestMetadataFactory() + { + var schemas = MetadataFactory.GetMetadataSchemaVersions(); + Assert.That(schemas, Has.Count.EqualTo(1)); + var defines = MetadataFactory.GetMetadataDefineVersions(); + Assert.That(defines, Has.Count.EqualTo(129)); + } + } +} \ No newline at end of file From 684480d56e47c74080fa7a0aaa24e8835894629f Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Mon, 16 Sep 2024 17:30:15 +0200 Subject: [PATCH 02/51] Start implementing JSON-Parser --- RDMSharp/Metadata/JSONDefinesResources.cs | 11 - RDMSharp/Metadata/MetadataBag.cs | 35 +++ RDMSharp/Metadata/MetadataFactory.cs | 64 ++++- RDMSharp/Metadata/MetadataJSONObjectDefine.cs | 237 ++++++++++++++++++ RDMSharp/Metadata/MetadataSchemaVersion.cs | 41 --- ...ataDefineVersion.cs => MetadataVersion.cs} | 31 ++- RDMSharp/RDMSharp.csproj | 4 +- RDMSharpTests/TestJSONDefines.cs | 11 +- 8 files changed, 353 insertions(+), 81 deletions(-) delete mode 100644 RDMSharp/Metadata/JSONDefinesResources.cs create mode 100644 RDMSharp/Metadata/MetadataBag.cs create mode 100644 RDMSharp/Metadata/MetadataJSONObjectDefine.cs delete mode 100644 RDMSharp/Metadata/MetadataSchemaVersion.cs rename RDMSharp/Metadata/{MetadataDefineVersion.cs => MetadataVersion.cs} (57%) diff --git a/RDMSharp/Metadata/JSONDefinesResources.cs b/RDMSharp/Metadata/JSONDefinesResources.cs deleted file mode 100644 index ad88f51..0000000 --- a/RDMSharp/Metadata/JSONDefinesResources.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace RDMSharp -{ - public static class JSONDefinesResources - { - public static string[] GetResources() - { - var assembly = typeof(JSONDefinesResources).Assembly; - return assembly.GetManifestResourceNames(); - } - } -} diff --git a/RDMSharp/Metadata/MetadataBag.cs b/RDMSharp/Metadata/MetadataBag.cs new file mode 100644 index 0000000..46bf348 --- /dev/null +++ b/RDMSharp/Metadata/MetadataBag.cs @@ -0,0 +1,35 @@ +using System.IO; + +namespace RDMSharp.Metadata +{ + public readonly struct MetadataBag + { + public readonly string Version; + public readonly string Path; + public readonly string Name; + public readonly string Content; + public readonly bool IsSchema; + public MetadataBag(MetadataVersion metadataVersion) : this(metadataVersion.Version,metadataVersion.Name,metadataVersion.IsSchema, getContent(metadataVersion.Path), metadataVersion.Path) + { + } + public MetadataBag(string version, string name, bool isSchema, string content, string path) + { + Version = version; + Name= name; + IsSchema = isSchema; + Path = path; + Content = content; + } + private static string getContent(string path) + { + var assembly = typeof(MetadataFactory).Assembly; + using Stream stream = assembly.GetManifestResourceStream(path); + using StreamReader reader = new StreamReader(stream); + return reader.ReadToEnd(); + } + public override string ToString() + { + return $"{Name} [{Version}]"; + } + } +} diff --git a/RDMSharp/Metadata/MetadataFactory.cs b/RDMSharp/Metadata/MetadataFactory.cs index ef018c1..b66dd3d 100644 --- a/RDMSharp/Metadata/MetadataFactory.cs +++ b/RDMSharp/Metadata/MetadataFactory.cs @@ -1,5 +1,9 @@ -using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.Linq; +using System.Text.Json; +using System.Text.Json.Nodes; +using Json.Schema; namespace RDMSharp.Metadata { @@ -7,21 +11,67 @@ public static class MetadataFactory { private const string SCHEMA_FILE_NAME = "schema.json"; private const string JSON_ENDING = ".json"; + private static List metadataVersionList; + private static Dictionary> metadataVersionDefinesBagDictionary; + public static IReadOnlyCollection MetadataVersionList + { + get + { + if (metadataVersionList == null) + { + metadataVersionList = new List(); + fillDefaultMetadataVersionList(); + } + return metadataVersionList.AsReadOnly(); + } + } public static string[] GetResources() { var assembly = typeof(MetadataFactory).Assembly; return assembly.GetManifestResourceNames(); } + private static void fillDefaultMetadataVersionList() + { + metadataVersionList.AddRange(GetResources().Select(r => new MetadataVersion(r))); + + if (metadataVersionDefinesBagDictionary == null) + metadataVersionDefinesBagDictionary = new Dictionary>(); + + var schemaList = GetMetadataSchemaVersions(); + ConcurrentDictionary versionSchemas= new ConcurrentDictionary(); + + foreach (var mv in metadataVersionList.Where(_mv => !_mv.IsSchema)) + { + var schema = schemaList.First(s => s.Version.Equals(mv.Version)); + if(!versionSchemas.TryGetValue(schema.Version, out JsonSchema jsonSchema)) + { + jsonSchema= JsonSchema.FromText(new MetadataBag(schema).Content); ; + versionSchemas.TryAdd(schema.Version, jsonSchema); + } + MetadataBag metadataBag = new MetadataBag(mv); + var result = jsonSchema.Evaluate(JsonNode.Parse(metadataBag.Content)); + if (result.IsValid) + { + MetadataJSONObjectDefine jsonDefine = JsonSerializer.Deserialize(metadataBag.Content); + if (!metadataVersionDefinesBagDictionary.ContainsKey(schema)) + metadataVersionDefinesBagDictionary.Add(schema, new List()); + + metadataVersionDefinesBagDictionary[schema].Add(jsonDefine); + } + else + { + + } + } + } - public static IList GetMetadataSchemaVersions() + public static IReadOnlyCollection GetMetadataSchemaVersions() { - var list = GetResources().Where(r => r.EndsWith(SCHEMA_FILE_NAME)); - return list.Select(r=>new MetadataSchemaVersion(r)).ToList(); + return MetadataVersionList.Where(r => r.IsSchema).ToList().AsReadOnly(); } - public static IList GetMetadataDefineVersions() + public static IReadOnlyCollection GetMetadataDefineVersions() { - var list = GetResources().Where(r => r.EndsWith(JSON_ENDING) && !r.EndsWith(SCHEMA_FILE_NAME)); - return list.Select(r => new MetadataDefineVersion(r)).ToList(); + return MetadataVersionList.Where(r => !r.IsSchema).ToList().AsReadOnly(); } } } diff --git a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs new file mode 100644 index 0000000..24b36a4 --- /dev/null +++ b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs @@ -0,0 +1,237 @@ +using System.Text.Json; +using System; +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata +{ + public readonly struct MetadataJSONObjectDefine + { + [JsonPropertyName("name")] + public readonly string Name { get; } + [JsonPropertyName("manufacturer_id")] + public readonly ushort ManufacturerID { get; } + [JsonPropertyName("pid")] + public readonly ushort PID { get; } + [JsonPropertyName("version")] + public readonly ushort Version { get; } + [JsonPropertyName("get_request_subdevice_range")] + public readonly SubdevicesForRequests[] GetRequestSubdeviceRange { get; } + [JsonPropertyName("get_response_subdevice_range")] + public readonly SubdevicesForResponses[] GetResponseSubdeviceRange { get; } + [JsonPropertyName("set_request_subdevice_range")] + public readonly SubdevicesForRequests[] SetReequestsSubdeviceRange { get; } + [JsonPropertyName("set_response_subdevice_range")] + public readonly SubdevicesForResponses[] SetResponseSubdeviceRange { get; } + + [JsonConstructor] + public MetadataJSONObjectDefine(string name, ushort manufacturerID, ushort pID, ushort version, SubdevicesForRequests[] getRequestSubdeviceRange, SubdevicesForResponses[] getResponseSubdeviceRange, SubdevicesForRequests[] setReequestsSubdeviceRange, SubdevicesForResponses[] setResponseSubdeviceRange) + { + Name = name; + ManufacturerID = manufacturerID; + PID = pID; + Version = version; + GetRequestSubdeviceRange = getRequestSubdeviceRange; + GetResponseSubdeviceRange = getResponseSubdeviceRange; + SetReequestsSubdeviceRange = setReequestsSubdeviceRange; + SetResponseSubdeviceRange = setResponseSubdeviceRange; + } + + public override string ToString() + { + return $"{ManufacturerID:X4} {PID:X4} {Name}"; + } + } + [JsonConverter(typeof(SubdevicesForRequestsConverter))] + public readonly struct SubdevicesForRequests + { + public enum ESubdevicesForRequests + { + [JsonPropertyName("root")] + Root, + [JsonPropertyName("subdevices")] + Subdevices, + [JsonPropertyName("broadcast")] + Broadcast + } + public readonly ESubdevicesForRequests? EnumValue { get; } + public readonly SubdeviceType? ObjectValue { get; } + public SubdevicesForRequests(ESubdevicesForRequests enumValue) + { + EnumValue = enumValue; + } + public SubdevicesForRequests(SubdeviceType objectValue) + { + ObjectValue = objectValue; + } + public override string ToString() + { + if (EnumValue.HasValue) + return EnumValue.Value.ToString(); + if (ObjectValue.HasValue) + return ObjectValue.Value.ToString(); + return base.ToString(); + } + } + public readonly struct SubdevicesForResponses + { + public enum ESubdevicesForResponses + { + [JsonPropertyName("root")] + Root, + [JsonPropertyName("subdevices")] + Subdevices, + [JsonPropertyName("broadcast")] + Broadcast, + [JsonPropertyName("match")] + Match + } + public readonly ESubdevicesForResponses? EnumValue { get; } + public readonly SubdeviceType? ObjectValue { get; } + public SubdevicesForResponses(ESubdevicesForResponses enumValue) + { + EnumValue = enumValue; + } + public SubdevicesForResponses(SubdeviceType objectValue) + { + ObjectValue = objectValue; + } + public override string ToString() + { + if (EnumValue.HasValue) + return EnumValue.Value.ToString(); + if (ObjectValue.HasValue) + return ObjectValue.Value.ToString(); + return base.ToString(); + } + } + [JsonConverter(typeof(SubdeviceTypeConverter))] + public readonly struct SubdeviceType + { + public readonly ushort? Value { get; } + public readonly SubdeviceRange? Range { get; } + public SubdeviceType(ushort value) : this() + { + Value = value; + } + + public SubdeviceType(SubdeviceRange range) : this() + { + Range = range; + } + public override string ToString() + { + if(Value.HasValue) + return $"Subdevice Value: {Value:X4}"; + if (Range.HasValue) + return Range.ToString(); + return base.ToString(); + } + } + public readonly struct SubdeviceRange + { + [JsonPropertyName("minimum")] + public readonly ushort Minimum { get; } + + [JsonPropertyName("maximum")] + public readonly ushort Maximum { get; } + + [JsonConstructor] + public SubdeviceRange(ushort minimum, ushort maximum) : this() + { + Minimum = minimum; + Maximum = maximum; + } + public override string ToString() + { + return $"Subdevice Range: {Minimum:X4} - {Maximum:X4}"; + } + } + public class SubdeviceTypeConverter : JsonConverter + { + public override SubdeviceType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Number) + { + var number = JsonSerializer.Deserialize(ref reader, options); + return new SubdeviceType(number); + } + else if (reader.TokenType == JsonTokenType.StartObject) + { + var objectValue = JsonSerializer.Deserialize(ref reader, options); + return new SubdeviceType(objectValue); + } + + throw new JsonException("Unexpected JSON format for FieldContainer."); + } + + public override void Write(Utf8JsonWriter writer, SubdeviceType value, JsonSerializerOptions options) + { + if (value.Value.HasValue) + JsonSerializer.Serialize(writer, value.Value.Value, options); + else if (value.Range.HasValue) + JsonSerializer.Serialize(writer, value.Range.Value, options); + } + } + public class SubdevicesForRequestsConverter : JsonConverter + { + public override SubdevicesForRequests Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.String) + { + var _options = new JsonSerializerOptions(options) + { + Converters = { new JsonStringEnumConverter() }, + PropertyNameCaseInsensitive = true + }; + var enumValue = JsonSerializer.Deserialize(ref reader, _options); + return new SubdevicesForRequests(enumValue); + } + else if (reader.TokenType == JsonTokenType.StartObject || reader.TokenType == JsonTokenType.Number) + { + var objectValue = JsonSerializer.Deserialize(ref reader, options); + return new SubdevicesForRequests(objectValue); + } + + throw new JsonException("Unexpected JSON format for FieldContainer."); + } + + public override void Write(Utf8JsonWriter writer, SubdevicesForRequests value, JsonSerializerOptions options) + { + if (value.EnumValue.HasValue) + JsonSerializer.Serialize(writer, value.EnumValue.Value, options); + else if (value.ObjectValue != null) + JsonSerializer.Serialize(writer, value.ObjectValue, options); + } + } + public class SubdevicesForReponseConverter : JsonConverter + { + public override SubdevicesForResponses Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.String) + { + var _options = new JsonSerializerOptions(options) + { + Converters = { new JsonStringEnumConverter() }, + PropertyNameCaseInsensitive = true + }; + var enumValue = JsonSerializer.Deserialize(ref reader, _options); + return new SubdevicesForResponses(enumValue); + } + else if (reader.TokenType == JsonTokenType.StartObject || reader.TokenType == JsonTokenType.Number) + { + var objectValue = JsonSerializer.Deserialize(ref reader, options); + return new SubdevicesForResponses(objectValue); + } + + throw new JsonException("Unexpected JSON format for FieldContainer."); + } + + public override void Write(Utf8JsonWriter writer, SubdevicesForResponses value, JsonSerializerOptions options) + { + if (value.EnumValue.HasValue) + JsonSerializer.Serialize(writer, value.EnumValue.Value, options); + else if (value.ObjectValue != null) + JsonSerializer.Serialize(writer, value.ObjectValue, options); + } + } +} diff --git a/RDMSharp/Metadata/MetadataSchemaVersion.cs b/RDMSharp/Metadata/MetadataSchemaVersion.cs deleted file mode 100644 index 7b14d97..0000000 --- a/RDMSharp/Metadata/MetadataSchemaVersion.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.IO; -using System.Text.RegularExpressions; - -namespace RDMSharp.Metadata -{ - public readonly struct MetadataSchemaVersion - { - public readonly string Version; - public readonly string Schema; - public readonly string Path; - public MetadataSchemaVersion(string path) : this(getVersion(path), getSchema(path), path) - { - } - public MetadataSchemaVersion(string version, string schema, string path) - { - Version = version; - Schema = schema; - Path = path; - } - private static string getVersion(string path) - { - string pattern = @"_(\d+)\._(\d+)\._(\d+)"; - var match = Regex.Match(path, pattern); - - if (match.Success) - { - return match.Value.Replace("_", ""); - } - else - throw new Exception($"Can't extract Version from Path: {path}"); - } - private static string getSchema(string path) - { - var assembly = typeof(MetadataFactory).Assembly; - using Stream stream = assembly.GetManifestResourceStream(path); - using StreamReader reader = new StreamReader(stream); - return reader.ReadToEnd(); - } - } -} diff --git a/RDMSharp/Metadata/MetadataDefineVersion.cs b/RDMSharp/Metadata/MetadataVersion.cs similarity index 57% rename from RDMSharp/Metadata/MetadataDefineVersion.cs rename to RDMSharp/Metadata/MetadataVersion.cs index 9a7ce32..946880e 100644 --- a/RDMSharp/Metadata/MetadataDefineVersion.cs +++ b/RDMSharp/Metadata/MetadataVersion.cs @@ -1,23 +1,23 @@ using System; -using System.IO; using System.Text.RegularExpressions; namespace RDMSharp.Metadata { - public readonly struct MetadataDefineVersion + public readonly struct MetadataVersion { public readonly string Version; - public readonly string Define; public readonly string Path; public readonly string Name; - public MetadataDefineVersion(string path) : this(getVersion(path), getDefine(path), path) + public readonly bool IsSchema; + public MetadataVersion(string path) : this(getVersion(path), getName(path), getIsSchema(path), path) { } - public MetadataDefineVersion(string version, string define, string path) + public MetadataVersion(string version, string name, bool isSchema, string path) { Version = version; - Define = define; Path = path; + Name = name; + IsSchema = isSchema; string pattern = @"[^\.]+\.[json]+$"; var match = Regex.Match(Path, pattern); @@ -40,12 +40,21 @@ private static string getVersion(string path) else throw new Exception($"Can't extract Version from Path: {path}"); } - private static string getDefine(string path) + private static bool getIsSchema(string path) { - var assembly = typeof(MetadataFactory).Assembly; - using Stream stream = assembly.GetManifestResourceStream(path); - using StreamReader reader = new StreamReader(stream); - return reader.ReadToEnd(); + return path.ToLower().EndsWith("schema.json"); + } + private static string getName(string path) + { + string pattern = @"[^\.]+\.[json]+$"; + var match = Regex.Match(path, pattern); + + if (match.Success) + { + return match.Value; + } + else + throw new Exception($"Can't extract Name from Path: {path}"); } public override string ToString() { diff --git a/RDMSharp/RDMSharp.csproj b/RDMSharp/RDMSharp.csproj index f7c3d67..f3111ce 100644 --- a/RDMSharp/RDMSharp.csproj +++ b/RDMSharp/RDMSharp.csproj @@ -1,6 +1,6 @@  - netstandard2.0;net6.0;net7.0;net8.0 + net6.0;net7.0;net8.0 LICENSE 0.0.13 https://github.com/DMXControl/RDMSharp @@ -32,9 +32,11 @@ + + diff --git a/RDMSharpTests/TestJSONDefines.cs b/RDMSharpTests/TestJSONDefines.cs index e076d91..7c2d79f 100644 --- a/RDMSharpTests/TestJSONDefines.cs +++ b/RDMSharpTests/TestJSONDefines.cs @@ -2,7 +2,7 @@ namespace RDMSharpTests { - public class TestJSONMetadataDefines + public class TestMetadataFactoryStuff { [SetUp] public void Setup() @@ -15,15 +15,6 @@ public void Teardown() Console.OutputEncoding = System.Text.Encoding.Default; } - [Test] - public void TestJSONDefinesResources() - { - string[] resources = JSONDefinesResources.GetResources(); - Assert.That(resources, Is.Not.Empty); - Assert.That(resources, Has.Length.EqualTo(130)); - string[] schemas = resources.Where(r => r.EndsWith("schema.json")).ToArray(); - Assert.That(schemas, Has.Length.EqualTo(1)); - } [Test] public void TestMetadataFactory() { From 069f5ef46f6d30b12d9a04d34c1ce5125fc4a033 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Mon, 16 Sep 2024 17:47:22 +0200 Subject: [PATCH 03/51] CleanUp --- .../JSON/Converter/SubdeviceTypeConverter.cs | 33 +++ .../SubdevicesForRequestsConverter.cs | 38 ++++ .../SubdevicesForResponsesConverter.cs | 38 ++++ RDMSharp/Metadata/JSON/SubdeviceRange.cs | 24 +++ RDMSharp/Metadata/JSON/SubdeviceType.cs | 29 +++ .../Metadata/JSON/SubdevicesForRequests.cs | 37 ++++ .../Metadata/JSON/SubdevicesForResponses.cs | 39 ++++ RDMSharp/Metadata/MetadataJSONObjectDefine.cs | 194 +----------------- 8 files changed, 239 insertions(+), 193 deletions(-) create mode 100644 RDMSharp/Metadata/JSON/Converter/SubdeviceTypeConverter.cs create mode 100644 RDMSharp/Metadata/JSON/Converter/SubdevicesForRequestsConverter.cs create mode 100644 RDMSharp/Metadata/JSON/Converter/SubdevicesForResponsesConverter.cs create mode 100644 RDMSharp/Metadata/JSON/SubdeviceRange.cs create mode 100644 RDMSharp/Metadata/JSON/SubdeviceType.cs create mode 100644 RDMSharp/Metadata/JSON/SubdevicesForRequests.cs create mode 100644 RDMSharp/Metadata/JSON/SubdevicesForResponses.cs diff --git a/RDMSharp/Metadata/JSON/Converter/SubdeviceTypeConverter.cs b/RDMSharp/Metadata/JSON/Converter/SubdeviceTypeConverter.cs new file mode 100644 index 0000000..b7b4219 --- /dev/null +++ b/RDMSharp/Metadata/JSON/Converter/SubdeviceTypeConverter.cs @@ -0,0 +1,33 @@ +using System.Text.Json; +using System; +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.JSON.Converter +{ + public class SubdeviceTypeConverter : JsonConverter + { + public override SubdeviceType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Number) + { + var number = JsonSerializer.Deserialize(ref reader, options); + return new SubdeviceType(number); + } + else if (reader.TokenType == JsonTokenType.StartObject) + { + var objectValue = JsonSerializer.Deserialize(ref reader, options); + return new SubdeviceType(objectValue); + } + + throw new JsonException("Unexpected JSON format for FieldContainer."); + } + + public override void Write(Utf8JsonWriter writer, SubdeviceType value, JsonSerializerOptions options) + { + if (value.Value.HasValue) + JsonSerializer.Serialize(writer, value.Value.Value, options); + else if (value.Range.HasValue) + JsonSerializer.Serialize(writer, value.Range.Value, options); + } + } +} diff --git a/RDMSharp/Metadata/JSON/Converter/SubdevicesForRequestsConverter.cs b/RDMSharp/Metadata/JSON/Converter/SubdevicesForRequestsConverter.cs new file mode 100644 index 0000000..0c52387 --- /dev/null +++ b/RDMSharp/Metadata/JSON/Converter/SubdevicesForRequestsConverter.cs @@ -0,0 +1,38 @@ +using System.Text.Json; +using System; +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.JSON.Converter +{ + public class SubdevicesForRequestsConverter : JsonConverter + { + public override SubdevicesForRequests Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.String) + { + var _options = new JsonSerializerOptions(options) + { + Converters = { new JsonStringEnumConverter() }, + PropertyNameCaseInsensitive = true + }; + var enumValue = JsonSerializer.Deserialize(ref reader, _options); + return new SubdevicesForRequests(enumValue); + } + else if (reader.TokenType == JsonTokenType.StartObject || reader.TokenType == JsonTokenType.Number) + { + var objectValue = JsonSerializer.Deserialize(ref reader, options); + return new SubdevicesForRequests(objectValue); + } + + throw new JsonException("Unexpected JSON format for FieldContainer."); + } + + public override void Write(Utf8JsonWriter writer, SubdevicesForRequests value, JsonSerializerOptions options) + { + if (value.EnumValue.HasValue) + JsonSerializer.Serialize(writer, value.EnumValue.Value, options); + else if (value.ObjectValue != null) + JsonSerializer.Serialize(writer, value.ObjectValue, options); + } + } +} diff --git a/RDMSharp/Metadata/JSON/Converter/SubdevicesForResponsesConverter.cs b/RDMSharp/Metadata/JSON/Converter/SubdevicesForResponsesConverter.cs new file mode 100644 index 0000000..4a0b263 --- /dev/null +++ b/RDMSharp/Metadata/JSON/Converter/SubdevicesForResponsesConverter.cs @@ -0,0 +1,38 @@ +using System.Text.Json; +using System; +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.JSON.Converter +{ + public class SubdevicesForResponsesConverter : JsonConverter + { + public override SubdevicesForResponses Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.String) + { + var _options = new JsonSerializerOptions(options) + { + Converters = { new JsonStringEnumConverter() }, + PropertyNameCaseInsensitive = true + }; + var enumValue = JsonSerializer.Deserialize(ref reader, _options); + return new SubdevicesForResponses(enumValue); + } + else if (reader.TokenType == JsonTokenType.StartObject || reader.TokenType == JsonTokenType.Number) + { + var objectValue = JsonSerializer.Deserialize(ref reader, options); + return new SubdevicesForResponses(objectValue); + } + + throw new JsonException("Unexpected JSON format for FieldContainer."); + } + + public override void Write(Utf8JsonWriter writer, SubdevicesForResponses value, JsonSerializerOptions options) + { + if (value.EnumValue.HasValue) + JsonSerializer.Serialize(writer, value.EnumValue.Value, options); + else if (value.ObjectValue != null) + JsonSerializer.Serialize(writer, value.ObjectValue, options); + } + } +} diff --git a/RDMSharp/Metadata/JSON/SubdeviceRange.cs b/RDMSharp/Metadata/JSON/SubdeviceRange.cs new file mode 100644 index 0000000..bb1260e --- /dev/null +++ b/RDMSharp/Metadata/JSON/SubdeviceRange.cs @@ -0,0 +1,24 @@ +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.JSON +{ + public readonly struct SubdeviceRange + { + [JsonPropertyName("minimum")] + public readonly ushort Minimum { get; } + + [JsonPropertyName("maximum")] + public readonly ushort Maximum { get; } + + [JsonConstructor] + public SubdeviceRange(ushort minimum, ushort maximum) : this() + { + Minimum = minimum; + Maximum = maximum; + } + public override string ToString() + { + return $"Subdevice Range: {Minimum:X4} - {Maximum:X4}"; + } + } +} diff --git a/RDMSharp/Metadata/JSON/SubdeviceType.cs b/RDMSharp/Metadata/JSON/SubdeviceType.cs new file mode 100644 index 0000000..78785f4 --- /dev/null +++ b/RDMSharp/Metadata/JSON/SubdeviceType.cs @@ -0,0 +1,29 @@ +using System.Text.Json.Serialization; +using RDMSharp.Metadata.JSON.Converter; + +namespace RDMSharp.Metadata.JSON +{ + [JsonConverter(typeof(SubdeviceTypeConverter))] + public readonly struct SubdeviceType + { + public readonly ushort? Value { get; } + public readonly SubdeviceRange? Range { get; } + public SubdeviceType(ushort value) : this() + { + Value = value; + } + + public SubdeviceType(SubdeviceRange range) : this() + { + Range = range; + } + public override string ToString() + { + if (Value.HasValue) + return $"Subdevice Value: {Value:X4}"; + if (Range.HasValue) + return Range.ToString(); + return base.ToString(); + } + } +} diff --git a/RDMSharp/Metadata/JSON/SubdevicesForRequests.cs b/RDMSharp/Metadata/JSON/SubdevicesForRequests.cs new file mode 100644 index 0000000..148cbf9 --- /dev/null +++ b/RDMSharp/Metadata/JSON/SubdevicesForRequests.cs @@ -0,0 +1,37 @@ +using System.Text.Json.Serialization; +using RDMSharp.Metadata.JSON.Converter; + +namespace RDMSharp.Metadata.JSON +{ + [JsonConverter(typeof(SubdevicesForRequestsConverter))] + public readonly struct SubdevicesForRequests + { + public enum ESubdevicesForRequests + { + [JsonPropertyName("root")] + Root, + [JsonPropertyName("subdevices")] + Subdevices, + [JsonPropertyName("broadcast")] + Broadcast + } + public readonly ESubdevicesForRequests? EnumValue { get; } + public readonly SubdeviceType? ObjectValue { get; } + public SubdevicesForRequests(ESubdevicesForRequests enumValue) + { + EnumValue = enumValue; + } + public SubdevicesForRequests(SubdeviceType objectValue) + { + ObjectValue = objectValue; + } + public override string ToString() + { + if (EnumValue.HasValue) + return EnumValue.Value.ToString(); + if (ObjectValue.HasValue) + return ObjectValue.Value.ToString(); + return base.ToString(); + } + } +} diff --git a/RDMSharp/Metadata/JSON/SubdevicesForResponses.cs b/RDMSharp/Metadata/JSON/SubdevicesForResponses.cs new file mode 100644 index 0000000..da86e19 --- /dev/null +++ b/RDMSharp/Metadata/JSON/SubdevicesForResponses.cs @@ -0,0 +1,39 @@ +using System.Text.Json.Serialization; +using RDMSharp.Metadata.JSON.Converter; + +namespace RDMSharp.Metadata.JSON +{ + [JsonConverter(typeof(SubdevicesForResponsesConverter))] + public readonly struct SubdevicesForResponses + { + public enum ESubdevicesForResponses + { + [JsonPropertyName("root")] + Root, + [JsonPropertyName("subdevices")] + Subdevices, + [JsonPropertyName("broadcast")] + Broadcast, + [JsonPropertyName("match")] + Match + } + public readonly ESubdevicesForResponses? EnumValue { get; } + public readonly SubdeviceType? ObjectValue { get; } + public SubdevicesForResponses(ESubdevicesForResponses enumValue) + { + EnumValue = enumValue; + } + public SubdevicesForResponses(SubdeviceType objectValue) + { + ObjectValue = objectValue; + } + public override string ToString() + { + if (EnumValue.HasValue) + return EnumValue.Value.ToString(); + if (ObjectValue.HasValue) + return ObjectValue.Value.ToString(); + return base.ToString(); + } + } +} diff --git a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs index 24b36a4..aba8055 100644 --- a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs +++ b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs @@ -1,6 +1,7 @@ using System.Text.Json; using System; using System.Text.Json.Serialization; +using RDMSharp.Metadata.JSON; namespace RDMSharp.Metadata { @@ -41,197 +42,4 @@ public override string ToString() return $"{ManufacturerID:X4} {PID:X4} {Name}"; } } - [JsonConverter(typeof(SubdevicesForRequestsConverter))] - public readonly struct SubdevicesForRequests - { - public enum ESubdevicesForRequests - { - [JsonPropertyName("root")] - Root, - [JsonPropertyName("subdevices")] - Subdevices, - [JsonPropertyName("broadcast")] - Broadcast - } - public readonly ESubdevicesForRequests? EnumValue { get; } - public readonly SubdeviceType? ObjectValue { get; } - public SubdevicesForRequests(ESubdevicesForRequests enumValue) - { - EnumValue = enumValue; - } - public SubdevicesForRequests(SubdeviceType objectValue) - { - ObjectValue = objectValue; - } - public override string ToString() - { - if (EnumValue.HasValue) - return EnumValue.Value.ToString(); - if (ObjectValue.HasValue) - return ObjectValue.Value.ToString(); - return base.ToString(); - } - } - public readonly struct SubdevicesForResponses - { - public enum ESubdevicesForResponses - { - [JsonPropertyName("root")] - Root, - [JsonPropertyName("subdevices")] - Subdevices, - [JsonPropertyName("broadcast")] - Broadcast, - [JsonPropertyName("match")] - Match - } - public readonly ESubdevicesForResponses? EnumValue { get; } - public readonly SubdeviceType? ObjectValue { get; } - public SubdevicesForResponses(ESubdevicesForResponses enumValue) - { - EnumValue = enumValue; - } - public SubdevicesForResponses(SubdeviceType objectValue) - { - ObjectValue = objectValue; - } - public override string ToString() - { - if (EnumValue.HasValue) - return EnumValue.Value.ToString(); - if (ObjectValue.HasValue) - return ObjectValue.Value.ToString(); - return base.ToString(); - } - } - [JsonConverter(typeof(SubdeviceTypeConverter))] - public readonly struct SubdeviceType - { - public readonly ushort? Value { get; } - public readonly SubdeviceRange? Range { get; } - public SubdeviceType(ushort value) : this() - { - Value = value; - } - - public SubdeviceType(SubdeviceRange range) : this() - { - Range = range; - } - public override string ToString() - { - if(Value.HasValue) - return $"Subdevice Value: {Value:X4}"; - if (Range.HasValue) - return Range.ToString(); - return base.ToString(); - } - } - public readonly struct SubdeviceRange - { - [JsonPropertyName("minimum")] - public readonly ushort Minimum { get; } - - [JsonPropertyName("maximum")] - public readonly ushort Maximum { get; } - - [JsonConstructor] - public SubdeviceRange(ushort minimum, ushort maximum) : this() - { - Minimum = minimum; - Maximum = maximum; - } - public override string ToString() - { - return $"Subdevice Range: {Minimum:X4} - {Maximum:X4}"; - } - } - public class SubdeviceTypeConverter : JsonConverter - { - public override SubdeviceType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType == JsonTokenType.Number) - { - var number = JsonSerializer.Deserialize(ref reader, options); - return new SubdeviceType(number); - } - else if (reader.TokenType == JsonTokenType.StartObject) - { - var objectValue = JsonSerializer.Deserialize(ref reader, options); - return new SubdeviceType(objectValue); - } - - throw new JsonException("Unexpected JSON format for FieldContainer."); - } - - public override void Write(Utf8JsonWriter writer, SubdeviceType value, JsonSerializerOptions options) - { - if (value.Value.HasValue) - JsonSerializer.Serialize(writer, value.Value.Value, options); - else if (value.Range.HasValue) - JsonSerializer.Serialize(writer, value.Range.Value, options); - } - } - public class SubdevicesForRequestsConverter : JsonConverter - { - public override SubdevicesForRequests Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType == JsonTokenType.String) - { - var _options = new JsonSerializerOptions(options) - { - Converters = { new JsonStringEnumConverter() }, - PropertyNameCaseInsensitive = true - }; - var enumValue = JsonSerializer.Deserialize(ref reader, _options); - return new SubdevicesForRequests(enumValue); - } - else if (reader.TokenType == JsonTokenType.StartObject || reader.TokenType == JsonTokenType.Number) - { - var objectValue = JsonSerializer.Deserialize(ref reader, options); - return new SubdevicesForRequests(objectValue); - } - - throw new JsonException("Unexpected JSON format for FieldContainer."); - } - - public override void Write(Utf8JsonWriter writer, SubdevicesForRequests value, JsonSerializerOptions options) - { - if (value.EnumValue.HasValue) - JsonSerializer.Serialize(writer, value.EnumValue.Value, options); - else if (value.ObjectValue != null) - JsonSerializer.Serialize(writer, value.ObjectValue, options); - } - } - public class SubdevicesForReponseConverter : JsonConverter - { - public override SubdevicesForResponses Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType == JsonTokenType.String) - { - var _options = new JsonSerializerOptions(options) - { - Converters = { new JsonStringEnumConverter() }, - PropertyNameCaseInsensitive = true - }; - var enumValue = JsonSerializer.Deserialize(ref reader, _options); - return new SubdevicesForResponses(enumValue); - } - else if (reader.TokenType == JsonTokenType.StartObject || reader.TokenType == JsonTokenType.Number) - { - var objectValue = JsonSerializer.Deserialize(ref reader, options); - return new SubdevicesForResponses(objectValue); - } - - throw new JsonException("Unexpected JSON format for FieldContainer."); - } - - public override void Write(Utf8JsonWriter writer, SubdevicesForResponses value, JsonSerializerOptions options) - { - if (value.EnumValue.HasValue) - JsonSerializer.Serialize(writer, value.EnumValue.Value, options); - else if (value.ObjectValue != null) - JsonSerializer.Serialize(writer, value.ObjectValue, options); - } - } } From 8ef020003e403b38883a038eba6151d3cbe6f253 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Mon, 16 Sep 2024 21:46:10 +0200 Subject: [PATCH 04/51] Work on OneOfTypes --- RDMSharp/Metadata/JSON/Command.cs | 53 ++++++++ .../JSON/Converter/CommandConverter.cs | 46 +++++++ .../JSON/Converter/OneOfTypesConverter.cs | 81 ++++++++++++ RDMSharp/Metadata/MetadataJSONObjectDefine.cs | 29 ++++- RDMSharp/Metadata/OneOfTypes/BitFieldType.cs | 36 ++++++ RDMSharp/Metadata/OneOfTypes/BitType.cs | 33 +++++ RDMSharp/Metadata/OneOfTypes/BooleanType.cs | 34 ++++++ RDMSharp/Metadata/OneOfTypes/IntegerType.cs | 115 ++++++++++++++++++ .../Metadata/OneOfTypes/LabeledBooleanType.cs | 27 ++++ .../Metadata/OneOfTypes/LabeledIntegerType.cs | 27 ++++ RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs | 68 +++++++++++ RDMSharp/Metadata/OneOfTypes/ReferenceType.cs | 51 ++++++++ RDMSharp/Metadata/OneOfTypes/StringType.cs | 53 ++++++++ 13 files changed, 652 insertions(+), 1 deletion(-) create mode 100644 RDMSharp/Metadata/JSON/Command.cs create mode 100644 RDMSharp/Metadata/JSON/Converter/CommandConverter.cs create mode 100644 RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs create mode 100644 RDMSharp/Metadata/OneOfTypes/BitFieldType.cs create mode 100644 RDMSharp/Metadata/OneOfTypes/BitType.cs create mode 100644 RDMSharp/Metadata/OneOfTypes/BooleanType.cs create mode 100644 RDMSharp/Metadata/OneOfTypes/IntegerType.cs create mode 100644 RDMSharp/Metadata/OneOfTypes/LabeledBooleanType.cs create mode 100644 RDMSharp/Metadata/OneOfTypes/LabeledIntegerType.cs create mode 100644 RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs create mode 100644 RDMSharp/Metadata/OneOfTypes/ReferenceType.cs create mode 100644 RDMSharp/Metadata/OneOfTypes/StringType.cs diff --git a/RDMSharp/Metadata/JSON/Command.cs b/RDMSharp/Metadata/JSON/Command.cs new file mode 100644 index 0000000..77c54b3 --- /dev/null +++ b/RDMSharp/Metadata/JSON/Command.cs @@ -0,0 +1,53 @@ +using System.Linq; +using System.Text.Json.Serialization; +using RDMSharp.Metadata.JSON.Converter; +using OneOf= RDMSharp.Metadata.OneOfTypes.OneOfTypes; + +namespace RDMSharp.Metadata.JSON +{ + [JsonConverter(typeof(CommandConverter))] + public readonly struct Command + { + public enum ECommandDublicte + { + [JsonPropertyName("get_request")] + GetRequest, + [JsonPropertyName("get_response")] + GetResponse, + [JsonPropertyName("set_request")] + SetRequest, + [JsonPropertyName("set_response")] + SetResponse + } + public readonly ECommandDublicte? EnumValue { get; } + public readonly OneOf? SingleField { get; } + public readonly OneOf[] ListOfFields { get; } + + public bool GetIsEmpty() + { + return !(EnumValue.HasValue || SingleField.HasValue || ListOfFields.Length == 0); + } + public Command(ECommandDublicte enumValue) + { + EnumValue = enumValue; + } + public Command(OneOf singleField) + { + SingleField = singleField; + } + public Command(OneOf[] listOfFields) + { + ListOfFields = listOfFields; + } + public override string ToString() + { + if (EnumValue.HasValue) + return EnumValue.Value.ToString(); + if (SingleField.HasValue) + return SingleField.Value.ToString(); + if (ListOfFields != null) + return $"[ {string.Join("; ", ListOfFields.Select(f => f.ToString()))} ]"; + return base.ToString(); + } + } +} diff --git a/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs b/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs new file mode 100644 index 0000000..bd3578b --- /dev/null +++ b/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs @@ -0,0 +1,46 @@ +using System.Text.Json; +using System; +using System.Text.Json.Serialization; +using OneOf = RDMSharp.Metadata.OneOfTypes.OneOfTypes; + +namespace RDMSharp.Metadata.JSON.Converter +{ + public class CommandConverter : JsonConverter + { + public override Command Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.String) + { + var _options = new JsonSerializerOptions(options) + { + Converters = { new JsonStringEnumConverter(JsonNamingPolicy.SnakeCaseLower) }, + PropertyNameCaseInsensitive = true + }; + var enumValue = JsonSerializer.Deserialize(ref reader, _options); + return new Command(Command.ECommandDublicte.GetResponse); + } + else if (reader.TokenType == JsonTokenType.StartObject) + { + var singleField = JsonSerializer.Deserialize(ref reader, options); + return new Command(singleField); + } + else if (reader.TokenType == JsonTokenType.StartArray) + { + var listOfFields = JsonSerializer.Deserialize(ref reader, options); + return new Command(listOfFields); + } + + throw new JsonException("Unexpected JSON format for FieldContainer."); + } + + public override void Write(Utf8JsonWriter writer, Command value, JsonSerializerOptions options) + { + if (value.EnumValue.HasValue) + JsonSerializer.Serialize(writer, value.EnumValue.Value, options); + else if (value.SingleField != null) + JsonSerializer.Serialize(writer, value.SingleField.Value, options); + else if (value.ListOfFields != null) + JsonSerializer.Serialize(writer, value.ListOfFields, options); + } + } +} diff --git a/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs new file mode 100644 index 0000000..9526daf --- /dev/null +++ b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs @@ -0,0 +1,81 @@ +using RDMSharp.Metadata.OneOfTypes; +using System; +using System.Text.Json; +using System.Text.Json.Serialization; +using OneOf = RDMSharp.Metadata.OneOfTypes.OneOfTypes; + +namespace RDMSharp.Metadata.JSON.Converter +{ + public class OneOfTypesConverter : JsonConverter + { + public override OneOf Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + JsonElement element = JsonSerializer.Deserialize(ref reader, options); + if (!element.TryGetProperty("type", out JsonElement typeProperty)) + { + if (element.TryGetProperty("$ref", out JsonElement refProperty)) + { + var referenceType = element.Deserialize(options); + return new OneOf(referenceType); + } + throw new JsonException("Unexpected JSON format for FieldContainer."); + } + + string type= typeProperty.GetString(); + switch (type) + { + case "bit": + var bitType = element.Deserialize(options); + return new OneOf(bitType); + case "bitField": + var bitFieldType = element.Deserialize(options); + return new OneOf(bitFieldType); + case "boolean": + var booleanType = element.Deserialize(options); + return new OneOf(booleanType); + + case "compound": + break; // ToDo + + case "int8": + case "int16": + case "int32": + case "int64": + case "int128": + case "uint8": + case "uint16": + case "uint32": + case "uint64": + case "uint128": + var integerType = element.Deserialize(options); + return new OneOf(integerType); + + case "list": + break; // ToDo + + case "pdEnvelope": + break; // ToDo + + case "string": + var stringType = element.Deserialize(options); + return new OneOf(stringType); + + + case null: + default: + break; + } + + return new OneOf(); + throw new JsonException("Unexpected JSON format for FieldContainer."); + } + + public override void Write(Utf8JsonWriter writer, OneOf value, JsonSerializerOptions options) + { + if (value.BitType.HasValue) + JsonSerializer.Serialize(writer, value.BitType.Value, options); + else if (value.BitFieldType != null) + JsonSerializer.Serialize(writer, value.BitFieldType.Value, options); + } + } +} diff --git a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs index aba8055..a9ff59b 100644 --- a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs +++ b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs @@ -24,17 +24,44 @@ public readonly struct MetadataJSONObjectDefine [JsonPropertyName("set_response_subdevice_range")] public readonly SubdevicesForResponses[] SetResponseSubdeviceRange { get; } + [JsonPropertyName("get_request")] + public readonly Command GetRequest { get; } + [JsonPropertyName("get_response")] + public readonly Command GetResponse { get; } + [JsonPropertyName("set_request")] + public readonly Command SetRequest { get; } + [JsonPropertyName("set_response")] + public readonly Command SetResponse { get; } + [JsonConstructor] - public MetadataJSONObjectDefine(string name, ushort manufacturerID, ushort pID, ushort version, SubdevicesForRequests[] getRequestSubdeviceRange, SubdevicesForResponses[] getResponseSubdeviceRange, SubdevicesForRequests[] setReequestsSubdeviceRange, SubdevicesForResponses[] setResponseSubdeviceRange) + public MetadataJSONObjectDefine( + string name, + ushort manufacturerID, + ushort pID, + ushort version, + SubdevicesForRequests[] getRequestSubdeviceRange, + SubdevicesForResponses[] getResponseSubdeviceRange, + SubdevicesForRequests[] setReequestsSubdeviceRange, + SubdevicesForResponses[] setResponseSubdeviceRange, + Command getRequest, + Command getResponse, + Command setRequest, + Command setResponse) { Name = name; ManufacturerID = manufacturerID; PID = pID; Version = version; + GetRequestSubdeviceRange = getRequestSubdeviceRange; GetResponseSubdeviceRange = getResponseSubdeviceRange; SetReequestsSubdeviceRange = setReequestsSubdeviceRange; SetResponseSubdeviceRange = setResponseSubdeviceRange; + + GetRequest = getRequest; + GetResponse = getResponse; + SetRequest = setRequest; + SetResponse = setResponse; } public override string ToString() diff --git a/RDMSharp/Metadata/OneOfTypes/BitFieldType.cs b/RDMSharp/Metadata/OneOfTypes/BitFieldType.cs new file mode 100644 index 0000000..37fb3a4 --- /dev/null +++ b/RDMSharp/Metadata/OneOfTypes/BitFieldType.cs @@ -0,0 +1,36 @@ +using System.Linq; +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.OneOfTypes +{ + public readonly struct BitFieldType + { + [JsonConstructor] + public BitFieldType(string name, string type, ushort size, bool? valueForUnspecified, BitType[] bits) + { + Name = name; + Type = type; + Size = size; + ValueForUnspecified = valueForUnspecified; + Bits = bits; + } + + [JsonPropertyName("name")] + public readonly string Name { get; } + [JsonPropertyName("type")] + public readonly string Type { get; } + + [JsonPropertyName("size")] + public readonly ushort Size { get; } + + [JsonPropertyName("valueForUnspecified")] + public readonly bool? ValueForUnspecified { get; } + [JsonPropertyName("bits")] + public readonly BitType[] Bits { get; } + + public override string ToString() + { + return $"{Name} [ {string.Join("; ", Bits.Select(b => b.ToString()))} ]"; + } + } +} diff --git a/RDMSharp/Metadata/OneOfTypes/BitType.cs b/RDMSharp/Metadata/OneOfTypes/BitType.cs new file mode 100644 index 0000000..e16714e --- /dev/null +++ b/RDMSharp/Metadata/OneOfTypes/BitType.cs @@ -0,0 +1,33 @@ +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.OneOfTypes +{ + public readonly struct BitType + { + [JsonConstructor] + public BitType(string name, string type, ushort index, bool? reserved, bool? valueIfReserved) + { + Name = name; + Type = type; + Index = index; + Reserved = reserved; + ValueIfReserved = valueIfReserved; + } + + [JsonPropertyName("name")] + public readonly string Name { get; } + [JsonPropertyName("type")] + public readonly string Type { get; } + [JsonPropertyName("index")] + public readonly ushort Index { get; } + [JsonPropertyName("reserved")] + public readonly bool? Reserved { get; } + [JsonPropertyName("valueIfReserved")] + public readonly bool? ValueIfReserved { get; } + + public override string ToString() + { + return $"{Index} -> {Name}"; + } + } +} diff --git a/RDMSharp/Metadata/OneOfTypes/BooleanType.cs b/RDMSharp/Metadata/OneOfTypes/BooleanType.cs new file mode 100644 index 0000000..0efd083 --- /dev/null +++ b/RDMSharp/Metadata/OneOfTypes/BooleanType.cs @@ -0,0 +1,34 @@ +using System.Linq; +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.OneOfTypes +{ + public readonly struct BooleanType + { + [JsonPropertyName("name")] + public readonly string Name { get; } + [JsonPropertyName("type")] + public readonly string Type { get; } + [JsonPropertyName("labels")] + public readonly LabeledBooleanType[]? Labels { get; } + + + [JsonConstructor] + public BooleanType( + string name, + string type, + LabeledBooleanType[]? labels) + { + Name = name; + Type = type; + Labels = labels; + } + public override string ToString() + { + if (Labels == null) + return Name; + + return $"{Name} [ {string.Join("; ", Labels.Select(l => l.ToString()))} ]"; + } + } +} \ No newline at end of file diff --git a/RDMSharp/Metadata/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/OneOfTypes/IntegerType.cs new file mode 100644 index 0000000..0576434 --- /dev/null +++ b/RDMSharp/Metadata/OneOfTypes/IntegerType.cs @@ -0,0 +1,115 @@ +using System; +using System.Linq; +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.OneOfTypes +{ + public readonly struct IntegerType + { + public enum EType + { + [JsonPropertyName("int8")] + Int8, + [JsonPropertyName("int16")] + Int16, + [JsonPropertyName("int32")] + Int32, + [JsonPropertyName("int64")] + Int64, + [JsonPropertyName("int128")] + Int128, + [JsonPropertyName("uint8")] + UInt8, + [JsonPropertyName("uint16")] + UInt16, + [JsonPropertyName("uint32")] + UInt32, + [JsonPropertyName("uint64")] + UInt64, + [JsonPropertyName("uint128")] + UInt128 + } + [JsonPropertyName("name")] + public readonly string Name { get; } + [JsonPropertyName("type")] + [JsonConverter(typeof(JsonStringEnumConverter))] + public readonly EType Type { get; } + [JsonPropertyName("labels")] + public readonly LabeledIntegerType[]? Labels { get; } + [JsonPropertyName("restrictToLabeled")] + public readonly bool? RestrictToLabeled { get; } + [JsonPropertyName("ranges")] + public readonly Range[]? Ranges { get; } + [JsonPropertyName("units")] + public readonly ERDM_SensorUnit? Units { get; } + [JsonPropertyName("prefixPower")] + public readonly int? PrefixPower { get; } = 0; + [JsonPropertyName("prefixBase")] + public readonly int? PrefixBase { get; } = 10; + + + [JsonConstructor] + public IntegerType( + string name, + EType type, + LabeledIntegerType[]? labels, + bool? restrictToLabeled, + Range[]? ranges, + ERDM_SensorUnit? units, + int? prefixPower, + int? prefixBase) + { + Name = name; + Type = type; + Labels = labels; + RestrictToLabeled = restrictToLabeled; + Ranges = ranges; + Units = units; + PrefixPower = prefixPower; + PrefixBase = prefixBase; + } + + public override string ToString() + { + if (Labels != null) + return $"{Name} {Type} -> [ {string.Join("; ", Labels.Select(l => l.ToString()))} ]"; + + return $"{Name} {Type}"; + } + } + public readonly struct Range + { +#if NET7_0_OR_GREATER + [JsonPropertyName("minimum")] + public readonly Int128 Minimum { get; } + + [JsonPropertyName("maximum")] + public readonly Int128 Maximum { get; } + + [JsonConstructor] + public Range(Int128 minimum, Int128 maximum) : this() + { + Minimum = minimum; + Maximum = maximum; + } +#else + [JsonPropertyName("minimum")] + public readonly long Minimum { get; } + + [JsonPropertyName("maximum")] + public readonly long Maximum { get; } + + [JsonConstructor] + public Range(long minimum, long maximum) : this() + { + Minimum = minimum; + Maximum = maximum; + } +#endif + + public override string ToString() + { + return $"Range: {Minimum:X4} - {Maximum:X4}"; + } + } +} diff --git a/RDMSharp/Metadata/OneOfTypes/LabeledBooleanType.cs b/RDMSharp/Metadata/OneOfTypes/LabeledBooleanType.cs new file mode 100644 index 0000000..5cc108b --- /dev/null +++ b/RDMSharp/Metadata/OneOfTypes/LabeledBooleanType.cs @@ -0,0 +1,27 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.OneOfTypes +{ + public readonly struct LabeledBooleanType + { + [JsonPropertyName("name")] + public readonly string Name { get; } + [JsonPropertyName("value")] + public readonly bool Value { get; } + + [JsonConstructor] + public LabeledBooleanType( + string name, + bool value) + { + Name = name; + Value = value; + } + + public override string ToString() + { + return $"{Value} -> {Name}"; + } + } +} diff --git a/RDMSharp/Metadata/OneOfTypes/LabeledIntegerType.cs b/RDMSharp/Metadata/OneOfTypes/LabeledIntegerType.cs new file mode 100644 index 0000000..a167c26 --- /dev/null +++ b/RDMSharp/Metadata/OneOfTypes/LabeledIntegerType.cs @@ -0,0 +1,27 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.OneOfTypes +{ + public readonly struct LabeledIntegerType + { + [JsonPropertyName("name")] + public readonly string Name { get; } + [JsonPropertyName("value")] + public readonly long Value { get; } + + [JsonConstructor] + public LabeledIntegerType( + string name, + long value) + { + Name = name; + Value = value; + } + + public override string ToString() + { + return $"{Value} -> {Name}"; + } + } +} diff --git a/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs b/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs new file mode 100644 index 0000000..a6819db --- /dev/null +++ b/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs @@ -0,0 +1,68 @@ +using System.Text.Json.Serialization; +using RDMSharp.Metadata.JSON.Converter; + +namespace RDMSharp.Metadata.OneOfTypes +{ + [JsonConverter(typeof(OneOfTypesConverter))] + public readonly struct OneOfTypes + { + public readonly BitType? BitType { get; } + public readonly BitFieldType? BitFieldType { get; } + public readonly BooleanType? BooleanType { get; } + public readonly IntegerType? IntegerType { get; } + public readonly ReferenceType? ReferenceType { get; } + public readonly StringType? StringType { get; } + + public OneOfTypes(BitType bitType) + { + BitType = bitType; + } + + public OneOfTypes(BitFieldType bitFieldType) + { + BitFieldType = bitFieldType; + } + + public OneOfTypes(BooleanType booleanType) + { + BooleanType = booleanType; + } + public OneOfTypes(IntegerType integerType) + { + IntegerType = integerType; + } + + public OneOfTypes(ReferenceType referenceType) + { + ReferenceType = referenceType; + } + + public OneOfTypes(StringType stringType) + { + StringType = stringType; + } + + public override string ToString() + { + if (BitType.HasValue) + return BitType.Value.ToString(); + + if (BitFieldType.HasValue) + return BitFieldType.Value.ToString(); + + if (BooleanType.HasValue) + return BooleanType.Value.ToString(); + + if (IntegerType.HasValue) + return IntegerType.Value.ToString(); + + if (ReferenceType.HasValue) + return ReferenceType.Value.ToString(); + + if (StringType.HasValue) + return StringType.Value.ToString(); + + return base.ToString(); + } + } +} \ No newline at end of file diff --git a/RDMSharp/Metadata/OneOfTypes/ReferenceType.cs b/RDMSharp/Metadata/OneOfTypes/ReferenceType.cs new file mode 100644 index 0000000..4df6060 --- /dev/null +++ b/RDMSharp/Metadata/OneOfTypes/ReferenceType.cs @@ -0,0 +1,51 @@ +using RDMSharp.Metadata.JSON; +using System; +using System.Data; +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.OneOfTypes +{ + public readonly struct ReferenceType + { + [JsonPropertyName("$ref")] + public readonly string URI { get; } + public readonly Command.ECommandDublicte Command { get; } + public readonly ushort Pointer { get; } + + [JsonConstructor] + public ReferenceType(string uri) + { + URI = uri; + // Entferne das '#' und zerlege den Rest in Segmente + if (uri.StartsWith("#")) + { + string fragment = uri.Substring(1); // Entfernt das '#' + + // Zerlege den Pfad in einzelne Teile + string[] segments = fragment.Split('/', StringSplitOptions.RemoveEmptyEntries); + + // Ausgabe der einzelnen Teile + switch (segments[0]) + { + case "get_request": + Command = JSON.Command.ECommandDublicte.GetRequest; + break; + case "get_response": + Command = JSON.Command.ECommandDublicte.GetResponse; + break; + case "set_request": + Command = JSON.Command.ECommandDublicte.SetRequest; + break; + case "set_response": + Command = JSON.Command.ECommandDublicte.SetResponse; + break; + } + Pointer = ushort.Parse(segments[1]); + } + } + public override string ToString() + { + return URI; + } + } +} diff --git a/RDMSharp/Metadata/OneOfTypes/StringType.cs b/RDMSharp/Metadata/OneOfTypes/StringType.cs new file mode 100644 index 0000000..c374abd --- /dev/null +++ b/RDMSharp/Metadata/OneOfTypes/StringType.cs @@ -0,0 +1,53 @@ +using RDMSharp.Metadata.JSON; +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.OneOfTypes +{ + public readonly struct StringType + { + + [JsonPropertyName("name")] + public readonly string Name { get; } + [JsonPropertyName("format")] + public readonly string? Format { get; } + [JsonPropertyName("pattern")] + public readonly string? Pattern { get; } + [JsonPropertyName("minLength")] + public readonly ulong? MinLength { get; } + [JsonPropertyName("maxLength")] + public readonly ulong? MaxLength { get; } + [JsonPropertyName("minBytes")] + public readonly ulong? MinBytes { get; } + [JsonPropertyName("maxBytes")] + public readonly ulong? MaxBytes { get; } + [JsonPropertyName("restrictToASCII")] + public readonly bool? RestrictToASCII { get; } + + + [JsonConstructor] + public StringType( + string name, + string? format, + string? pattern, + ulong? minLength, + ulong? maxLength, + ulong? minBytes, + ulong? maxBytes, + bool? restrictToASCII) + { + Name = name; + Format = format; + Pattern = pattern; + MinLength = minLength; + MaxLength = maxLength; + MinBytes = minBytes; + MaxBytes = maxBytes; + RestrictToASCII = restrictToASCII; + } + + public override string ToString() + { + return Name; + } + } +} From d8c767c071315734592ed999b49528d1e175a849 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Mon, 16 Sep 2024 21:57:40 +0200 Subject: [PATCH 05/51] Minor --- RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs index 9526daf..eab40ab 100644 --- a/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs @@ -76,6 +76,14 @@ public override void Write(Utf8JsonWriter writer, OneOf value, JsonSerializerOpt JsonSerializer.Serialize(writer, value.BitType.Value, options); else if (value.BitFieldType != null) JsonSerializer.Serialize(writer, value.BitFieldType.Value, options); + else if (value.BooleanType != null) + JsonSerializer.Serialize(writer, value.BooleanType.Value, options); + else if (value.IntegerType != null) + JsonSerializer.Serialize(writer, value.IntegerType.Value, options); + else if (value.StringType != null) + JsonSerializer.Serialize(writer, value.StringType.Value, options); + else + throw new NotImplementedException(); } } } From 3489e5800c5df272f117d9e4899ffceec4c62d88 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Mon, 16 Sep 2024 22:00:24 +0200 Subject: [PATCH 06/51] Minor --- RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs index eab40ab..e3e133a 100644 --- a/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs @@ -78,6 +78,8 @@ public override void Write(Utf8JsonWriter writer, OneOf value, JsonSerializerOpt JsonSerializer.Serialize(writer, value.BitFieldType.Value, options); else if (value.BooleanType != null) JsonSerializer.Serialize(writer, value.BooleanType.Value, options); + else if (value.ReferenceType != null) + JsonSerializer.Serialize(writer, value.ReferenceType.Value, options); else if (value.IntegerType != null) JsonSerializer.Serialize(writer, value.IntegerType.Value, options); else if (value.StringType != null) From 56471b0fc90c9170f5547d762dfc125154bd1b13 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Tue, 17 Sep 2024 02:23:14 +0200 Subject: [PATCH 07/51] Add missing Types --- .../JSON/Converter/OneOfTypesConverter.cs | 92 +++++++++++-- RDMSharp/Metadata/MetadataJSONObjectDefine.cs | 16 +-- RDMSharp/Metadata/OneOfTypes/BytesType.cs | 41 ++++++ RDMSharp/Metadata/OneOfTypes/CompoundType.cs | 31 +++++ RDMSharp/Metadata/OneOfTypes/IntegerType.cs | 83 +++++------- RDMSharp/Metadata/OneOfTypes/ListType.cs | 39 ++++++ RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs | 121 ++++++++++++++++-- .../Metadata/OneOfTypes/PD_EnvelopeType.cs | 31 +++++ RDMSharp/Metadata/OneOfTypes/StringType.cs | 8 +- 9 files changed, 382 insertions(+), 80 deletions(-) create mode 100644 RDMSharp/Metadata/OneOfTypes/BytesType.cs create mode 100644 RDMSharp/Metadata/OneOfTypes/CompoundType.cs create mode 100644 RDMSharp/Metadata/OneOfTypes/ListType.cs create mode 100644 RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs diff --git a/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs index e3e133a..2685551 100644 --- a/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs @@ -27,34 +27,67 @@ public override OneOf Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSe case "bit": var bitType = element.Deserialize(options); return new OneOf(bitType); + case "bitField": var bitFieldType = element.Deserialize(options); return new OneOf(bitFieldType); + + case "bytes": + var bytesType = element.Deserialize(options); + return new OneOf(bytesType); + case "boolean": var booleanType = element.Deserialize(options); return new OneOf(booleanType); case "compound": - break; // ToDo + var compoundType = element.Deserialize(options); + return new OneOf(compoundType); case "int8": - case "int16": - case "int32": - case "int64": - case "int128": + var integerTypeInt8 = element.Deserialize>(options); + return new OneOf(integerTypeInt8); case "uint8": + var integerTypeUInt8 = element.Deserialize>(options); + return new OneOf(integerTypeUInt8); + + case "int16": + var integerTypeInt16 = element.Deserialize>(options); + return new OneOf(integerTypeInt16); case "uint16": + var integerTypeUInt16 = element.Deserialize>(options); + return new OneOf(integerTypeUInt16); + + case "int32": + var integerTypeInt32 = element.Deserialize>(options); + return new OneOf(integerTypeInt32); case "uint32": + var integerTypeUInt32 = element.Deserialize>(options); + return new OneOf(integerTypeUInt32); + + case "int64": + var integerTypeInt64 = element.Deserialize>(options); + return new OneOf(integerTypeInt64); case "uint64": + var integerTypeUInt64 = element.Deserialize>(options); + return new OneOf(integerTypeUInt64); + +#if NET7_0_OR_GREATER + case "int128": + var integerTypeInt128 = element.Deserialize>(options); + return new OneOf(integerTypeInt128); case "uint128": - var integerType = element.Deserialize(options); - return new OneOf(integerType); + var integerTypeUInt128 = element.Deserialize>(options); + return new OneOf(integerTypeUInt128); +#endif case "list": - break; // ToDo + var listType = element.Deserialize(options); + return new OneOf(listType); case "pdEnvelope": - break; // ToDo + var pdEnvelopeType = element.Deserialize(options); + return new OneOf(pdEnvelopeType); case "string": var stringType = element.Deserialize(options); @@ -66,7 +99,6 @@ public override OneOf Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSe break; } - return new OneOf(); throw new JsonException("Unexpected JSON format for FieldContainer."); } @@ -74,16 +106,52 @@ public override void Write(Utf8JsonWriter writer, OneOf value, JsonSerializerOpt { if (value.BitType.HasValue) JsonSerializer.Serialize(writer, value.BitType.Value, options); + else if (value.BitFieldType != null) JsonSerializer.Serialize(writer, value.BitFieldType.Value, options); + else if (value.BooleanType != null) JsonSerializer.Serialize(writer, value.BooleanType.Value, options); + else if (value.ReferenceType != null) JsonSerializer.Serialize(writer, value.ReferenceType.Value, options); - else if (value.IntegerType != null) - JsonSerializer.Serialize(writer, value.IntegerType.Value, options); + + else if (value.IntegerType_UInt8.HasValue) + JsonSerializer.Serialize(writer, value.IntegerType_UInt8.Value, options); + else if (value.IntegerType_Int8.HasValue) + JsonSerializer.Serialize(writer, value.IntegerType_Int8.Value, options); + + else if (value.IntegerType_UInt16.HasValue) + JsonSerializer.Serialize(writer, value.IntegerType_UInt16.Value, options); + else if (value.IntegerType_Int16.HasValue) + JsonSerializer.Serialize(writer, value.IntegerType_Int16.Value, options); + + else if (value.IntegerType_UInt32.HasValue) + JsonSerializer.Serialize(writer, value.IntegerType_UInt32.Value, options); + else if (value.IntegerType_Int32.HasValue) + JsonSerializer.Serialize(writer, value.IntegerType_Int32.Value, options); + + else if (value.IntegerType_UInt64.HasValue) + JsonSerializer.Serialize(writer, value.IntegerType_UInt64.Value, options); + else if (value.IntegerType_Int64.HasValue) + JsonSerializer.Serialize(writer, value.IntegerType_Int64.Value, options); +#if NET7_0_OR_GREATER + else if (value.IntegerType_UInt128.HasValue) + JsonSerializer.Serialize(writer, value.IntegerType_UInt128.Value, options); + else if (value.IntegerType_Int128.HasValue) + JsonSerializer.Serialize(writer, value.IntegerType_Int128.Value, options); +#endif else if (value.StringType != null) JsonSerializer.Serialize(writer, value.StringType.Value, options); + + else if (value.ListType != null) + JsonSerializer.Serialize(writer, value.ListType, options); + + else if (value.CompoundType != null) + JsonSerializer.Serialize(writer, value.CompoundType, options); + + else if (value.PD_EnvelopeType != null) + JsonSerializer.Serialize(writer, value.PD_EnvelopeType.Value, options); else throw new NotImplementedException(); } diff --git a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs index a9ff59b..e031603 100644 --- a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs +++ b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs @@ -25,13 +25,13 @@ public readonly struct MetadataJSONObjectDefine public readonly SubdevicesForResponses[] SetResponseSubdeviceRange { get; } [JsonPropertyName("get_request")] - public readonly Command GetRequest { get; } + public readonly Command? GetRequest { get; } [JsonPropertyName("get_response")] - public readonly Command GetResponse { get; } + public readonly Command? GetResponse { get; } [JsonPropertyName("set_request")] - public readonly Command SetRequest { get; } + public readonly Command? SetRequest { get; } [JsonPropertyName("set_response")] - public readonly Command SetResponse { get; } + public readonly Command? SetResponse { get; } [JsonConstructor] public MetadataJSONObjectDefine( @@ -43,10 +43,10 @@ public MetadataJSONObjectDefine( SubdevicesForResponses[] getResponseSubdeviceRange, SubdevicesForRequests[] setReequestsSubdeviceRange, SubdevicesForResponses[] setResponseSubdeviceRange, - Command getRequest, - Command getResponse, - Command setRequest, - Command setResponse) + Command? getRequest, + Command? getResponse, + Command? setRequest, + Command? setResponse) { Name = name; ManufacturerID = manufacturerID; diff --git a/RDMSharp/Metadata/OneOfTypes/BytesType.cs b/RDMSharp/Metadata/OneOfTypes/BytesType.cs new file mode 100644 index 0000000..fbd52f6 --- /dev/null +++ b/RDMSharp/Metadata/OneOfTypes/BytesType.cs @@ -0,0 +1,41 @@ +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.OneOfTypes +{ + public readonly struct BytesType + { + + [JsonPropertyName("name")] + public readonly string Name { get; } + + [JsonPropertyName("type")] + public readonly string Type { get; } + [JsonPropertyName("format")] + public readonly string? Format { get; } + [JsonPropertyName("minLength")] + public readonly ulong? MinLength { get; } + [JsonPropertyName("maxLength")] + public readonly ulong? MaxLength { get; } + + + [JsonConstructor] + public BytesType( + string name, + string type, + string? format, + ulong? minLength, + ulong? maxLength) + { + Name = name; + Type = type; + Format = format; + MinLength = minLength; + MaxLength = maxLength; + } + + public override string ToString() + { + return Name; + } + } +} diff --git a/RDMSharp/Metadata/OneOfTypes/CompoundType.cs b/RDMSharp/Metadata/OneOfTypes/CompoundType.cs new file mode 100644 index 0000000..aa83f18 --- /dev/null +++ b/RDMSharp/Metadata/OneOfTypes/CompoundType.cs @@ -0,0 +1,31 @@ +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.OneOfTypes +{ + public class CompoundType + { + [JsonPropertyName("name")] + public string Name { get; } + [JsonPropertyName("type")] + public string Type { get; } + [JsonPropertyName("subtypes")] + public OneOfTypes[] Subtypes { get; } + + + [JsonConstructor] + public CompoundType( + string name, + string type, + OneOfTypes[] subtypes) + { + Name = name; + Type = type; + Subtypes = subtypes; + } + + public override string ToString() + { + return $"{Name}"; + } + } +} \ No newline at end of file diff --git a/RDMSharp/Metadata/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/OneOfTypes/IntegerType.cs index 0576434..8ee5af2 100644 --- a/RDMSharp/Metadata/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/OneOfTypes/IntegerType.cs @@ -1,45 +1,47 @@ using System; using System.Linq; +using System.Numerics; +using System.Runtime.CompilerServices; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.OneOfTypes { - public readonly struct IntegerType + public enum EIntegerType + { + [JsonPropertyName("int8")] + Int8, + [JsonPropertyName("int16")] + Int16, + [JsonPropertyName("int32")] + Int32, + [JsonPropertyName("int64")] + Int64, + [JsonPropertyName("int128")] + Int128, + [JsonPropertyName("uint8")] + UInt8, + [JsonPropertyName("uint16")] + UInt16, + [JsonPropertyName("uint32")] + UInt32, + [JsonPropertyName("uint64")] + UInt64, + [JsonPropertyName("uint128")] + UInt128 + } + public readonly struct IntegerType { - public enum EType - { - [JsonPropertyName("int8")] - Int8, - [JsonPropertyName("int16")] - Int16, - [JsonPropertyName("int32")] - Int32, - [JsonPropertyName("int64")] - Int64, - [JsonPropertyName("int128")] - Int128, - [JsonPropertyName("uint8")] - UInt8, - [JsonPropertyName("uint16")] - UInt16, - [JsonPropertyName("uint32")] - UInt32, - [JsonPropertyName("uint64")] - UInt64, - [JsonPropertyName("uint128")] - UInt128 - } [JsonPropertyName("name")] public readonly string Name { get; } [JsonPropertyName("type")] [JsonConverter(typeof(JsonStringEnumConverter))] - public readonly EType Type { get; } + public readonly EIntegerType Type { get; } [JsonPropertyName("labels")] public readonly LabeledIntegerType[]? Labels { get; } [JsonPropertyName("restrictToLabeled")] public readonly bool? RestrictToLabeled { get; } [JsonPropertyName("ranges")] - public readonly Range[]? Ranges { get; } + public readonly Range[]? Ranges { get; } [JsonPropertyName("units")] public readonly ERDM_SensorUnit? Units { get; } [JsonPropertyName("prefixPower")] @@ -47,14 +49,13 @@ public enum EType [JsonPropertyName("prefixBase")] public readonly int? PrefixBase { get; } = 10; - [JsonConstructor] public IntegerType( string name, - EType type, + EIntegerType type, LabeledIntegerType[]? labels, bool? restrictToLabeled, - Range[]? ranges, + Range[]? ranges, ERDM_SensorUnit? units, int? prefixPower, int? prefixBase) @@ -77,35 +78,21 @@ public override string ToString() return $"{Name} {Type}"; } } - public readonly struct Range - { -#if NET7_0_OR_GREATER - [JsonPropertyName("minimum")] - public readonly Int128 Minimum { get; } - [JsonPropertyName("maximum")] - public readonly Int128 Maximum { get; } - - [JsonConstructor] - public Range(Int128 minimum, Int128 maximum) : this() - { - Minimum = minimum; - Maximum = maximum; - } -#else + public readonly struct Range + { [JsonPropertyName("minimum")] - public readonly long Minimum { get; } + public readonly T Minimum { get; } [JsonPropertyName("maximum")] - public readonly long Maximum { get; } + public readonly T Maximum { get; } [JsonConstructor] - public Range(long minimum, long maximum) : this() + public Range(T minimum, T maximum) { Minimum = minimum; Maximum = maximum; } -#endif public override string ToString() { diff --git a/RDMSharp/Metadata/OneOfTypes/ListType.cs b/RDMSharp/Metadata/OneOfTypes/ListType.cs new file mode 100644 index 0000000..546d772 --- /dev/null +++ b/RDMSharp/Metadata/OneOfTypes/ListType.cs @@ -0,0 +1,39 @@ +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.OneOfTypes +{ + public class ListType + { + [JsonPropertyName("name")] + public string Name { get; } + [JsonPropertyName("type")] + public string Type { get; } + [JsonPropertyName("itemType")] + public OneOfTypes ItemType { get; } + [JsonPropertyName("minItems")] + public int? MinItems { get; } + [JsonPropertyName("maxItems")] + public int? MaxItems { get; } + + + [JsonConstructor] + public ListType( + string name, + string type, + OneOfTypes itemType, + int? minItems, + int? maxItems) + { + Name = name; + Type = type; + ItemType = itemType; + MinItems = minItems; + MaxItems = maxItems; + } + + public override string ToString() + { + return $"{Name}"; + } + } +} \ No newline at end of file diff --git a/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs b/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs index a6819db..02c6552 100644 --- a/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs +++ b/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs @@ -1,4 +1,5 @@ -using System.Text.Json.Serialization; +using System; +using System.Text.Json.Serialization; using RDMSharp.Metadata.JSON.Converter; namespace RDMSharp.Metadata.OneOfTypes @@ -8,39 +9,104 @@ public readonly struct OneOfTypes { public readonly BitType? BitType { get; } public readonly BitFieldType? BitFieldType { get; } + public readonly BytesType? BytesType { get; } public readonly BooleanType? BooleanType { get; } - public readonly IntegerType? IntegerType { get; } + public readonly IntegerType? IntegerType_UInt8 { get; } + public readonly IntegerType? IntegerType_Int8 { get; } + public readonly IntegerType? IntegerType_UInt16 { get; } + public readonly IntegerType? IntegerType_Int16 { get; } + public readonly IntegerType? IntegerType_UInt32 { get; } + public readonly IntegerType? IntegerType_Int32 { get; } + public readonly IntegerType? IntegerType_UInt64 { get; } + public readonly IntegerType? IntegerType_Int64 { get; } +#if NET7_0_OR_GREATER + public readonly IntegerType? IntegerType_UInt128 { get; } + public readonly IntegerType? IntegerType_Int128 { get; } +#endif public readonly ReferenceType? ReferenceType { get; } + public readonly ListType? ListType { get; } + public readonly CompoundType? CompoundType { get; } public readonly StringType? StringType { get; } + public readonly PD_EnvelopeType? PD_EnvelopeType { get; } public OneOfTypes(BitType bitType) { BitType = bitType; } - public OneOfTypes(BitFieldType bitFieldType) { BitFieldType = bitFieldType; } - + public OneOfTypes(BytesType bytesType) + { + BytesType = bytesType; + } public OneOfTypes(BooleanType booleanType) { BooleanType = booleanType; } - public OneOfTypes(IntegerType integerType) + public OneOfTypes(IntegerType integerType_UInt8) { - IntegerType = integerType; + IntegerType_UInt8 = integerType_UInt8; } - + public OneOfTypes(IntegerType integerType_Int8) + { + IntegerType_Int8 = integerType_Int8; + } + public OneOfTypes(IntegerType integerType_UInt16) + { + IntegerType_UInt16 = integerType_UInt16; + } + public OneOfTypes(IntegerType integerType_Int16) + { + IntegerType_Int16 = integerType_Int16; + } + public OneOfTypes(IntegerType integerType_UInt32) + { + IntegerType_UInt32 = integerType_UInt32; + } + public OneOfTypes(IntegerType integerType_Int32) + { + IntegerType_Int32 = integerType_Int32; + } + public OneOfTypes(IntegerType integerType_UInt64) + { + IntegerType_UInt64 = integerType_UInt64; + } + public OneOfTypes(IntegerType integerType_Int64) + { + IntegerType_Int64 = integerType_Int64; + } +#if NET7_0_OR_GREATER + public OneOfTypes(IntegerType integerType_UInt128) + { + IntegerType_UInt128 = integerType_UInt128; + } + public OneOfTypes(IntegerType integerType_Int128) + { + IntegerType_Int128 = integerType_Int128; + } +#endif public OneOfTypes(ReferenceType referenceType) { ReferenceType = referenceType; } - public OneOfTypes(StringType stringType) { StringType = stringType; } + public OneOfTypes(ListType listType) + { + ListType = listType; + } + public OneOfTypes(CompoundType compoundType) + { + CompoundType = compoundType; + } + public OneOfTypes(PD_EnvelopeType pdEnvelopeType) + { + PD_EnvelopeType = pdEnvelopeType; + } public override string ToString() { @@ -50,11 +116,37 @@ public override string ToString() if (BitFieldType.HasValue) return BitFieldType.Value.ToString(); + if (BytesType.HasValue) + return BytesType.Value.ToString(); + if (BooleanType.HasValue) return BooleanType.Value.ToString(); - if (IntegerType.HasValue) - return IntegerType.Value.ToString(); + if (IntegerType_UInt8.HasValue) + return IntegerType_UInt8.Value.ToString(); + if (IntegerType_UInt8.HasValue) + return IntegerType_UInt8.Value.ToString(); + + if (IntegerType_UInt16.HasValue) + return IntegerType_UInt16.Value.ToString(); + if (IntegerType_UInt16.HasValue) + return IntegerType_UInt16.Value.ToString(); + + if (IntegerType_UInt32.HasValue) + return IntegerType_UInt32.Value.ToString(); + if (IntegerType_UInt32.HasValue) + return IntegerType_UInt32.Value.ToString(); + + if (IntegerType_UInt64.HasValue) + return IntegerType_UInt64.Value.ToString(); + if (IntegerType_UInt64.HasValue) + return IntegerType_UInt64.Value.ToString(); +#if NET7_0_OR_GREATER + if (IntegerType_UInt128.HasValue) + return IntegerType_UInt128.Value.ToString(); + if (IntegerType_UInt128.HasValue) + return IntegerType_UInt128.Value.ToString(); +#endif if (ReferenceType.HasValue) return ReferenceType.Value.ToString(); @@ -62,6 +154,15 @@ public override string ToString() if (StringType.HasValue) return StringType.Value.ToString(); + if (ListType != null) + return ListType.ToString(); + + if (CompoundType != null) + return CompoundType.ToString(); + + if (PD_EnvelopeType.HasValue) + return PD_EnvelopeType.Value.ToString(); + return base.ToString(); } } diff --git a/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs b/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs new file mode 100644 index 0000000..09b7526 --- /dev/null +++ b/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs @@ -0,0 +1,31 @@ +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.OneOfTypes +{ + public readonly struct PD_EnvelopeType + { + + [JsonPropertyName("name")] + public readonly string Name { get; } + [JsonPropertyName("length")] + public readonly byte Length { get; } + + + [JsonConstructor] + public PD_EnvelopeType( + string name, + byte length) + { + Name = name; + Length = length; + } + + public override string ToString() + { + if (string.IsNullOrWhiteSpace(Name)) + return $"PDL: {Length} ({Length:X2})"; + + return $"PDL: {Length} ({Length:X2}) {Name}"; + } + } +} diff --git a/RDMSharp/Metadata/OneOfTypes/StringType.cs b/RDMSharp/Metadata/OneOfTypes/StringType.cs index c374abd..1186aa5 100644 --- a/RDMSharp/Metadata/OneOfTypes/StringType.cs +++ b/RDMSharp/Metadata/OneOfTypes/StringType.cs @@ -1,5 +1,4 @@ -using RDMSharp.Metadata.JSON; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace RDMSharp.Metadata.OneOfTypes { @@ -8,6 +7,9 @@ public readonly struct StringType [JsonPropertyName("name")] public readonly string Name { get; } + + [JsonPropertyName("type")] + public readonly string Type { get; } [JsonPropertyName("format")] public readonly string? Format { get; } [JsonPropertyName("pattern")] @@ -27,6 +29,7 @@ public readonly struct StringType [JsonConstructor] public StringType( string name, + string type, string? format, string? pattern, ulong? minLength, @@ -36,6 +39,7 @@ public StringType( bool? restrictToASCII) { Name = name; + Type = type; Format = format; Pattern = pattern; MinLength = minLength; From a5ffb11960bb64add811e343033128450cf21b53 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Tue, 17 Sep 2024 02:25:43 +0200 Subject: [PATCH 08/51] Minor --- RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs index 2685551..047414f 100644 --- a/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs @@ -150,7 +150,7 @@ public override void Write(Utf8JsonWriter writer, OneOf value, JsonSerializerOpt else if (value.CompoundType != null) JsonSerializer.Serialize(writer, value.CompoundType, options); - else if (value.PD_EnvelopeType != null) + else if (value.PD_EnvelopeType.HasValue) JsonSerializer.Serialize(writer, value.PD_EnvelopeType.Value, options); else throw new NotImplementedException(); From 22bce8b125ead8fcd4688ef264171373a2c36cc2 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Tue, 17 Sep 2024 16:51:22 +0200 Subject: [PATCH 09/51] Wrote Test for JSON-Deserielizer --- RDMSharp/Metadata/JSON/Command.cs | 4 + .../Metadata/JSON/CommonPropertiesForNamed.cs | 31 +++++++ .../JSON/Converter/CommandConverter.cs | 9 +-- .../JSON/Converter/CustomEnumConverter.cs | 36 +++++++++ .../JSON/Converter/OneOfTypesConverter.cs | 69 ++++++++-------- .../SubdevicesForRequestsConverter.cs | 13 ++- .../SubdevicesForResponsesConverter.cs | 13 ++- RDMSharp/Metadata/JSON/SubdeviceType.cs | 2 + .../Metadata/JSON/SubdevicesForRequests.cs | 3 + .../Metadata/JSON/SubdevicesForResponses.cs | 3 + RDMSharp/Metadata/MetadataFactory.cs | 4 +- RDMSharp/Metadata/MetadataJSONObjectDefine.cs | 40 ++++++++-- RDMSharp/Metadata/OneOfTypes/BitFieldType.cs | 48 +++++++++-- RDMSharp/Metadata/OneOfTypes/BitType.cs | 49 ++++++++++-- RDMSharp/Metadata/OneOfTypes/BooleanType.cs | 42 +++++++--- RDMSharp/Metadata/OneOfTypes/BytesType.cs | 54 +++++++++---- RDMSharp/Metadata/OneOfTypes/CompoundType.cs | 38 +++++++-- RDMSharp/Metadata/OneOfTypes/IntegerType.cs | 77 +++++++++++++----- .../Metadata/OneOfTypes/LabeledBooleanType.cs | 35 ++++++-- .../Metadata/OneOfTypes/LabeledIntegerType.cs | 35 ++++++-- RDMSharp/Metadata/OneOfTypes/ListType.cs | 45 ++++++++--- RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs | 68 ++++++++-------- .../Metadata/OneOfTypes/PD_EnvelopeType.cs | 39 ++++++--- RDMSharp/Metadata/OneOfTypes/ReferenceType.cs | 3 +- RDMSharp/Metadata/OneOfTypes/StringType.cs | 80 +++++++++++++------ .../MetadataJSONObjectDefineTestSubject.cs | 40 ++++++++++ .../MetadataJSONObjectDefineTests.cs | 51 ++++++++++++ 27 files changed, 709 insertions(+), 222 deletions(-) create mode 100644 RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs create mode 100644 RDMSharp/Metadata/JSON/Converter/CustomEnumConverter.cs create mode 100644 RDMSharpTests/MetadataJSONObjectDefineTestSubject.cs create mode 100644 RDMSharpTests/MetadataJSONObjectDefineTests.cs diff --git a/RDMSharp/Metadata/JSON/Command.cs b/RDMSharp/Metadata/JSON/Command.cs index 77c54b3..b8d71f9 100644 --- a/RDMSharp/Metadata/JSON/Command.cs +++ b/RDMSharp/Metadata/JSON/Command.cs @@ -8,6 +8,7 @@ namespace RDMSharp.Metadata.JSON [JsonConverter(typeof(CommandConverter))] public readonly struct Command { + [JsonConverter(typeof(CustomEnumConverter))] public enum ECommandDublicte { [JsonPropertyName("get_request")] @@ -19,8 +20,11 @@ public enum ECommandDublicte [JsonPropertyName("set_response")] SetResponse } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public readonly ECommandDublicte? EnumValue { get; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public readonly OneOf? SingleField { get; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public readonly OneOf[] ListOfFields { get; } public bool GetIsEmpty() diff --git a/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs b/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs new file mode 100644 index 0000000..2d804d7 --- /dev/null +++ b/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs @@ -0,0 +1,31 @@ +using RDMSharp.Metadata.JSON.Converter; +using System.Linq; +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.JSON +{ + public abstract class CommonPropertiesForNamed + { + + [JsonPropertyName("name")] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public abstract string Name { get; } + [JsonPropertyName("displayName")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public abstract string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public abstract string? Notes { get; } + [JsonPropertyName("resources")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public abstract string[]? Resources { get; } + + public override string ToString() + { + if(!string.IsNullOrWhiteSpace(DisplayName)) + return DisplayName; + + return Name; + } + } +} diff --git a/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs b/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs index bd3578b..6928b28 100644 --- a/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs @@ -11,13 +11,8 @@ public override Command Read(ref Utf8JsonReader reader, Type typeToConvert, Json { if (reader.TokenType == JsonTokenType.String) { - var _options = new JsonSerializerOptions(options) - { - Converters = { new JsonStringEnumConverter(JsonNamingPolicy.SnakeCaseLower) }, - PropertyNameCaseInsensitive = true - }; - var enumValue = JsonSerializer.Deserialize(ref reader, _options); - return new Command(Command.ECommandDublicte.GetResponse); + var enumValue = JsonSerializer.Deserialize(ref reader, options); + return new Command(enumValue); } else if (reader.TokenType == JsonTokenType.StartObject) { diff --git a/RDMSharp/Metadata/JSON/Converter/CustomEnumConverter.cs b/RDMSharp/Metadata/JSON/Converter/CustomEnumConverter.cs new file mode 100644 index 0000000..77b887f --- /dev/null +++ b/RDMSharp/Metadata/JSON/Converter/CustomEnumConverter.cs @@ -0,0 +1,36 @@ +using System; +using System.Reflection; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.JSON.Converter +{ + public class CustomEnumConverter : JsonConverter where T : struct, Enum + { + public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + string enumValue = reader.GetString(); + + foreach (var field in typeof(T).GetFields()) + { + if (field.GetCustomAttribute()?.Name == enumValue) + { + return (T)field.GetValue(null); + } + } + + throw new JsonException($"Unknown enum value: {enumValue}"); + } + + public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + { + var field = typeof(T).GetField(value.ToString()); + + var attribute = field.GetCustomAttribute(); + string enumString = attribute?.Name ?? value.ToString(); + + writer.WriteStringValue(enumString); + } + } + +} diff --git a/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs index 047414f..7bf57bb 100644 --- a/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs @@ -99,50 +99,53 @@ public override OneOf Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSe break; } - throw new JsonException("Unexpected JSON format for FieldContainer."); + throw new JsonException($"Unexpected JSON format Type: {type} for FieldContainer."); } public override void Write(Utf8JsonWriter writer, OneOf value, JsonSerializerOptions options) { - if (value.BitType.HasValue) - JsonSerializer.Serialize(writer, value.BitType.Value, options); + if (value.BitType != null) + JsonSerializer.Serialize(writer, value.BitType, options); else if (value.BitFieldType != null) - JsonSerializer.Serialize(writer, value.BitFieldType.Value, options); + JsonSerializer.Serialize(writer, value.BitFieldType, options); else if (value.BooleanType != null) - JsonSerializer.Serialize(writer, value.BooleanType.Value, options); + JsonSerializer.Serialize(writer, value.BooleanType, options); + + else if (value.BytesType != null) + JsonSerializer.Serialize(writer, value.BytesType, options); else if (value.ReferenceType != null) - JsonSerializer.Serialize(writer, value.ReferenceType.Value, options); - - else if (value.IntegerType_UInt8.HasValue) - JsonSerializer.Serialize(writer, value.IntegerType_UInt8.Value, options); - else if (value.IntegerType_Int8.HasValue) - JsonSerializer.Serialize(writer, value.IntegerType_Int8.Value, options); - - else if (value.IntegerType_UInt16.HasValue) - JsonSerializer.Serialize(writer, value.IntegerType_UInt16.Value, options); - else if (value.IntegerType_Int16.HasValue) - JsonSerializer.Serialize(writer, value.IntegerType_Int16.Value, options); - - else if (value.IntegerType_UInt32.HasValue) - JsonSerializer.Serialize(writer, value.IntegerType_UInt32.Value, options); - else if (value.IntegerType_Int32.HasValue) - JsonSerializer.Serialize(writer, value.IntegerType_Int32.Value, options); - - else if (value.IntegerType_UInt64.HasValue) - JsonSerializer.Serialize(writer, value.IntegerType_UInt64.Value, options); - else if (value.IntegerType_Int64.HasValue) - JsonSerializer.Serialize(writer, value.IntegerType_Int64.Value, options); + JsonSerializer.Serialize(writer, value.ReferenceType, options); + + else if (value.IntegerType_UInt8 != null) + JsonSerializer.Serialize(writer, value.IntegerType_UInt8, options); + else if (value.IntegerType_Int8 != null) + JsonSerializer.Serialize(writer, value.IntegerType_Int8, options); + + else if (value.IntegerType_UInt16 != null) + JsonSerializer.Serialize(writer, value.IntegerType_UInt16, options); + else if (value.IntegerType_Int16 != null) + JsonSerializer.Serialize(writer, value.IntegerType_Int16, options); + + else if (value.IntegerType_UInt32 != null) + JsonSerializer.Serialize(writer, value.IntegerType_UInt32, options); + else if (value.IntegerType_Int32 != null) + JsonSerializer.Serialize(writer, value.IntegerType_Int32, options); + + else if (value.IntegerType_UInt64 != null) + JsonSerializer.Serialize(writer, value.IntegerType_UInt64, options); + else if (value.IntegerType_Int64 != null) + JsonSerializer.Serialize(writer, value.IntegerType_Int64, options); #if NET7_0_OR_GREATER - else if (value.IntegerType_UInt128.HasValue) - JsonSerializer.Serialize(writer, value.IntegerType_UInt128.Value, options); - else if (value.IntegerType_Int128.HasValue) - JsonSerializer.Serialize(writer, value.IntegerType_Int128.Value, options); + else if (value.IntegerType_UInt128 != null) + JsonSerializer.Serialize(writer, value.IntegerType_UInt128, options); + else if (value.IntegerType_Int128 != null) + JsonSerializer.Serialize(writer, value.IntegerType_Int128, options); #endif else if (value.StringType != null) - JsonSerializer.Serialize(writer, value.StringType.Value, options); + JsonSerializer.Serialize(writer, value.StringType, options); else if (value.ListType != null) JsonSerializer.Serialize(writer, value.ListType, options); @@ -150,8 +153,8 @@ public override void Write(Utf8JsonWriter writer, OneOf value, JsonSerializerOpt else if (value.CompoundType != null) JsonSerializer.Serialize(writer, value.CompoundType, options); - else if (value.PD_EnvelopeType.HasValue) - JsonSerializer.Serialize(writer, value.PD_EnvelopeType.Value, options); + else if (value.PD_EnvelopeType != null) + JsonSerializer.Serialize(writer, value.PD_EnvelopeType, options); else throw new NotImplementedException(); } diff --git a/RDMSharp/Metadata/JSON/Converter/SubdevicesForRequestsConverter.cs b/RDMSharp/Metadata/JSON/Converter/SubdevicesForRequestsConverter.cs index 0c52387..5ae514b 100644 --- a/RDMSharp/Metadata/JSON/Converter/SubdevicesForRequestsConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/SubdevicesForRequestsConverter.cs @@ -10,12 +10,7 @@ public override SubdevicesForRequests Read(ref Utf8JsonReader reader, Type typeT { if (reader.TokenType == JsonTokenType.String) { - var _options = new JsonSerializerOptions(options) - { - Converters = { new JsonStringEnumConverter() }, - PropertyNameCaseInsensitive = true - }; - var enumValue = JsonSerializer.Deserialize(ref reader, _options); + var enumValue = JsonSerializer.Deserialize(ref reader, options); return new SubdevicesForRequests(enumValue); } else if (reader.TokenType == JsonTokenType.StartObject || reader.TokenType == JsonTokenType.Number) @@ -30,7 +25,11 @@ public override SubdevicesForRequests Read(ref Utf8JsonReader reader, Type typeT public override void Write(Utf8JsonWriter writer, SubdevicesForRequests value, JsonSerializerOptions options) { if (value.EnumValue.HasValue) - JsonSerializer.Serialize(writer, value.EnumValue.Value, options); + JsonSerializer.Serialize(writer, value.EnumValue.Value, new JsonSerializerOptions(options) + { + Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) }, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }); else if (value.ObjectValue != null) JsonSerializer.Serialize(writer, value.ObjectValue, options); } diff --git a/RDMSharp/Metadata/JSON/Converter/SubdevicesForResponsesConverter.cs b/RDMSharp/Metadata/JSON/Converter/SubdevicesForResponsesConverter.cs index 4a0b263..d0d36b7 100644 --- a/RDMSharp/Metadata/JSON/Converter/SubdevicesForResponsesConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/SubdevicesForResponsesConverter.cs @@ -10,12 +10,7 @@ public override SubdevicesForResponses Read(ref Utf8JsonReader reader, Type type { if (reader.TokenType == JsonTokenType.String) { - var _options = new JsonSerializerOptions(options) - { - Converters = { new JsonStringEnumConverter() }, - PropertyNameCaseInsensitive = true - }; - var enumValue = JsonSerializer.Deserialize(ref reader, _options); + var enumValue = JsonSerializer.Deserialize(ref reader, options); return new SubdevicesForResponses(enumValue); } else if (reader.TokenType == JsonTokenType.StartObject || reader.TokenType == JsonTokenType.Number) @@ -30,7 +25,11 @@ public override SubdevicesForResponses Read(ref Utf8JsonReader reader, Type type public override void Write(Utf8JsonWriter writer, SubdevicesForResponses value, JsonSerializerOptions options) { if (value.EnumValue.HasValue) - JsonSerializer.Serialize(writer, value.EnumValue.Value, options); + JsonSerializer.Serialize(writer, value.EnumValue.Value, new JsonSerializerOptions(options) + { + Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) }, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }); else if (value.ObjectValue != null) JsonSerializer.Serialize(writer, value.ObjectValue, options); } diff --git a/RDMSharp/Metadata/JSON/SubdeviceType.cs b/RDMSharp/Metadata/JSON/SubdeviceType.cs index 78785f4..cf5c7ba 100644 --- a/RDMSharp/Metadata/JSON/SubdeviceType.cs +++ b/RDMSharp/Metadata/JSON/SubdeviceType.cs @@ -6,7 +6,9 @@ namespace RDMSharp.Metadata.JSON [JsonConverter(typeof(SubdeviceTypeConverter))] public readonly struct SubdeviceType { + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public readonly ushort? Value { get; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public readonly SubdeviceRange? Range { get; } public SubdeviceType(ushort value) : this() { diff --git a/RDMSharp/Metadata/JSON/SubdevicesForRequests.cs b/RDMSharp/Metadata/JSON/SubdevicesForRequests.cs index 148cbf9..68d63fd 100644 --- a/RDMSharp/Metadata/JSON/SubdevicesForRequests.cs +++ b/RDMSharp/Metadata/JSON/SubdevicesForRequests.cs @@ -6,6 +6,7 @@ namespace RDMSharp.Metadata.JSON [JsonConverter(typeof(SubdevicesForRequestsConverter))] public readonly struct SubdevicesForRequests { + [JsonConverter(typeof(CustomEnumConverter))] public enum ESubdevicesForRequests { [JsonPropertyName("root")] @@ -15,7 +16,9 @@ public enum ESubdevicesForRequests [JsonPropertyName("broadcast")] Broadcast } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public readonly ESubdevicesForRequests? EnumValue { get; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public readonly SubdeviceType? ObjectValue { get; } public SubdevicesForRequests(ESubdevicesForRequests enumValue) { diff --git a/RDMSharp/Metadata/JSON/SubdevicesForResponses.cs b/RDMSharp/Metadata/JSON/SubdevicesForResponses.cs index da86e19..15177f0 100644 --- a/RDMSharp/Metadata/JSON/SubdevicesForResponses.cs +++ b/RDMSharp/Metadata/JSON/SubdevicesForResponses.cs @@ -6,6 +6,7 @@ namespace RDMSharp.Metadata.JSON [JsonConverter(typeof(SubdevicesForResponsesConverter))] public readonly struct SubdevicesForResponses { + [JsonConverter(typeof(CustomEnumConverter))] public enum ESubdevicesForResponses { [JsonPropertyName("root")] @@ -17,7 +18,9 @@ public enum ESubdevicesForResponses [JsonPropertyName("match")] Match } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public readonly ESubdevicesForResponses? EnumValue { get; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public readonly SubdeviceType? ObjectValue { get; } public SubdevicesForResponses(ESubdevicesForResponses enumValue) { diff --git a/RDMSharp/Metadata/MetadataFactory.cs b/RDMSharp/Metadata/MetadataFactory.cs index b66dd3d..eaef084 100644 --- a/RDMSharp/Metadata/MetadataFactory.cs +++ b/RDMSharp/Metadata/MetadataFactory.cs @@ -33,7 +33,7 @@ public static string[] GetResources() private static void fillDefaultMetadataVersionList() { metadataVersionList.AddRange(GetResources().Select(r => new MetadataVersion(r))); - + return; if (metadataVersionDefinesBagDictionary == null) metadataVersionDefinesBagDictionary = new Dictionary>(); @@ -45,7 +45,7 @@ private static void fillDefaultMetadataVersionList() var schema = schemaList.First(s => s.Version.Equals(mv.Version)); if(!versionSchemas.TryGetValue(schema.Version, out JsonSchema jsonSchema)) { - jsonSchema= JsonSchema.FromText(new MetadataBag(schema).Content); ; + jsonSchema= JsonSchema.FromText(new MetadataBag(schema).Content); versionSchemas.TryAdd(schema.Version, jsonSchema); } MetadataBag metadataBag = new MetadataBag(mv); diff --git a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs index e031603..62d2e8a 100644 --- a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs +++ b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs @@ -9,6 +9,9 @@ public readonly struct MetadataJSONObjectDefine { [JsonPropertyName("name")] public readonly string Name { get; } + [JsonPropertyName("notes")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public readonly string? Notes { get; } [JsonPropertyName("manufacturer_id")] public readonly ushort ManufacturerID { get; } [JsonPropertyName("pid")] @@ -16,39 +19,57 @@ public readonly struct MetadataJSONObjectDefine [JsonPropertyName("version")] public readonly ushort Version { get; } [JsonPropertyName("get_request_subdevice_range")] - public readonly SubdevicesForRequests[] GetRequestSubdeviceRange { get; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyOrder(11)] + public readonly SubdevicesForRequests[]? GetRequestSubdeviceRange { get; } [JsonPropertyName("get_response_subdevice_range")] - public readonly SubdevicesForResponses[] GetResponseSubdeviceRange { get; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyOrder(13)] + public readonly SubdevicesForResponses[]? GetResponseSubdeviceRange { get; } [JsonPropertyName("set_request_subdevice_range")] - public readonly SubdevicesForRequests[] SetReequestsSubdeviceRange { get; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyOrder(15)] + public readonly SubdevicesForRequests[]? SetReequestsSubdeviceRange { get; } [JsonPropertyName("set_response_subdevice_range")] - public readonly SubdevicesForResponses[] SetResponseSubdeviceRange { get; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyOrder(17)] + public readonly SubdevicesForResponses[]? SetResponseSubdeviceRange { get; } [JsonPropertyName("get_request")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyOrder(12)] public readonly Command? GetRequest { get; } [JsonPropertyName("get_response")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyOrder(14)] public readonly Command? GetResponse { get; } [JsonPropertyName("set_request")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyOrder(16)] public readonly Command? SetRequest { get; } [JsonPropertyName("set_response")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyOrder(18)] public readonly Command? SetResponse { get; } [JsonConstructor] public MetadataJSONObjectDefine( string name, + string? notes, ushort manufacturerID, ushort pID, ushort version, - SubdevicesForRequests[] getRequestSubdeviceRange, - SubdevicesForResponses[] getResponseSubdeviceRange, - SubdevicesForRequests[] setReequestsSubdeviceRange, - SubdevicesForResponses[] setResponseSubdeviceRange, + SubdevicesForRequests[]? getRequestSubdeviceRange, + SubdevicesForResponses[]? getResponseSubdeviceRange, + SubdevicesForRequests[]? setReequestsSubdeviceRange, + SubdevicesForResponses[]? setResponseSubdeviceRange, Command? getRequest, Command? getResponse, Command? setRequest, Command? setResponse) { Name = name; + Notes = notes; ManufacturerID = manufacturerID; PID = pID; Version = version; @@ -66,6 +87,9 @@ public MetadataJSONObjectDefine( public override string ToString() { + if (!string.IsNullOrWhiteSpace(Notes)) + return $"{ManufacturerID:X4} {PID:X4} {Name} ({Notes})"; + return $"{ManufacturerID:X4} {PID:X4} {Name}"; } } diff --git a/RDMSharp/Metadata/OneOfTypes/BitFieldType.cs b/RDMSharp/Metadata/OneOfTypes/BitFieldType.cs index 37fb3a4..61d5c76 100644 --- a/RDMSharp/Metadata/OneOfTypes/BitFieldType.cs +++ b/RDMSharp/Metadata/OneOfTypes/BitFieldType.cs @@ -1,14 +1,25 @@ -using System.Linq; +using RDMSharp.Metadata.JSON; +using System.Linq; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.OneOfTypes { - public readonly struct BitFieldType + public class BitFieldType : CommonPropertiesForNamed { [JsonConstructor] - public BitFieldType(string name, string type, ushort size, bool? valueForUnspecified, BitType[] bits) + public BitFieldType(string name, + string? displayName, + string? notes, + string[]? resources, + string type, + ushort size, + bool? valueForUnspecified, + BitType[] bits) : base() { Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; Type = type; Size = size; ValueForUnspecified = valueForUnspecified; @@ -16,17 +27,38 @@ public BitFieldType(string name, string type, ushort size, bool? valueForUnspeci } [JsonPropertyName("name")] - public readonly string Name { get; } + [JsonPropertyOrder(1)] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override string Name { get; } + [JsonPropertyName("displayName")] + [JsonPropertyOrder(2)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonPropertyOrder(4)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string? Notes { get; } + [JsonPropertyName("resources")] + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string[]? Resources { get; } + [JsonPropertyName("type")] - public readonly string Type { get; } + [JsonPropertyOrder(3)] + public string Type { get; } [JsonPropertyName("size")] - public readonly ushort Size { get; } + [JsonPropertyOrder(31)] + public ushort Size { get; } [JsonPropertyName("valueForUnspecified")] - public readonly bool? ValueForUnspecified { get; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyOrder(32)] + public bool? ValueForUnspecified { get; } [JsonPropertyName("bits")] - public readonly BitType[] Bits { get; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyOrder(41)] + public BitType[] Bits { get; } public override string ToString() { diff --git a/RDMSharp/Metadata/OneOfTypes/BitType.cs b/RDMSharp/Metadata/OneOfTypes/BitType.cs index e16714e..7e69584 100644 --- a/RDMSharp/Metadata/OneOfTypes/BitType.cs +++ b/RDMSharp/Metadata/OneOfTypes/BitType.cs @@ -1,13 +1,24 @@ -using System.Text.Json.Serialization; +using RDMSharp.Metadata.JSON; +using System.Text.Json.Serialization; namespace RDMSharp.Metadata.OneOfTypes { - public readonly struct BitType + public class BitType : CommonPropertiesForNamed { [JsonConstructor] - public BitType(string name, string type, ushort index, bool? reserved, bool? valueIfReserved) + public BitType(string name, + string? displayName, + string? notes, + string[]? resources, + string? type, + ushort index, + bool? reserved, + bool? valueIfReserved) : base() { Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; Type = type; Index = index; Reserved = reserved; @@ -15,15 +26,37 @@ public BitType(string name, string type, ushort index, bool? reserved, bool? val } [JsonPropertyName("name")] - public readonly string Name { get; } + [JsonPropertyOrder(1)] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override string Name { get; } + [JsonPropertyName("displayName")] + [JsonPropertyOrder(2)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonPropertyOrder(4)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string? Notes { get; } + [JsonPropertyName("resources")] + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string[]? Resources { get; } + [JsonPropertyName("type")] - public readonly string Type { get; } + [JsonPropertyOrder(3)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Type { get; } [JsonPropertyName("index")] - public readonly ushort Index { get; } + [JsonPropertyOrder(21)] + public ushort Index { get; } [JsonPropertyName("reserved")] - public readonly bool? Reserved { get; } + [JsonPropertyOrder(31)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Reserved { get; } [JsonPropertyName("valueIfReserved")] - public readonly bool? ValueIfReserved { get; } + [JsonPropertyOrder(32)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? ValueIfReserved { get; } public override string ToString() { diff --git a/RDMSharp/Metadata/OneOfTypes/BooleanType.cs b/RDMSharp/Metadata/OneOfTypes/BooleanType.cs index 0efd083..6850dbc 100644 --- a/RDMSharp/Metadata/OneOfTypes/BooleanType.cs +++ b/RDMSharp/Metadata/OneOfTypes/BooleanType.cs @@ -1,25 +1,49 @@ -using System.Linq; +using RDMSharp.Metadata.JSON; +using System.Linq; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.OneOfTypes { - public readonly struct BooleanType + public class BooleanType : CommonPropertiesForNamed { [JsonPropertyName("name")] - public readonly string Name { get; } + [JsonPropertyOrder(1)] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override string Name { get; } + [JsonPropertyName("displayName")] + [JsonPropertyOrder(2)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonPropertyOrder(4)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string? Notes { get; } + [JsonPropertyName("resources")] + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string[]? Resources { get; } + [JsonPropertyName("type")] - public readonly string Type { get; } + [JsonPropertyOrder(3)] + public string Type { get; } [JsonPropertyName("labels")] - public readonly LabeledBooleanType[]? Labels { get; } + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public LabeledBooleanType[]? Labels { get; } [JsonConstructor] - public BooleanType( - string name, - string type, - LabeledBooleanType[]? labels) + public BooleanType(string name, + string? displayName, + string? notes, + string[]? resources, + string type, + LabeledBooleanType[]? labels) : base() { Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; Type = type; Labels = labels; } diff --git a/RDMSharp/Metadata/OneOfTypes/BytesType.cs b/RDMSharp/Metadata/OneOfTypes/BytesType.cs index fbd52f6..65d4b11 100644 --- a/RDMSharp/Metadata/OneOfTypes/BytesType.cs +++ b/RDMSharp/Metadata/OneOfTypes/BytesType.cs @@ -1,32 +1,58 @@ -using System.Text.Json.Serialization; +using RDMSharp.Metadata.JSON; +using System.Text.Json.Serialization; namespace RDMSharp.Metadata.OneOfTypes { - public readonly struct BytesType + public class BytesType : CommonPropertiesForNamed { - [JsonPropertyName("name")] - public readonly string Name { get; } + [JsonPropertyOrder(1)] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override string Name { get; } + [JsonPropertyName("displayName")] + [JsonPropertyOrder(2)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonPropertyOrder(4)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string? Notes { get; } + [JsonPropertyName("resources")] + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string[]? Resources { get; } [JsonPropertyName("type")] - public readonly string Type { get; } + [JsonPropertyOrder(3)] + public string Type { get; } [JsonPropertyName("format")] - public readonly string? Format { get; } + [JsonPropertyOrder(11)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Format { get; } [JsonPropertyName("minLength")] - public readonly ulong? MinLength { get; } + [JsonPropertyOrder(12)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public ulong? MinLength { get; } [JsonPropertyName("maxLength")] - public readonly ulong? MaxLength { get; } + [JsonPropertyOrder(13)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public ulong? MaxLength { get; } [JsonConstructor] - public BytesType( - string name, - string type, - string? format, - ulong? minLength, - ulong? maxLength) + public BytesType(string name, + string? displayName, + string? notes, + string[]? resources, + string type, + string? format, + ulong? minLength, + ulong? maxLength) : base() { Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; Type = type; Format = format; MinLength = minLength; diff --git a/RDMSharp/Metadata/OneOfTypes/CompoundType.cs b/RDMSharp/Metadata/OneOfTypes/CompoundType.cs index aa83f18..802c138 100644 --- a/RDMSharp/Metadata/OneOfTypes/CompoundType.cs +++ b/RDMSharp/Metadata/OneOfTypes/CompoundType.cs @@ -1,24 +1,48 @@ -using System.Text.Json.Serialization; +using Humanizer.Localisation; +using RDMSharp.Metadata.JSON; +using System.Text.Json.Serialization; namespace RDMSharp.Metadata.OneOfTypes { - public class CompoundType + public class CompoundType : CommonPropertiesForNamed { [JsonPropertyName("name")] - public string Name { get; } + [JsonPropertyOrder(1)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string Name { get; } + [JsonPropertyName("displayName")] + [JsonPropertyOrder(2)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonPropertyOrder(4)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string? Notes { get; } + [JsonPropertyName("resources")] + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string[]? Resources { get; } + [JsonPropertyName("type")] + [JsonPropertyOrder(3)] public string Type { get; } [JsonPropertyName("subtypes")] + [JsonPropertyOrder(11)] public OneOfTypes[] Subtypes { get; } [JsonConstructor] - public CompoundType( - string name, - string type, - OneOfTypes[] subtypes) + public CompoundType(string name, + string? displayName, + string? notes, + string[]? resources, + string type, + OneOfTypes[] subtypes) { Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; Type = type; Subtypes = subtypes; } diff --git a/RDMSharp/Metadata/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/OneOfTypes/IntegerType.cs index 8ee5af2..bbfcd0f 100644 --- a/RDMSharp/Metadata/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/OneOfTypes/IntegerType.cs @@ -1,11 +1,12 @@ -using System; +using Humanizer.Localisation; +using RDMSharp.Metadata.JSON; +using RDMSharp.Metadata.JSON.Converter; using System.Linq; -using System.Numerics; -using System.Runtime.CompilerServices; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.OneOfTypes { + [JsonConverter(typeof(CustomEnumConverter))] public enum EIntegerType { [JsonPropertyName("int8")] @@ -29,38 +30,70 @@ public enum EIntegerType [JsonPropertyName("uint128")] UInt128 } - public readonly struct IntegerType + public class IntegerType: CommonPropertiesForNamed { [JsonPropertyName("name")] - public readonly string Name { get; } + [JsonPropertyOrder(1)] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override string Name { get; } + [JsonPropertyName("displayName")] + [JsonPropertyOrder(2)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonPropertyOrder(4)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string? Notes { get; } + [JsonPropertyName("resources")] + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string[]? Resources { get; } + [JsonPropertyName("type")] - [JsonConverter(typeof(JsonStringEnumConverter))] - public readonly EIntegerType Type { get; } + [JsonPropertyOrder(3)] + public EIntegerType Type { get; } [JsonPropertyName("labels")] - public readonly LabeledIntegerType[]? Labels { get; } + [JsonPropertyOrder(31)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public LabeledIntegerType[]? Labels { get; } [JsonPropertyName("restrictToLabeled")] - public readonly bool? RestrictToLabeled { get; } + [JsonPropertyOrder(32)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? RestrictToLabeled { get; } [JsonPropertyName("ranges")] - public readonly Range[]? Ranges { get; } + [JsonPropertyOrder(11)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Range[]? Ranges { get; } [JsonPropertyName("units")] - public readonly ERDM_SensorUnit? Units { get; } + [JsonPropertyOrder(21)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public ERDM_SensorUnit? Units { get; } [JsonPropertyName("prefixPower")] - public readonly int? PrefixPower { get; } = 0; + [JsonPropertyOrder(22)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? PrefixPower { get; } = 0; [JsonPropertyName("prefixBase")] - public readonly int? PrefixBase { get; } = 10; + [JsonPropertyOrder(23)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? PrefixBase { get; } = 10; [JsonConstructor] - public IntegerType( - string name, - EIntegerType type, - LabeledIntegerType[]? labels, - bool? restrictToLabeled, - Range[]? ranges, - ERDM_SensorUnit? units, - int? prefixPower, - int? prefixBase) + public IntegerType(string name, + string? displayName, + string? notes, + string[]? resources, + EIntegerType type, + LabeledIntegerType[]? labels, + bool? restrictToLabeled, + Range[]? ranges, + ERDM_SensorUnit? units, + int? prefixPower, + int? prefixBase) : base() { Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; Type = type; Labels = labels; RestrictToLabeled = restrictToLabeled; diff --git a/RDMSharp/Metadata/OneOfTypes/LabeledBooleanType.cs b/RDMSharp/Metadata/OneOfTypes/LabeledBooleanType.cs index 5cc108b..e367f4d 100644 --- a/RDMSharp/Metadata/OneOfTypes/LabeledBooleanType.cs +++ b/RDMSharp/Metadata/OneOfTypes/LabeledBooleanType.cs @@ -1,21 +1,42 @@ -using System.Text.Json; +using RDMSharp.Metadata.JSON; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.OneOfTypes { - public readonly struct LabeledBooleanType + public class LabeledBooleanType : CommonPropertiesForNamed { [JsonPropertyName("name")] - public readonly string Name { get; } + [JsonPropertyOrder(1)] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override string Name { get; } + [JsonPropertyName("displayName")] + [JsonPropertyOrder(2)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonPropertyOrder(4)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string? Notes { get; } + [JsonPropertyName("resources")] + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string[]? Resources { get; } + [JsonPropertyName("value")] - public readonly bool Value { get; } + [JsonPropertyOrder(3)] + public bool Value { get; } [JsonConstructor] - public LabeledBooleanType( - string name, - bool value) + public LabeledBooleanType(string name, + string? displayName, + string? notes, + string[]? resources, + bool value) :base() { Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; Value = value; } diff --git a/RDMSharp/Metadata/OneOfTypes/LabeledIntegerType.cs b/RDMSharp/Metadata/OneOfTypes/LabeledIntegerType.cs index a167c26..f1e0d5b 100644 --- a/RDMSharp/Metadata/OneOfTypes/LabeledIntegerType.cs +++ b/RDMSharp/Metadata/OneOfTypes/LabeledIntegerType.cs @@ -1,21 +1,42 @@ -using System.Text.Json; +using RDMSharp.Metadata.JSON; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.OneOfTypes { - public readonly struct LabeledIntegerType + public class LabeledIntegerType : CommonPropertiesForNamed { [JsonPropertyName("name")] - public readonly string Name { get; } + [JsonPropertyOrder(1)] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override string Name { get; } + [JsonPropertyName("displayName")] + [JsonPropertyOrder(2)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonPropertyOrder(4)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string? Notes { get; } + [JsonPropertyName("resources")] + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string[]? Resources { get; } + [JsonPropertyName("value")] - public readonly long Value { get; } + [JsonPropertyOrder(3)] + public long Value { get; } [JsonConstructor] - public LabeledIntegerType( - string name, - long value) + public LabeledIntegerType(string name, + string? displayName, + string? notes, + string[]? resources, + long value) : base() { Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; Value = value; } diff --git a/RDMSharp/Metadata/OneOfTypes/ListType.cs b/RDMSharp/Metadata/OneOfTypes/ListType.cs index 546d772..55ed42f 100644 --- a/RDMSharp/Metadata/OneOfTypes/ListType.cs +++ b/RDMSharp/Metadata/OneOfTypes/ListType.cs @@ -1,30 +1,57 @@ -using System.Text.Json.Serialization; +using RDMSharp.Metadata.JSON; +using System.Text.Json.Serialization; namespace RDMSharp.Metadata.OneOfTypes { - public class ListType + public class ListType : CommonPropertiesForNamed { [JsonPropertyName("name")] - public string Name { get; } + [JsonPropertyOrder(1)] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override string Name { get; } + [JsonPropertyName("displayName")] + [JsonPropertyOrder(2)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonPropertyOrder(4)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string? Notes { get; } + [JsonPropertyName("resources")] + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string[]? Resources { get; } + [JsonPropertyName("type")] + [JsonPropertyOrder(3)] public string Type { get; } [JsonPropertyName("itemType")] + [JsonPropertyOrder(21)] public OneOfTypes ItemType { get; } [JsonPropertyName("minItems")] + [JsonPropertyOrder(31)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public int? MinItems { get; } [JsonPropertyName("maxItems")] + [JsonPropertyOrder(32)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public int? MaxItems { get; } [JsonConstructor] - public ListType( - string name, - string type, - OneOfTypes itemType, - int? minItems, - int? maxItems) + public ListType(string name, + string? displayName, + string? notes, + string[]? resources, + string type, + OneOfTypes itemType, + int? minItems, + int? maxItems) : base() { Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; Type = type; ItemType = itemType; MinItems = minItems; diff --git a/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs b/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs index 02c6552..196ea07 100644 --- a/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs +++ b/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs @@ -110,49 +110,49 @@ public OneOfTypes(PD_EnvelopeType pdEnvelopeType) public override string ToString() { - if (BitType.HasValue) - return BitType.Value.ToString(); + if (BitType != null) + return BitType.ToString(); - if (BitFieldType.HasValue) - return BitFieldType.Value.ToString(); + if (BitFieldType != null) + return BitFieldType.ToString(); - if (BytesType.HasValue) - return BytesType.Value.ToString(); + if (BytesType != null) + return BytesType.ToString(); - if (BooleanType.HasValue) - return BooleanType.Value.ToString(); + if (BooleanType != null) + return BooleanType.ToString(); - if (IntegerType_UInt8.HasValue) - return IntegerType_UInt8.Value.ToString(); - if (IntegerType_UInt8.HasValue) - return IntegerType_UInt8.Value.ToString(); + if (IntegerType_UInt8 != null) + return IntegerType_UInt8.ToString(); + if (IntegerType_UInt8 != null) + return IntegerType_UInt8.ToString(); - if (IntegerType_UInt16.HasValue) - return IntegerType_UInt16.Value.ToString(); - if (IntegerType_UInt16.HasValue) - return IntegerType_UInt16.Value.ToString(); + if (IntegerType_UInt16 != null) + return IntegerType_UInt16.ToString(); + if (IntegerType_UInt16 != null) + return IntegerType_UInt16.ToString(); - if (IntegerType_UInt32.HasValue) - return IntegerType_UInt32.Value.ToString(); - if (IntegerType_UInt32.HasValue) - return IntegerType_UInt32.Value.ToString(); + if (IntegerType_UInt32 != null) + return IntegerType_UInt32.ToString(); + if (IntegerType_UInt32 != null ) + return IntegerType_UInt32.ToString(); - if (IntegerType_UInt64.HasValue) - return IntegerType_UInt64.Value.ToString(); - if (IntegerType_UInt64.HasValue) - return IntegerType_UInt64.Value.ToString(); + if (IntegerType_UInt64 != null) + return IntegerType_UInt64.ToString(); + if (IntegerType_UInt64 != null) + return IntegerType_UInt64.ToString(); #if NET7_0_OR_GREATER - if (IntegerType_UInt128.HasValue) - return IntegerType_UInt128.Value.ToString(); - if (IntegerType_UInt128.HasValue) - return IntegerType_UInt128.Value.ToString(); + if (IntegerType_UInt128 != null) + return IntegerType_UInt128.ToString(); + if (IntegerType_UInt128 != null) + return IntegerType_UInt128.ToString(); #endif - if (ReferenceType.HasValue) - return ReferenceType.Value.ToString(); + if (ReferenceType != null) + return ReferenceType.ToString(); - if (StringType.HasValue) - return StringType.Value.ToString(); + if (StringType != null) + return StringType.ToString(); if (ListType != null) return ListType.ToString(); @@ -160,8 +160,8 @@ public override string ToString() if (CompoundType != null) return CompoundType.ToString(); - if (PD_EnvelopeType.HasValue) - return PD_EnvelopeType.Value.ToString(); + if (PD_EnvelopeType != null) + return PD_EnvelopeType.ToString(); return base.ToString(); } diff --git a/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs b/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs index 09b7526..891b3a0 100644 --- a/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs +++ b/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs @@ -1,22 +1,43 @@ -using System.Text.Json.Serialization; +using RDMSharp.Metadata.JSON; +using System.Text.Json.Serialization; namespace RDMSharp.Metadata.OneOfTypes { - public readonly struct PD_EnvelopeType + public class PD_EnvelopeType : CommonPropertiesForNamed { - [JsonPropertyName("name")] - public readonly string Name { get; } + [JsonPropertyOrder(1)] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override string Name { get; } + [JsonPropertyName("displayName")] + [JsonPropertyOrder(2)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonPropertyOrder(4)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string? Notes { get; } + [JsonPropertyName("resources")] + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string[]? Resources { get; } + [JsonPropertyName("length")] - public readonly byte Length { get; } + [JsonPropertyOrder(3)] + public byte Length { get; } [JsonConstructor] - public PD_EnvelopeType( - string name, - byte length) + public PD_EnvelopeType(string name, + string? displayName, + string? notes, + string[]? resources, + byte length) : base() { Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; Length = length; } @@ -25,7 +46,7 @@ public override string ToString() if (string.IsNullOrWhiteSpace(Name)) return $"PDL: {Length} ({Length:X2})"; - return $"PDL: {Length} ({Length:X2}) {Name}"; + return $"PDL: {Length} ({Length:X2}) {base.ToString()}"; } } } diff --git a/RDMSharp/Metadata/OneOfTypes/ReferenceType.cs b/RDMSharp/Metadata/OneOfTypes/ReferenceType.cs index 4df6060..1ca63ae 100644 --- a/RDMSharp/Metadata/OneOfTypes/ReferenceType.cs +++ b/RDMSharp/Metadata/OneOfTypes/ReferenceType.cs @@ -1,6 +1,5 @@ using RDMSharp.Metadata.JSON; using System; -using System.Data; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.OneOfTypes @@ -9,7 +8,9 @@ public readonly struct ReferenceType { [JsonPropertyName("$ref")] public readonly string URI { get; } + [JsonIgnore(Condition = JsonIgnoreCondition.Always)] public readonly Command.ECommandDublicte Command { get; } + [JsonIgnore(Condition = JsonIgnoreCondition.Always)] public readonly ushort Pointer { get; } [JsonConstructor] diff --git a/RDMSharp/Metadata/OneOfTypes/StringType.cs b/RDMSharp/Metadata/OneOfTypes/StringType.cs index 1186aa5..d767044 100644 --- a/RDMSharp/Metadata/OneOfTypes/StringType.cs +++ b/RDMSharp/Metadata/OneOfTypes/StringType.cs @@ -1,44 +1,78 @@ -using System.Text.Json.Serialization; +using RDMSharp.Metadata.JSON; +using System.Text.Json.Serialization; namespace RDMSharp.Metadata.OneOfTypes { - public readonly struct StringType + public class StringType : CommonPropertiesForNamed { - [JsonPropertyName("name")] - public readonly string Name { get; } + [JsonPropertyOrder(1)] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + public override string Name { get; } + [JsonPropertyName("displayName")] + [JsonPropertyOrder(2)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string DisplayName { get; } + [JsonPropertyName("notes")] + [JsonPropertyOrder(25)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string? Notes { get; } + [JsonPropertyName("resources")] + [JsonPropertyOrder(5)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public override string[]? Resources { get; } [JsonPropertyName("type")] - public readonly string Type { get; } + [JsonPropertyOrder(3)] + public string Type { get; } [JsonPropertyName("format")] - public readonly string? Format { get; } + [JsonPropertyOrder(21)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Format { get; } [JsonPropertyName("pattern")] - public readonly string? Pattern { get; } + [JsonPropertyOrder(22)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Pattern { get; } [JsonPropertyName("minLength")] - public readonly ulong? MinLength { get; } + [JsonPropertyOrder(31)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public ulong? MinLength { get; } [JsonPropertyName("maxLength")] - public readonly ulong? MaxLength { get; } + [JsonPropertyOrder(32)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public ulong? MaxLength { get; } [JsonPropertyName("minBytes")] - public readonly ulong? MinBytes { get; } + [JsonPropertyOrder(41)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public ulong? MinBytes { get; } [JsonPropertyName("maxBytes")] - public readonly ulong? MaxBytes { get; } + [JsonPropertyOrder(42)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public ulong? MaxBytes { get; } [JsonPropertyName("restrictToASCII")] - public readonly bool? RestrictToASCII { get; } + [JsonPropertyOrder(51)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? RestrictToASCII { get; } [JsonConstructor] - public StringType( - string name, - string type, - string? format, - string? pattern, - ulong? minLength, - ulong? maxLength, - ulong? minBytes, - ulong? maxBytes, - bool? restrictToASCII) + public StringType(string name, + string? displayName, + string? notes, + string[]? resources, + string type, + string? format, + string? pattern, + ulong? minLength, + ulong? maxLength, + ulong? minBytes, + ulong? maxBytes, + bool? restrictToASCII) { Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; Type = type; Format = format; Pattern = pattern; @@ -51,7 +85,7 @@ public StringType( public override string ToString() { - return Name; + return base.ToString(); } } } diff --git a/RDMSharpTests/MetadataJSONObjectDefineTestSubject.cs b/RDMSharpTests/MetadataJSONObjectDefineTestSubject.cs new file mode 100644 index 0000000..e5da7ae --- /dev/null +++ b/RDMSharpTests/MetadataJSONObjectDefineTestSubject.cs @@ -0,0 +1,40 @@ +using RDMSharp.Metadata; +using System.Collections.Concurrent; + +namespace RDMSharpTests +{ + public class MetadataJSONObjectDefineTestSubject + { + public static readonly object[] TestSubjects = getTestSubjects(); + private static object[] getTestSubjects() + { + List instances = new List(); + List metadataVersionList= new List(); + metadataVersionList.AddRange(MetadataFactory.GetResources().Select(r => new MetadataVersion(r))); + var schemaList = MetadataFactory.GetMetadataSchemaVersions(); + ConcurrentDictionary versionSchemas = new ConcurrentDictionary(); + + foreach (var mv in metadataVersionList.Where(_mv => !_mv.IsSchema)) + { + var _schema = schemaList.First(s => s.Version.Equals(mv.Version)); + if (!versionSchemas.TryGetValue(_schema.Version, out MetadataBag schema)) + { + schema = new MetadataBag(_schema); + versionSchemas.TryAdd(_schema.Version, schema); + } + instances.Add(new MetadataJSONObjectDefineTestSubject(schema, new MetadataBag(mv))); + } + return instances.ToArray(); + } + public readonly MetadataBag Schema; + public readonly MetadataBag Define; + + public override string ToString() => Define.Name; + + public MetadataJSONObjectDefineTestSubject(MetadataBag schema, MetadataBag define) + { + Schema = schema; + Define = define; + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/MetadataJSONObjectDefineTests.cs b/RDMSharpTests/MetadataJSONObjectDefineTests.cs new file mode 100644 index 0000000..12a184f --- /dev/null +++ b/RDMSharpTests/MetadataJSONObjectDefineTests.cs @@ -0,0 +1,51 @@ +using Json.Schema; +using RDMSharp.Metadata; +using System.Text.Json; +using System.Text.Json.Nodes; + +namespace RDMSharpTests +{ + [TestFixtureSource(typeof(MetadataJSONObjectDefineTestSubject), nameof(MetadataJSONObjectDefineTestSubject.TestSubjects))] + public class MetadataJSONObjectDefineTests + { + private readonly MetadataJSONObjectDefineTestSubject testSubject; + + public MetadataJSONObjectDefineTests(MetadataJSONObjectDefineTestSubject _TestSubject) + { + testSubject = _TestSubject; + } + + + [Test] + public void TestValidateAgainstSchema() + { + JsonSchema jsonSchema = JsonSchema.FromText(testSubject.Schema.Content); + var result = jsonSchema.Evaluate(JsonNode.Parse(testSubject.Define.Content)); + Assert.That(result, Is.Not.Null); + Assert.That(result.IsValid, Is.True); + } + [Test] + public void TestDeseriaizeAndSerialize() + { + MetadataJSONObjectDefine deserialized = JsonSerializer.Deserialize(testSubject.Define.Content); + Assert.That(deserialized.Version, Is.AtLeast(1)); + Assert.That(deserialized.Name, Is.Not.WhiteSpace); + Assert.That(deserialized.Name, Is.Not.Empty); + string serialized = JsonSerializer.Serialize(deserialized); + Assert.That(PrittyJSON(serialized),Is.EqualTo(PrittyJSON(testSubject.Define.Content))); + } + + private static string PrittyJSON(string jsonString) + { + var jsonObject = JsonSerializer.Deserialize(jsonString); + + var options = new JsonSerializerOptions + { + WriteIndented = true, + }; + + string formattedJson = JsonSerializer.Serialize(jsonObject, options); + return formattedJson; + } + } +} \ No newline at end of file From 0696394ed84c26ee5a8a7f98c0178aa5188d0342 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Tue, 17 Sep 2024 17:21:45 +0200 Subject: [PATCH 10/51] Remove Not working and not defined Parameters Fix Invalid Schema xD --- RDMSharp/Metadata/JSON/Command.cs | 4 +- .../e1.20/CONTROLLER_FLAG_SUPPORT.json | 19 ------- .../1.0.0/Defines/e1.20/NACK_DESCRIPTION.json | 18 ------ .../1.0.0/Defines/e1.20/PACKED_PID_INDEX.json | 35 ------------ .../1.0.0/Defines/e1.20/PACKED_PID_SUB.json | 57 ------------------- .../e1.20/QUEUED_MESSAGE_PID_SUBSCRIBE.json | 9 --- .../QUEUED_MESSAGE_SENSOR_SUBSCRIBE.json | 18 ------ .../e1.20/SUPPORTED_PARAMETERS_ENHANCED.json | 33 ----------- .../Resources/JSON-Defines/1.0.0/schema.json | 3 +- .../MetadataJSONObjectDefineTests.cs | 12 +++- 10 files changed, 15 insertions(+), 193 deletions(-) delete mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CONTROLLER_FLAG_SUPPORT.json delete mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/NACK_DESCRIPTION.json delete mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_INDEX.json delete mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_SUB.json delete mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_PID_SUBSCRIBE.json delete mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_SENSOR_SUBSCRIBE.json delete mode 100644 RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUPPORTED_PARAMETERS_ENHANCED.json diff --git a/RDMSharp/Metadata/JSON/Command.cs b/RDMSharp/Metadata/JSON/Command.cs index b8d71f9..0ed1536 100644 --- a/RDMSharp/Metadata/JSON/Command.cs +++ b/RDMSharp/Metadata/JSON/Command.cs @@ -18,7 +18,9 @@ public enum ECommandDublicte [JsonPropertyName("set_request")] SetRequest, [JsonPropertyName("set_response")] - SetResponse + SetResponse, + [JsonPropertyName("different_pid")] + DifferentDid } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public readonly ECommandDublicte? EnumValue { get; } diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CONTROLLER_FLAG_SUPPORT.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CONTROLLER_FLAG_SUPPORT.json deleted file mode 100644 index 4705fd3..0000000 --- a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/CONTROLLER_FLAG_SUPPORT.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "CONTROLLER_FLAG_SUPPORT", - "manufacturer_id": 0, - "pid": -1, - "version": 1, - "get_request_subdevice_range": [ "root" ], - "get_request": [], - "get_response": [ - { - "name": "controller_flags", - "type": "bitField", - "size": 8, - "bits": [ - { "name": "unicode", "index": 0 }, - { "name": "hi_res_ack_timer_support", "index": 1 } - ] - } - ] -} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/NACK_DESCRIPTION.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/NACK_DESCRIPTION.json deleted file mode 100644 index 8680eae..0000000 --- a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/NACK_DESCRIPTION.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "NACK_DESCRIPTION", - "manufacturer_id": 0, - "pid": -1, - "version": 1, - "get_request_subdevice_range": [ "root" ], - "get_request": [ - { "name": "nack_reason_number", "type": "uint16" } - ], - "get_response": [ - { "name": "nack_reason_number", "type": "uint16" }, - { - "name": "description", - "type": "string", - "maxLength": 32 - } - ] -} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_INDEX.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_INDEX.json deleted file mode 100644 index 672aeed..0000000 --- a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_INDEX.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "PACKED_PID_INDEX", - "manufacturer_id": 0, - "pid": -1, - "version": 1, - "get_request_subdevice_range": [ "root", "subdevices" ], - "get_request": [ - { - "name": "pid", - "type": "uint16", - "notes": "Some PIDs are disallowed from being packed. See \"Table A-3: RDM Categories/Parameter ID Defines\" of the ANSI E1.20-202x specification." - }, - { "name": "first_item", "type": "uint16" }, - { - "name": "item_count", - "type": "uint16", - "labels": [ - { "name": "All Data", "value": 65535 } - ] - } - ], - "get_response": [ - { "name": "pid", "type": "uint16" }, - { "name": "first_item", "type": "uint16" }, - { "name": "entry_count", "type": "uint8" }, - { - "name": "entries", - "type": "list", - "itemType": { "type": "pdEnvelope" } - } - ], - "set_request_subdevice_range": [ "root", "subdevices" ], - "set_request": "get_response", - "set_response": [] -} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_SUB.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_SUB.json deleted file mode 100644 index fdd3aa9..0000000 --- a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/PACKED_PID_SUB.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "PACKED_PID_SUB", - "manufacturer_id": 0, - "pid": -1, - "version": 1, - "get_request_subdevice_range": [ "root" ], - "get_request": [ - { - "name": "pid", - "type": "uint16", - "notes": "Some PIDs are disallowed from being packed. See \"Table A-3: RDM Categories/Parameter ID Defines\" of the ANSI E1.20-202x specification." - }, - { "name": "index", "type": "uint16" }, - { - "name": "first_subdevice", - "type": "uint16", - "ranges": [ - { "minimum": 0, "maximum": 65520 } - ] - }, - { - "name": "subdevice_count", - "type": "uint16", - "ranges": [ - { "minimum": 1, "maximum": 65520 }, - { "minimum": 65535, "maximum": 65535 } - ], - "labels": [ - { "name": "All Subdevices", "value": 65535 } - ] - } - ], - "get_response": [ - { "name": "pid", "type": "uint16" }, - { "name": "index", "type": "uint16" }, - { - "name": "entries", - "type": "list", - "itemType": { - "type": "compound", - "subtypes": [ - { - "name": "subdevice", - "type": "uint16", - "ranges": [ - { "minimum": 0, "maximum": 65520 } - ] - }, - { "name": "subdevice_entry", "type": "pdEnvelope" } - ] - } - } - ], - "set_request_subdevice_range": [ "root" ], - "set_request": "get_response", - "set_response": [] -} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_PID_SUBSCRIBE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_PID_SUBSCRIBE.json deleted file mode 100644 index 23c5113..0000000 --- a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_PID_SUBSCRIBE.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "QUEUED_MESSAGE_PID_SUBSCRIBE WHERE IS THIS IN THE SPEC?", - "manufacturer_id": 0, - "pid": -1, - "version": 1, - "get_request_subdevice_range": [ "root", "subdevices" ], - "get_request": [], - "get_response": [] -} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_SENSOR_SUBSCRIBE.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_SENSOR_SUBSCRIBE.json deleted file mode 100644 index c1b3359..0000000 --- a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/QUEUED_MESSAGE_SENSOR_SUBSCRIBE.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "QUEUED_MESSAGE_SENSOR_SUBSCRIBE", - "manufacturer_id": 0, - "pid": -1, - "version": 1, - "get_request_subdevice_range": [ "root", "subdevices" ], - "get_request": [], - "get_response": [ - { - "name": "sensor_numbers", - "type": "list", - "itemType": { - "name": "sensor_number", - "type": "uint8" - } - } - ] -} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUPPORTED_PARAMETERS_ENHANCED.json b/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUPPORTED_PARAMETERS_ENHANCED.json deleted file mode 100644 index 78c382c..0000000 --- a/RDMSharp/Resources/JSON-Defines/1.0.0/Defines/e1.20/SUPPORTED_PARAMETERS_ENHANCED.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "SUPPORTED_PARAMETERS_ENHANCED", - "manufacturer_id": 0, - "pid": -1, - "version": 1, - "get_request_subdevice_range": [ "root", "subdevices" ], - "get_request": [], - "get_response": [ - { - "name": "pids", - "type": "list", - "itemType": { - "type": "compound", - "subtypes": [ - { "name": "pid", "type": "uint16" }, - { - "name": "pid_support", - "type": "bitField", - "size": 16, - "bits": [ - { "name": "get_supported", "index": 0 }, - { "name": "set_supported", "index": 1 }, - { "name": "packed_pid_sub_get_supported", "index": 2 }, - { "name": "packed_pid_sub_set_supported", "index": 3 }, - { "name": "packed_pid_index_get_supported", "index": 4 }, - { "name": "packed_pid_index_set_supported", "index": 5 } - ] - } - ] - } - } - ] -} diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/schema.json b/RDMSharp/Resources/JSON-Defines/1.0.0/schema.json index c877fdd..1112a3a 100644 --- a/RDMSharp/Resources/JSON-Defines/1.0.0/schema.json +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/schema.json @@ -211,7 +211,8 @@ "get_request", "get_response", "set_request", - "set_response" + "set_response", + "different_pid" ] } ] diff --git a/RDMSharpTests/MetadataJSONObjectDefineTests.cs b/RDMSharpTests/MetadataJSONObjectDefineTests.cs index 12a184f..204c878 100644 --- a/RDMSharpTests/MetadataJSONObjectDefineTests.cs +++ b/RDMSharpTests/MetadataJSONObjectDefineTests.cs @@ -2,6 +2,7 @@ using RDMSharp.Metadata; using System.Text.Json; using System.Text.Json.Nodes; +using Newtonsoft.Json.Linq; namespace RDMSharpTests { @@ -32,7 +33,14 @@ public void TestDeseriaizeAndSerialize() Assert.That(deserialized.Name, Is.Not.WhiteSpace); Assert.That(deserialized.Name, Is.Not.Empty); string serialized = JsonSerializer.Serialize(deserialized); - Assert.That(PrittyJSON(serialized),Is.EqualTo(PrittyJSON(testSubject.Define.Content))); + + var original = JToken.Parse(PrittyJSON(testSubject.Define.Content)); + var smashed = JToken.Parse(PrittyJSON(serialized)); + + Assert.That(JToken.DeepEquals(smashed, original)); + + + Warn.Unless(PrittyJSON(serialized),Is.EqualTo(PrittyJSON(testSubject.Define.Content))); } private static string PrittyJSON(string jsonString) @@ -41,7 +49,7 @@ private static string PrittyJSON(string jsonString) var options = new JsonSerializerOptions { - WriteIndented = true, + WriteIndented = false, }; string formattedJson = JsonSerializer.Serialize(jsonObject, options); From 50c89170b5af0ae7bd832c33d9104e27a0f1d671 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Tue, 17 Sep 2024 21:15:21 +0200 Subject: [PATCH 11/51] Add more Tests and improve code while adding Tests --- RDMSharp/Metadata/JSON/Command.cs | 11 +- RDMSharp/Metadata/MetadataBag.cs | 2 + RDMSharp/Metadata/MetadataJSONObjectDefine.cs | 11 +- RDMSharp/Metadata/OneOfTypes/CompoundType.cs | 3 +- RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs | 73 ++++------ .../Metadata/OneOfTypes/PD_EnvelopeType.cs | 15 +- .../MetadataJSONObjectDefineTestSubject.cs | 26 ++++ .../MetadataJSONObjectDefineTests.cs | 129 +++++++++++++++++- RDMSharpTests/RDMSharpTests.csproj | 12 +- .../Mocks/MOCK_128BIT_INTEGER_TEST.json | 18 +++ .../MOCK_ALL_INTEGER_TEST_EXCEPT_128BIT.json | 42 ++++++ .../Defines/Mocks/MOCK_DISPLAY_NAME.json | 62 +++++++++ .../Defines/Mocks/MOCK_PD_ENVELOPED.json | 25 ++++ .../Defines/Mocks/MOCK_SINGLE_FIELD.json | 20 +++ .../Defines/Mocks/MOCK_SUBDEVICE_TYPES.json | 35 +++++ RDMSharpTests/TestJSONDefines.cs | 11 +- 16 files changed, 425 insertions(+), 70 deletions(-) create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_128BIT_INTEGER_TEST.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_ALL_INTEGER_TEST_EXCEPT_128BIT.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_DISPLAY_NAME.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_PD_ENVELOPED.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_SINGLE_FIELD.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_SUBDEVICE_TYPES.json diff --git a/RDMSharp/Metadata/JSON/Command.cs b/RDMSharp/Metadata/JSON/Command.cs index 0ed1536..4728c2c 100644 --- a/RDMSharp/Metadata/JSON/Command.cs +++ b/RDMSharp/Metadata/JSON/Command.cs @@ -27,11 +27,18 @@ public enum ECommandDublicte [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public readonly OneOf? SingleField { get; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public readonly OneOf[] ListOfFields { get; } + public readonly OneOf[]? ListOfFields { get; } public bool GetIsEmpty() { - return !(EnumValue.HasValue || SingleField.HasValue || ListOfFields.Length == 0); + if (EnumValue != null) + return false; + if (SingleField != null) + return false; + if (ListOfFields != null) + return ListOfFields.Length == 0; + + return true; } public Command(ECommandDublicte enumValue) { diff --git a/RDMSharp/Metadata/MetadataBag.cs b/RDMSharp/Metadata/MetadataBag.cs index 46bf348..e43e556 100644 --- a/RDMSharp/Metadata/MetadataBag.cs +++ b/RDMSharp/Metadata/MetadataBag.cs @@ -22,6 +22,8 @@ public MetadataBag(string version, string name, bool isSchema, string content, s } private static string getContent(string path) { + if (string.IsNullOrWhiteSpace(path)) + return null; var assembly = typeof(MetadataFactory).Assembly; using Stream stream = assembly.GetManifestResourceStream(path); using StreamReader reader = new StreamReader(stream); diff --git a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs index 62d2e8a..4745e62 100644 --- a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs +++ b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs @@ -9,6 +9,9 @@ public readonly struct MetadataJSONObjectDefine { [JsonPropertyName("name")] public readonly string Name { get; } + [JsonPropertyName("displayName")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public readonly string? DisplayName { get; } [JsonPropertyName("notes")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public readonly string? Notes { get; } @@ -29,7 +32,7 @@ public readonly struct MetadataJSONObjectDefine [JsonPropertyName("set_request_subdevice_range")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyOrder(15)] - public readonly SubdevicesForRequests[]? SetReequestsSubdeviceRange { get; } + public readonly SubdevicesForRequests[]? SetRequestsSubdeviceRange { get; } [JsonPropertyName("set_response_subdevice_range")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyOrder(17)] @@ -55,13 +58,14 @@ public readonly struct MetadataJSONObjectDefine [JsonConstructor] public MetadataJSONObjectDefine( string name, + string? displayName, string? notes, ushort manufacturerID, ushort pID, ushort version, SubdevicesForRequests[]? getRequestSubdeviceRange, SubdevicesForResponses[]? getResponseSubdeviceRange, - SubdevicesForRequests[]? setReequestsSubdeviceRange, + SubdevicesForRequests[]? setRequestsSubdeviceRange, SubdevicesForResponses[]? setResponseSubdeviceRange, Command? getRequest, Command? getResponse, @@ -69,6 +73,7 @@ public MetadataJSONObjectDefine( Command? setResponse) { Name = name; + DisplayName = displayName; Notes = notes; ManufacturerID = manufacturerID; PID = pID; @@ -76,7 +81,7 @@ public MetadataJSONObjectDefine( GetRequestSubdeviceRange = getRequestSubdeviceRange; GetResponseSubdeviceRange = getResponseSubdeviceRange; - SetReequestsSubdeviceRange = setReequestsSubdeviceRange; + SetRequestsSubdeviceRange = setRequestsSubdeviceRange; SetResponseSubdeviceRange = setResponseSubdeviceRange; GetRequest = getRequest; diff --git a/RDMSharp/Metadata/OneOfTypes/CompoundType.cs b/RDMSharp/Metadata/OneOfTypes/CompoundType.cs index 802c138..072a290 100644 --- a/RDMSharp/Metadata/OneOfTypes/CompoundType.cs +++ b/RDMSharp/Metadata/OneOfTypes/CompoundType.cs @@ -1,5 +1,4 @@ -using Humanizer.Localisation; -using RDMSharp.Metadata.JSON; +using RDMSharp.Metadata.JSON; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.OneOfTypes diff --git a/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs b/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs index 196ea07..66dd454 100644 --- a/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs +++ b/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs @@ -1,5 +1,6 @@ using System; using System.Text.Json.Serialization; +using RDMSharp.Metadata.JSON; using RDMSharp.Metadata.JSON.Converter; namespace RDMSharp.Metadata.OneOfTypes @@ -7,6 +8,7 @@ namespace RDMSharp.Metadata.OneOfTypes [JsonConverter(typeof(OneOfTypesConverter))] public readonly struct OneOfTypes { + public readonly CommonPropertiesForNamed? ObjectType; public readonly BitType? BitType { get; } public readonly BitFieldType? BitFieldType { get; } public readonly BytesType? BytesType { get; } @@ -32,59 +34,73 @@ public readonly struct OneOfTypes public OneOfTypes(BitType bitType) { BitType = bitType; + ObjectType = bitType; } public OneOfTypes(BitFieldType bitFieldType) { BitFieldType = bitFieldType; + ObjectType = bitFieldType; } public OneOfTypes(BytesType bytesType) { BytesType = bytesType; + ObjectType = bytesType; } public OneOfTypes(BooleanType booleanType) { BooleanType = booleanType; + ObjectType = booleanType; } public OneOfTypes(IntegerType integerType_UInt8) { IntegerType_UInt8 = integerType_UInt8; + ObjectType = integerType_UInt8; } public OneOfTypes(IntegerType integerType_Int8) { IntegerType_Int8 = integerType_Int8; + ObjectType = integerType_Int8; } public OneOfTypes(IntegerType integerType_UInt16) { IntegerType_UInt16 = integerType_UInt16; + ObjectType = integerType_UInt16; } public OneOfTypes(IntegerType integerType_Int16) { IntegerType_Int16 = integerType_Int16; + ObjectType = integerType_Int16; } public OneOfTypes(IntegerType integerType_UInt32) { IntegerType_UInt32 = integerType_UInt32; + ObjectType = integerType_UInt32; } public OneOfTypes(IntegerType integerType_Int32) { IntegerType_Int32 = integerType_Int32; + ObjectType = integerType_Int32; } public OneOfTypes(IntegerType integerType_UInt64) { IntegerType_UInt64 = integerType_UInt64; + ObjectType = integerType_UInt64; } public OneOfTypes(IntegerType integerType_Int64) { IntegerType_Int64 = integerType_Int64; + ObjectType = integerType_Int64; } #if NET7_0_OR_GREATER public OneOfTypes(IntegerType integerType_UInt128) { IntegerType_UInt128 = integerType_UInt128; + ObjectType = integerType_UInt128; } public OneOfTypes(IntegerType integerType_Int128) { IntegerType_Int128 = integerType_Int128; + ObjectType = integerType_Int128; } #endif public OneOfTypes(ReferenceType referenceType) @@ -94,75 +110,32 @@ public OneOfTypes(ReferenceType referenceType) public OneOfTypes(StringType stringType) { StringType = stringType; + ObjectType = stringType; } public OneOfTypes(ListType listType) { ListType = listType; + ObjectType = listType; } public OneOfTypes(CompoundType compoundType) { CompoundType = compoundType; + ObjectType = compoundType; } public OneOfTypes(PD_EnvelopeType pdEnvelopeType) { PD_EnvelopeType = pdEnvelopeType; + ObjectType = pdEnvelopeType; } public override string ToString() { - if (BitType != null) - return BitType.ToString(); - - if (BitFieldType != null) - return BitFieldType.ToString(); - - if (BytesType != null) - return BytesType.ToString(); - - if (BooleanType != null) - return BooleanType.ToString(); - - if (IntegerType_UInt8 != null) - return IntegerType_UInt8.ToString(); - if (IntegerType_UInt8 != null) - return IntegerType_UInt8.ToString(); - - if (IntegerType_UInt16 != null) - return IntegerType_UInt16.ToString(); - if (IntegerType_UInt16 != null) - return IntegerType_UInt16.ToString(); - - if (IntegerType_UInt32 != null) - return IntegerType_UInt32.ToString(); - if (IntegerType_UInt32 != null ) - return IntegerType_UInt32.ToString(); - - if (IntegerType_UInt64 != null) - return IntegerType_UInt64.ToString(); - if (IntegerType_UInt64 != null) - return IntegerType_UInt64.ToString(); -#if NET7_0_OR_GREATER - if (IntegerType_UInt128 != null) - return IntegerType_UInt128.ToString(); - if (IntegerType_UInt128 != null) - return IntegerType_UInt128.ToString(); -#endif - + if (ObjectType != null) + return ObjectType.ToString(); + if (ReferenceType != null) return ReferenceType.ToString(); - if (StringType != null) - return StringType.ToString(); - - if (ListType != null) - return ListType.ToString(); - - if (CompoundType != null) - return CompoundType.ToString(); - - if (PD_EnvelopeType != null) - return PD_EnvelopeType.ToString(); - return base.ToString(); } } diff --git a/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs b/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs index 891b3a0..964776e 100644 --- a/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs +++ b/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs @@ -7,7 +7,7 @@ public class PD_EnvelopeType : CommonPropertiesForNamed { [JsonPropertyName("name")] [JsonPropertyOrder(1)] - [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public override string Name { get; } [JsonPropertyName("displayName")] [JsonPropertyOrder(2)] @@ -22,9 +22,14 @@ public class PD_EnvelopeType : CommonPropertiesForNamed [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public override string[]? Resources { get; } - [JsonPropertyName("length")] + [JsonPropertyName("type")] [JsonPropertyOrder(3)] - public byte Length { get; } + public string Type { get; } + + [JsonPropertyName("length")] + [JsonPropertyOrder(6)] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public byte? Length { get; } [JsonConstructor] @@ -32,12 +37,14 @@ public PD_EnvelopeType(string name, string? displayName, string? notes, string[]? resources, - byte length) : base() + string type, + byte? length) : base() { Name = name; DisplayName = displayName; Notes = notes; Resources = resources; + Type = type; Length = length; } diff --git a/RDMSharpTests/MetadataJSONObjectDefineTestSubject.cs b/RDMSharpTests/MetadataJSONObjectDefineTestSubject.cs index e5da7ae..9652aab 100644 --- a/RDMSharpTests/MetadataJSONObjectDefineTestSubject.cs +++ b/RDMSharpTests/MetadataJSONObjectDefineTestSubject.cs @@ -1,11 +1,17 @@ using RDMSharp.Metadata; using System.Collections.Concurrent; +using System.Reflection; namespace RDMSharpTests { public class MetadataJSONObjectDefineTestSubject { public static readonly object[] TestSubjects = getTestSubjects(); + internal static string[] GetResources() + { + var assembly = Assembly.GetExecutingAssembly(); + return assembly.GetManifestResourceNames(); + } private static object[] getTestSubjects() { List instances = new List(); @@ -24,8 +30,28 @@ private static object[] getTestSubjects() } instances.Add(new MetadataJSONObjectDefineTestSubject(schema, new MetadataBag(mv))); } + foreach (var mv in GetResources().Select(r => new MetadataVersion(r))) + { + var _schema = schemaList.First(s => s.Version.Equals(mv.Version)); + if (!versionSchemas.TryGetValue(_schema.Version, out MetadataBag schema)) + { + schema = new MetadataBag(_schema); + versionSchemas.TryAdd(_schema.Version, schema); + } + instances.Add(new MetadataJSONObjectDefineTestSubject(schema, new MetadataBag(mv.Version,mv.Name,mv.IsSchema,getContent(mv.Path),mv.Path))); + } return instances.ToArray(); } + private static string getContent(string path) + { + if (string.IsNullOrWhiteSpace(path)) + return null; + var assembly = typeof(MetadataJSONObjectDefineTestSubject).Assembly; + using Stream stream = assembly.GetManifestResourceStream(path); + using StreamReader reader = new StreamReader(stream); + return reader.ReadToEnd(); + } + public readonly MetadataBag Schema; public readonly MetadataBag Define; diff --git a/RDMSharpTests/MetadataJSONObjectDefineTests.cs b/RDMSharpTests/MetadataJSONObjectDefineTests.cs index 204c878..cd49d61 100644 --- a/RDMSharpTests/MetadataJSONObjectDefineTests.cs +++ b/RDMSharpTests/MetadataJSONObjectDefineTests.cs @@ -3,6 +3,9 @@ using System.Text.Json; using System.Text.Json.Nodes; using Newtonsoft.Json.Linq; +using RDMSharp.Metadata.JSON; +using NUnit.Framework.Internal.Commands; +using RDMSharp.Metadata.OneOfTypes; namespace RDMSharpTests { @@ -28,19 +31,133 @@ public void TestValidateAgainstSchema() [Test] public void TestDeseriaizeAndSerialize() { - MetadataJSONObjectDefine deserialized = JsonSerializer.Deserialize(testSubject.Define.Content); + try + { + MetadataJSONObjectDefine deserialized = JsonSerializer.Deserialize(testSubject.Define.Content); + Assert.That(deserialized.Version, Is.AtLeast(1)); + Assert.That(deserialized.Name, Is.Not.WhiteSpace); + Assert.That(deserialized.Name, Is.Not.Empty); + string serialized = JsonSerializer.Serialize(deserialized); + + var original = JToken.Parse(PrittyJSON(testSubject.Define.Content)); + var smashed = JToken.Parse(PrittyJSON(serialized)); + + Assert.Multiple(() => + { + Assert.That(JToken.DeepEquals(smashed, original)); + + + Warn.Unless(PrittyJSON(serialized), Is.EqualTo(PrittyJSON(testSubject.Define.Content))); + }); + } + catch (JsonException ex) + { +#if !NET7_0_OR_GREATER + Warn.If(ex.Message, Is.EqualTo("Unexpected JSON format Type: int128 for FieldContainer.").Or.EqualTo("Unexpected JSON format Type: uint128 for FieldContainer."), "Due to .NET6 limitations"); + return; +#else + throw; +#endif + } + } + [Test] + public void TestDeseriaizedObject() + { + MetadataJSONObjectDefine deserialized = new MetadataJSONObjectDefine(); + testString(testSubject.Define.ToString()); + try + { + deserialized = JsonSerializer.Deserialize(testSubject.Define.Content); + } + catch (JsonException ex) + { +#if !NET7_0_OR_GREATER + Warn.If(ex.Message, Is.EqualTo("Unexpected JSON format Type: int128 for FieldContainer.").Or.EqualTo("Unexpected JSON format Type: uint128 for FieldContainer."), "Due to .NET6 limitations"); + return; +#else + throw; +#endif + } Assert.That(deserialized.Version, Is.AtLeast(1)); Assert.That(deserialized.Name, Is.Not.WhiteSpace); Assert.That(deserialized.Name, Is.Not.Empty); - string serialized = JsonSerializer.Serialize(deserialized); - var original = JToken.Parse(PrittyJSON(testSubject.Define.Content)); - var smashed = JToken.Parse(PrittyJSON(serialized)); + testString(deserialized.ToString()); - Assert.That(JToken.DeepEquals(smashed, original)); + if (deserialized.GetRequestSubdeviceRange != null) + { + testString(string.Join("; ", deserialized.GetRequestSubdeviceRange.Select(r => r.ToString()))!); + } + if (deserialized.GetResponseSubdeviceRange != null) + { + testString(string.Join("; ", deserialized.GetResponseSubdeviceRange.Select(r => r.ToString()))!); + } + if (deserialized.SetRequestsSubdeviceRange != null) + { + testString(string.Join("; ", deserialized.SetRequestsSubdeviceRange.Select(r => r.ToString()))!); + } + if (deserialized.SetResponseSubdeviceRange != null) + { + testString(string.Join("; ", deserialized.SetResponseSubdeviceRange.Select(r => r.ToString()))!); + } + + if (deserialized.GetRequest != null) + testCommand(deserialized.GetRequest.Value); + + if (deserialized.GetResponse != null) + testCommand(deserialized.GetResponse.Value); + if (deserialized.SetRequest != null) + testCommand(deserialized.SetRequest.Value); - Warn.Unless(PrittyJSON(serialized),Is.EqualTo(PrittyJSON(testSubject.Define.Content))); + if (deserialized.SetResponse != null) + testCommand(deserialized.SetResponse.Value); + + + void testString(string str) + { + Assert.That(str, Is.Not.WhiteSpace); + Assert.That(str, Is.Not.Empty); + Assert.That(str, Does.Not.Contain("{")); + Assert.That(str, Does.Not.Contain("}")); + } + void testCommand(Command command) + { + testString(command.ToString()!); + if(command.EnumValue is Command.ECommandDublicte _enum) + { + Assert.That(command.GetIsEmpty(), Is.False); + testString(_enum.ToString()!); + return; + } + else if (command.SingleField is OneOfTypes singleField) + { + Assert.That(command.GetIsEmpty(), Is.False); + testString(singleField.ToString()!); + if (singleField.ObjectType is CommonPropertiesForNamed common) + testCommon(common); + return; + } + else if (command.ListOfFields is OneOfTypes[] listOfFields) + { + if (listOfFields.Length != 0) + { + Assert.That(command.GetIsEmpty(), Is.False); + testString(string.Join("; ", listOfFields.Select(r => r.ToString()))!); + foreach (var field in listOfFields) + { + if (field.ObjectType is CommonPropertiesForNamed common) + testCommon(common); + } + return; + } + } + Assert.That(command.GetIsEmpty(), Is.True); + } + void testCommon(CommonPropertiesForNamed common) + { + testString(common.ToString()!); + } } private static string PrittyJSON(string jsonString) diff --git a/RDMSharpTests/RDMSharpTests.csproj b/RDMSharpTests/RDMSharpTests.csproj index bcd1ef9..cd260da 100644 --- a/RDMSharpTests/RDMSharpTests.csproj +++ b/RDMSharpTests/RDMSharpTests.csproj @@ -9,7 +9,6 @@ latest False - @@ -23,7 +22,16 @@ - + + + + + + + + + + diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_128BIT_INTEGER_TEST.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_128BIT_INTEGER_TEST.json new file mode 100644 index 0000000..f82be9e --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_128BIT_INTEGER_TEST.json @@ -0,0 +1,18 @@ +{ + "name": "MOCK_128BIT_INTEGER_TEST", + "manufacturer_id": 4365, + "pid": 4874, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "timeout", + "type": "int128" + }, + { + "name": "timeout", + "type": "uint128" + } + ], + "get_response": "get_request" +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_ALL_INTEGER_TEST_EXCEPT_128BIT.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_ALL_INTEGER_TEST_EXCEPT_128BIT.json new file mode 100644 index 0000000..53d5d10 --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_ALL_INTEGER_TEST_EXCEPT_128BIT.json @@ -0,0 +1,42 @@ +{ + "name": "MOCK_ALL_INTEGER_TEST_EXCEPT_128BIT", + "manufacturer_id": 4365, + "pid": 4874, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "timeout", + "type": "int8" + }, + { + "name": "timeout", + "type": "uint8" + }, + { + "name": "timeout", + "type": "int16" + }, + { + "name": "timeout", + "type": "uint16" + }, + { + "name": "timeout", + "type": "int32" + }, + { + "name": "timeout", + "type": "uint32" + }, + { + "name": "timeout", + "type": "int64" + }, + { + "name": "timeout", + "type": "uint64" + } + ], + "get_response": "get_request" +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_DISPLAY_NAME.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_DISPLAY_NAME.json new file mode 100644 index 0000000..e0f8138 --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_DISPLAY_NAME.json @@ -0,0 +1,62 @@ +{ + "name": "MOCK_DISPLAY_NAME", + "displayName": "Mock Display Name", + "manufacturer_id": 4365, + "pid": 4874, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "timeout", + "displayName": "Timeout", + "type": "uint16", + "units": 21, + "prefixPower": 0, + "labels": [ + { + "name": "Disabled", + "displayName": "Disabled Label", + "value": 0 + } + ] + }, + { + "name": "label", + "displayName": "Label", + "type": "string", + "maxLength": 32, + "restrictToASCII": true + }, + { + "name": "status", + "displayName": "Status", + "type": "boolean" + }, + { + "name": "slots", + "displayName": "Slots", + "type": "list", + "itemType": { + "displayName": "Compound", + "type": "compound", + "subtypes": [ + { + "name": "id", + "type": "uint16" + }, + { + "name": "type", + "type": "uint8" + }, + { + "name": "label_id", + "type": "uint16" + } + ] + }, + "minItems": 2, + "maxItems": 6 + } + ], + "get_response": "get_request" +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_PD_ENVELOPED.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_PD_ENVELOPED.json new file mode 100644 index 0000000..82da703 --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_PD_ENVELOPED.json @@ -0,0 +1,25 @@ +{ + "name": "MOCK_PD_ENVELOPED", + "manufacturer_id": 4365, + "pid": 4874, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "timeout", + "displayName": "Timeout", + "type": "pdEnvelope", + "length": 21 + }, + { + "name": "subdevice_entry", + "type": "pdEnvelope" + }, + { + "name": "entries", + "type": "list", + "itemType": { "type": "pdEnvelope" } + } + ], + "get_response": "get_request" +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_SINGLE_FIELD.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_SINGLE_FIELD.json new file mode 100644 index 0000000..8db8e8f --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_SINGLE_FIELD.json @@ -0,0 +1,20 @@ +{ + "name": "MOCK_SINGLE_FIELD", + "manufacturer_id": 4365, + "pid": 4874, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": { + "name": "timeout", + "type": "uint16", + "units": 21, + "prefixPower": 0, + "labels": [ + { + "name": "Disabled", + "value": 0 + } + ] + }, + "get_response": "get_request" +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_SUBDEVICE_TYPES.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_SUBDEVICE_TYPES.json new file mode 100644 index 0000000..61fc0ab --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_SUBDEVICE_TYPES.json @@ -0,0 +1,35 @@ +{ + "name": "MOCK_SUBDEVICE_TYPES", + "manufacturer_id": 3456, + "pid": 5678, + "version": 1, + "get_request_subdevice_range": [ + "root", + "subdevices", + 1, + 2, + 3, + 4, + 5, + { + "minimum": 70, + "maximum": 200 + } + ], + "get_request": [], + "get_response_subdevice_range": [ + "root", + "subdevices", + 45, + 75, + 86, + 99, + 23, + { + "minimum": 56, + "maximum": 79 + }, + 256 + ], + "get_response": [] +} \ No newline at end of file diff --git a/RDMSharpTests/TestJSONDefines.cs b/RDMSharpTests/TestJSONDefines.cs index 7c2d79f..b7a2200 100644 --- a/RDMSharpTests/TestJSONDefines.cs +++ b/RDMSharpTests/TestJSONDefines.cs @@ -21,7 +21,16 @@ public void TestMetadataFactory() var schemas = MetadataFactory.GetMetadataSchemaVersions(); Assert.That(schemas, Has.Count.EqualTo(1)); var defines = MetadataFactory.GetMetadataDefineVersions(); - Assert.That(defines, Has.Count.EqualTo(129)); + Assert.That(defines, Has.Count.EqualTo(122)); + foreach (var define in defines) + testString(define.ToString()); + } + void testString(string str) + { + Assert.That(str, Is.Not.WhiteSpace); + Assert.That(str, Is.Not.Empty); + Assert.That(str, Does.Not.Contain("{")); + Assert.That(str, Does.Not.Contain("}")); } } } \ No newline at end of file From 081c37643bf6a3bba66d56c77c5eb9cfebcec1dc Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Tue, 17 Sep 2024 21:52:09 +0200 Subject: [PATCH 12/51] More optimizations --- .../JSON/Converter/CommandConverter.cs | 6 +++- RDMSharp/Metadata/OneOfTypes/CompoundType.cs | 5 --- RDMSharp/Metadata/OneOfTypes/IntegerType.cs | 21 ----------- .../Metadata/OneOfTypes/PD_EnvelopeType.cs | 8 ++--- RDMSharp/Metadata/OneOfTypes/Range.cs | 25 +++++++++++++ .../MetadataJSONObjectDefineTests.cs | 35 +++++++++++++++++-- 6 files changed, 66 insertions(+), 34 deletions(-) create mode 100644 RDMSharp/Metadata/OneOfTypes/Range.cs diff --git a/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs b/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs index 6928b28..c1dbd25 100644 --- a/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs @@ -22,6 +22,8 @@ public override Command Read(ref Utf8JsonReader reader, Type typeToConvert, Json else if (reader.TokenType == JsonTokenType.StartArray) { var listOfFields = JsonSerializer.Deserialize(ref reader, options); + if (listOfFields.Length == 0) + return new Command(); return new Command(listOfFields); } @@ -30,7 +32,9 @@ public override Command Read(ref Utf8JsonReader reader, Type typeToConvert, Json public override void Write(Utf8JsonWriter writer, Command value, JsonSerializerOptions options) { - if (value.EnumValue.HasValue) + if (value.GetIsEmpty()) + JsonSerializer.Serialize(writer, new object[0], options); + else if (value.EnumValue.HasValue) JsonSerializer.Serialize(writer, value.EnumValue.Value, options); else if (value.SingleField != null) JsonSerializer.Serialize(writer, value.SingleField.Value, options); diff --git a/RDMSharp/Metadata/OneOfTypes/CompoundType.cs b/RDMSharp/Metadata/OneOfTypes/CompoundType.cs index 072a290..32c6dad 100644 --- a/RDMSharp/Metadata/OneOfTypes/CompoundType.cs +++ b/RDMSharp/Metadata/OneOfTypes/CompoundType.cs @@ -45,10 +45,5 @@ public CompoundType(string name, Type = type; Subtypes = subtypes; } - - public override string ToString() - { - return $"{Name}"; - } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/OneOfTypes/IntegerType.cs index bbfcd0f..b7c4191 100644 --- a/RDMSharp/Metadata/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/OneOfTypes/IntegerType.cs @@ -111,25 +111,4 @@ public override string ToString() return $"{Name} {Type}"; } } - - public readonly struct Range - { - [JsonPropertyName("minimum")] - public readonly T Minimum { get; } - - [JsonPropertyName("maximum")] - public readonly T Maximum { get; } - - [JsonConstructor] - public Range(T minimum, T maximum) - { - Minimum = minimum; - Maximum = maximum; - } - - public override string ToString() - { - return $"Range: {Minimum:X4} - {Maximum:X4}"; - } - } } diff --git a/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs b/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs index 964776e..7d9ccaf 100644 --- a/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs +++ b/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs @@ -50,10 +50,10 @@ public PD_EnvelopeType(string name, public override string ToString() { - if (string.IsNullOrWhiteSpace(Name)) - return $"PDL: {Length} ({Length:X2})"; - - return $"PDL: {Length} ({Length:X2}) {base.ToString()}"; + if (Length.HasValue) + return $"PDL: {Length} ({Length:X2}) {base.ToString()}".Trim(); + + return base.ToString(); } } } diff --git a/RDMSharp/Metadata/OneOfTypes/Range.cs b/RDMSharp/Metadata/OneOfTypes/Range.cs new file mode 100644 index 0000000..8eab275 --- /dev/null +++ b/RDMSharp/Metadata/OneOfTypes/Range.cs @@ -0,0 +1,25 @@ +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.OneOfTypes +{ + public readonly struct Range + { + [JsonPropertyName("minimum")] + public readonly T Minimum { get; } + + [JsonPropertyName("maximum")] + public readonly T Maximum { get; } + + [JsonConstructor] + public Range(T minimum, T maximum) + { + Minimum = minimum; + Maximum = maximum; + } + + public override string ToString() + { + return $"Range: {Minimum:X4} - {Maximum:X4}"; + } + } +} diff --git a/RDMSharpTests/MetadataJSONObjectDefineTests.cs b/RDMSharpTests/MetadataJSONObjectDefineTests.cs index cd49d61..f54f839 100644 --- a/RDMSharpTests/MetadataJSONObjectDefineTests.cs +++ b/RDMSharpTests/MetadataJSONObjectDefineTests.cs @@ -114,14 +114,14 @@ public void TestDeseriaizedObject() testCommand(deserialized.SetResponse.Value); - void testString(string str) + static void testString(string str) { Assert.That(str, Is.Not.WhiteSpace); Assert.That(str, Is.Not.Empty); Assert.That(str, Does.Not.Contain("{")); Assert.That(str, Does.Not.Contain("}")); } - void testCommand(Command command) + static void testCommand(Command command) { testString(command.ToString()!); if(command.EnumValue is Command.ECommandDublicte _enum) @@ -154,9 +154,38 @@ void testCommand(Command command) } Assert.That(command.GetIsEmpty(), Is.True); } - void testCommon(CommonPropertiesForNamed common) + static void testCommon(CommonPropertiesForNamed common) { testString(common.ToString()!); + if (common is IntegerType integerByte) + testIntegerType(integerByte); + else if (common is IntegerType integerSByte) + testIntegerType(integerSByte); + else if (common is IntegerType integerShort) + testIntegerType(integerShort); + else if (common is IntegerType integerUShort) + testIntegerType(integerUShort); + else if (common is IntegerType integerInt) + testIntegerType(integerInt); + else if (common is IntegerType integerUInt) + testIntegerType(integerUInt); + else if (common is IntegerType integerLong) + testIntegerType(integerLong); + else if (common is IntegerType integerULong) + testIntegerType(integerULong); +#if NET7_0_OR_GREATER + else if (common is IntegerType integerInt128) + testIntegerType(integerInt128); + else if (common is IntegerType integerUInt128) + testIntegerType(integerUInt128); +#endif + } + static void testIntegerType(IntegerType integerType) + { + testString(integerType.ToString()!); + if (integerType.Ranges != null) + foreach (Range range in integerType.Ranges) + testString(range.ToString()!); } } From ed6d313336e762b7dd9f23c9a2774907b19ea22e Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 18 Sep 2024 20:59:30 +0200 Subject: [PATCH 13/51] More tests and optimizations --- RDMSharp/Metadata/JSON/Command.cs | 2 +- .../JSON/Converter/CommandConverter.cs | 2 +- .../JSON/Converter/CustomEnumConverter.cs | 2 +- .../JSON/Converter/OneOfTypesConverter.cs | 15 +---- .../SubdevicesForRequestsConverter.cs | 9 +-- .../SubdevicesForResponsesConverter.cs | 9 +-- .../{ => JSON}/OneOfTypes/BitFieldType.cs | 12 ++-- .../Metadata/{ => JSON}/OneOfTypes/BitType.cs | 16 ++--- .../{ => JSON}/OneOfTypes/BooleanType.cs | 16 ++--- .../{ => JSON}/OneOfTypes/BytesType.cs | 16 ++--- .../{ => JSON}/OneOfTypes/CompoundType.cs | 12 ++-- .../{ => JSON}/OneOfTypes/IntegerType.cs | 22 +++---- .../OneOfTypes/LabeledBooleanType.cs | 14 ++-- .../OneOfTypes/LabeledIntegerType.cs | 12 ++-- .../{ => JSON}/OneOfTypes/ListType.cs | 14 ++-- .../{ => JSON}/OneOfTypes/OneOfTypes.cs | 64 ++++++++----------- .../{ => JSON}/OneOfTypes/PD_EnvelopeType.cs | 14 ++-- .../Metadata/{ => JSON}/OneOfTypes/Range.cs | 2 +- .../{ => JSON}/OneOfTypes/ReferenceType.cs | 7 +- .../{ => JSON}/OneOfTypes/StringType.cs | 20 +++--- RDMSharp/Metadata/JSON/SubdeviceType.cs | 6 +- .../Metadata/JSON/SubdevicesForRequests.cs | 6 +- .../Metadata/JSON/SubdevicesForResponses.cs | 6 +- RDMSharp/Metadata/MetadataBag.cs | 11 +++- RDMSharp/Metadata/MetadataFactory.cs | 6 +- RDMSharp/Metadata/MetadataVersion.cs | 37 +++++++---- .../MetadataJSONObjectDefineTests.cs | 22 ++++++- RDMSharpTests/RDMSharpTests.csproj | 6 ++ .../Mocks/MOCK_INVALID_COMMAND_NUMBER.json | 9 +++ .../Defines/Mocks/MOCK_INVALID_ENUM.json | 9 +++ .../Mocks/MOCK_INVALID_ONEOF_TYPE.json | 14 ++++ .../MOCK_INVALID_SUBDEVICE_TYPE_REQUEST.json | 9 +++ .../MOCK_INVALID_SUBDEVICE_TYPE_RESPONSE.json | 10 +++ .../Defines/Mocks/MOCK_REFERENCE_TYPE.json | 42 ++++++++++++ RDMSharpTests/TestJSONDefines.cs | 36 ----------- RDMSharpTests/TestMetadataFactoryStuff.cs | 63 ++++++++++++++++++ 36 files changed, 340 insertions(+), 232 deletions(-) rename RDMSharp/Metadata/{ => JSON}/OneOfTypes/BitFieldType.cs (88%) rename RDMSharp/Metadata/{ => JSON}/OneOfTypes/BitType.cs (85%) rename RDMSharp/Metadata/{ => JSON}/OneOfTypes/BooleanType.cs (79%) rename RDMSharp/Metadata/{ => JSON}/OneOfTypes/BytesType.cs (84%) rename RDMSharp/Metadata/{ => JSON}/OneOfTypes/CompoundType.cs (83%) rename RDMSharp/Metadata/{ => JSON}/OneOfTypes/IntegerType.cs (86%) rename RDMSharp/Metadata/{ => JSON}/OneOfTypes/LabeledBooleanType.cs (77%) rename RDMSharp/Metadata/{ => JSON}/OneOfTypes/LabeledIntegerType.cs (81%) rename RDMSharp/Metadata/{ => JSON}/OneOfTypes/ListType.cs (86%) rename RDMSharp/Metadata/{ => JSON}/OneOfTypes/OneOfTypes.cs (60%) rename RDMSharp/Metadata/{ => JSON}/OneOfTypes/PD_EnvelopeType.cs (84%) rename RDMSharp/Metadata/{ => JSON}/OneOfTypes/Range.cs (92%) rename RDMSharp/Metadata/{ => JSON}/OneOfTypes/ReferenceType.cs (84%) rename RDMSharp/Metadata/{ => JSON}/OneOfTypes/StringType.cs (87%) create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_COMMAND_NUMBER.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_ENUM.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_ONEOF_TYPE.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_SUBDEVICE_TYPE_REQUEST.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_SUBDEVICE_TYPE_RESPONSE.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_REFERENCE_TYPE.json delete mode 100644 RDMSharpTests/TestJSONDefines.cs create mode 100644 RDMSharpTests/TestMetadataFactoryStuff.cs diff --git a/RDMSharp/Metadata/JSON/Command.cs b/RDMSharp/Metadata/JSON/Command.cs index 4728c2c..3611e26 100644 --- a/RDMSharp/Metadata/JSON/Command.cs +++ b/RDMSharp/Metadata/JSON/Command.cs @@ -1,7 +1,7 @@ using System.Linq; using System.Text.Json.Serialization; using RDMSharp.Metadata.JSON.Converter; -using OneOf= RDMSharp.Metadata.OneOfTypes.OneOfTypes; +using OneOf = RDMSharp.Metadata.JSON.OneOfTypes.OneOfTypes; namespace RDMSharp.Metadata.JSON { diff --git a/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs b/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs index c1dbd25..89eaeb8 100644 --- a/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/CommandConverter.cs @@ -1,7 +1,7 @@ using System.Text.Json; using System; using System.Text.Json.Serialization; -using OneOf = RDMSharp.Metadata.OneOfTypes.OneOfTypes; +using OneOf = RDMSharp.Metadata.JSON.OneOfTypes.OneOfTypes; namespace RDMSharp.Metadata.JSON.Converter { diff --git a/RDMSharp/Metadata/JSON/Converter/CustomEnumConverter.cs b/RDMSharp/Metadata/JSON/Converter/CustomEnumConverter.cs index 77b887f..e18aa8c 100644 --- a/RDMSharp/Metadata/JSON/Converter/CustomEnumConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/CustomEnumConverter.cs @@ -27,7 +27,7 @@ public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions var field = typeof(T).GetField(value.ToString()); var attribute = field.GetCustomAttribute(); - string enumString = attribute?.Name ?? value.ToString(); + string enumString = attribute.Name; writer.WriteStringValue(enumString); } diff --git a/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs index 7bf57bb..dd080c6 100644 --- a/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs @@ -1,8 +1,8 @@ -using RDMSharp.Metadata.OneOfTypes; +using RDMSharp.Metadata.JSON.OneOfTypes; using System; using System.Text.Json; using System.Text.Json.Serialization; -using OneOf = RDMSharp.Metadata.OneOfTypes.OneOfTypes; +using OneOf = RDMSharp.Metadata.JSON.OneOfTypes.OneOfTypes; namespace RDMSharp.Metadata.JSON.Converter { @@ -24,10 +24,6 @@ public override OneOf Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSe string type= typeProperty.GetString(); switch (type) { - case "bit": - var bitType = element.Deserialize(options); - return new OneOf(bitType); - case "bitField": var bitFieldType = element.Deserialize(options); return new OneOf(bitFieldType); @@ -104,10 +100,7 @@ public override OneOf Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSe public override void Write(Utf8JsonWriter writer, OneOf value, JsonSerializerOptions options) { - if (value.BitType != null) - JsonSerializer.Serialize(writer, value.BitType, options); - - else if (value.BitFieldType != null) + if (value.BitFieldType != null) JsonSerializer.Serialize(writer, value.BitFieldType, options); else if (value.BooleanType != null) @@ -155,8 +148,6 @@ public override void Write(Utf8JsonWriter writer, OneOf value, JsonSerializerOpt else if (value.PD_EnvelopeType != null) JsonSerializer.Serialize(writer, value.PD_EnvelopeType, options); - else - throw new NotImplementedException(); } } } diff --git a/RDMSharp/Metadata/JSON/Converter/SubdevicesForRequestsConverter.cs b/RDMSharp/Metadata/JSON/Converter/SubdevicesForRequestsConverter.cs index 5ae514b..306ef97 100644 --- a/RDMSharp/Metadata/JSON/Converter/SubdevicesForRequestsConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/SubdevicesForRequestsConverter.cs @@ -13,13 +13,8 @@ public override SubdevicesForRequests Read(ref Utf8JsonReader reader, Type typeT var enumValue = JsonSerializer.Deserialize(ref reader, options); return new SubdevicesForRequests(enumValue); } - else if (reader.TokenType == JsonTokenType.StartObject || reader.TokenType == JsonTokenType.Number) - { - var objectValue = JsonSerializer.Deserialize(ref reader, options); - return new SubdevicesForRequests(objectValue); - } - - throw new JsonException("Unexpected JSON format for FieldContainer."); + var objectValue = JsonSerializer.Deserialize(ref reader, options); + return new SubdevicesForRequests(objectValue); } public override void Write(Utf8JsonWriter writer, SubdevicesForRequests value, JsonSerializerOptions options) diff --git a/RDMSharp/Metadata/JSON/Converter/SubdevicesForResponsesConverter.cs b/RDMSharp/Metadata/JSON/Converter/SubdevicesForResponsesConverter.cs index d0d36b7..114bf17 100644 --- a/RDMSharp/Metadata/JSON/Converter/SubdevicesForResponsesConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/SubdevicesForResponsesConverter.cs @@ -13,13 +13,8 @@ public override SubdevicesForResponses Read(ref Utf8JsonReader reader, Type type var enumValue = JsonSerializer.Deserialize(ref reader, options); return new SubdevicesForResponses(enumValue); } - else if (reader.TokenType == JsonTokenType.StartObject || reader.TokenType == JsonTokenType.Number) - { - var objectValue = JsonSerializer.Deserialize(ref reader, options); - return new SubdevicesForResponses(objectValue); - } - - throw new JsonException("Unexpected JSON format for FieldContainer."); + var objectValue = JsonSerializer.Deserialize(ref reader, options); + return new SubdevicesForResponses(objectValue); } public override void Write(Utf8JsonWriter writer, SubdevicesForResponses value, JsonSerializerOptions options) diff --git a/RDMSharp/Metadata/OneOfTypes/BitFieldType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs similarity index 88% rename from RDMSharp/Metadata/OneOfTypes/BitFieldType.cs rename to RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs index 61d5c76..432e503 100644 --- a/RDMSharp/Metadata/OneOfTypes/BitFieldType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs @@ -2,15 +2,15 @@ using System.Linq; using System.Text.Json.Serialization; -namespace RDMSharp.Metadata.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes { public class BitFieldType : CommonPropertiesForNamed { [JsonConstructor] public BitFieldType(string name, - string? displayName, - string? notes, - string[]? resources, + string displayName, + string notes, + string[] resources, string type, ushort size, bool? valueForUnspecified, @@ -37,11 +37,11 @@ public BitFieldType(string name, [JsonPropertyName("notes")] [JsonPropertyOrder(4)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string? Notes { get; } + public override string Notes { get; } [JsonPropertyName("resources")] [JsonPropertyOrder(5)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string[]? Resources { get; } + public override string[] Resources { get; } [JsonPropertyName("type")] [JsonPropertyOrder(3)] diff --git a/RDMSharp/Metadata/OneOfTypes/BitType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs similarity index 85% rename from RDMSharp/Metadata/OneOfTypes/BitType.cs rename to RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs index 7e69584..292a194 100644 --- a/RDMSharp/Metadata/OneOfTypes/BitType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs @@ -1,16 +1,16 @@ using RDMSharp.Metadata.JSON; using System.Text.Json.Serialization; -namespace RDMSharp.Metadata.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes { public class BitType : CommonPropertiesForNamed { [JsonConstructor] public BitType(string name, - string? displayName, - string? notes, - string[]? resources, - string? type, + string displayName, + string notes, + string[] resources, + string type, ushort index, bool? reserved, bool? valueIfReserved) : base() @@ -36,16 +36,16 @@ public BitType(string name, [JsonPropertyName("notes")] [JsonPropertyOrder(4)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string? Notes { get; } + public override string Notes { get; } [JsonPropertyName("resources")] [JsonPropertyOrder(5)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string[]? Resources { get; } + public override string[] Resources { get; } [JsonPropertyName("type")] [JsonPropertyOrder(3)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? Type { get; } + public string Type { get; } [JsonPropertyName("index")] [JsonPropertyOrder(21)] public ushort Index { get; } diff --git a/RDMSharp/Metadata/OneOfTypes/BooleanType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs similarity index 79% rename from RDMSharp/Metadata/OneOfTypes/BooleanType.cs rename to RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs index 6850dbc..011f954 100644 --- a/RDMSharp/Metadata/OneOfTypes/BooleanType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs @@ -2,7 +2,7 @@ using System.Linq; using System.Text.Json.Serialization; -namespace RDMSharp.Metadata.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes { public class BooleanType : CommonPropertiesForNamed { @@ -17,11 +17,11 @@ public class BooleanType : CommonPropertiesForNamed [JsonPropertyName("notes")] [JsonPropertyOrder(4)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string? Notes { get; } + public override string Notes { get; } [JsonPropertyName("resources")] [JsonPropertyOrder(5)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string[]? Resources { get; } + public override string[] Resources { get; } [JsonPropertyName("type")] [JsonPropertyOrder(3)] @@ -29,16 +29,16 @@ public class BooleanType : CommonPropertiesForNamed [JsonPropertyName("labels")] [JsonPropertyOrder(5)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public LabeledBooleanType[]? Labels { get; } + public LabeledBooleanType[] Labels { get; } [JsonConstructor] public BooleanType(string name, - string? displayName, - string? notes, - string[]? resources, + string displayName, + string notes, + string[] resources, string type, - LabeledBooleanType[]? labels) : base() + LabeledBooleanType[] labels) : base() { Name = name; DisplayName = displayName; diff --git a/RDMSharp/Metadata/OneOfTypes/BytesType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs similarity index 84% rename from RDMSharp/Metadata/OneOfTypes/BytesType.cs rename to RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs index 65d4b11..105c9c6 100644 --- a/RDMSharp/Metadata/OneOfTypes/BytesType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs @@ -1,7 +1,7 @@ using RDMSharp.Metadata.JSON; using System.Text.Json.Serialization; -namespace RDMSharp.Metadata.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes { public class BytesType : CommonPropertiesForNamed { @@ -16,11 +16,11 @@ public class BytesType : CommonPropertiesForNamed [JsonPropertyName("notes")] [JsonPropertyOrder(4)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string? Notes { get; } + public override string Notes { get; } [JsonPropertyName("resources")] [JsonPropertyOrder(5)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string[]? Resources { get; } + public override string[] Resources { get; } [JsonPropertyName("type")] [JsonPropertyOrder(3)] @@ -28,7 +28,7 @@ public class BytesType : CommonPropertiesForNamed [JsonPropertyName("format")] [JsonPropertyOrder(11)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? Format { get; } + public string Format { get; } [JsonPropertyName("minLength")] [JsonPropertyOrder(12)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] @@ -41,11 +41,11 @@ public class BytesType : CommonPropertiesForNamed [JsonConstructor] public BytesType(string name, - string? displayName, - string? notes, - string[]? resources, + string displayName, + string notes, + string[] resources, string type, - string? format, + string format, ulong? minLength, ulong? maxLength) : base() { diff --git a/RDMSharp/Metadata/OneOfTypes/CompoundType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs similarity index 83% rename from RDMSharp/Metadata/OneOfTypes/CompoundType.cs rename to RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs index 32c6dad..88ab4a9 100644 --- a/RDMSharp/Metadata/OneOfTypes/CompoundType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs @@ -1,7 +1,7 @@ using RDMSharp.Metadata.JSON; using System.Text.Json.Serialization; -namespace RDMSharp.Metadata.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes { public class CompoundType : CommonPropertiesForNamed { @@ -16,11 +16,11 @@ public class CompoundType : CommonPropertiesForNamed [JsonPropertyName("notes")] [JsonPropertyOrder(4)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string? Notes { get; } + public override string Notes { get; } [JsonPropertyName("resources")] [JsonPropertyOrder(5)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string[]? Resources { get; } + public override string[] Resources { get; } [JsonPropertyName("type")] [JsonPropertyOrder(3)] @@ -32,9 +32,9 @@ public class CompoundType : CommonPropertiesForNamed [JsonConstructor] public CompoundType(string name, - string? displayName, - string? notes, - string[]? resources, + string displayName, + string notes, + string[] resources, string type, OneOfTypes[] subtypes) { diff --git a/RDMSharp/Metadata/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs similarity index 86% rename from RDMSharp/Metadata/OneOfTypes/IntegerType.cs rename to RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs index b7c4191..be43e41 100644 --- a/RDMSharp/Metadata/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text.Json.Serialization; -namespace RDMSharp.Metadata.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes { [JsonConverter(typeof(CustomEnumConverter))] public enum EIntegerType @@ -30,7 +30,7 @@ public enum EIntegerType [JsonPropertyName("uint128")] UInt128 } - public class IntegerType: CommonPropertiesForNamed + public class IntegerType : CommonPropertiesForNamed { [JsonPropertyName("name")] [JsonPropertyOrder(1)] @@ -43,11 +43,11 @@ public class IntegerType: CommonPropertiesForNamed [JsonPropertyName("notes")] [JsonPropertyOrder(4)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string? Notes { get; } + public override string Notes { get; } [JsonPropertyName("resources")] [JsonPropertyOrder(5)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string[]? Resources { get; } + public override string[] Resources { get; } [JsonPropertyName("type")] [JsonPropertyOrder(3)] @@ -55,7 +55,7 @@ public class IntegerType: CommonPropertiesForNamed [JsonPropertyName("labels")] [JsonPropertyOrder(31)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public LabeledIntegerType[]? Labels { get; } + public LabeledIntegerType[] Labels { get; } [JsonPropertyName("restrictToLabeled")] [JsonPropertyOrder(32)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] @@ -63,7 +63,7 @@ public class IntegerType: CommonPropertiesForNamed [JsonPropertyName("ranges")] [JsonPropertyOrder(11)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public Range[]? Ranges { get; } + public Range[] Ranges { get; } [JsonPropertyName("units")] [JsonPropertyOrder(21)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] @@ -79,13 +79,13 @@ public class IntegerType: CommonPropertiesForNamed [JsonConstructor] public IntegerType(string name, - string? displayName, - string? notes, - string[]? resources, + string displayName, + string notes, + string[] resources, EIntegerType type, - LabeledIntegerType[]? labels, + LabeledIntegerType[] labels, bool? restrictToLabeled, - Range[]? ranges, + Range[] ranges, ERDM_SensorUnit? units, int? prefixPower, int? prefixBase) : base() diff --git a/RDMSharp/Metadata/OneOfTypes/LabeledBooleanType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs similarity index 77% rename from RDMSharp/Metadata/OneOfTypes/LabeledBooleanType.cs rename to RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs index e367f4d..d7f9d7d 100644 --- a/RDMSharp/Metadata/OneOfTypes/LabeledBooleanType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs @@ -1,7 +1,7 @@ using RDMSharp.Metadata.JSON; using System.Text.Json.Serialization; -namespace RDMSharp.Metadata.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes { public class LabeledBooleanType : CommonPropertiesForNamed { @@ -16,11 +16,11 @@ public class LabeledBooleanType : CommonPropertiesForNamed [JsonPropertyName("notes")] [JsonPropertyOrder(4)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string? Notes { get; } + public override string Notes { get; } [JsonPropertyName("resources")] [JsonPropertyOrder(5)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string[]? Resources { get; } + public override string[] Resources { get; } [JsonPropertyName("value")] [JsonPropertyOrder(3)] @@ -28,10 +28,10 @@ public class LabeledBooleanType : CommonPropertiesForNamed [JsonConstructor] public LabeledBooleanType(string name, - string? displayName, - string? notes, - string[]? resources, - bool value) :base() + string displayName, + string notes, + string[] resources, + bool value) : base() { Name = name; DisplayName = displayName; diff --git a/RDMSharp/Metadata/OneOfTypes/LabeledIntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs similarity index 81% rename from RDMSharp/Metadata/OneOfTypes/LabeledIntegerType.cs rename to RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs index f1e0d5b..2e45d06 100644 --- a/RDMSharp/Metadata/OneOfTypes/LabeledIntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs @@ -1,7 +1,7 @@ using RDMSharp.Metadata.JSON; using System.Text.Json.Serialization; -namespace RDMSharp.Metadata.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes { public class LabeledIntegerType : CommonPropertiesForNamed { @@ -16,11 +16,11 @@ public class LabeledIntegerType : CommonPropertiesForNamed [JsonPropertyName("notes")] [JsonPropertyOrder(4)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string? Notes { get; } + public override string Notes { get; } [JsonPropertyName("resources")] [JsonPropertyOrder(5)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string[]? Resources { get; } + public override string[] Resources { get; } [JsonPropertyName("value")] [JsonPropertyOrder(3)] @@ -28,9 +28,9 @@ public class LabeledIntegerType : CommonPropertiesForNamed [JsonConstructor] public LabeledIntegerType(string name, - string? displayName, - string? notes, - string[]? resources, + string displayName, + string notes, + string[] resources, long value) : base() { Name = name; diff --git a/RDMSharp/Metadata/OneOfTypes/ListType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs similarity index 86% rename from RDMSharp/Metadata/OneOfTypes/ListType.cs rename to RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs index 55ed42f..0129bc7 100644 --- a/RDMSharp/Metadata/OneOfTypes/ListType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs @@ -1,7 +1,7 @@ using RDMSharp.Metadata.JSON; using System.Text.Json.Serialization; -namespace RDMSharp.Metadata.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes { public class ListType : CommonPropertiesForNamed { @@ -16,11 +16,11 @@ public class ListType : CommonPropertiesForNamed [JsonPropertyName("notes")] [JsonPropertyOrder(4)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string? Notes { get; } + public override string Notes { get; } [JsonPropertyName("resources")] [JsonPropertyOrder(5)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string[]? Resources { get; } + public override string[] Resources { get; } [JsonPropertyName("type")] [JsonPropertyOrder(3)] @@ -40,9 +40,9 @@ public class ListType : CommonPropertiesForNamed [JsonConstructor] public ListType(string name, - string? displayName, - string? notes, - string[]? resources, + string displayName, + string notes, + string[] resources, string type, OneOfTypes itemType, int? minItems, @@ -60,7 +60,7 @@ public ListType(string name, public override string ToString() { - return $"{Name}"; + return DisplayName ?? Name; } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs similarity index 60% rename from RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs rename to RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs index 66dd454..b4416ad 100644 --- a/RDMSharp/Metadata/OneOfTypes/OneOfTypes.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs @@ -3,39 +3,33 @@ using RDMSharp.Metadata.JSON; using RDMSharp.Metadata.JSON.Converter; -namespace RDMSharp.Metadata.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes { [JsonConverter(typeof(OneOfTypesConverter))] public readonly struct OneOfTypes { - public readonly CommonPropertiesForNamed? ObjectType; - public readonly BitType? BitType { get; } - public readonly BitFieldType? BitFieldType { get; } - public readonly BytesType? BytesType { get; } - public readonly BooleanType? BooleanType { get; } - public readonly IntegerType? IntegerType_UInt8 { get; } - public readonly IntegerType? IntegerType_Int8 { get; } - public readonly IntegerType? IntegerType_UInt16 { get; } - public readonly IntegerType? IntegerType_Int16 { get; } - public readonly IntegerType? IntegerType_UInt32 { get; } - public readonly IntegerType? IntegerType_Int32 { get; } - public readonly IntegerType? IntegerType_UInt64 { get; } - public readonly IntegerType? IntegerType_Int64 { get; } + public readonly CommonPropertiesForNamed ObjectType; + public readonly BitFieldType BitFieldType { get; } + public readonly BytesType BytesType { get; } + public readonly BooleanType BooleanType { get; } + public readonly IntegerType IntegerType_UInt8 { get; } + public readonly IntegerType IntegerType_Int8 { get; } + public readonly IntegerType IntegerType_UInt16 { get; } + public readonly IntegerType IntegerType_Int16 { get; } + public readonly IntegerType IntegerType_UInt32 { get; } + public readonly IntegerType IntegerType_Int32 { get; } + public readonly IntegerType IntegerType_UInt64 { get; } + public readonly IntegerType IntegerType_Int64 { get; } #if NET7_0_OR_GREATER - public readonly IntegerType? IntegerType_UInt128 { get; } - public readonly IntegerType? IntegerType_Int128 { get; } + public readonly IntegerType IntegerType_UInt128 { get; } + public readonly IntegerType IntegerType_Int128 { get; } #endif public readonly ReferenceType? ReferenceType { get; } - public readonly ListType? ListType { get; } - public readonly CompoundType? CompoundType { get; } - public readonly StringType? StringType { get; } - public readonly PD_EnvelopeType? PD_EnvelopeType { get; } + public readonly ListType ListType { get; } + public readonly CompoundType CompoundType { get; } + public readonly StringType StringType { get; } + public readonly PD_EnvelopeType PD_EnvelopeType { get; } - public OneOfTypes(BitType bitType) - { - BitType = bitType; - ObjectType = bitType; - } public OneOfTypes(BitFieldType bitFieldType) { BitFieldType = bitFieldType; @@ -61,32 +55,32 @@ public OneOfTypes(IntegerType integerType_Int8) IntegerType_Int8 = integerType_Int8; ObjectType = integerType_Int8; } - public OneOfTypes(IntegerType integerType_UInt16) + public OneOfTypes(IntegerType integerType_UInt16) { IntegerType_UInt16 = integerType_UInt16; ObjectType = integerType_UInt16; } - public OneOfTypes(IntegerType integerType_Int16) + public OneOfTypes(IntegerType integerType_Int16) { IntegerType_Int16 = integerType_Int16; ObjectType = integerType_Int16; } - public OneOfTypes(IntegerType integerType_UInt32) + public OneOfTypes(IntegerType integerType_UInt32) { IntegerType_UInt32 = integerType_UInt32; ObjectType = integerType_UInt32; } - public OneOfTypes(IntegerType integerType_Int32) + public OneOfTypes(IntegerType integerType_Int32) { IntegerType_Int32 = integerType_Int32; ObjectType = integerType_Int32; } - public OneOfTypes(IntegerType integerType_UInt64) + public OneOfTypes(IntegerType integerType_UInt64) { IntegerType_UInt64 = integerType_UInt64; ObjectType = integerType_UInt64; } - public OneOfTypes(IntegerType integerType_Int64) + public OneOfTypes(IntegerType integerType_Int64) { IntegerType_Int64 = integerType_Int64; ObjectType = integerType_Int64; @@ -130,13 +124,7 @@ public OneOfTypes(PD_EnvelopeType pdEnvelopeType) public override string ToString() { - if (ObjectType != null) - return ObjectType.ToString(); - - if (ReferenceType != null) - return ReferenceType.ToString(); - - return base.ToString(); + return ObjectType?.ToString() ?? ReferenceType.ToString(); } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs similarity index 84% rename from RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs rename to RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs index 7d9ccaf..c87ca53 100644 --- a/RDMSharp/Metadata/OneOfTypes/PD_EnvelopeType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs @@ -1,7 +1,7 @@ using RDMSharp.Metadata.JSON; using System.Text.Json.Serialization; -namespace RDMSharp.Metadata.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes { public class PD_EnvelopeType : CommonPropertiesForNamed { @@ -16,11 +16,11 @@ public class PD_EnvelopeType : CommonPropertiesForNamed [JsonPropertyName("notes")] [JsonPropertyOrder(4)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string? Notes { get; } + public override string Notes { get; } [JsonPropertyName("resources")] [JsonPropertyOrder(5)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string[]? Resources { get; } + public override string[] Resources { get; } [JsonPropertyName("type")] [JsonPropertyOrder(3)] @@ -34,9 +34,9 @@ public class PD_EnvelopeType : CommonPropertiesForNamed [JsonConstructor] public PD_EnvelopeType(string name, - string? displayName, - string? notes, - string[]? resources, + string displayName, + string notes, + string[] resources, string type, byte? length) : base() { @@ -52,7 +52,7 @@ public override string ToString() { if (Length.HasValue) return $"PDL: {Length} ({Length:X2}) {base.ToString()}".Trim(); - + return base.ToString(); } } diff --git a/RDMSharp/Metadata/OneOfTypes/Range.cs b/RDMSharp/Metadata/JSON/OneOfTypes/Range.cs similarity index 92% rename from RDMSharp/Metadata/OneOfTypes/Range.cs rename to RDMSharp/Metadata/JSON/OneOfTypes/Range.cs index 8eab275..fa230a1 100644 --- a/RDMSharp/Metadata/OneOfTypes/Range.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/Range.cs @@ -1,6 +1,6 @@ using System.Text.Json.Serialization; -namespace RDMSharp.Metadata.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes { public readonly struct Range { diff --git a/RDMSharp/Metadata/OneOfTypes/ReferenceType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs similarity index 84% rename from RDMSharp/Metadata/OneOfTypes/ReferenceType.cs rename to RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs index 1ca63ae..55d8d71 100644 --- a/RDMSharp/Metadata/OneOfTypes/ReferenceType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs @@ -2,7 +2,7 @@ using System; using System.Text.Json.Serialization; -namespace RDMSharp.Metadata.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes { public readonly struct ReferenceType { @@ -17,15 +17,12 @@ public readonly struct ReferenceType public ReferenceType(string uri) { URI = uri; - // Entferne das '#' und zerlege den Rest in Segmente if (uri.StartsWith("#")) { - string fragment = uri.Substring(1); // Entfernt das '#' + string fragment = uri.Substring(1); - // Zerlege den Pfad in einzelne Teile string[] segments = fragment.Split('/', StringSplitOptions.RemoveEmptyEntries); - // Ausgabe der einzelnen Teile switch (segments[0]) { case "get_request": diff --git a/RDMSharp/Metadata/OneOfTypes/StringType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs similarity index 87% rename from RDMSharp/Metadata/OneOfTypes/StringType.cs rename to RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs index d767044..2465e59 100644 --- a/RDMSharp/Metadata/OneOfTypes/StringType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs @@ -1,7 +1,7 @@ using RDMSharp.Metadata.JSON; using System.Text.Json.Serialization; -namespace RDMSharp.Metadata.OneOfTypes +namespace RDMSharp.Metadata.JSON.OneOfTypes { public class StringType : CommonPropertiesForNamed { @@ -16,11 +16,11 @@ public class StringType : CommonPropertiesForNamed [JsonPropertyName("notes")] [JsonPropertyOrder(25)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string? Notes { get; } + public override string Notes { get; } [JsonPropertyName("resources")] [JsonPropertyOrder(5)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public override string[]? Resources { get; } + public override string[] Resources { get; } [JsonPropertyName("type")] [JsonPropertyOrder(3)] @@ -28,11 +28,11 @@ public class StringType : CommonPropertiesForNamed [JsonPropertyName("format")] [JsonPropertyOrder(21)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? Format { get; } + public string Format { get; } [JsonPropertyName("pattern")] [JsonPropertyOrder(22)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? Pattern { get; } + public string Pattern { get; } [JsonPropertyName("minLength")] [JsonPropertyOrder(31)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] @@ -57,12 +57,12 @@ public class StringType : CommonPropertiesForNamed [JsonConstructor] public StringType(string name, - string? displayName, - string? notes, - string[]? resources, + string displayName, + string notes, + string[] resources, string type, - string? format, - string? pattern, + string format, + string pattern, ulong? minLength, ulong? maxLength, ulong? minBytes, diff --git a/RDMSharp/Metadata/JSON/SubdeviceType.cs b/RDMSharp/Metadata/JSON/SubdeviceType.cs index cf5c7ba..312cdf3 100644 --- a/RDMSharp/Metadata/JSON/SubdeviceType.cs +++ b/RDMSharp/Metadata/JSON/SubdeviceType.cs @@ -21,11 +21,7 @@ public SubdeviceType(SubdeviceRange range) : this() } public override string ToString() { - if (Value.HasValue) - return $"Subdevice Value: {Value:X4}"; - if (Range.HasValue) - return Range.ToString(); - return base.ToString(); + return Value?.ToString() ?? Range.ToString(); } } } diff --git a/RDMSharp/Metadata/JSON/SubdevicesForRequests.cs b/RDMSharp/Metadata/JSON/SubdevicesForRequests.cs index 68d63fd..9c80418 100644 --- a/RDMSharp/Metadata/JSON/SubdevicesForRequests.cs +++ b/RDMSharp/Metadata/JSON/SubdevicesForRequests.cs @@ -30,11 +30,7 @@ public SubdevicesForRequests(SubdeviceType objectValue) } public override string ToString() { - if (EnumValue.HasValue) - return EnumValue.Value.ToString(); - if (ObjectValue.HasValue) - return ObjectValue.Value.ToString(); - return base.ToString(); + return EnumValue?.ToString() ?? ObjectValue.ToString(); } } } diff --git a/RDMSharp/Metadata/JSON/SubdevicesForResponses.cs b/RDMSharp/Metadata/JSON/SubdevicesForResponses.cs index 15177f0..86e6649 100644 --- a/RDMSharp/Metadata/JSON/SubdevicesForResponses.cs +++ b/RDMSharp/Metadata/JSON/SubdevicesForResponses.cs @@ -32,11 +32,7 @@ public SubdevicesForResponses(SubdeviceType objectValue) } public override string ToString() { - if (EnumValue.HasValue) - return EnumValue.Value.ToString(); - if (ObjectValue.HasValue) - return ObjectValue.Value.ToString(); - return base.ToString(); + return EnumValue?.ToString() ?? ObjectValue.ToString(); } } } diff --git a/RDMSharp/Metadata/MetadataBag.cs b/RDMSharp/Metadata/MetadataBag.cs index e43e556..c14dc62 100644 --- a/RDMSharp/Metadata/MetadataBag.cs +++ b/RDMSharp/Metadata/MetadataBag.cs @@ -1,4 +1,8 @@ -using System.IO; +using System; +using System.IO; +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("RDMSharpTests")] namespace RDMSharp.Metadata { @@ -20,10 +24,11 @@ public MetadataBag(string version, string name, bool isSchema, string content, s Path = path; Content = content; } - private static string getContent(string path) + internal static string getContent(string path) { if (string.IsNullOrWhiteSpace(path)) - return null; + throw new ArgumentNullException(nameof(path)); + var assembly = typeof(MetadataFactory).Assembly; using Stream stream = assembly.GetManifestResourceStream(path); using StreamReader reader = new StreamReader(stream); diff --git a/RDMSharp/Metadata/MetadataFactory.cs b/RDMSharp/Metadata/MetadataFactory.cs index eaef084..b173b8c 100644 --- a/RDMSharp/Metadata/MetadataFactory.cs +++ b/RDMSharp/Metadata/MetadataFactory.cs @@ -33,7 +33,7 @@ public static string[] GetResources() private static void fillDefaultMetadataVersionList() { metadataVersionList.AddRange(GetResources().Select(r => new MetadataVersion(r))); - return; + if (metadataVersionDefinesBagDictionary == null) metadataVersionDefinesBagDictionary = new Dictionary>(); @@ -58,10 +58,6 @@ private static void fillDefaultMetadataVersionList() metadataVersionDefinesBagDictionary[schema].Add(jsonDefine); } - else - { - - } } } diff --git a/RDMSharp/Metadata/MetadataVersion.cs b/RDMSharp/Metadata/MetadataVersion.cs index 946880e..1b3d237 100644 --- a/RDMSharp/Metadata/MetadataVersion.cs +++ b/RDMSharp/Metadata/MetadataVersion.cs @@ -1,6 +1,9 @@ using System; +using System.Runtime.CompilerServices; using System.Text.RegularExpressions; +[assembly: InternalsVisibleTo("RDMSharpTests")] + namespace RDMSharp.Metadata { public readonly struct MetadataVersion @@ -18,18 +21,15 @@ public MetadataVersion(string version, string name, bool isSchema, string path) Path = path; Name = name; IsSchema = isSchema; - string pattern = @"[^\.]+\.[json]+$"; - var match = Regex.Match(Path, pattern); - - if (match.Success) - { - Name = match.Value; - } - else - throw new Exception($"Can't extract Name from Path: {path}"); } - private static string getVersion(string path) + internal static string getVersion(string path) { + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentNullException(nameof(path)); + + if (!path.ToLower().EndsWith(".json")) + throw new ArgumentException($"The given Paths should end with .json ({nameof(path)})"); + string pattern = @"_(\d+)\._(\d+)\._(\d+)"; var match = Regex.Match(path, pattern); @@ -38,14 +38,23 @@ private static string getVersion(string path) return match.Value.Replace("_", ""); } else - throw new Exception($"Can't extract Version from Path: {path}"); + throw new FormatException($"Can't extract Version from Path: {path}"); } - private static bool getIsSchema(string path) + internal static bool getIsSchema(string path) { + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentNullException(nameof(path)); + + if (!path.ToLower().EndsWith(".json")) + throw new ArgumentException($"The given Paths should end with .json ({nameof(path)})"); + return path.ToLower().EndsWith("schema.json"); } - private static string getName(string path) + internal static string getName(string path) { + if (string.IsNullOrWhiteSpace(path)) + throw new ArgumentNullException(nameof(path)); + string pattern = @"[^\.]+\.[json]+$"; var match = Regex.Match(path, pattern); @@ -54,7 +63,7 @@ private static string getName(string path) return match.Value; } else - throw new Exception($"Can't extract Name from Path: {path}"); + throw new FormatException($"The given Paths should end with .json ({nameof(path)})"); } public override string ToString() { diff --git a/RDMSharpTests/MetadataJSONObjectDefineTests.cs b/RDMSharpTests/MetadataJSONObjectDefineTests.cs index f54f839..49eda4b 100644 --- a/RDMSharpTests/MetadataJSONObjectDefineTests.cs +++ b/RDMSharpTests/MetadataJSONObjectDefineTests.cs @@ -5,7 +5,7 @@ using Newtonsoft.Json.Linq; using RDMSharp.Metadata.JSON; using NUnit.Framework.Internal.Commands; -using RDMSharp.Metadata.OneOfTypes; +using RDMSharp.Metadata.JSON.OneOfTypes; namespace RDMSharpTests { @@ -26,7 +26,10 @@ public void TestValidateAgainstSchema() JsonSchema jsonSchema = JsonSchema.FromText(testSubject.Schema.Content); var result = jsonSchema.Evaluate(JsonNode.Parse(testSubject.Define.Content)); Assert.That(result, Is.Not.Null); - Assert.That(result.IsValid, Is.True); + if (!testSubject.Define.Name.ToLower().Contains("invalid")) + Assert.That(result.IsValid, Is.True); + else + Assert.That(result.IsValid, Is.False); } [Test] public void TestDeseriaizeAndSerialize() @@ -52,6 +55,9 @@ public void TestDeseriaizeAndSerialize() } catch (JsonException ex) { + if (testSubject.Define.Name.ToLower().Contains("invalid")) + return; + #if !NET7_0_OR_GREATER Warn.If(ex.Message, Is.EqualTo("Unexpected JSON format Type: int128 for FieldContainer.").Or.EqualTo("Unexpected JSON format Type: uint128 for FieldContainer."), "Due to .NET6 limitations"); return; @@ -71,6 +77,8 @@ public void TestDeseriaizedObject() } catch (JsonException ex) { + if (testSubject.Define.Name.ToLower().Contains("invalid")) + return; #if !NET7_0_OR_GREATER Warn.If(ex.Message, Is.EqualTo("Unexpected JSON format Type: int128 for FieldContainer.").Or.EqualTo("Unexpected JSON format Type: uint128 for FieldContainer."), "Due to .NET6 limitations"); return; @@ -136,6 +144,8 @@ static void testCommand(Command command) testString(singleField.ToString()!); if (singleField.ObjectType is CommonPropertiesForNamed common) testCommon(common); + else if(singleField.ReferenceType is ReferenceType reference) + testReference(reference); return; } else if (command.ListOfFields is OneOfTypes[] listOfFields) @@ -148,6 +158,8 @@ static void testCommand(Command command) { if (field.ObjectType is CommonPropertiesForNamed common) testCommon(common); + else if (field.ReferenceType is ReferenceType reference) + testReference(reference); } return; } @@ -180,6 +192,12 @@ static void testCommon(CommonPropertiesForNamed common) testIntegerType(integerUInt128); #endif } + static void testReference(ReferenceType reference) + { + testString(reference.ToString()); + Assert.That(reference.Command, Is.EqualTo(Command.ECommandDublicte.GetRequest).Or.EqualTo(Command.ECommandDublicte.GetResponse).Or.EqualTo(Command.ECommandDublicte.SetRequest).Or.EqualTo(Command.ECommandDublicte.SetResponse)); + Assert.That(reference.Pointer, Is.AtLeast(0)); + } static void testIntegerType(IntegerType integerType) { testString(integerType.ToString()!); diff --git a/RDMSharpTests/RDMSharpTests.csproj b/RDMSharpTests/RDMSharpTests.csproj index cd260da..0d6e617 100644 --- a/RDMSharpTests/RDMSharpTests.csproj +++ b/RDMSharpTests/RDMSharpTests.csproj @@ -29,7 +29,13 @@ + + + + + + diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_COMMAND_NUMBER.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_COMMAND_NUMBER.json new file mode 100644 index 0000000..16c77bf --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_COMMAND_NUMBER.json @@ -0,0 +1,9 @@ +{ + "name": "MOCK_INVALID_COMMAND_NUMBER", + "manufacturer_id": 3456, + "pid": 5678, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": 22, + "get_response": [] +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_ENUM.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_ENUM.json new file mode 100644 index 0000000..21e6a67 --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_ENUM.json @@ -0,0 +1,9 @@ +{ + "name": "MOCK_INVALID_ENUM", + "manufacturer_id": 3456, + "pid": 5678, + "version": 1, + "get_request_subdevice_range": [ "root", "INVALID" ], + "get_request": [], + "get_response": [] +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_ONEOF_TYPE.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_ONEOF_TYPE.json new file mode 100644 index 0000000..12822f6 --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_ONEOF_TYPE.json @@ -0,0 +1,14 @@ +{ + "name": "MOCK_INVALID_ONEOF_TYPE", + "manufacturer_id": 3456, + "pid": 5678, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "Invalid Type", + "invalid": "invalid" + } + ], + "get_response": [] +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_SUBDEVICE_TYPE_REQUEST.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_SUBDEVICE_TYPE_REQUEST.json new file mode 100644 index 0000000..67b8e77 --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_SUBDEVICE_TYPE_REQUEST.json @@ -0,0 +1,9 @@ +{ + "name": "MOCK_INVALID_SUBDEVICE_TYPE_REQUEST", + "manufacturer_id": 3456, + "pid": 5678, + "version": 1, + "get_request_subdevice_range": [ "root", null, [ 2, 3, 4 ] ], + "get_request": [], + "get_response": [] +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_SUBDEVICE_TYPE_RESPONSE.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_SUBDEVICE_TYPE_RESPONSE.json new file mode 100644 index 0000000..5b5ca98 --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_SUBDEVICE_TYPE_RESPONSE.json @@ -0,0 +1,10 @@ +{ + "name": "MOCK_INVALID_SUBDEVICE_TYPE_RESPONSE", + "manufacturer_id": 3456, + "pid": 5678, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response_subdevice_range": [ "root", [ 2, 5 ], null ], + "get_response": [] +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_REFERENCE_TYPE.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_REFERENCE_TYPE.json new file mode 100644 index 0000000..0869137 --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_REFERENCE_TYPE.json @@ -0,0 +1,42 @@ +{ + "name": "MOCK_REFERENCE_TYPE", + "manufacturer_id": 3456, + "pid": 5678, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "root_personality", + "type": "uint8", + "ranges": [ + { + "minimum": 1, + "maximum": 255 + } + ] + }, + { + "name": "subdevice", + "type": "uint16", + "labels": [ + { + "name": "root", + "value": 0 + } + ] + }, + { + "name": "subdevice_personality", + "type": "uint8", + "labels": [ + { + "name": "root", + "value": 0 + } + ] + } + ], + "get_response": [ + { "$ref": "#/set_response/0" } + ] +} \ No newline at end of file diff --git a/RDMSharpTests/TestJSONDefines.cs b/RDMSharpTests/TestJSONDefines.cs deleted file mode 100644 index b7a2200..0000000 --- a/RDMSharpTests/TestJSONDefines.cs +++ /dev/null @@ -1,36 +0,0 @@ -using RDMSharp.Metadata; - -namespace RDMSharpTests -{ - public class TestMetadataFactoryStuff - { - [SetUp] - public void Setup() - { - Console.OutputEncoding = System.Text.Encoding.Unicode; - } - [TearDown] - public void Teardown() - { - Console.OutputEncoding = System.Text.Encoding.Default; - } - - [Test] - public void TestMetadataFactory() - { - var schemas = MetadataFactory.GetMetadataSchemaVersions(); - Assert.That(schemas, Has.Count.EqualTo(1)); - var defines = MetadataFactory.GetMetadataDefineVersions(); - Assert.That(defines, Has.Count.EqualTo(122)); - foreach (var define in defines) - testString(define.ToString()); - } - void testString(string str) - { - Assert.That(str, Is.Not.WhiteSpace); - Assert.That(str, Is.Not.Empty); - Assert.That(str, Does.Not.Contain("{")); - Assert.That(str, Does.Not.Contain("}")); - } - } -} \ No newline at end of file diff --git a/RDMSharpTests/TestMetadataFactoryStuff.cs b/RDMSharpTests/TestMetadataFactoryStuff.cs new file mode 100644 index 0000000..307437c --- /dev/null +++ b/RDMSharpTests/TestMetadataFactoryStuff.cs @@ -0,0 +1,63 @@ +using RDMSharp.Metadata; + +namespace RDMSharpTests +{ + public class TestMetadataFactoryStuff + { + [SetUp] + public void Setup() + { + Console.OutputEncoding = System.Text.Encoding.Unicode; + } + [TearDown] + public void Teardown() + { + Console.OutputEncoding = System.Text.Encoding.Default; + } + + [Test] + public void TestMetadataFactory() + { + var schemas = MetadataFactory.GetMetadataSchemaVersions(); + Assert.That(schemas, Has.Count.EqualTo(1)); + var defines = MetadataFactory.GetMetadataDefineVersions(); + Assert.That(defines, Has.Count.EqualTo(122)); + foreach (var define in defines) + testString(define.ToString()); + } + + [Test] + public void TestMetadataVersion() + { + var mv = new MetadataVersion("RDMSharp.Resources.JSON_Defines._1._0._0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.json"); + testString(mv.ToString()); + Assert.Multiple(() => + { + Assert.Throws(typeof(ArgumentNullException), () => MetadataVersion.getVersion(null)); + Assert.Throws(typeof(ArgumentNullException), () => MetadataVersion.getName(null)); + Assert.Throws(typeof(ArgumentNullException), () => MetadataVersion.getIsSchema(null)); + + Assert.Throws(typeof(FormatException), () => MetadataVersion.getVersion("RDMSharp.Resources.JSON_Defines.1.0.0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.json")); + Assert.Throws(typeof(FormatException), () => MetadataVersion.getVersion("RDMSharp.Resources.JSON_Defines._1._X._0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.json")); + Assert.Throws(typeof(ArgumentException), () => MetadataVersion.getVersion("RDMSharp.Resources.JSON_Defines._1._0._0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.jsan")); + Assert.Throws(typeof(FormatException), () => MetadataVersion.getName("RDMSharp.Resources.JSON_Defines._1._0._0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.jsan")); + Assert.Throws(typeof(ArgumentException), () => MetadataVersion.getIsSchema("RDMSharp.Resources.JSON_Defines._1._0._0.Defines.e1._20.BOOT_SOFTWARE_VERSION_ID.jsan")); + }); + } + + [Test] + public void TestMetadataBag() + { + var bag = new MetadataBag("1.0.2", "NAME.json", false, "content", "Path"); + testString(bag.ToString()); + Assert.Throws(typeof(ArgumentNullException), () => MetadataBag.getContent(null)); + } + static void testString(string str) + { + Assert.That(str, Is.Not.WhiteSpace); + Assert.That(str, Is.Not.Empty); + Assert.That(str, Does.Not.Contain("{")); + Assert.That(str, Does.Not.Contain("}")); + } + } +} \ No newline at end of file From 3ab852944e8080512bbe1bc7a3a1300a9c69cacd Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 18 Sep 2024 21:04:44 +0200 Subject: [PATCH 14/51] MInor --- RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs index dd080c6..982c005 100644 --- a/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs +++ b/RDMSharp/Metadata/JSON/Converter/OneOfTypesConverter.cs @@ -88,11 +88,6 @@ public override OneOf Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSe case "string": var stringType = element.Deserialize(options); return new OneOf(stringType); - - - case null: - default: - break; } throw new JsonException($"Unexpected JSON format Type: {type} for FieldContainer."); From 402368fa05673724ffa15be6389f6b041f33d301 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 19 Sep 2024 18:53:17 +0200 Subject: [PATCH 15/51] Implement PDL-Calculation Implement Reference stuff Mote Tests Add Argument Validation to most Konstructors of JSON Type-Stuff --- RDMSharp/Metadata/JSON/Command.cs | 12 ++ .../Metadata/JSON/CommonPropertiesForNamed.cs | 6 +- .../Metadata/JSON/OneOfTypes/BitFieldType.cs | 13 +- RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs | 9 +- .../Metadata/JSON/OneOfTypes/BooleanType.cs | 19 ++- .../Metadata/JSON/OneOfTypes/BytesType.cs | 28 +++- .../Metadata/JSON/OneOfTypes/CompoundType.cs | 14 +- .../Metadata/JSON/OneOfTypes/IntegerType.cs | 70 +++++++- .../JSON/OneOfTypes/LabeledBooleanType.cs | 9 +- .../JSON/OneOfTypes/LabeledIntegerType.cs | 6 +- RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs | 52 +++++- .../Metadata/JSON/OneOfTypes/OneOfTypes.cs | 15 +- .../JSON/OneOfTypes/PD_EnvelopeType.cs | 13 +- .../Metadata/JSON/OneOfTypes/ReferenceType.cs | 12 +- .../Metadata/JSON/OneOfTypes/StringType.cs | 24 ++- RDMSharp/Metadata/MetadataJSONObjectDefine.cs | 131 ++++++++++++--- RDMSharp/RDM/PDL.cs | 64 ++++++++ .../MetadataJSONObjectDefineTestSubject.cs | 6 +- .../JSON}/MetadataJSONObjectDefineTests.cs | 43 +++-- .../Metadata/JSON/TestBitFieldType.cs | 28 ++++ RDMSharpTests/Metadata/JSON/TestBitType.cs | 15 ++ .../Metadata/JSON/TestBooleanType.cs | 41 +++++ RDMSharpTests/Metadata/JSON/TestBytesType.cs | 45 ++++++ RDMSharpTests/Metadata/JSON/TestCommand.cs | 15 ++ .../Metadata/JSON/TestCompoundType.cs | 29 ++++ .../Metadata/JSON/TestIntegerType.cs | 151 ++++++++++++++++++ .../Metadata/JSON/TestLabeledBooleanType.cs | 15 ++ .../Metadata/JSON/TestLabeledIntegerType.cs | 15 ++ RDMSharpTests/Metadata/JSON/TestListType.cs | 65 ++++++++ .../Metadata/JSON/TestPD_EnvelopeType.cs | 23 +++ .../TestMetadataFactoryStuff.cs | 2 +- RDMSharpTests/TestManyObjects.cs | 62 ++++++- 32 files changed, 987 insertions(+), 65 deletions(-) create mode 100644 RDMSharp/RDM/PDL.cs rename RDMSharpTests/{ => Metadata/JSON}/MetadataJSONObjectDefineTestSubject.cs (92%) rename RDMSharpTests/{ => Metadata/JSON}/MetadataJSONObjectDefineTests.cs (87%) create mode 100644 RDMSharpTests/Metadata/JSON/TestBitFieldType.cs create mode 100644 RDMSharpTests/Metadata/JSON/TestBitType.cs create mode 100644 RDMSharpTests/Metadata/JSON/TestBooleanType.cs create mode 100644 RDMSharpTests/Metadata/JSON/TestBytesType.cs create mode 100644 RDMSharpTests/Metadata/JSON/TestCommand.cs create mode 100644 RDMSharpTests/Metadata/JSON/TestCompoundType.cs create mode 100644 RDMSharpTests/Metadata/JSON/TestIntegerType.cs create mode 100644 RDMSharpTests/Metadata/JSON/TestLabeledBooleanType.cs create mode 100644 RDMSharpTests/Metadata/JSON/TestLabeledIntegerType.cs create mode 100644 RDMSharpTests/Metadata/JSON/TestListType.cs create mode 100644 RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs rename RDMSharpTests/{ => Metadata}/TestMetadataFactoryStuff.cs (98%) diff --git a/RDMSharp/Metadata/JSON/Command.cs b/RDMSharp/Metadata/JSON/Command.cs index 3611e26..02e47db 100644 --- a/RDMSharp/Metadata/JSON/Command.cs +++ b/RDMSharp/Metadata/JSON/Command.cs @@ -1,6 +1,7 @@ using System.Linq; using System.Text.Json.Serialization; using RDMSharp.Metadata.JSON.Converter; +using RDMSharp.RDM; using OneOf = RDMSharp.Metadata.JSON.OneOfTypes.OneOfTypes; namespace RDMSharp.Metadata.JSON @@ -52,6 +53,17 @@ public Command(OneOf[] listOfFields) { ListOfFields = listOfFields; } + public PDL GetDataLength() + { + if(GetIsEmpty()) + return new PDL(); + if (SingleField.HasValue) + return SingleField.Value.GetDataLength(); + if (ListOfFields != null) + return new PDL(ListOfFields.Select(f => f.GetDataLength()).ToArray()); + + throw new System.NotSupportedException(); + } public override string ToString() { if (EnumValue.HasValue) diff --git a/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs b/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs index 2d804d7..c61c8aa 100644 --- a/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs +++ b/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs @@ -1,12 +1,12 @@ -using RDMSharp.Metadata.JSON.Converter; +using System; using System.Linq; using System.Text.Json.Serialization; +using RDMSharp.RDM; namespace RDMSharp.Metadata.JSON { public abstract class CommonPropertiesForNamed { - [JsonPropertyName("name")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public abstract string Name { get; } @@ -20,6 +20,8 @@ public abstract class CommonPropertiesForNamed [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public abstract string[]? Resources { get; } + public abstract PDL GetDataLength(); + public override string ToString() { if(!string.IsNullOrWhiteSpace(DisplayName)) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs index 432e503..bdcefca 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs @@ -1,4 +1,5 @@ -using RDMSharp.Metadata.JSON; +using RDMSharp.RDM; +using System; using System.Linq; using System.Text.Json.Serialization; @@ -16,6 +17,11 @@ public BitFieldType(string name, bool? valueForUnspecified, BitType[] bits) : base() { + if (!"bitField".Equals(type)) + throw new ArgumentException($"Argument {nameof(type)} has to be \"bitField\""); + if (size % 8 != 0) + throw new ArgumentOutOfRangeException($"Argument {nameof(size)} has to be a multiple of 8"); + Name = name; DisplayName = displayName; Notes = notes; @@ -60,6 +66,11 @@ public BitFieldType(string name, [JsonPropertyOrder(41)] public BitType[] Bits { get; } + public override PDL GetDataLength() + { + return new PDL((uint)(Size / 8)); + } + public override string ToString() { return $"{Name} [ {string.Join("; ", Bits.Select(b => b.ToString()))} ]"; diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs index 292a194..c523666 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs @@ -1,5 +1,5 @@ -using RDMSharp.Metadata.JSON; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; +using RDMSharp.RDM; namespace RDMSharp.Metadata.JSON.OneOfTypes { @@ -58,6 +58,11 @@ public BitType(string name, [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public bool? ValueIfReserved { get; } + public override PDL GetDataLength() + { + throw new System.NotSupportedException(); + } + public override string ToString() { return $"{Index} -> {Name}"; diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs index 011f954..d5d1b9d 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs @@ -1,4 +1,4 @@ -using RDMSharp.Metadata.JSON; +using RDMSharp.RDM; using System.Linq; using System.Text.Json.Serialization; @@ -40,12 +40,24 @@ public BooleanType(string name, string type, LabeledBooleanType[] labels) : base() { + if (!"boolean".Equals(type)) + throw new System.ArgumentException($"Argument {nameof(type)} has to be \"boolean\""); + + if (((labels?.Length) ?? 2) != 2) + throw new System.ArgumentException($"Argument {nameof(labels)} has to be null oa an array of 2"); + Name = name; DisplayName = displayName; Notes = notes; Resources = resources; Type = type; Labels = labels; + + if (labels != null) + { + if (labels[0].Value == labels[1].Value) + throw new System.ArgumentException($"Argument {nameof(labels)}, both Values are the same, one has to be false, the other true"); + } } public override string ToString() { @@ -54,5 +66,10 @@ public override string ToString() return $"{Name} [ {string.Join("; ", Labels.Select(l => l.ToString()))} ]"; } + + public override PDL GetDataLength() + { + return new PDL(1); + } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs index 105c9c6..26df217 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs @@ -1,4 +1,5 @@ -using RDMSharp.Metadata.JSON; +using RDMSharp.RDM; +using System; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -32,11 +33,11 @@ public class BytesType : CommonPropertiesForNamed [JsonPropertyName("minLength")] [JsonPropertyOrder(12)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public ulong? MinLength { get; } + public uint? MinLength { get; } [JsonPropertyName("maxLength")] [JsonPropertyOrder(13)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public ulong? MaxLength { get; } + public uint? MaxLength { get; } [JsonConstructor] @@ -46,9 +47,21 @@ public BytesType(string name, string[] resources, string type, string format, - ulong? minLength, - ulong? maxLength) : base() + uint? minLength, + uint? maxLength) : base() { + if (!"bytes".Equals(type)) + throw new ArgumentException($"Argument {nameof(type)} has to be \"bytes\""); + if (minLength.HasValue && maxLength.HasValue) + if (minLength > maxLength) + throw new ArgumentOutOfRangeException($"Argument {nameof(minLength)} has to be <= {nameof(maxLength)}"); + if (minLength.HasValue) + if (minLength > PDL.MAX_LENGTH) + throw new ArgumentOutOfRangeException($"Argument {nameof(minLength)} has to be <= {PDL.MAX_LENGTH}"); + if (maxLength.HasValue) + if (maxLength > PDL.MAX_LENGTH) + throw new ArgumentOutOfRangeException($"Argument {nameof(maxLength)} has to be <= {PDL.MAX_LENGTH}"); + Name = name; DisplayName = displayName; Notes = notes; @@ -63,5 +76,10 @@ public override string ToString() { return Name; } + + public override PDL GetDataLength() + { + return new PDL((uint)(MinLength ?? 1), (uint)(MaxLength ?? PDL.MAX_LENGTH)); + } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs index 88ab4a9..cf17d7c 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs @@ -1,4 +1,5 @@ -using RDMSharp.Metadata.JSON; +using RDMSharp.RDM; +using System.Linq; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -38,6 +39,12 @@ public CompoundType(string name, string type, OneOfTypes[] subtypes) { + if (!"compound".Equals(type)) + throw new System.ArgumentException($"Argument {nameof(type)} has to be \"compound\""); + + if (((subtypes?.Length) ?? 0) < 1) + throw new System.ArgumentException($"Argument {nameof(subtypes)} has to be at least a size of 1"); + Name = name; DisplayName = displayName; Notes = notes; @@ -45,5 +52,10 @@ public CompoundType(string name, Type = type; Subtypes = subtypes; } + + public override PDL GetDataLength() + { + return new PDL(Subtypes.Select(s => s.GetDataLength()).ToArray()); + } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs index be43e41..974d2c3 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs @@ -1,6 +1,6 @@ -using Humanizer.Localisation; -using RDMSharp.Metadata.JSON; -using RDMSharp.Metadata.JSON.Converter; +using RDMSharp.Metadata.JSON.Converter; +using RDMSharp.RDM; +using System; using System.Linq; using System.Text.Json.Serialization; @@ -90,6 +90,41 @@ public IntegerType(string name, int? prefixPower, int? prefixBase) : base() { + T dummy = default; + switch (dummy) + { + case sbyte when type is not EIntegerType.Int8: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.Int8}\""); + + case byte when type is not EIntegerType.UInt8: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt8}\""); + + case short when type is not EIntegerType.Int16: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.Int16}\""); + + case ushort when type is not EIntegerType.UInt16: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt16}\""); + + case int when type is not EIntegerType.Int32: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.Int32}\""); + + case uint when type is not EIntegerType.UInt32: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt32}\""); + + case long when type is not EIntegerType.Int64: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.Int64}\""); + + case ulong when type is not EIntegerType.UInt64: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt64}\""); +#if NET7_0_OR_GREATER + case Int128 when type is not EIntegerType.Int128: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.Int128}\""); + + case UInt128 when type is not EIntegerType.UInt128: + throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt128}\""); +#endif + } + Name = name; DisplayName = displayName; Notes = notes; @@ -110,5 +145,34 @@ public override string ToString() return $"{Name} {Type}"; } + + public override PDL GetDataLength() + { + switch (Type) + { + case EIntegerType.Int8: + case EIntegerType.UInt8: + return new PDL(1); + + case EIntegerType.Int16: + case EIntegerType.UInt16: + return new PDL(2); + + case EIntegerType.Int32: + case EIntegerType.UInt32: + return new PDL(4); + + case EIntegerType.Int64: + case EIntegerType.UInt64: + return new PDL(8); + + default: +#if NET7_0_OR_GREATER + case EIntegerType.Int128: + case EIntegerType.UInt128: +#endif + return new PDL(16); + } + } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs index d7f9d7d..cffa971 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs @@ -1,5 +1,5 @@ -using RDMSharp.Metadata.JSON; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; +using RDMSharp.RDM; namespace RDMSharp.Metadata.JSON.OneOfTypes { @@ -44,5 +44,10 @@ public override string ToString() { return $"{Value} -> {Name}"; } + + public override PDL GetDataLength() + { + throw new System.NotSupportedException(); + } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs index 2e45d06..5a8e766 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs @@ -1,4 +1,4 @@ -using RDMSharp.Metadata.JSON; +using RDMSharp.RDM; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -44,5 +44,9 @@ public override string ToString() { return $"{Value} -> {Name}"; } + public override PDL GetDataLength() + { + throw new System.NotSupportedException(); + } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs index 0129bc7..6bca31a 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs @@ -1,4 +1,5 @@ -using RDMSharp.Metadata.JSON; +using RDMSharp.RDM; +using System; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -31,11 +32,11 @@ public class ListType : CommonPropertiesForNamed [JsonPropertyName("minItems")] [JsonPropertyOrder(31)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public int? MinItems { get; } + public uint? MinItems { get; } [JsonPropertyName("maxItems")] [JsonPropertyOrder(32)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public int? MaxItems { get; } + public uint? MaxItems { get; } [JsonConstructor] @@ -45,9 +46,15 @@ public ListType(string name, string[] resources, string type, OneOfTypes itemType, - int? minItems, - int? maxItems) : base() + uint? minItems, + uint? maxItems) : base() { + if (!"list".Equals(type)) + throw new ArgumentException($"Argument {nameof(type)} has to be \"list\""); + + if (itemType.IsEmpty()) + throw new ArgumentException($"Argument {nameof(itemType)} is Empty, this is not allowed"); + Name = name; DisplayName = displayName; Notes = notes; @@ -62,5 +69,40 @@ public override string ToString() { return DisplayName ?? Name; } + + public override PDL GetDataLength() + { + uint min = 0; + uint max = 0; + + if (MinItems.HasValue) + min = MinItems.Value; + if (MaxItems.HasValue) + max = MaxItems.Value; + + PDL itemPDL = ItemType.GetDataLength(); + if (itemPDL.Value.HasValue) + { + min *= itemPDL.Value.Value; + max *= itemPDL.Value.Value; + } + else + { + if (itemPDL.MinLength.HasValue) + min *= itemPDL.MinLength.Value; + if (itemPDL.MaxLength.HasValue) + max *= itemPDL.MaxLength.Value; + } + + if (max == 0) + if (!MaxItems.HasValue) + if (MinItems.HasValue) + max = PDL.MAX_LENGTH; + + if (min == max) + return new PDL(min); + + return new PDL(min, max); + } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs index b4416ad..d1493b0 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs @@ -1,7 +1,7 @@ -using System; +using RDMSharp.Metadata.JSON.Converter; +using RDMSharp.RDM; +using System; using System.Text.Json.Serialization; -using RDMSharp.Metadata.JSON; -using RDMSharp.Metadata.JSON.Converter; namespace RDMSharp.Metadata.JSON.OneOfTypes { @@ -122,6 +122,15 @@ public OneOfTypes(PD_EnvelopeType pdEnvelopeType) ObjectType = pdEnvelopeType; } + public bool IsEmpty() + { + return ObjectType == null && ReferenceType == null; + } + public PDL GetDataLength() + { + return ObjectType?.GetDataLength() ?? ReferenceType?.GetDataLength() ?? new PDL(); + } + public override string ToString() { return ObjectType?.ToString() ?? ReferenceType.ToString(); diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs index c87ca53..4dd695f 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs @@ -1,4 +1,4 @@ -using RDMSharp.Metadata.JSON; +using RDMSharp.RDM; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -40,6 +40,9 @@ public PD_EnvelopeType(string name, string type, byte? length) : base() { + if (!"pdEnvelope".Equals(type)) + throw new System.ArgumentException($"Argument {nameof(type)} has to be \"pdEnvelope\""); + Name = name; DisplayName = displayName; Notes = notes; @@ -55,5 +58,13 @@ public override string ToString() return base.ToString(); } + + public override PDL GetDataLength() + { + if(Length.HasValue) + return new PDL(Length.Value); + + return new PDL(); + } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs index 55d8d71..03a82f2 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs @@ -1,4 +1,4 @@ -using RDMSharp.Metadata.JSON; +using RDMSharp.RDM; using System; using System.Text.Json.Serialization; @@ -12,6 +12,8 @@ public readonly struct ReferenceType public readonly Command.ECommandDublicte Command { get; } [JsonIgnore(Condition = JsonIgnoreCondition.Always)] public readonly ushort Pointer { get; } + [JsonIgnore(Condition = JsonIgnoreCondition.Always)] + public readonly CommonPropertiesForNamed? ReferencedObject { get; } [JsonConstructor] public ReferenceType(string uri) @@ -41,6 +43,14 @@ public ReferenceType(string uri) Pointer = ushort.Parse(segments[1]); } } + public ReferenceType(string uri, CommonPropertiesForNamed referencedObject) : this(uri) + { + ReferencedObject = referencedObject; + } + public PDL GetDataLength() + { + return ReferencedObject?.GetDataLength() ?? new PDL(); + } public override string ToString() { return URI; diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs index 2465e59..b459702 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs @@ -1,4 +1,4 @@ -using RDMSharp.Metadata.JSON; +using RDMSharp.RDM; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -69,6 +69,9 @@ public StringType(string name, ulong? maxBytes, bool? restrictToASCII) { + if (!"string".Equals(type)) + throw new System.ArgumentException($"Argument {nameof(type)} has to be \"string\""); + Name = name; DisplayName = displayName; Notes = notes; @@ -87,5 +90,24 @@ public override string ToString() { return base.ToString(); } + + public override PDL GetDataLength() + { + uint min = 0; + uint? max = null; + if (MinLength.HasValue) + min = (uint)MinLength.Value; + if (MaxLength.HasValue) + max = (uint)MaxLength.Value; + if (MinBytes.HasValue) + min = (uint)MinBytes.Value; + if (MaxBytes.HasValue) + max = (uint)MaxBytes.Value; + + if (!max.HasValue) + return new PDL(min, PDL.MAX_LENGTH); + + return new PDL(min, max.Value); + } } } diff --git a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs index 4745e62..3e48719 100644 --- a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs +++ b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs @@ -1,59 +1,60 @@ -using System.Text.Json; -using System; +using RDMSharp.Metadata.JSON; +using RDMSharp.Metadata.JSON.OneOfTypes; +using System.Collections.Generic; +using System.Linq; using System.Text.Json.Serialization; -using RDMSharp.Metadata.JSON; namespace RDMSharp.Metadata { - public readonly struct MetadataJSONObjectDefine + public class MetadataJSONObjectDefine { [JsonPropertyName("name")] - public readonly string Name { get; } + public string Name { get; } [JsonPropertyName("displayName")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public readonly string? DisplayName { get; } + public string? DisplayName { get; } [JsonPropertyName("notes")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public readonly string? Notes { get; } + public string? Notes { get; } [JsonPropertyName("manufacturer_id")] - public readonly ushort ManufacturerID { get; } + public ushort ManufacturerID { get; } [JsonPropertyName("pid")] - public readonly ushort PID { get; } + public ushort PID { get; } [JsonPropertyName("version")] - public readonly ushort Version { get; } + public ushort Version { get; } [JsonPropertyName("get_request_subdevice_range")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyOrder(11)] - public readonly SubdevicesForRequests[]? GetRequestSubdeviceRange { get; } + public SubdevicesForRequests[]? GetRequestSubdeviceRange { get; } [JsonPropertyName("get_response_subdevice_range")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyOrder(13)] - public readonly SubdevicesForResponses[]? GetResponseSubdeviceRange { get; } + public SubdevicesForResponses[]? GetResponseSubdeviceRange { get; } [JsonPropertyName("set_request_subdevice_range")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyOrder(15)] - public readonly SubdevicesForRequests[]? SetRequestsSubdeviceRange { get; } + public SubdevicesForRequests[]? SetRequestsSubdeviceRange { get; } [JsonPropertyName("set_response_subdevice_range")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyOrder(17)] - public readonly SubdevicesForResponses[]? SetResponseSubdeviceRange { get; } + public SubdevicesForResponses[]? SetResponseSubdeviceRange { get; } [JsonPropertyName("get_request")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyOrder(12)] - public readonly Command? GetRequest { get; } + public Command? GetRequest { get; } [JsonPropertyName("get_response")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyOrder(14)] - public readonly Command? GetResponse { get; } + public Command? GetResponse { get; } [JsonPropertyName("set_request")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyOrder(16)] - public readonly Command? SetRequest { get; } + public Command? SetRequest { get; } [JsonPropertyName("set_response")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyOrder(18)] - public readonly Command? SetResponse { get; } + public Command? SetResponse { get; } [JsonConstructor] public MetadataJSONObjectDefine( @@ -84,10 +85,96 @@ public MetadataJSONObjectDefine( SetRequestsSubdeviceRange = setRequestsSubdeviceRange; SetResponseSubdeviceRange = setResponseSubdeviceRange; - GetRequest = getRequest; - GetResponse = getResponse; - SetRequest = setRequest; - SetResponse = setResponse; + //GetRequest = getRequest; + //GetResponse = getResponse; + //SetRequest = setRequest; + //SetResponse = setResponse; + + if (getRequest.HasValue) + GetRequest = setReferenceObjects(getRequest.Value); + if (getResponse.HasValue) + GetResponse = setReferenceObjects(getResponse.Value); + if (setRequest.HasValue) + SetRequest = setReferenceObjects(setRequest.Value); + if (setResponse.HasValue) + SetResponse = setReferenceObjects(setResponse.Value); + + + Command setReferenceObjects(Command command) + { + if (command.SingleField.HasValue) + { + var result= setReferenceObjects(command.SingleField.Value); + if (!result.Equals(command.SingleField.Value)) + return new Command(result); + } + + if (command.ListOfFields != null) + { + List listOfFields = new List(); + foreach (OneOfTypes oneOf in command.ListOfFields) + { + var result = setReferenceObjects(oneOf); + if (!result.Equals(oneOf)) + listOfFields.Add(result); + else + listOfFields.Add(oneOf); + } + if (!listOfFields.SequenceEqual(command.ListOfFields)) + return new Command(listOfFields.ToArray()); + } + + return command; + + OneOfTypes setReferenceObjects(OneOfTypes oneOf) + { + if (!oneOf.ReferenceType.HasValue) + return oneOf; + + ReferenceType reference = oneOf.ReferenceType.Value; + + switch (reference.Command) + { + case Command.ECommandDublicte.GetRequest: + reference = new ReferenceType(reference.URI, getRequest?.ListOfFields[reference.Pointer].ObjectType); + break; + case Command.ECommandDublicte.GetResponse: + reference = new ReferenceType(reference.URI, getResponse?.ListOfFields[reference.Pointer].ObjectType); + break; + case Command.ECommandDublicte.SetRequest: + reference = new ReferenceType(reference.URI, setRequest?.ListOfFields[reference.Pointer].ObjectType); + break; + case Command.ECommandDublicte.SetResponse: + reference = new ReferenceType(reference.URI, setResponse?.ListOfFields[reference.Pointer].ObjectType); + break; + } + return new OneOfTypes(reference); + } + } + } + + public void GetCommand(Command.ECommandDublicte eCommand,out Command? command) + { + command = null; + switch (eCommand) + { + case Command.ECommandDublicte.GetRequest: + command = GetRequest.Value; + break; + case Command.ECommandDublicte.GetResponse: + command = GetResponse.Value; + break; + case Command.ECommandDublicte.SetRequest: + command = SetRequest.Value; + break; + case Command.ECommandDublicte.SetResponse: + command = SetResponse.Value; + break; + } + if (command.HasValue) + if (command.Value.EnumValue.HasValue) + GetCommand(command.Value.EnumValue.Value, out command); + } public override string ToString() diff --git a/RDMSharp/RDM/PDL.cs b/RDMSharp/RDM/PDL.cs new file mode 100644 index 0000000..c951daf --- /dev/null +++ b/RDMSharp/RDM/PDL.cs @@ -0,0 +1,64 @@ +using System; +using System.Linq; + +namespace RDMSharp.RDM +{ + public readonly struct PDL + { + public const uint MAX_LENGTH = 0xE7 * 0xFF; + public readonly uint? Value { get; } + public readonly uint? MinLength { get; } + public readonly uint? MaxLength { get; } + + public PDL() + { + Value = 0; + } + public PDL(uint value) : this() + { + if (value >= MAX_LENGTH) + throw new ArgumentOutOfRangeException($"The Parameter {nameof(value)} should be in range of 0 - {MAX_LENGTH}"); + + Value = value; + } + + public PDL(uint minLength, uint maxLength) : this() + { + if (minLength > MAX_LENGTH) + throw new ArgumentOutOfRangeException($"The Parameter {nameof(minLength)} should be in range of 0 - {MAX_LENGTH}"); + if (maxLength > MAX_LENGTH) + throw new ArgumentOutOfRangeException($"The Parameter {nameof(maxLength)} should be in range of 0 - {MAX_LENGTH}"); + + if (minLength == maxLength) + Value = minLength; + else + { + MinLength = Math.Min(minLength, maxLength); + MaxLength = Math.Max(minLength, maxLength); + Value = null; + } + } + + public PDL(params PDL[] pdls) + { + uint value = 0, min = 0, max = 0; + + foreach (PDL pdl in pdls.Where(p => p.Value.HasValue)) + value += pdl.Value.Value; + + foreach (PDL pdl in pdls.Where(p => p.MinLength.HasValue)) + min += pdl.MinLength.Value; + foreach (PDL pdl in pdls.Where(p => p.MaxLength.HasValue)) + max += pdl.MaxLength.Value; + + if (min == max) + Value = Math.Min(MAX_LENGTH, value + min); + else + { + MinLength = Math.Min(MAX_LENGTH, value + Math.Min(min, max)); + MaxLength = Math.Min(MAX_LENGTH, value + Math.Max(min, max)); + Value = null; + } + } + } +} diff --git a/RDMSharpTests/MetadataJSONObjectDefineTestSubject.cs b/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTestSubject.cs similarity index 92% rename from RDMSharpTests/MetadataJSONObjectDefineTestSubject.cs rename to RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTestSubject.cs index 9652aab..7cf019b 100644 --- a/RDMSharpTests/MetadataJSONObjectDefineTestSubject.cs +++ b/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTestSubject.cs @@ -2,7 +2,7 @@ using System.Collections.Concurrent; using System.Reflection; -namespace RDMSharpTests +namespace RDMSharpTests.Metadata.JSON { public class MetadataJSONObjectDefineTestSubject { @@ -15,7 +15,7 @@ internal static string[] GetResources() private static object[] getTestSubjects() { List instances = new List(); - List metadataVersionList= new List(); + List metadataVersionList = new List(); metadataVersionList.AddRange(MetadataFactory.GetResources().Select(r => new MetadataVersion(r))); var schemaList = MetadataFactory.GetMetadataSchemaVersions(); ConcurrentDictionary versionSchemas = new ConcurrentDictionary(); @@ -38,7 +38,7 @@ private static object[] getTestSubjects() schema = new MetadataBag(_schema); versionSchemas.TryAdd(_schema.Version, schema); } - instances.Add(new MetadataJSONObjectDefineTestSubject(schema, new MetadataBag(mv.Version,mv.Name,mv.IsSchema,getContent(mv.Path),mv.Path))); + instances.Add(new MetadataJSONObjectDefineTestSubject(schema, new MetadataBag(mv.Version, mv.Name, mv.IsSchema, getContent(mv.Path), mv.Path))); } return instances.ToArray(); } diff --git a/RDMSharpTests/MetadataJSONObjectDefineTests.cs b/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTests.cs similarity index 87% rename from RDMSharpTests/MetadataJSONObjectDefineTests.cs rename to RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTests.cs index 49eda4b..9132a2b 100644 --- a/RDMSharpTests/MetadataJSONObjectDefineTests.cs +++ b/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTests.cs @@ -1,13 +1,13 @@ using Json.Schema; -using RDMSharp.Metadata; -using System.Text.Json; -using System.Text.Json.Nodes; using Newtonsoft.Json.Linq; +using RDMSharp.Metadata; using RDMSharp.Metadata.JSON; -using NUnit.Framework.Internal.Commands; using RDMSharp.Metadata.JSON.OneOfTypes; +using RDMSharp.RDM; +using System.Text.Json; +using System.Text.Json.Nodes; -namespace RDMSharpTests +namespace RDMSharpTests.Metadata.JSON { [TestFixtureSource(typeof(MetadataJSONObjectDefineTestSubject), nameof(MetadataJSONObjectDefineTestSubject.TestSubjects))] public class MetadataJSONObjectDefineTests @@ -69,7 +69,7 @@ public void TestDeseriaizeAndSerialize() [Test] public void TestDeseriaizedObject() { - MetadataJSONObjectDefine deserialized = new MetadataJSONObjectDefine(); + MetadataJSONObjectDefine deserialized = null; testString(testSubject.Define.ToString()); try { @@ -110,16 +110,36 @@ public void TestDeseriaizedObject() } if (deserialized.GetRequest != null) + { testCommand(deserialized.GetRequest.Value); + deserialized.GetCommand(Command.ECommandDublicte.GetRequest, out Command? command); + if (command != null) + testCommand(command.Value); + } if (deserialized.GetResponse != null) + { testCommand(deserialized.GetResponse.Value); + deserialized.GetCommand(Command.ECommandDublicte.GetResponse, out Command? command); + if (command != null) + testCommand(command.Value); + } if (deserialized.SetRequest != null) + { testCommand(deserialized.SetRequest.Value); + deserialized.GetCommand(Command.ECommandDublicte.SetRequest, out Command? command); + if (command != null) + testCommand(command.Value); + } if (deserialized.SetResponse != null) + { testCommand(deserialized.SetResponse.Value); + deserialized.GetCommand(Command.ECommandDublicte.SetResponse, out Command? command); + if (command != null) + testCommand(command.Value); + } static void testString(string str) @@ -132,19 +152,24 @@ static void testString(string str) static void testCommand(Command command) { testString(command.ToString()!); - if(command.EnumValue is Command.ECommandDublicte _enum) + PDL? pdl = null; + if (command.EnumValue is Command.ECommandDublicte _enum) { Assert.That(command.GetIsEmpty(), Is.False); testString(_enum.ToString()!); return; } - else if (command.SingleField is OneOfTypes singleField) + + Assert.DoesNotThrow(() => { pdl = command.GetDataLength(); }); + Assert.That(pdl.HasValue, Is.True); + + if (command.SingleField is OneOfTypes singleField) { Assert.That(command.GetIsEmpty(), Is.False); testString(singleField.ToString()!); if (singleField.ObjectType is CommonPropertiesForNamed common) testCommon(common); - else if(singleField.ReferenceType is ReferenceType reference) + else if (singleField.ReferenceType is ReferenceType reference) testReference(reference); return; } diff --git a/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs b/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs new file mode 100644 index 0000000..a5752ee --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs @@ -0,0 +1,28 @@ +using RDMSharp.Metadata.JSON.OneOfTypes; +using RDMSharp.RDM; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestBitFieldType + { + [Test] + public void TestMany() + { + var bitTypes=new BitType[2]; + bitTypes[0] = new BitType("NAME11", "DISPLAY_NAME11", "NOTES11", null, null, 2, false, false); + bitTypes[1] = new BitType("NAME22", "DISPLAY_NAME22", "NOTES22", null, null, 4, false, false); + var bitFieldType = new BitFieldType("NAME", "DISPLAY_NAME", "NOTES", null, "bitField",16, false, bitTypes); + Assert.That(bitFieldType.Size, Is.EqualTo(16)); + Assert.That(bitFieldType.Bits, Has.Length.EqualTo(2)); + + Assert.DoesNotThrow(() => + { + PDL pdl = bitFieldType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(2)); + }); + + Assert.Throws(typeof(ArgumentException), () => bitFieldType = new BitFieldType("NAME", "DISPLAY_NAME", "NOTES", null, "botField", 16, false, bitTypes)); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => bitFieldType = new BitFieldType("NAME", "DISPLAY_NAME", "NOTES", null, "bitField", 7, false, bitTypes)); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestBitType.cs b/RDMSharpTests/Metadata/JSON/TestBitType.cs new file mode 100644 index 0000000..1a4730a --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestBitType.cs @@ -0,0 +1,15 @@ +using RDMSharp.Metadata.JSON.OneOfTypes; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestBitType + { + [Test] + public void TestMany() + { + var bitType = new BitType("NAME", "DISPLAY_NAME", "NOTES", null, "bit", 1, true, false); + Assert.That(bitType.Index, Is.EqualTo(1)); + Assert.Throws(typeof(NotSupportedException), () => bitType.GetDataLength()); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestBooleanType.cs b/RDMSharpTests/Metadata/JSON/TestBooleanType.cs new file mode 100644 index 0000000..4ac0a76 --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestBooleanType.cs @@ -0,0 +1,41 @@ +using RDMSharp.Metadata.JSON.OneOfTypes; +using RDMSharp.RDM; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestBooleanType + { + [Test] + public void TestMany() + { + var labeledBooleanType = new LabeledBooleanType[2]; + labeledBooleanType[0] = new LabeledBooleanType("NAME11", "DISPLAY_NAME11", "NOTES11", null, false); + labeledBooleanType[1] = new LabeledBooleanType("NAME22", "DISPLAY_NAME22", "NOTES22", null, true); + var booleanType = new BooleanType("NAME", "DISPLAY_NAME", "NOTES", null, "boolean", labeledBooleanType); + Assert.That(booleanType.Labels, Has.Length.EqualTo(2)); + + Assert.DoesNotThrow(() => + { + PDL pdl = booleanType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(1)); + }); + + Assert.Throws(typeof(ArgumentException), () => booleanType = new BooleanType("NAME", "DISPLAY_NAME", "NOTES", null, "bolean", labeledBooleanType)); + + labeledBooleanType = new LabeledBooleanType[1]; + labeledBooleanType[0] = new LabeledBooleanType("NAME11", "DISPLAY_NAME11", "NOTES11", null, false); + Assert.Throws(typeof(ArgumentException), () => booleanType = new BooleanType("NAME", "DISPLAY_NAME", "NOTES", null, "boolean", labeledBooleanType)); + + labeledBooleanType = new LabeledBooleanType[3]; + labeledBooleanType[0] = new LabeledBooleanType("NAME11", "DISPLAY_NAME11", "NOTES11", null, false); + labeledBooleanType[1] = new LabeledBooleanType("NAME22", "DISPLAY_NAME22", "NOTES22", null, true); + labeledBooleanType[2] = new LabeledBooleanType("NAME33", "DISPLAY_NAME33", "NOTES33", null, false); + Assert.Throws(typeof(ArgumentException), () => booleanType = new BooleanType("NAME", "DISPLAY_NAME", "NOTES", null, "boolean", labeledBooleanType)); + + labeledBooleanType = new LabeledBooleanType[2]; + labeledBooleanType[0] = new LabeledBooleanType("NAME11", "DISPLAY_NAME11", "NOTES11", null, false); + labeledBooleanType[1] = new LabeledBooleanType("NAME22", "DISPLAY_NAME22", "NOTES22", null, false); + Assert.Throws(typeof(ArgumentException), () => booleanType = new BooleanType("NAME", "DISPLAY_NAME", "NOTES", null, "boolean", labeledBooleanType)); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestBytesType.cs b/RDMSharpTests/Metadata/JSON/TestBytesType.cs new file mode 100644 index 0000000..6b05b3a --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestBytesType.cs @@ -0,0 +1,45 @@ +using RDMSharp.Metadata.JSON.OneOfTypes; +using RDMSharp.RDM; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestBytesType + { + [Test] + public void TestMany() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, null, null); + Assert.That(bytesType.MinLength, Is.Null); + Assert.That(bytesType.MaxLength, Is.Null); + + bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 1, null); + Assert.That(bytesType.MinLength, Is.EqualTo(1)); + Assert.That(bytesType.MaxLength, Is.Null); + + Assert.DoesNotThrow(() => + { + PDL pdl = bytesType.GetDataLength(); + Assert.That(pdl.Value, Is.Null); + Assert.That(pdl.MinLength, Is.EqualTo(1)); + Assert.That(pdl.MaxLength, Is.EqualTo(PDL.MAX_LENGTH)); + }); + + bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 1, 3); + Assert.That(bytesType.MinLength, Is.EqualTo(1)); + Assert.That(bytesType.MaxLength, Is.EqualTo(3)); + + Assert.DoesNotThrow(() => + { + PDL pdl = bytesType.GetDataLength(); + Assert.That(pdl.Value, Is.Null); + Assert.That(pdl.MinLength, Is.EqualTo(1)); + Assert.That(pdl.MaxLength, Is.EqualTo(3)); + }); + + Assert.Throws(typeof(ArgumentException), () => bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bites", null, 1, 5)); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 6, 5)); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 4294567890, null)); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 2, 4294567890)); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestCommand.cs b/RDMSharpTests/Metadata/JSON/TestCommand.cs new file mode 100644 index 0000000..09bfda6 --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestCommand.cs @@ -0,0 +1,15 @@ +using RDMSharp.Metadata.JSON; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestCommand + { + [Test] + public void TestMany() + { + var command = new Command( Command.ECommandDublicte.GetResponse); + Assert.That(command.GetIsEmpty(), Is.False); + Assert.Throws(typeof(NotSupportedException), () => command.GetDataLength()); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestCompoundType.cs b/RDMSharpTests/Metadata/JSON/TestCompoundType.cs new file mode 100644 index 0000000..3090f79 --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestCompoundType.cs @@ -0,0 +1,29 @@ +using RDMSharp.Metadata.JSON.OneOfTypes; +using RDMSharp.RDM; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestCompoundType + { + [Test] + public void TestMany() + { + OneOfTypes[] oneOf = new OneOfTypes[2]; + oneOf[0] = new OneOfTypes(new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)); + oneOf[1] = new OneOfTypes(new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int8, null, null, null, null, null, null)); + + var compoundType = new CompoundType("NAME", "DISPLAY_NAME", "NOTES", null, "compound", oneOf); + Assert.That(compoundType.Subtypes, Has.Length.EqualTo(2)); + + Assert.DoesNotThrow(() => + { + PDL pdl = compoundType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(2)); + }); + + Assert.Throws(typeof(ArgumentException), () => compoundType = new CompoundType("NAME", "DISPLAY_NAME", "NOTES", null, "kompound", oneOf)); + Assert.Throws(typeof(ArgumentException), () => compoundType = new CompoundType("NAME", "DISPLAY_NAME", "NOTES", null, "compound", null)); + Assert.Throws(typeof(ArgumentException), () => compoundType = new CompoundType("NAME", "DISPLAY_NAME", "NOTES", null, "compound", new OneOfTypes[0])); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestIntegerType.cs b/RDMSharpTests/Metadata/JSON/TestIntegerType.cs new file mode 100644 index 0000000..d6e8628 --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestIntegerType.cs @@ -0,0 +1,151 @@ +using RDMSharp.Metadata.JSON.OneOfTypes; +using RDMSharp.RDM; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestIntegerType + { + [Test] + public void TestManyInt8() + { + var integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int8, null, null, null, null, null, null); + Assert.That(integerType.Type, Is.EqualTo(EIntegerType.Int8)); + + Assert.DoesNotThrow(() => + { + PDL pdl = integerType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(1)); + }); + + Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)); + } + [Test] + public void TestManyUInt8() + { + var integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null); + Assert.That(integerType.Type, Is.EqualTo(EIntegerType.UInt8)); + + Assert.DoesNotThrow(() => + { + PDL pdl = integerType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(1)); + }); + + Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int8, null, null, null, null, null, null)); + } + [Test] + public void TestManyInt16() + { + var integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int16, null, null, null, null, null, null); + Assert.That(integerType.Type, Is.EqualTo(EIntegerType.Int16)); + + Assert.DoesNotThrow(() => + { + PDL pdl = integerType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(2)); + }); + + Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt16, null, null, null, null, null, null)); + } + [Test] + public void TestManyUInt16() + { + var integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt16, null, null, null, null, null, null); + Assert.That(integerType.Type, Is.EqualTo(EIntegerType.UInt16)); + + Assert.DoesNotThrow(() => + { + PDL pdl = integerType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(2)); + }); + + Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int16, null, null, null, null, null, null)); + } + [Test] + public void TestManyInt32() + { + var integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int32, null, null, null, null, null, null); + Assert.That(integerType.Type, Is.EqualTo(EIntegerType.Int32)); + + Assert.DoesNotThrow(() => + { + PDL pdl = integerType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(4)); + }); + + Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt32, null, null, null, null, null, null)); + } + [Test] + public void TestManyUInt32() + { + var integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt32, null, null, null, null, null, null); + Assert.That(integerType.Type, Is.EqualTo(EIntegerType.UInt32)); + + Assert.DoesNotThrow(() => + { + PDL pdl = integerType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(4)); + }); + + Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int32, null, null, null, null, null, null)); + } + [Test] + public void TestManyInt64() + { + var integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int64, null, null, null, null, null, null); + Assert.That(integerType.Type, Is.EqualTo(EIntegerType.Int64)); + + Assert.DoesNotThrow(() => + { + PDL pdl = integerType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(8)); + }); + + Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt64, null, null, null, null, null, null)); + } + [Test] + public void TestManyUInt64() + { + var integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt64, null, null, null, null, null, null); + Assert.That(integerType.Type, Is.EqualTo(EIntegerType.UInt64)); + + Assert.DoesNotThrow(() => + { + PDL pdl = integerType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(8)); + }); + + Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int64, null, null, null, null, null, null)); + } +#if NET7_0_OR_GREATER + [Test] + public void TestManyInt128() + { + var integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int128, null, null, null, null, null, null); + Assert.That(integerType.Type, Is.EqualTo(EIntegerType.Int128)); + + Assert.DoesNotThrow(() => + { + PDL pdl = integerType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(16)); + }); + + Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt128, null, null, null, null, null, null)); + } + [Test] + public void TestManyUInt128() + { + var integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt128, null, null, null, null, null, null); + Assert.That(integerType.Type, Is.EqualTo(EIntegerType.UInt128)); + + Assert.DoesNotThrow(() => + { + PDL pdl = integerType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(16)); + }); + + Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int128, null, null, null, null, null, null)); + } +#endif + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestLabeledBooleanType.cs b/RDMSharpTests/Metadata/JSON/TestLabeledBooleanType.cs new file mode 100644 index 0000000..b7c0b68 --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestLabeledBooleanType.cs @@ -0,0 +1,15 @@ +using RDMSharp.Metadata.JSON.OneOfTypes; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestLabeledBooleanType + { + [Test] + public void TestMany() + { + var labeledBooleanType = new LabeledBooleanType("NAME", "DISPLAY_NAME", "NOTES", null, true); + Assert.That(labeledBooleanType.Value, Is.True); + Assert.Throws(typeof(NotSupportedException), () => labeledBooleanType.GetDataLength()); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestLabeledIntegerType.cs b/RDMSharpTests/Metadata/JSON/TestLabeledIntegerType.cs new file mode 100644 index 0000000..9008fba --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestLabeledIntegerType.cs @@ -0,0 +1,15 @@ +using RDMSharp.Metadata.JSON.OneOfTypes; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestLabeledIntegerType + { + [Test] + public void TestMany() + { + var labeledIntegerType = new LabeledIntegerType("NAME", "DISPLAY_NAME", "NOTES", null, 3); + Assert.That(labeledIntegerType.Value, Is.EqualTo(3)); + Assert.Throws(typeof(NotSupportedException), () => labeledIntegerType.GetDataLength()); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestListType.cs b/RDMSharpTests/Metadata/JSON/TestListType.cs new file mode 100644 index 0000000..f5f73ff --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestListType.cs @@ -0,0 +1,65 @@ +using RDMSharp.Metadata.JSON.OneOfTypes; +using RDMSharp.RDM; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestListType + { + [Test] + public void TestMany() + { + var listType = new ListType("NAME", "DISPLAY_NAME", "NOTES", null, "list", new OneOfTypes(new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)), null, null); + Assert.That(listType.MinItems, Is.Null); + Assert.That(listType.MaxItems, Is.Null); + + Assert.DoesNotThrow(() => + { + PDL pdl = listType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(0)); + }); + + Assert.Throws(typeof(ArgumentException), () => listType = new ListType("NAME", "DISPLAY_NAME", "NOTES", null, "lost", new OneOfTypes(new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)), null, null)); + Assert.Throws(typeof(ArgumentException), () => listType = new ListType("NAME", "DISPLAY_NAME", "NOTES", null, "list", new OneOfTypes(), null, null)); + + var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, null, null, 3, 10, null); + listType = new ListType("NAME", "DISPLAY_NAME", "NOTES", null, "list", new OneOfTypes(stringType), 1, 3); + Assert.DoesNotThrow(() => + { + PDL pdl = listType.GetDataLength(); + Assert.That(pdl.Value, Is.Null); + Assert.That(pdl.MinLength, Is.EqualTo(3)); + Assert.That(pdl.MaxLength, Is.EqualTo(30)); + }); + + stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, null, null,32, 32, null); + listType = new ListType("NAME", "DISPLAY_NAME", "NOTES", null, "list", new OneOfTypes(stringType), 1, 3); + Assert.DoesNotThrow(() => + { + PDL pdl = listType.GetDataLength(); + Assert.That(pdl.Value, Is.Null); + Assert.That(pdl.MinLength, Is.EqualTo(32)); + Assert.That(pdl.MaxLength, Is.EqualTo(96)); + }); + + stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, null, null, 32, 32, null); + listType = new ListType("NAME", "DISPLAY_NAME", "NOTES", null, "list", new OneOfTypes(stringType), null, 3); + Assert.DoesNotThrow(() => + { + PDL pdl = listType.GetDataLength(); + Assert.That(pdl.Value, Is.Null); + Assert.That(pdl.MinLength, Is.EqualTo(0)); + Assert.That(pdl.MaxLength, Is.EqualTo(96)); + }); + + stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, null, null, 32, 32, null); + listType = new ListType("NAME", "DISPLAY_NAME", "NOTES", null, "list", new OneOfTypes(stringType), 1, null); + Assert.DoesNotThrow(() => + { + PDL pdl = listType.GetDataLength(); + Assert.That(pdl.Value, Is.Null); + Assert.That(pdl.MinLength, Is.EqualTo(32)); + Assert.That(pdl.MaxLength, Is.EqualTo(PDL.MAX_LENGTH)); + }); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs b/RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs new file mode 100644 index 0000000..eb2cd33 --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs @@ -0,0 +1,23 @@ +using RDMSharp.Metadata.JSON.OneOfTypes; +using RDMSharp.RDM; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestPD_EnvelopeType + { + [Test] + public void TestMany() + { + var pdEnvelopeType = new PD_EnvelopeType("NAME", "DISPLAY_NAME", "NOTES", null, "pdEnvelope", 2); + Assert.That(pdEnvelopeType.Length, Is.EqualTo(2)); + + Assert.DoesNotThrow(() => + { + PDL pdl = pdEnvelopeType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(2)); + }); + + Assert.Throws(typeof(ArgumentException), () => pdEnvelopeType = new PD_EnvelopeType("NAME", "DISPLAY_NAME", "NOTES", null, "pdEnvelop", 2)); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/TestMetadataFactoryStuff.cs b/RDMSharpTests/Metadata/TestMetadataFactoryStuff.cs similarity index 98% rename from RDMSharpTests/TestMetadataFactoryStuff.cs rename to RDMSharpTests/Metadata/TestMetadataFactoryStuff.cs index 307437c..4bfbfa0 100644 --- a/RDMSharpTests/TestMetadataFactoryStuff.cs +++ b/RDMSharpTests/Metadata/TestMetadataFactoryStuff.cs @@ -1,6 +1,6 @@ using RDMSharp.Metadata; -namespace RDMSharpTests +namespace RDMSharpTests.Metadata { public class TestMetadataFactoryStuff { diff --git a/RDMSharpTests/TestManyObjects.cs b/RDMSharpTests/TestManyObjects.cs index 8c1b9b9..2af1335 100644 --- a/RDMSharpTests/TestManyObjects.cs +++ b/RDMSharpTests/TestManyObjects.cs @@ -1,3 +1,4 @@ +using RDMSharp.RDM; using System.Collections.Concurrent; using System.Reflection; @@ -245,7 +246,7 @@ public void TestSlot() }); } } - [Test] + [Test] public void TestGeneratedPersonality() { Assert.Throws(typeof(ArgumentOutOfRangeException), () => new GeneratedPersonality(0, "5CH RGB", @@ -284,5 +285,64 @@ public void TestGeneratedPersonality() Assert.That(pers.ID, Is.EqualTo(1)); }); } + [Test] + public void TestPDL() + { + Assert.Multiple(() => + { + PDL pdl = new PDL(); + Assert.That(pdl.Value.HasValue, Is.True); + Assert.That(pdl.MinLength.HasValue, Is.False); + Assert.That(pdl.MaxLength.HasValue, Is.False); + Assert.That(pdl.Value.Value, Is.EqualTo(0)); + + pdl = new PDL(13); + Assert.That(pdl.Value.HasValue, Is.True); + Assert.That(pdl.MinLength.HasValue, Is.False); + Assert.That(pdl.MaxLength.HasValue, Is.False); + Assert.That(pdl.Value.Value, Is.EqualTo(13)); + + + pdl = new PDL(3, 5); + Assert.That(pdl.Value.HasValue, Is.False); + Assert.That(pdl.MinLength.HasValue, Is.True); + Assert.That(pdl.MaxLength.HasValue, Is.True); + Assert.That(pdl.MinLength.Value, Is.EqualTo(3)); + Assert.That(pdl.MaxLength.Value, Is.EqualTo(5)); + + pdl = new PDL(5, 5); + Assert.That(pdl.Value.HasValue, Is.True); + Assert.That(pdl.MinLength.HasValue, Is.False); + Assert.That(pdl.MaxLength.HasValue, Is.False); + Assert.That(pdl.Value.Value, Is.EqualTo(5)); + + + List list = new List(); + list.Add(new PDL(1)); + list.Add(new PDL(2)); + list.Add(new PDL(3)); + pdl = new PDL(list.ToArray()); + Assert.That(pdl.Value.HasValue, Is.True); + Assert.That(pdl.MinLength.HasValue, Is.False); + Assert.That(pdl.MaxLength.HasValue, Is.False); + Assert.That(pdl.Value.Value, Is.EqualTo(6)); + + list.Clear(); + list.Add(new PDL(1, 2)); + list.Add(new PDL(1, 2)); + list.Add(new PDL(3, 4)); + pdl = new PDL(list.ToArray()); + Assert.That(pdl.Value.HasValue, Is.False); + Assert.That(pdl.MinLength.HasValue, Is.True); + Assert.That(pdl.MaxLength.HasValue, Is.True); + Assert.That(pdl.MinLength.Value, Is.EqualTo(5)); + Assert.That(pdl.MaxLength.Value, Is.EqualTo(8)); + + + Assert.Throws(typeof(ArgumentOutOfRangeException), () => new PDL(uint.MaxValue)); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => new PDL(uint.MaxValue, 9)); + Assert.Throws(typeof(ArgumentOutOfRangeException), () => new PDL(1, uint.MaxValue)); + }); + } } } \ No newline at end of file From 5a0bbe95a6853509960f7bfc752aa1e503e66988 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 19 Sep 2024 20:53:44 +0200 Subject: [PATCH 16/51] More Tests --- .../Metadata/JSON/OneOfTypes/IntegerType.cs | 2 +- .../Metadata/JSON/OneOfTypes/ReferenceType.cs | 2 + RDMSharp/Metadata/MetadataJSONObjectDefine.cs | 27 +++++++++-- .../JSON/MetadataJSONObjectDefineTests.cs | 2 + RDMSharpTests/Metadata/JSON/TestOneOfTypes.cs | 18 ++++++++ .../Metadata/JSON/TestReferenceType.cs | 27 +++++++++++ RDMSharpTests/Metadata/JSON/TestStringType.cs | 45 +++++++++++++++++++ RDMSharpTests/RDMSharpTests.csproj | 7 +++ ...IS_VALID_REFERENCE_TYPE_NOT_DEFINED_1.json | 11 +++++ ...IS_VALID_REFERENCE_TYPE_NOT_DEFINED_2.json | 11 +++++ ...IS_VALID_REFERENCE_TYPE_NOT_DEFINED_3.json | 11 +++++ ...IS_VALID_REFERENCE_TYPE_NOT_DEFINED_4.json | 11 +++++ .../Mocks/MOCK_INVALID_NO_GET_PAIR.json | 8 ++++ .../Mocks/MOCK_INVALID_NO_SET_PAIR.json | 8 ++++ .../Defines/Mocks/MOCK_REFERENCE_TYPE.json | 25 ++++++++++- .../Mocks/MOCK_SINGLE_FIELD_REFERENCE.json | 40 +++++++++++++++++ 16 files changed, 249 insertions(+), 6 deletions(-) create mode 100644 RDMSharpTests/Metadata/JSON/TestOneOfTypes.cs create mode 100644 RDMSharpTests/Metadata/JSON/TestReferenceType.cs create mode 100644 RDMSharpTests/Metadata/JSON/TestStringType.cs create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_1.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_2.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_3.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_4.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_NO_GET_PAIR.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_NO_SET_PAIR.json create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_SINGLE_FIELD_REFERENCE.json diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs index 974d2c3..ecfec7d 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs @@ -166,11 +166,11 @@ public override PDL GetDataLength() case EIntegerType.UInt64: return new PDL(8); - default: #if NET7_0_OR_GREATER case EIntegerType.Int128: case EIntegerType.UInt128: #endif + default: return new PDL(16); } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs index 03a82f2..c9fc608 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs @@ -42,6 +42,8 @@ public ReferenceType(string uri) } Pointer = ushort.Parse(segments[1]); } + else + throw new ArgumentException($"{nameof(uri)} has to start with \'#\'"); } public ReferenceType(string uri, CommonPropertiesForNamed referencedObject) : this(uri) { diff --git a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs index 3e48719..dbc20b0 100644 --- a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs +++ b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs @@ -1,7 +1,9 @@ using RDMSharp.Metadata.JSON; using RDMSharp.Metadata.JSON.OneOfTypes; +using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json; using System.Text.Json.Serialization; namespace RDMSharp.Metadata @@ -73,6 +75,12 @@ public MetadataJSONObjectDefine( Command? setRequest, Command? setResponse) { + if (getRequest.HasValue ^ getResponse.HasValue) + throw new JsonException($"Both {nameof(getRequest)} & {nameof(getResponse)} and have to be defined in {name}"); + + if (setRequest.HasValue ^ setResponse.HasValue) + throw new JsonException($"Both {nameof(setRequest)} & {nameof(setResponse)} and have to be defined in {name}"); + Name = name; DisplayName = displayName; Notes = notes; @@ -136,16 +144,27 @@ OneOfTypes setReferenceObjects(OneOfTypes oneOf) switch (reference.Command) { case Command.ECommandDublicte.GetRequest: - reference = new ReferenceType(reference.URI, getRequest?.ListOfFields[reference.Pointer].ObjectType); + if (!getRequest.HasValue) + throw new JsonException($"The Referenced Command ({reference.Command.ToString()})is not defined"); + reference = new ReferenceType(reference.URI, getRequest.Value.ListOfFields[reference.Pointer].ObjectType); break; + case Command.ECommandDublicte.GetResponse: - reference = new ReferenceType(reference.URI, getResponse?.ListOfFields[reference.Pointer].ObjectType); + if (!getResponse.HasValue) + throw new JsonException($"The Referenced Command ({reference.Command.ToString()})is not defined"); + reference = new ReferenceType(reference.URI, getResponse.Value.ListOfFields[reference.Pointer].ObjectType); break; + case Command.ECommandDublicte.SetRequest: - reference = new ReferenceType(reference.URI, setRequest?.ListOfFields[reference.Pointer].ObjectType); + if (!setRequest.HasValue) + throw new JsonException($"The Referenced Command ({reference.Command.ToString()})is not defined"); + reference = new ReferenceType(reference.URI, setRequest.Value.ListOfFields[reference.Pointer].ObjectType); break; + case Command.ECommandDublicte.SetResponse: - reference = new ReferenceType(reference.URI, setResponse?.ListOfFields[reference.Pointer].ObjectType); + if (!setResponse.HasValue) + throw new JsonException($"The Referenced Command ({reference.Command.ToString()})is not defined"); + reference = new ReferenceType(reference.URI, setResponse.Value.ListOfFields[reference.Pointer].ObjectType); break; } return new OneOfTypes(reference); diff --git a/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTests.cs b/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTests.cs index 9132a2b..26167bf 100644 --- a/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTests.cs +++ b/RDMSharpTests/Metadata/JSON/MetadataJSONObjectDefineTests.cs @@ -28,6 +28,8 @@ public void TestValidateAgainstSchema() Assert.That(result, Is.Not.Null); if (!testSubject.Define.Name.ToLower().Contains("invalid")) Assert.That(result.IsValid, Is.True); + else if (testSubject.Define.Name.ToLower().Contains("invalid_but_schema_is_valid")) + Assert.That(result.IsValid, Is.True); else Assert.That(result.IsValid, Is.False); } diff --git a/RDMSharpTests/Metadata/JSON/TestOneOfTypes.cs b/RDMSharpTests/Metadata/JSON/TestOneOfTypes.cs new file mode 100644 index 0000000..26e05ed --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestOneOfTypes.cs @@ -0,0 +1,18 @@ +using RDMSharp.Metadata.JSON.OneOfTypes; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestOneOfTypes + { + [Test] + public void TestMany() + { + var oneOfTypes = new OneOfTypes(); + Assert.That(oneOfTypes.IsEmpty, Is.True); + Assert.DoesNotThrow(() => + { + Assert.That(oneOfTypes.GetDataLength().Value, Is.EqualTo(0)); + }); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestReferenceType.cs b/RDMSharpTests/Metadata/JSON/TestReferenceType.cs new file mode 100644 index 0000000..9b10362 --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestReferenceType.cs @@ -0,0 +1,27 @@ +using RDMSharp.Metadata.JSON; +using RDMSharp.Metadata.JSON.OneOfTypes; +using RDMSharp.RDM; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestReferenceType + { + [Test] + public void TestMany() + { + var referenceType = new ReferenceType("#/get_request/0"); + Assert.That(referenceType.Command, Is.EqualTo(Command.ECommandDublicte.GetRequest)); + Assert.That(referenceType.Pointer, Is.EqualTo(0)); + + Assert.DoesNotThrow(() => + { + PDL pdl = referenceType.GetDataLength(); + Assert.That(pdl.Value, Is.EqualTo(0)); + Assert.That(pdl.MinLength, Is.Null); + Assert.That(pdl.MaxLength, Is.Null); + }); + + Assert.Throws(typeof(ArgumentException), () => referenceType = new ReferenceType("%/get_request/0")); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestStringType.cs b/RDMSharpTests/Metadata/JSON/TestStringType.cs new file mode 100644 index 0000000..734a5c1 --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestStringType.cs @@ -0,0 +1,45 @@ +using RDMSharp.Metadata.JSON.OneOfTypes; +using RDMSharp.RDM; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestStringType + { + [Test] + public void TestMany() + { + var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null,null,null,null,null,null,null); + Assert.That(stringType.MinLength, Is.Null); + Assert.That(stringType.MaxLength, Is.Null); + + + Assert.DoesNotThrow(() => + { + PDL pdl = stringType.GetDataLength(); + Assert.That(pdl.Value, Is.Null); + Assert.That(pdl.MinLength, Is.EqualTo(0)); + Assert.That(pdl.MaxLength, Is.EqualTo(PDL.MAX_LENGTH)); + }); + + stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, 1, 32, null, null, null); + Assert.DoesNotThrow(() => + { + PDL pdl = stringType.GetDataLength(); + Assert.That(pdl.Value, Is.Null); + Assert.That(pdl.MinLength, Is.EqualTo(1)); + Assert.That(pdl.MaxLength, Is.EqualTo(32)); + }); + + stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, 1, 32, 0, 34, null); + Assert.DoesNotThrow(() => + { + PDL pdl = stringType.GetDataLength(); + Assert.That(pdl.Value, Is.Null); + Assert.That(pdl.MinLength, Is.EqualTo(0)); + Assert.That(pdl.MaxLength, Is.EqualTo(34)); + }); + + Assert.Throws(typeof(ArgumentException), () => stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "sting", null, null, null, null, null, null, null)); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/RDMSharpTests.csproj b/RDMSharpTests/RDMSharpTests.csproj index 0d6e617..f193e40 100644 --- a/RDMSharpTests/RDMSharpTests.csproj +++ b/RDMSharpTests/RDMSharpTests.csproj @@ -29,14 +29,21 @@ + + + + + + + diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_1.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_1.json new file mode 100644 index 0000000..5862d9b --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_1.json @@ -0,0 +1,11 @@ +{ + "name": "MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_1", + "manufacturer_id": 3456, + "pid": 5678, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { "$ref": "#/set_response/0" } + ] +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_2.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_2.json new file mode 100644 index 0000000..6230687 --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_2.json @@ -0,0 +1,11 @@ +{ + "name": "MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_2", + "manufacturer_id": 3456, + "pid": 5678, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [], + "get_response": [ + { "$ref": "#/set_request/0" } + ] +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_3.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_3.json new file mode 100644 index 0000000..a591e55 --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_3.json @@ -0,0 +1,11 @@ +{ + "name": "MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_3", + "manufacturer_id": 3456, + "pid": 5678, + "version": 1, + "set_request_subdevice_range": [ "root", "subdevices" ], + "set_request": [], + "set_response": [ + { "$ref": "#/get_response/0" } + ] +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_4.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_4.json new file mode 100644 index 0000000..1cf0087 --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_4.json @@ -0,0 +1,11 @@ +{ + "name": "MOCK_INVALID_BUT_SCHEMA_IS_VALID_REFERENCE_TYPE_NOT_DEFINED_3", + "manufacturer_id": 3456, + "pid": 5678, + "version": 1, + "set_request_subdevice_range": [ "root", "subdevices" ], + "set_request": [], + "set_response": [ + { "$ref": "#/get_request/0" } + ] +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_NO_GET_PAIR.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_NO_GET_PAIR.json new file mode 100644 index 0000000..694408a --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_NO_GET_PAIR.json @@ -0,0 +1,8 @@ +{ + "name": "MOCK_INVALID_NO_GET_PAIR", + "manufacturer_id": 3456, + "pid": 5678, + "version": 1, + "get_request_subdevice_range": [ "root", 1 ], + "get_request": [] +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_NO_SET_PAIR.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_NO_SET_PAIR.json new file mode 100644 index 0000000..389a86f --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_NO_SET_PAIR.json @@ -0,0 +1,8 @@ +{ + "name": "MOCK_INVALID_NO_SET_PAIR", + "manufacturer_id": 3456, + "pid": 5678, + "version": 1, + "set_request_subdevice_range": [ "root", 1 ], + "set_request": [] +} \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_REFERENCE_TYPE.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_REFERENCE_TYPE.json index 0869137..9204deb 100644 --- a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_REFERENCE_TYPE.json +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_REFERENCE_TYPE.json @@ -3,7 +3,7 @@ "manufacturer_id": 3456, "pid": 5678, "version": 1, - "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request_subdevice_range": [ "root", "subdevices" ], "get_request": [ { "name": "root_personality", @@ -38,5 +38,28 @@ ], "get_response": [ { "$ref": "#/set_response/0" } + ], + "set_request": [], + "set_response": [ + { + "name": "root_personality", + "type": "uint8", + "ranges": [ + { + "minimum": 1, + "maximum": 255 + } + ] + }, + { + "name": "subdevice", + "type": "uint16", + "labels": [ + { + "name": "root", + "value": 0 + } + ] + } ] } \ No newline at end of file diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_SINGLE_FIELD_REFERENCE.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_SINGLE_FIELD_REFERENCE.json new file mode 100644 index 0000000..26c7c82 --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_SINGLE_FIELD_REFERENCE.json @@ -0,0 +1,40 @@ +{ + "name": "MOCK_SINGLE_FIELD_REFERENCE", + "manufacturer_id": 4365, + "pid": 4874, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "root_personality", + "type": "uint8", + "ranges": [ + { + "minimum": 1, + "maximum": 255 + } + ] + }, + { + "name": "subdevice", + "type": "uint16", + "labels": [ + { + "name": "root", + "value": 0 + } + ] + }, + { + "name": "subdevice_personality", + "type": "uint8", + "labels": [ + { + "name": "root", + "value": 0 + } + ] + } + ], + "get_response": { "$ref": "#/get_request/0" } +} \ No newline at end of file From c9202aaefd3c79673ca6c934d696376169f2a8e8 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Fri, 20 Sep 2024 14:23:27 +0200 Subject: [PATCH 17/51] Add more Tests, achieve 100% Code Coverage on Metadata for now --- RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs | 8 +------- RDMSharpTests/RDMSharpTests.csproj | 1 + .../1.0.0/Defines/Mocks/MOCK_INVALID_TYPE.json | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_TYPE.json diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs index ecfec7d..0128c3c 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs @@ -165,14 +165,8 @@ public override PDL GetDataLength() case EIntegerType.Int64: case EIntegerType.UInt64: return new PDL(8); - -#if NET7_0_OR_GREATER - case EIntegerType.Int128: - case EIntegerType.UInt128: -#endif - default: - return new PDL(16); } + return new PDL(16); } } } diff --git a/RDMSharpTests/RDMSharpTests.csproj b/RDMSharpTests/RDMSharpTests.csproj index f193e40..81eccf2 100644 --- a/RDMSharpTests/RDMSharpTests.csproj +++ b/RDMSharpTests/RDMSharpTests.csproj @@ -40,6 +40,7 @@ + diff --git a/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_TYPE.json b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_TYPE.json new file mode 100644 index 0000000..05ac1ef --- /dev/null +++ b/RDMSharpTests/Resources/JSON-Defines/1.0.0/Defines/Mocks/MOCK_INVALID_TYPE.json @@ -0,0 +1,14 @@ +{ + "name": "MOCK_INVALID_TYPE", + "manufacturer_id": 3456, + "pid": 5678, + "version": 1, + "get_request_subdevice_range": [ "root", "subdevices" ], + "get_request": [ + { + "name": "Invalid Type", + "type": "invalid" + } + ], + "get_response": [] +} \ No newline at end of file From ff47503fe3893b98a361541abf57a44279811139 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Sat, 21 Sep 2024 15:23:51 +0200 Subject: [PATCH 18/51] Start Implement Type Parsing --- RDMSharp/Metadata/DataTree.cs | 30 +++++ RDMSharp/Metadata/DefineNotFoundException.cs | 15 +++ .../Metadata/JSON/CommonPropertiesForNamed.cs | 2 + .../Metadata/JSON/OneOfTypes/BitFieldType.cs | 9 ++ RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs | 10 +- .../Metadata/JSON/OneOfTypes/BooleanType.cs | 18 +++ .../Metadata/JSON/OneOfTypes/BytesType.cs | 9 ++ .../Metadata/JSON/OneOfTypes/CompoundType.cs | 24 ++++ .../Metadata/JSON/OneOfTypes/IntegerType.cs | 45 +++++--- .../JSON/OneOfTypes/LabeledBooleanType.cs | 10 +- .../JSON/OneOfTypes/LabeledIntegerType.cs | 8 +- RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs | 20 ++++ .../Metadata/JSON/OneOfTypes/OneOfTypes.cs | 11 ++ .../JSON/OneOfTypes/PD_EnvelopeType.cs | 5 + .../Metadata/JSON/OneOfTypes/ReferenceType.cs | 4 + .../Metadata/JSON/OneOfTypes/StringType.cs | 38 +++++-- RDMSharp/Metadata/MetadataFactory.cs | 106 +++++++++++++++++- RDMSharp/Metadata/MetadataJSONObjectDefine.cs | 10 ++ RDMSharp/Metadata/ParameterBag.cs | 74 ++++++++++++ RDMSharp/RDM/PDL.cs | 10 +- RDMSharp/RDM/PeerToPeerProcess.cs | 18 +++ .../Resources/JSON-Defines/1.0.0/schema.json | 16 +++ RDMSharpTests/RDMSharpTests.csproj | 3 + 23 files changed, 464 insertions(+), 31 deletions(-) create mode 100644 RDMSharp/Metadata/DataTree.cs create mode 100644 RDMSharp/Metadata/DefineNotFoundException.cs create mode 100644 RDMSharp/Metadata/ParameterBag.cs create mode 100644 RDMSharp/RDM/PeerToPeerProcess.cs diff --git a/RDMSharp/Metadata/DataTree.cs b/RDMSharp/Metadata/DataTree.cs new file mode 100644 index 0000000..31c0b39 --- /dev/null +++ b/RDMSharp/Metadata/DataTree.cs @@ -0,0 +1,30 @@ +namespace RDMSharp.Metadata +{ + public readonly struct DataTree + { + public readonly string Name; + public readonly uint Index; + public readonly object? Value; + public readonly DataTree[]? Children; + + private DataTree(string name, uint index) + { + Name = name; + Index = index; + } + public DataTree(string name, uint index, object value) : this(name, index) + { + Value = value; + } + + public DataTree(string name, uint index, DataTree[] children) : this(name, index) + { + Children = children; + } + + public override string ToString() + { + return $"{Name}: {Value}"; + } + } +} diff --git a/RDMSharp/Metadata/DefineNotFoundException.cs b/RDMSharp/Metadata/DefineNotFoundException.cs new file mode 100644 index 0000000..602a6e7 --- /dev/null +++ b/RDMSharp/Metadata/DefineNotFoundException.cs @@ -0,0 +1,15 @@ +using System; + +namespace RDMSharp.Metadata +{ + public class DefineNotFoundException : Exception + { + public DefineNotFoundException() + { + } + + public DefineNotFoundException(string message) : base(message) + { + } + } +} diff --git a/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs b/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs index c61c8aa..0877ad1 100644 --- a/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs +++ b/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs @@ -22,6 +22,8 @@ public abstract class CommonPropertiesForNamed public abstract PDL GetDataLength(); + public abstract byte[] ParsePayloadToData(DataTree dataTree); + public override string ToString() { if(!string.IsNullOrWhiteSpace(DisplayName)) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs index bdcefca..3ce922a 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs @@ -75,5 +75,14 @@ public override string ToString() { return $"{Name} [ {string.Join("; ", Bits.Select(b => b.ToString()))} ]"; } + public override byte[] ParsePayloadToData(DataTree dataTree) + { + if (!string.Equals(dataTree.Name, this.Name)) + throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); + + /// ToDo + + throw new ArithmeticException($"The given Object from {nameof(dataTree.Value)} can't be parsed"); + } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs index c523666..ac39b6a 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs @@ -1,4 +1,5 @@ -using System.Text.Json.Serialization; +using System; +using System.Text.Json.Serialization; using RDMSharp.RDM; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -60,7 +61,12 @@ public BitType(string name, public override PDL GetDataLength() { - throw new System.NotSupportedException(); + throw new NotSupportedException(); + } + + public override byte[] ParsePayloadToData(DataTree dataTree) + { + throw new NotSupportedException(); } public override string ToString() diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs index d5d1b9d..58f7016 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs @@ -1,4 +1,5 @@ using RDMSharp.RDM; +using System; using System.Linq; using System.Text.Json.Serialization; @@ -71,5 +72,22 @@ public override PDL GetDataLength() { return new PDL(1); } + + public override byte[] ParsePayloadToData(DataTree dataTree) + { + if (!string.Equals(dataTree.Name, this.Name)) + throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); + if(dataTree.Value is bool value) + { + switch (value) + { + case false: + return new byte[] { 0x00 }; + case true: + return new byte[] { 0x01 }; + } + } + throw new ArithmeticException($"The given Object from {nameof(dataTree.Value)} can't be parsed"); + } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs index 26df217..0b65a32 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs @@ -81,5 +81,14 @@ public override PDL GetDataLength() { return new PDL((uint)(MinLength ?? 1), (uint)(MaxLength ?? PDL.MAX_LENGTH)); } + public override byte[] ParsePayloadToData(DataTree dataTree) + { + if (!string.Equals(dataTree.Name, this.Name)) + throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); + + /// ToDo + + throw new ArithmeticException($"The given Object from {nameof(dataTree.Value)} can't be parsed"); + } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs index cf17d7c..54160a0 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs @@ -1,4 +1,6 @@ using RDMSharp.RDM; +using System.Collections.Generic; +using System; using System.Linq; using System.Text.Json.Serialization; @@ -57,5 +59,27 @@ public override PDL GetDataLength() { return new PDL(Subtypes.Select(s => s.GetDataLength()).ToArray()); } + public override byte[] ParsePayloadToData(DataTree dataTree) + { + if (!string.Equals(dataTree.Name, this.Name)) + throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); + + if(dataTree.Children.Length!= Subtypes.Length) + throw new ArithmeticException($"The given {nameof(dataTree)} and {nameof(Subtypes)} has different length "); + + List data = new List(); + for (int i = 0; i < dataTree.Children.Length; i++) + { + if (Subtypes[i].IsEmpty()) + throw new ArithmeticException($"The given Object from {nameof(Subtypes)}[{i}] is Empty"); + + data.AddRange(Subtypes[i].ParsePayloadToData(dataTree.Children[i])); + } + + if (GetDataLength().IsValid(data.Count)) + throw new ArithmeticException($"Parsed DataLengt not fits Calculated DataLength"); + + return data.ToArray(); + } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs index 0128c3c..2e9c5c1 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs @@ -90,7 +90,22 @@ public IntegerType(string name, int? prefixPower, int? prefixBase) : base() { - T dummy = default; + validateType(type); + Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; + Type = type; + Labels = labels; + RestrictToLabeled = restrictToLabeled; + Ranges = ranges; + Units = units; + PrefixPower = prefixPower; + PrefixBase = prefixBase; + } + + private static void validateType(EIntegerType type, T dummy = default) + { switch (dummy) { case sbyte when type is not EIntegerType.Int8: @@ -124,18 +139,6 @@ public IntegerType(string name, throw new ArgumentException($"Argument {nameof(type)} has to be \"{EIntegerType.UInt128}\""); #endif } - - Name = name; - DisplayName = displayName; - Notes = notes; - Resources = resources; - Type = type; - Labels = labels; - RestrictToLabeled = restrictToLabeled; - Ranges = ranges; - Units = units; - PrefixPower = prefixPower; - PrefixBase = prefixBase; } public override string ToString() @@ -168,5 +171,21 @@ public override PDL GetDataLength() } return new PDL(16); } + public override byte[] ParsePayloadToData(DataTree dataTree) + { + if (!string.Equals(dataTree.Name, this.Name)) + throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); + + if(dataTree.Value is not T value) + throw new ArithmeticException($"The given Object from {nameof(dataTree.Value)} can't be parsed, it should be {typeof(T).Name}"); + + validateType(Type, value); + var data = Tools.ValueToData(dataTree.Value); + + if (GetDataLength().IsValid(data.Length)) + throw new ArithmeticException($"Parsed DataLengt not fits Calculated DataLength"); + + return data; + } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs index cffa971..42d52ad 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs @@ -1,4 +1,5 @@ -using System.Text.Json.Serialization; +using System; +using System.Text.Json.Serialization; using RDMSharp.RDM; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -47,7 +48,12 @@ public override string ToString() public override PDL GetDataLength() { - throw new System.NotSupportedException(); + throw new NotSupportedException(); + } + + public override byte[] ParsePayloadToData(DataTree dataTree) + { + throw new NotSupportedException(); } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs index 5a8e766..8e266ea 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs @@ -1,4 +1,5 @@ using RDMSharp.RDM; +using System; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -46,7 +47,12 @@ public override string ToString() } public override PDL GetDataLength() { - throw new System.NotSupportedException(); + throw new NotSupportedException(); + } + + public override byte[] ParsePayloadToData(DataTree dataTree) + { + throw new NotSupportedException(); } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs index 6bca31a..4dd4438 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs @@ -1,5 +1,6 @@ using RDMSharp.RDM; using System; +using System.Collections.Generic; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -104,5 +105,24 @@ public override PDL GetDataLength() return new PDL(min, max); } + public override byte[] ParsePayloadToData(DataTree dataTree) + { + if (!string.Equals(dataTree.Name, this.Name)) + throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); + + List data = new List(); + for (int i = 0; i < dataTree.Children.Length; i++) + { + if(ItemType.IsEmpty()) + throw new ArithmeticException($"The given Object from {nameof(ItemType)} is Empty"); + + data.AddRange(ItemType.ParsePayloadToData(dataTree.Children[i])); + } + + if (GetDataLength().IsValid(data.Count)) + throw new ArithmeticException($"Parsed DataLengt not fits Calculated DataLength"); + + return data.ToArray(); + } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs index d1493b0..be7552b 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs @@ -1,6 +1,7 @@ using RDMSharp.Metadata.JSON.Converter; using RDMSharp.RDM; using System; +using System.Collections.Generic; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -130,6 +131,16 @@ public PDL GetDataLength() { return ObjectType?.GetDataLength() ?? ReferenceType?.GetDataLength() ?? new PDL(); } + public byte[] ParsePayloadToData(DataTree dataTree) + { + CommonPropertiesForNamed objectType = ObjectType ?? ReferenceType?.ReferencedObject; + var data = objectType.ParsePayloadToData(dataTree); + + if (GetDataLength().IsValid(data.Length)) + throw new ArithmeticException($"Parsed DataLengt not fits Calculated DataLength"); + + return data; + } public override string ToString() { diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs index 4dd695f..706cd67 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs @@ -66,5 +66,10 @@ public override PDL GetDataLength() return new PDL(); } + + public override byte[] ParsePayloadToData(DataTree dataTree) + { + return new byte[0]; + } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs index c9fc608..fa0d822 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs @@ -53,6 +53,10 @@ public PDL GetDataLength() { return ReferencedObject?.GetDataLength() ?? new PDL(); } + public byte[] ParsePayloadToData(DataTree dataTree) + { + return ReferencedObject.ParsePayloadToData(dataTree); + } public override string ToString() { return URI; diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs index b459702..7750dab 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs @@ -1,4 +1,6 @@ using RDMSharp.RDM; +using System; +using System.Text; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -36,19 +38,19 @@ public class StringType : CommonPropertiesForNamed [JsonPropertyName("minLength")] [JsonPropertyOrder(31)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public ulong? MinLength { get; } + public uint? MinLength { get; } [JsonPropertyName("maxLength")] [JsonPropertyOrder(32)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public ulong? MaxLength { get; } + public uint? MaxLength { get; } [JsonPropertyName("minBytes")] [JsonPropertyOrder(41)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public ulong? MinBytes { get; } + public uint? MinBytes { get; } [JsonPropertyName("maxBytes")] [JsonPropertyOrder(42)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public ulong? MaxBytes { get; } + public uint? MaxBytes { get; } [JsonPropertyName("restrictToASCII")] [JsonPropertyOrder(51)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] @@ -63,14 +65,14 @@ public StringType(string name, string type, string format, string pattern, - ulong? minLength, - ulong? maxLength, - ulong? minBytes, - ulong? maxBytes, + uint? minLength, + uint? maxLength, + uint? minBytes, + uint? maxBytes, bool? restrictToASCII) { if (!"string".Equals(type)) - throw new System.ArgumentException($"Argument {nameof(type)} has to be \"string\""); + throw new ArgumentException($"Argument {nameof(type)} has to be \"string\""); Name = name; DisplayName = displayName; @@ -109,5 +111,23 @@ public override PDL GetDataLength() return new PDL(min, max.Value); } + public override byte[] ParsePayloadToData(DataTree dataTree) + { + if (!string.Equals(dataTree.Name, this.Name)) + throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); + + if (dataTree.Value is string @string) + { + if (MaxLength.HasValue) + @string = @string.Substring(0, (int)MaxLength); + + if (RestrictToASCII == true) + Encoding.ASCII.GetBytes(@string); + else + Encoding.UTF8.GetBytes(@string); + } + + throw new ArithmeticException($"The given Object from {nameof(dataTree.Value)} can't be parsed"); + } } } diff --git a/RDMSharp/Metadata/MetadataFactory.cs b/RDMSharp/Metadata/MetadataFactory.cs index b173b8c..1d56400 100644 --- a/RDMSharp/Metadata/MetadataFactory.cs +++ b/RDMSharp/Metadata/MetadataFactory.cs @@ -1,9 +1,15 @@ -using System.Collections.Concurrent; +using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Text.Json; using System.Text.Json.Nodes; using Json.Schema; +using RDMSharp.Metadata.JSON; +using RDMSharp.Metadata.JSON.OneOfTypes; + +[assembly: InternalsVisibleTo("RDMSharpTests")] namespace RDMSharp.Metadata { @@ -13,6 +19,7 @@ public static class MetadataFactory private const string JSON_ENDING = ".json"; private static List metadataVersionList; private static Dictionary> metadataVersionDefinesBagDictionary; + private static ConcurrentDictionary parameterBagDefineCache; public static IReadOnlyCollection MetadataVersionList { get @@ -36,7 +43,7 @@ private static void fillDefaultMetadataVersionList() if (metadataVersionDefinesBagDictionary == null) metadataVersionDefinesBagDictionary = new Dictionary>(); - + var schemaList = GetMetadataSchemaVersions(); ConcurrentDictionary versionSchemas= new ConcurrentDictionary(); @@ -69,5 +76,100 @@ public static IReadOnlyCollection GetMetadataDefineVersions() { return MetadataVersionList.Where(r => !r.IsSchema).ToList().AsReadOnly(); } + internal static MetadataJSONObjectDefine GetDefine(ParameterBag parameter) + { + if (parameterBagDefineCache == null) + parameterBagDefineCache = new ConcurrentDictionary(); + + if(parameterBagDefineCache.TryGetValue(parameter, out var define)) + return define; + + define = getDefine(parameter); + if (define != null) + { + parameterBagDefineCache.TryAdd(parameter, define); + return define; + } + throw new DefineNotFoundException($"{parameter}"); + } + private static MetadataJSONObjectDefine getDefine(ParameterBag parameter) + { + var version = GetMetadataSchemaVersions().First(); + var possibleDefines = metadataVersionDefinesBagDictionary[version].FindAll(d => d.PID == (ushort)parameter.PID && d.ManufacturerID == parameter.ManufacturerID); + if (possibleDefines.Count == 1) + return possibleDefines[0]; + + if (possibleDefines.Count > 1) + { + MetadataJSONObjectDefine define = possibleDefines.FirstOrDefault(d => d.DeviceModelID == null && d.SoftwareVersionID == null); + if (parameter.DeviceModelID != null) + { + possibleDefines = possibleDefines.Where(d => d.DeviceModelID == parameter.DeviceModelID).ToList(); + if (possibleDefines.Count == 1) + define = possibleDefines[0]; + else if (possibleDefines.Count > 1) + { + define = possibleDefines.FirstOrDefault(d => d.SoftwareVersionID == null) ?? define; + if (parameter.SoftwareVersionID != null) + { + define = possibleDefines.FirstOrDefault(d => d.SoftwareVersionID == parameter.SoftwareVersionID) ?? define; + + if (define == null) + define = possibleDefines.MinBy(d => parameter.SoftwareVersionID - d.SoftwareVersionID); + } + } + } + return possibleDefines.MaxBy(d => d.Version); + } + if (parameter.ManufacturerID == 0) + throw new InvalidOperationException($"{parameter.ManufacturerID} of 0 should lead to exact 1 Define"); + + + + throw new DefineNotFoundException($"{parameter}"); + } + + internal static byte[] ParsePayloadToData(MetadataJSONObjectDefine define, Command.ECommandDublicte commandType, object payload) + { + define.GetCommand(commandType, out Command? _command); + if (_command is not Command command) + throw new InvalidOperationException(); + + if (payload is DataTree dataTree) + { + OneOfTypes[] oneofTypes = null; + if (command.SingleField.HasValue) + oneofTypes = new OneOfTypes[] { command.SingleField.Value }; + else if (command.ListOfFields.Length != 0) + oneofTypes = command.ListOfFields; + + } + + throw new ArithmeticException(); + } + internal static object ParseDataToPayload(MetadataJSONObjectDefine define, Command.ECommandDublicte commandType, byte[] data) + { + define.GetCommand(commandType, out Command? _command); + if (_command is not Command command) + throw new InvalidOperationException(); + + throw new ArithmeticException(); + } + internal static byte[] GetRequestMessageData(ParameterBag parameter, object payloadData) + { + return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicte.GetRequest, payloadData); + } + internal static byte[] GetResponseMessageData(ParameterBag parameter, object payloadData) + { + return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicte.GetResponse, payloadData); + } + internal static byte[] SetRequestMessageData(ParameterBag parameter, object payloadData) + { + return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicte.SetRequest, payloadData); + } + internal static byte[] SetResponseMessageData(ParameterBag parameter, object payloadData) + { + return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicte.SetResponse, payloadData); + } } } diff --git a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs index dbc20b0..e8e23da 100644 --- a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs +++ b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs @@ -20,6 +20,12 @@ public class MetadataJSONObjectDefine public string? Notes { get; } [JsonPropertyName("manufacturer_id")] public ushort ManufacturerID { get; } + [JsonPropertyName("device_model_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public ushort? DeviceModelID { get; } + [JsonPropertyName("software_version_id")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public uint? SoftwareVersionID { get; } [JsonPropertyName("pid")] public ushort PID { get; } [JsonPropertyName("version")] @@ -64,6 +70,8 @@ public MetadataJSONObjectDefine( string? displayName, string? notes, ushort manufacturerID, + ushort deviceModelID, + ushort softwareVersionID, ushort pID, ushort version, SubdevicesForRequests[]? getRequestSubdeviceRange, @@ -85,6 +93,8 @@ public MetadataJSONObjectDefine( DisplayName = displayName; Notes = notes; ManufacturerID = manufacturerID; + DeviceModelID = deviceModelID; + SoftwareVersionID = softwareVersionID; PID = pID; Version = version; diff --git a/RDMSharp/Metadata/ParameterBag.cs b/RDMSharp/Metadata/ParameterBag.cs new file mode 100644 index 0000000..fc0df97 --- /dev/null +++ b/RDMSharp/Metadata/ParameterBag.cs @@ -0,0 +1,74 @@ +using System; + +namespace RDMSharp.Metadata +{ + internal readonly struct ParameterBag : IEquatable + { + public readonly ERDM_Parameter PID { get; } + public readonly ushort ManufacturerID { get; } + public readonly ushort? DeviceModelID { get; } + public readonly uint? SoftwareVersionID { get; } + + public ParameterBag(ERDM_Parameter pid, ushort manufacturerID = 0, ushort? deviceModelID = null, uint? softwareVersionID = null) + { + if ((ushort)pid >= 0x8000) + { + if (manufacturerID == 0) + throw new ArgumentNullException($"{nameof(pid)} in range 0x8000 -0xFFFF requires {nameof(manufacturerID)} != 0"); + } + else + { + manufacturerID = 0; + deviceModelID = null; + softwareVersionID = null; + } + + PID = pid; + ManufacturerID = manufacturerID; + DeviceModelID = deviceModelID; + SoftwareVersionID = softwareVersionID; + } + public override string ToString() + { + if (ManufacturerID != 0) + { + if (DeviceModelID != null) + { + if (SoftwareVersionID != null) + return $"{PID} ManufacturerID: {ManufacturerID}, DeviceModelID: {DeviceModelID}, SoftwareVersionID: {SoftwareVersionID}"; + return $"{PID} ManufacturerID: {ManufacturerID}, DeviceModelID: {DeviceModelID}"; + } + return $"{PID} ManufacturerID: {ManufacturerID}"; + } + return $"{PID}"; + } + + public override bool Equals(object obj) + { + return obj is ParameterBag bag && Equals(bag); + } + + public bool Equals(ParameterBag other) + { + return PID == other.PID && + ManufacturerID == other.ManufacturerID && + DeviceModelID == other.DeviceModelID && + SoftwareVersionID == other.SoftwareVersionID; + } + + public override int GetHashCode() + { + return HashCode.Combine(PID, ManufacturerID, DeviceModelID, SoftwareVersionID); + } + + public static bool operator ==(ParameterBag left, ParameterBag right) + { + return left.Equals(right); + } + + public static bool operator !=(ParameterBag left, ParameterBag right) + { + return !(left == right); + } + } +} diff --git a/RDMSharp/RDM/PDL.cs b/RDMSharp/RDM/PDL.cs index c951daf..e213398 100644 --- a/RDMSharp/RDM/PDL.cs +++ b/RDMSharp/RDM/PDL.cs @@ -21,7 +21,6 @@ public PDL(uint value) : this() Value = value; } - public PDL(uint minLength, uint maxLength) : this() { if (minLength > MAX_LENGTH) @@ -38,7 +37,6 @@ public PDL(uint minLength, uint maxLength) : this() Value = null; } } - public PDL(params PDL[] pdls) { uint value = 0, min = 0, max = 0; @@ -60,5 +58,13 @@ public PDL(params PDL[] pdls) Value = null; } } + + public bool IsValid(int length) + { + if (Value.HasValue) + return Value == length; + + return MinLength <= length && length <= MaxLength; + } } } diff --git a/RDMSharp/RDM/PeerToPeerProcess.cs b/RDMSharp/RDM/PeerToPeerProcess.cs new file mode 100644 index 0000000..f75fb01 --- /dev/null +++ b/RDMSharp/RDM/PeerToPeerProcess.cs @@ -0,0 +1,18 @@ +using RDMSharp.Metadata; +using System; + +namespace RDMSharp +{ + internal class PeerToPeerProcess + { + public PeerToPeerProcess(ERDM_Command command, ERDM_Parameter parameter, object payloadObject = null) + { + if (command != ERDM_Command.GET_COMMAND) + if (command != ERDM_Command.SET_COMMAND) + throw new ArgumentException($"{nameof(command)} should be {ERDM_Command.GET_COMMAND} or {ERDM_Command.SET_COMMAND}"); + + + //MetadataFactory. + } + } +} \ No newline at end of file diff --git a/RDMSharp/Resources/JSON-Defines/1.0.0/schema.json b/RDMSharp/Resources/JSON-Defines/1.0.0/schema.json index 1112a3a..f8fa984 100644 --- a/RDMSharp/Resources/JSON-Defines/1.0.0/schema.json +++ b/RDMSharp/Resources/JSON-Defines/1.0.0/schema.json @@ -14,6 +14,22 @@ "minimum": 0, "maximum": 65535 }, + "device_model_id": { + "$comment": "The Device Model ID is a 16-bit value determined by the manufacturer. Users may expect to see these values in the UI as hexadecimal.", + "title": "Device Model ID", + "description": "The Device Model ID.", + "type": "integer", + "minimum": 0, + "maximum": 65535 + }, + "software_version_id": { + "$comment": "The Software Version ID is a 32-bit value determined by the manufacturer.", + "title": "Software Version ID", + "description": "The Software Version ID.", + "type": "integer", + "minimum": 0, + "maximum": 4294967295 + }, "pid": { "title": "PID", "description": "The parameter ID.", diff --git a/RDMSharpTests/RDMSharpTests.csproj b/RDMSharpTests/RDMSharpTests.csproj index 81eccf2..e847399 100644 --- a/RDMSharpTests/RDMSharpTests.csproj +++ b/RDMSharpTests/RDMSharpTests.csproj @@ -49,5 +49,8 @@ + + + From c13e5b623abab1c7eb3714472887097782083e1d Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Tue, 24 Sep 2024 15:08:58 +0200 Subject: [PATCH 19/51] Fix Build --- .../Metadata/JSON/OneOfTypes/BooleanType.cs | 6 ++--- .../Metadata/JSON/OneOfTypes/CompoundType.cs | 4 +-- .../Metadata/JSON/OneOfTypes/OneOfTypes.cs | 1 - .../JSON/OneOfTypes/PD_EnvelopeType.cs | 3 ++- RDMSharp/Metadata/MetadataFactory.cs | 25 ++++++++++++------- RDMSharp/Metadata/MetadataJSONObjectDefine.cs | 19 +++++++++----- 6 files changed, 36 insertions(+), 22 deletions(-) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs index 58f7016..f4e5871 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs @@ -42,10 +42,10 @@ public BooleanType(string name, LabeledBooleanType[] labels) : base() { if (!"boolean".Equals(type)) - throw new System.ArgumentException($"Argument {nameof(type)} has to be \"boolean\""); + throw new ArgumentException($"Argument {nameof(type)} has to be \"boolean\""); if (((labels?.Length) ?? 2) != 2) - throw new System.ArgumentException($"Argument {nameof(labels)} has to be null oa an array of 2"); + throw new ArgumentException($"Argument {nameof(labels)} has to be null oa an array of 2"); Name = name; DisplayName = displayName; @@ -57,7 +57,7 @@ public BooleanType(string name, if (labels != null) { if (labels[0].Value == labels[1].Value) - throw new System.ArgumentException($"Argument {nameof(labels)}, both Values are the same, one has to be false, the other true"); + throw new ArgumentException($"Argument {nameof(labels)}, both Values are the same, one has to be false, the other true"); } } public override string ToString() diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs index 54160a0..17f4e00 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs @@ -42,10 +42,10 @@ public CompoundType(string name, OneOfTypes[] subtypes) { if (!"compound".Equals(type)) - throw new System.ArgumentException($"Argument {nameof(type)} has to be \"compound\""); + throw new ArgumentException($"Argument {nameof(type)} has to be \"compound\""); if (((subtypes?.Length) ?? 0) < 1) - throw new System.ArgumentException($"Argument {nameof(subtypes)} has to be at least a size of 1"); + throw new ArgumentException($"Argument {nameof(subtypes)} has to be at least a size of 1"); Name = name; DisplayName = displayName; diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs index be7552b..fd60845 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs @@ -1,7 +1,6 @@ using RDMSharp.Metadata.JSON.Converter; using RDMSharp.RDM; using System; -using System.Collections.Generic; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs index 706cd67..c7cc7f9 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs @@ -1,4 +1,5 @@ using RDMSharp.RDM; +using System; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -41,7 +42,7 @@ public PD_EnvelopeType(string name, byte? length) : base() { if (!"pdEnvelope".Equals(type)) - throw new System.ArgumentException($"Argument {nameof(type)} has to be \"pdEnvelope\""); + throw new ArgumentException($"Argument {nameof(type)} has to be \"pdEnvelope\""); Name = name; DisplayName = displayName; diff --git a/RDMSharp/Metadata/MetadataFactory.cs b/RDMSharp/Metadata/MetadataFactory.cs index 1d56400..9e33ba9 100644 --- a/RDMSharp/Metadata/MetadataFactory.cs +++ b/RDMSharp/Metadata/MetadataFactory.cs @@ -27,7 +27,7 @@ public static IReadOnlyCollection MetadataVersionList if (metadataVersionList == null) { metadataVersionList = new List(); - fillDefaultMetadataVersionList(); + metadataVersionList.AddRange(GetResources().Select(r => new MetadataVersion(r))); } return metadataVersionList.AsReadOnly(); } @@ -78,17 +78,24 @@ public static IReadOnlyCollection GetMetadataDefineVersions() } internal static MetadataJSONObjectDefine GetDefine(ParameterBag parameter) { - if (parameterBagDefineCache == null) - parameterBagDefineCache = new ConcurrentDictionary(); + try + { + if (parameterBagDefineCache == null) + parameterBagDefineCache = new ConcurrentDictionary(); - if(parameterBagDefineCache.TryGetValue(parameter, out var define)) - return define; + if (parameterBagDefineCache.TryGetValue(parameter, out var define)) + return define; - define = getDefine(parameter); - if (define != null) + define = getDefine(parameter); + if (define != null) + { + parameterBagDefineCache.TryAdd(parameter, define); + return define; + } + } + catch (Exception ex) { - parameterBagDefineCache.TryAdd(parameter, define); - return define; + } throw new DefineNotFoundException($"{parameter}"); } diff --git a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs index e8e23da..a3b52b7 100644 --- a/RDMSharp/Metadata/MetadataJSONObjectDefine.cs +++ b/RDMSharp/Metadata/MetadataJSONObjectDefine.cs @@ -12,24 +12,31 @@ public class MetadataJSONObjectDefine { [JsonPropertyName("name")] public string Name { get; } + [JsonPropertyName("displayName")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? DisplayName { get; } + [JsonPropertyName("notes")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Notes { get; } [JsonPropertyName("manufacturer_id")] public ushort ManufacturerID { get; } + [JsonPropertyName("device_model_id")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public ushort? DeviceModelID { get; } + [JsonPropertyName("software_version_id")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public uint? SoftwareVersionID { get; } + [JsonPropertyName("pid")] public ushort PID { get; } + [JsonPropertyName("version")] public ushort Version { get; } + [JsonPropertyName("get_request_subdevice_range")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyOrder(11)] @@ -70,8 +77,8 @@ public MetadataJSONObjectDefine( string? displayName, string? notes, ushort manufacturerID, - ushort deviceModelID, - ushort softwareVersionID, + ushort? deviceModelID, + uint? softwareVersionID, ushort pID, ushort version, SubdevicesForRequests[]? getRequestSubdeviceRange, @@ -103,10 +110,10 @@ public MetadataJSONObjectDefine( SetRequestsSubdeviceRange = setRequestsSubdeviceRange; SetResponseSubdeviceRange = setResponseSubdeviceRange; - //GetRequest = getRequest; - //GetResponse = getResponse; - //SetRequest = setRequest; - //SetResponse = setResponse; + GetRequest = getRequest; + GetResponse = getResponse; + SetRequest = setRequest; + SetResponse = setResponse; if (getRequest.HasValue) GetRequest = setReferenceObjects(getRequest.Value); From d8eb6f161fd28e48298f5998576bb96c8201ac9d Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Tue, 24 Sep 2024 18:01:50 +0200 Subject: [PATCH 20/51] WIP --- RDMSharp/Metadata/DataTree.cs | 17 ++- RDMSharp/Metadata/DataTreeIssue.cs | 12 ++ .../Metadata/JSON/CommonPropertiesForNamed.cs | 1 + .../Metadata/JSON/OneOfTypes/BitFieldType.cs | 40 +++++- RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs | 4 + .../Metadata/JSON/OneOfTypes/BooleanType.cs | 12 ++ .../Metadata/JSON/OneOfTypes/BytesType.cs | 9 ++ .../Metadata/JSON/OneOfTypes/CompoundType.cs | 14 ++ .../Metadata/JSON/OneOfTypes/IntegerType.cs | 47 ++++++ .../JSON/OneOfTypes/LabeledBooleanType.cs | 4 + .../JSON/OneOfTypes/LabeledIntegerType.cs | 4 + RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs | 35 +++++ .../Metadata/JSON/OneOfTypes/OneOfTypes.cs | 11 +- .../JSON/OneOfTypes/PD_EnvelopeType.cs | 5 + .../Metadata/JSON/OneOfTypes/ReferenceType.cs | 7 + .../Metadata/JSON/OneOfTypes/StringType.cs | 34 +++++ RDMSharp/RDM/Tools.cs | 135 +++++++++++++++--- 17 files changed, 361 insertions(+), 30 deletions(-) create mode 100644 RDMSharp/Metadata/DataTreeIssue.cs diff --git a/RDMSharp/Metadata/DataTree.cs b/RDMSharp/Metadata/DataTree.cs index 31c0b39..cf0088d 100644 --- a/RDMSharp/Metadata/DataTree.cs +++ b/RDMSharp/Metadata/DataTree.cs @@ -6,18 +6,25 @@ public readonly struct DataTree public readonly uint Index; public readonly object? Value; public readonly DataTree[]? Children; + public readonly DataTreeIssue[]? Issues; - private DataTree(string name, uint index) + private DataTree(string name, uint index, DataTreeIssue[]? issues = null) { Name = name; Index = index; + Issues = issues; } - public DataTree(string name, uint index, object value) : this(name, index) + public DataTree(DataTree dataTree, uint index) : this(dataTree.Name, index, dataTree.Issues) + { + Value = dataTree.Value; + Children = dataTree.Children; + } + public DataTree(string name, uint index, object value, DataTreeIssue[]? issues = null) : this(name, index, issues) { Value = value; } - public DataTree(string name, uint index, DataTree[] children) : this(name, index) + public DataTree(string name, uint index, DataTree[] children, DataTreeIssue[]? issues = null) : this(name, index, issues) { Children = children; } @@ -25,6 +32,6 @@ public DataTree(string name, uint index, DataTree[] children) : this(name, index public override string ToString() { return $"{Name}: {Value}"; - } + } } -} +} \ No newline at end of file diff --git a/RDMSharp/Metadata/DataTreeIssue.cs b/RDMSharp/Metadata/DataTreeIssue.cs new file mode 100644 index 0000000..6947e41 --- /dev/null +++ b/RDMSharp/Metadata/DataTreeIssue.cs @@ -0,0 +1,12 @@ +namespace RDMSharp.Metadata +{ + public readonly struct DataTreeIssue + { + public readonly string Description; + + public DataTreeIssue(string description) + { + Description = description; + } + } +} diff --git a/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs b/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs index 0877ad1..17f7e97 100644 --- a/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs +++ b/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs @@ -23,6 +23,7 @@ public abstract class CommonPropertiesForNamed public abstract PDL GetDataLength(); public abstract byte[] ParsePayloadToData(DataTree dataTree); + public abstract DataTree ParseDataToPayload(ref byte[] data); public override string ToString() { diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs index 3ce922a..777c4d0 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs @@ -1,6 +1,8 @@ using RDMSharp.RDM; using System; +using System.Collections.Generic; using System.Linq; +using System.Text; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -79,10 +81,44 @@ public override byte[] ParsePayloadToData(DataTree dataTree) { if (!string.Equals(dataTree.Name, this.Name)) throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); + if (dataTree.Children.Length != this.Bits.Length) + throw new ArithmeticException($"The given {nameof(dataTree.Children)}.{nameof(dataTree.Children.Length)}({dataTree.Children.Length}) not match {nameof(Bits)}.{nameof(Bits.Length)}({Bits.Length})"); - /// ToDo + bool[] data = new bool[Size]; + if (ValueForUnspecified.HasValue) + for (int i = 0; i < Size; i++) + data[i] = ValueForUnspecified.Value; - throw new ArithmeticException($"The given Object from {nameof(dataTree.Value)} can't be parsed"); + foreach (DataTree bitDataTree in dataTree.Children) + { + BitType bit = Bits.FirstOrDefault(b=>b.Name== bitDataTree.Name); + if (bit == null) + throw new ArithmeticException($"Can't find matching BitType {bitDataTree.Name}"); + if (bitDataTree.Index != bit.Index) + throw new ArithmeticException($"The given DataTree {nameof(bitDataTree.Index)}({bitDataTree.Index}) not match BitType {nameof(bit.Index)}({bit.Index})"); + if (bitDataTree.Value is not bool value) + throw new ArithmeticException($"DataTree VAlue is not bool"); + + data[bit.Index] = value; + } + + return Tools.ValueToData(data); + } + public override DataTree ParseDataToPayload(ref byte[] data) + { + List bitDataTrees = new List(); + List issueList = new List(); + int byteCount = (Size / 8); + if (byteCount != data.Length) + issueList.Add(new DataTreeIssue($"Data length not match given Size/8 ({byteCount})")); + + bool[] bools = Tools.DataToBoolArray(ref data, this.Size); + foreach (BitType bitType in Bits) + bitDataTrees.Add(new DataTree(bitType.Name, bitType.Index, bools[bitType.Index])); + + data = data.Skip(byteCount).ToArray(); + + return new DataTree(this.Name, 0, bitDataTrees.OrderBy(b=>b.Index), issueList.Count != 0 ? issueList.ToArray() : null); } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs index ac39b6a..fb0b65f 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs @@ -68,6 +68,10 @@ public override byte[] ParsePayloadToData(DataTree dataTree) { throw new NotSupportedException(); } + public override DataTree ParseDataToPayload(ref byte[] data) + { + throw new NotSupportedException(); + } public override string ToString() { diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs index f4e5871..887a0b6 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs @@ -1,5 +1,7 @@ using RDMSharp.RDM; using System; +using System.Collections.Generic; +using System.Drawing; using System.Linq; using System.Text.Json.Serialization; @@ -89,5 +91,15 @@ public override byte[] ParsePayloadToData(DataTree dataTree) } throw new ArithmeticException($"The given Object from {nameof(dataTree.Value)} can't be parsed"); } + + public override DataTree ParseDataToPayload(ref byte[] data) + { + List issueList = new List(); + if (data.Length != 1) + issueList.Add(new DataTreeIssue($"Data length is not 1")); + + data = data.Skip(1).ToArray(); + return new DataTree(this.Name, 0, Tools.DataToBool(ref data), issueList.Count != 0 ? issueList.ToArray() : null); + } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs index 0b65a32..87fd190 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs @@ -1,5 +1,7 @@ using RDMSharp.RDM; using System; +using System.Collections.Generic; +using System.Linq; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -90,5 +92,12 @@ public override byte[] ParsePayloadToData(DataTree dataTree) throw new ArithmeticException($"The given Object from {nameof(dataTree.Value)} can't be parsed"); } + public override DataTree ParseDataToPayload(ref byte[] data) + { + List issueList = new List(); + + data = data.Skip(data.Length).ToArray(); + return new DataTree(this.Name, 0, data, issueList.Count != 0 ? issueList.ToArray() : null); + } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs index 17f4e00..77dc566 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs @@ -3,6 +3,7 @@ using System; using System.Linq; using System.Text.Json.Serialization; +using System.Drawing; namespace RDMSharp.Metadata.JSON.OneOfTypes { @@ -81,5 +82,18 @@ public override byte[] ParsePayloadToData(DataTree dataTree) return data.ToArray(); } + public override DataTree ParseDataToPayload(ref byte[] data) + { + List subTypeDataTree = new List(); + List issueList = new List(); + + for (int i = 0; i < Subtypes.Length; i++) + { + OneOfTypes subType = Subtypes[i]; + subTypeDataTree.Add(new DataTree(subType.ParseDataToPayload(ref data), (uint)i)); + } + + return new DataTree(this.Name, 0, subTypeDataTree.OrderBy(b => b.Index), issueList.Count != 0 ? issueList.ToArray() : null); + } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs index 2e9c5c1..e91239b 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs @@ -1,6 +1,7 @@ using RDMSharp.Metadata.JSON.Converter; using RDMSharp.RDM; using System; +using System.Collections.Generic; using System.Linq; using System.Text.Json.Serialization; @@ -187,5 +188,51 @@ public override byte[] ParsePayloadToData(DataTree dataTree) return data; } + public override DataTree ParseDataToPayload(ref byte[] data) + { + List issueList = new List(); + if (data.Length < GetDataLength().Value) + issueList.Add(new DataTreeIssue("Given Data not fits PDL")); + + object value = null; + + switch (this.Type) + { + case EIntegerType.Int8: + value = Tools.DataToSByte(ref data); + break; + case EIntegerType.UInt8: + value = Tools.DataToByte(ref data); + break; + case EIntegerType.Int16: + value = Tools.DataToShort(ref data); + break; + case EIntegerType.UInt16: + value = Tools.DataToUShort(ref data); + break; + case EIntegerType.Int32: + value = Tools.DataToInt(ref data); + break; + case EIntegerType.UInt32: + value = Tools.DataToUInt(ref data); + break; + case EIntegerType.Int64: + value = Tools.DataToLong(ref data); + break; + case EIntegerType.UInt64: + value = Tools.DataToULong(ref data); + break; +#if NET7_0_OR_GREATER + case EIntegerType.Int128: + value = Tools.DataToInt128(ref data); + break; + case EIntegerType.UInt128: + value = Tools.DataToUInt128(ref data); + break; +#endif + } + + return new DataTree(this.Name, 0, value, issueList.Count != 0 ? issueList.ToArray() : null); + } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs index 42d52ad..5ea6b4b 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs @@ -55,5 +55,9 @@ public override byte[] ParsePayloadToData(DataTree dataTree) { throw new NotSupportedException(); } + public override DataTree ParseDataToPayload(ref byte[] data) + { + throw new NotSupportedException(); + } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs index 8e266ea..7d33280 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs @@ -54,5 +54,9 @@ public override byte[] ParsePayloadToData(DataTree dataTree) { throw new NotSupportedException(); } + public override DataTree ParseDataToPayload(ref byte[] data) + { + throw new NotSupportedException(); + } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs index 4dd4438..62cbab7 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs @@ -124,5 +124,40 @@ public override byte[] ParsePayloadToData(DataTree dataTree) return data.ToArray(); } + + public override DataTree ParseDataToPayload(ref byte[] data) + { + List dataTrees = new List(); + List issueList = new List(); + + uint index = 0; + while (_continue(ref data)) + { + dataTrees.Add(new DataTree(ItemType.ParseDataToPayload(ref data), index)); + index++; + } + + return new DataTree(Name, 0, dataTrees, issueList.Count != 0 ? issueList.ToArray() : null); + + bool _continue(ref byte[] data) + { + if (data.Length == 0) + { + if (MinItems.HasValue) + if (dataTrees.Count < MinItems.Value) + issueList.Add(new DataTreeIssue($"Given data falls shorts of {nameof(MinItems)}")); + return false; + } + if (MaxItems.HasValue) + if (dataTrees.Count > MaxItems.Value) + { + if (dataTrees.Count > 0) + issueList.Add(new DataTreeIssue($"Given data exceeds {nameof(MaxItems)}")); + return false; + } + + return true; + } + } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs index fd60845..b86c842 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs @@ -136,10 +136,19 @@ public byte[] ParsePayloadToData(DataTree dataTree) var data = objectType.ParsePayloadToData(dataTree); if (GetDataLength().IsValid(data.Length)) - throw new ArithmeticException($"Parsed DataLengt not fits Calculated DataLength"); + throw new ArithmeticException($"Parsed Data.Lenght not fits Calculated DataLength"); return data; } + public DataTree ParseDataToPayload(ref byte[] data) + { + CommonPropertiesForNamed objectType = ObjectType ?? ReferenceType?.ReferencedObject; + + if (GetDataLength().IsValid(data.Length)) + throw new ArithmeticException($"Parsed Data.Lenght not fits Calculated DataLength"); + + return objectType.ParseDataToPayload(ref data); + } public override string ToString() { diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs index c7cc7f9..70dd548 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/PD_EnvelopeType.cs @@ -72,5 +72,10 @@ public override byte[] ParsePayloadToData(DataTree dataTree) { return new byte[0]; } + + public override DataTree ParseDataToPayload(ref byte[] data) + { + return new DataTree(Name, 0, null); + } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs index fa0d822..542b17d 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs @@ -1,6 +1,8 @@ using RDMSharp.RDM; using System; +using System.Collections.Generic; using System.Text.Json.Serialization; +using System.Xml.Linq; namespace RDMSharp.Metadata.JSON.OneOfTypes { @@ -57,6 +59,11 @@ public byte[] ParsePayloadToData(DataTree dataTree) { return ReferencedObject.ParsePayloadToData(dataTree); } + + public DataTree ParseDataToPayload(ref byte[] data) + { + return ReferencedObject.ParseDataToPayload(ref data); + } public override string ToString() { return URI; diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs index 7750dab..698a660 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs @@ -1,5 +1,7 @@ using RDMSharp.RDM; using System; +using System.Collections.Generic; +using System.Linq; using System.Text; using System.Text.Json.Serialization; @@ -129,5 +131,37 @@ public override byte[] ParsePayloadToData(DataTree dataTree) throw new ArithmeticException($"The given Object from {nameof(dataTree.Value)} can't be parsed"); } + + public override DataTree ParseDataToPayload(ref byte[] data) + { + List issueList = new List(); + if (MaxBytes.HasValue && data.Length > MaxBytes) + issueList.Add(new DataTreeIssue($"Data length exceeds {nameof(MaxBytes)}, the Data has {data.Length}, but {nameof(MaxBytes)} is {MaxBytes}")); + if (MinBytes.HasValue && data.Length < MinBytes) + issueList.Add(new DataTreeIssue($"Data length falls shorts of {nameof(MinBytes)}, the Data has {data.Length}, but {nameof(MinBytes)} is {MinBytes}")); + + string str = null; + uint length = (uint)data.Length; + if (MaxLength.HasValue) + length = MaxLength.Value; + if (MaxBytes.HasValue) + length = MaxBytes.Value; + + if (data.Any(c => c == 0)) + length = (uint)data.TakeWhile(c => c != 0).Count() + 1; + + if (RestrictToASCII == true) + str = Encoding.ASCII.GetString(data, 0, (int)length); + else + str = Encoding.UTF8.GetString(data, 0, (int)length); + + if (MaxLength.HasValue && str.Length > MaxLength) + issueList.Add(new DataTreeIssue($"String length exceeds {nameof(MaxLength)}, the Data has {str.Length}, but {nameof(MaxLength)} is {MaxLength}")); + if (MinLength.HasValue && str.Length < MinLength) + issueList.Add(new DataTreeIssue($"String length falls shorts of {nameof(MinLength)}, the Data has {str.Length}, but {nameof(MinLength)} is {MinLength}")); + + data = data.Skip((int)length).ToArray(); + return new DataTree(this.Name, 0, str, issueList.Count != 0 ? issueList.ToArray() : null); + } } } diff --git a/RDMSharp/RDM/Tools.cs b/RDMSharp/RDM/Tools.cs index 4214ccc..35ed6c8 100644 --- a/RDMSharp/RDM/Tools.cs +++ b/RDMSharp/RDM/Tools.cs @@ -192,8 +192,14 @@ public static byte[] ValueToData(object value, int trim = 32) case long @long: return DoEightByte((ulong)@long); case ulong @ulong: - return DoEightByte(@ulong); - + return DoEightByte(@ulong); +#if NET7_0_OR_GREATER + case Int128 @long: + return DoSixteenByte((UInt128)@long); + case UInt128 @ulong: + return DoSixteenByte(@ulong); +#endif + case string @string: if (trim >= 1) if (@string.Length > trim) @@ -213,18 +219,22 @@ public static byte[] ValueToData(object value, int trim = 32) byte[] DoOneByte(byte b) => new byte[] { b }; byte[] DoTwoByte(ushort s) => new byte[] { (byte)(s >> 8), (byte)s }; byte[] DoFourByte(uint i) => new byte[] { (byte)(i >> 24), (byte)(i >> 16), (byte)(i >> 8), (byte)i }; - byte[] DoEightByte(ulong i) => new byte[] { (byte)(i >> 56), (byte)(i >> 48), (byte)(i >> 40), (byte)(i >> 32), (byte)(i >> 24), (byte)(i >> 16), (byte)(i >> 8), (byte)i }; + byte[] DoEightByte(ulong i) => new byte[] { (byte)(i >> 56), (byte)(i >> 48), (byte)(i >> 40), (byte)(i >> 32), (byte)(i >> 24), (byte)(i >> 16), (byte)(i >> 8), (byte)i }; +#if NET7_0_OR_GREATER + byte[] DoSixteenByte(UInt128 i) => new byte[] { (byte)(i >> 120), (byte)(i >> 112), (byte)(i >> 104), (byte)(i >> 96), (byte)(i >> 88), (byte)(i >> 80), (byte)(i >> 72), (byte)(i >> 64), (byte)(i >> 56), (byte)(i >> 48), (byte)(i >> 40), (byte)(i >> 32), (byte)(i >> 24), (byte)(i >> 16), (byte)(i >> 8), (byte)i }; +#endif } - - public static byte DataToByte(ref byte[] data) + + public static byte DataToByte(ref byte[] data) { const int length = 1; if (data.Length < length) throw new IndexOutOfRangeException(); - byte res = (byte)data[0]; + byte result = (byte)data[0]; + data = data.Skip(length).ToArray(); - return res; + return result; } public static sbyte DataToSByte(ref byte[] data) { @@ -232,9 +242,10 @@ public static sbyte DataToSByte(ref byte[] data) if (data.Length < length) throw new IndexOutOfRangeException(); - sbyte res = (sbyte)data[0]; + sbyte result = (sbyte)data[0]; + data = data.Skip(length).ToArray(); - return res; + return result; } public static short DataToShort(ref byte[] data) { @@ -242,9 +253,10 @@ public static short DataToShort(ref byte[] data) if (data.Length < length) throw new IndexOutOfRangeException(); - short res = (short)((data[0] << 8) | data[1]); + short result = (short)((data[0] << 8) | data[1]); + data = data.Skip(length).ToArray(); - return res; + return result; } public static ushort DataToUShort(ref byte[] data) { @@ -252,9 +264,10 @@ public static ushort DataToUShort(ref byte[] data) if (data.Length < length) throw new IndexOutOfRangeException(); - ushort res = (ushort)((data[0] << 8) | data[1]); + ushort result = (ushort)((data[0] << 8) | data[1]); + data = data.Skip(length).ToArray(); - return res; + return result; } public static int DataToInt(ref byte[] data) { @@ -262,9 +275,13 @@ public static int DataToInt(ref byte[] data) if (data.Length < length) throw new IndexOutOfRangeException(); - int res = (int)((data[0] << 24) | (data[1] << 16) | data[2] << 8 | data[3]); + int result = (int)data[0] << 24 | + (int)data[1] << 16 | + (int)data[2] << 8 | + (int)data[3]; + data = data.Skip(length).ToArray(); - return res; + return result; } public static uint DataToUInt(ref byte[] data) { @@ -272,9 +289,13 @@ public static uint DataToUInt(ref byte[] data) if (data.Length < length) throw new IndexOutOfRangeException(); - uint res = (uint)((data[0] << 24) | (data[1] << 16) | data[2] << 8 | data[3]); + uint result = (uint)data[0] << 24 | + (uint)data[1] << 16 | + (uint)data[2] << 8 | + (uint)data[3]; + data = data.Skip(length).ToArray(); - return res; + return result; } public static long DataToLong(ref byte[] data) { @@ -282,9 +303,17 @@ public static long DataToLong(ref byte[] data) if (data.Length < length) throw new IndexOutOfRangeException(); - long res = (long)((((long)data[0]) << 56) | (((long)data[1]) << 48) | (((long)data[2]) << 40) | (((long)data[3]) << 32) | (((long)data[4]) << 24) | (((long)data[5]) << 16) | ((long)data[6]) << 8 | ((long)data[7])); + long result = (long)data[0] << 56 | + (long)data[1] << 48 | + (long)data[2] << 40 | + (long)data[3] << 32 | + (long)data[4] << 24 | + (long)data[5] << 16 | + (long)data[6] << 8 | + (long)data[7]; + data = data.Skip(length).ToArray(); - return res; + return result; } public static ulong DataToULong(ref byte[] data) { @@ -292,10 +321,72 @@ public static ulong DataToULong(ref byte[] data) if (data.Length < length) throw new IndexOutOfRangeException(); - ulong res = (ulong)((((ulong)data[0]) << 56) | (((ulong)data[1]) << 48) | (((ulong)data[2]) << 40) | (((ulong)data[3]) << 32) | (((ulong)data[4]) << 24) | (((ulong)data[5]) << 16) | ((ulong)data[6]) << 8 | ((ulong)data[7])); + ulong result = (ulong)data[0] << 56 | + (ulong)data[1] << 48 | + (ulong)data[2] << 40 | + (ulong)data[3] << 32 | + (ulong)data[4] << 24 | + (ulong)data[5] << 16 | + (ulong)data[6] << 8 | + (ulong)data[7]; + data = data.Skip(length).ToArray(); - return res; - } + return result; + } +#if NET7_0_OR_GREATER + public static Int128 DataToInt128(ref byte[] data) + { + const int length = 16; + if (data.Length < length) + throw new IndexOutOfRangeException(); + + Int128 result = (Int128)data[0] << 120 | + (Int128)data[1] << 112 | + (Int128)data[2] << 104 | + (Int128)data[3] << 96 | + (Int128)data[4] << 88 | + (Int128)data[5] << 80 | + (Int128)data[6] << 72 | + (Int128)data[7] << 64 | + (Int128)data[8] << 56 | + (Int128)data[9] << 48 | + (Int128)data[10] << 40 | + (Int128)data[11] << 32 | + (Int128)data[12] << 24 | + (Int128)data[13] << 16 | + (Int128)data[14] << 8 | + (Int128)data[15]; + + data = data.Skip(length).ToArray(); + return result; + } + public static UInt128 DataToUInt128(ref byte[] data) + { + const int length = 16; + if (data.Length < length) + throw new IndexOutOfRangeException(); + + UInt128 result = (UInt128)data[0] << 120 | + (UInt128)data[1] << 112 | + (UInt128)data[2] << 104 | + (UInt128)data[3] << 96 | + (UInt128)data[4] << 88 | + (UInt128)data[5] << 80 | + (UInt128)data[6] << 72 | + (UInt128)data[7] << 64 | + (UInt128)data[8] << 56 | + (UInt128)data[9] << 48 | + (UInt128)data[10] << 40 | + (UInt128)data[11] << 32 | + (UInt128)data[12] << 24 | + (UInt128)data[13] << 16 | + (UInt128)data[14] << 8 | + (UInt128)data[15]; + + data = data.Skip(length).ToArray(); + return result; + } +#endif public static UID DataToRDMUID(ref byte[] data) { const int length = 6; From c0516caa81c80497ad446a8f26ee6c15c4a16ae0 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Tue, 24 Sep 2024 21:08:06 +0200 Subject: [PATCH 21/51] WIP --- RDMSharp/Metadata/DataTree.cs | 38 +++- .../Metadata/JSON/OneOfTypes/CompoundType.cs | 2 +- .../Metadata/JSON/OneOfTypes/IntegerType.cs | 131 ++++++++++++-- RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs | 2 +- .../Metadata/JSON/OneOfTypes/OneOfTypes.cs | 4 +- .../Metadata/JSON/TestIntegerType.cs | 170 ++++++++++++++++++ 6 files changed, 330 insertions(+), 17 deletions(-) diff --git a/RDMSharp/Metadata/DataTree.cs b/RDMSharp/Metadata/DataTree.cs index cf0088d..ace3feb 100644 --- a/RDMSharp/Metadata/DataTree.cs +++ b/RDMSharp/Metadata/DataTree.cs @@ -1,6 +1,9 @@ -namespace RDMSharp.Metadata +using System; +using System.Collections.Generic; + +namespace RDMSharp.Metadata { - public readonly struct DataTree + public readonly struct DataTree : IEquatable { public readonly string Name; public readonly uint Index; @@ -32,6 +35,35 @@ public DataTree(string name, uint index, DataTree[] children, DataTreeIssue[]? i public override string ToString() { return $"{Name}: {Value}"; - } + } + + public override bool Equals(object obj) + { + return obj is DataTree tree && Equals(tree); + } + + public bool Equals(DataTree other) + { + return Name == other.Name && + Index == other.Index && + EqualityComparer.Default.Equals(Value, other.Value) && + EqualityComparer.Default.Equals(Children, other.Children) && + EqualityComparer.Default.Equals(Issues, other.Issues); + } + + public override int GetHashCode() + { + return HashCode.Combine(Name, Index, Value, Children, Issues); + } + + public static bool operator ==(DataTree left, DataTree right) + { + return left.Equals(right); + } + + public static bool operator !=(DataTree left, DataTree right) + { + return !(left == right); + } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs index 77dc566..16eb863 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs @@ -77,7 +77,7 @@ public override byte[] ParsePayloadToData(DataTree dataTree) data.AddRange(Subtypes[i].ParsePayloadToData(dataTree.Children[i])); } - if (GetDataLength().IsValid(data.Count)) + if (!GetDataLength().IsValid(data.Count)) throw new ArithmeticException($"Parsed DataLengt not fits Calculated DataLength"); return data.ToArray(); diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs index e91239b..04bb01d 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs @@ -2,7 +2,9 @@ using RDMSharp.RDM; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; +using System.Runtime; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -172,27 +174,136 @@ public override PDL GetDataLength() } return new PDL(16); } + + private T convertFormatedValueToRaw(object formated) + { + int pBase = PrefixBase ?? 10; + int pPower = PrefixPower ?? 0; + if (pPower == 0) + return (T)formated; + + object rawValue = null; + + double multiplyer = (double)Math.Pow(pBase, pPower); + switch (formated) + { + case double _double: + rawValue = _double / multiplyer; + break; + case long _long: + rawValue = _long / multiplyer; + break; + case ulong _ulong: + rawValue = _ulong / multiplyer; + break; + + default: + return (T)formated; + } + + if (rawValue is not null) + return (T)Convert.ChangeType(rawValue, typeof(T)); + + throw new NotImplementedException(); + } + + private object convertRawValueToFormated(T raw) + { + int pBase = PrefixBase ?? 10; + int pPower = PrefixPower ?? 0; + if (pPower == 0) + return raw; + + double multiplicator = (long)Math.Pow(pBase, pPower); + bool isNegativ = Math.Sign(multiplicator) == -1; + bool isDezimal = PrefixPower < 0; + + switch (raw) + { + case sbyte int8: + if (isDezimal) + return (double)(multiplicator * int8); + if (isNegativ) + return (long)(multiplicator * int8); + return (ulong)(multiplicator * int8); + + case byte uint8: + if (isDezimal) + return (double)(multiplicator * uint8); + if (isNegativ) + return (long)(multiplicator * uint8); + return (ulong)(multiplicator * uint8); + + case short int16: + if (isDezimal) + return (double)(multiplicator * int16); + if (isNegativ) + return (long)(multiplicator * int16); + return (ulong)(multiplicator * int16); + + case ushort uint16: + if (isDezimal) + return (double)(multiplicator * uint16); + if (isNegativ) + return (long)(multiplicator * uint16); + return (ulong)(multiplicator * uint16); + + case int int32: + if (isDezimal) + return (double)(multiplicator * int32); + if (isNegativ) + return (long)(multiplicator * int32); + return (ulong)(multiplicator * int32); + + case uint uint32: + if (isDezimal) + return (double)(multiplicator * uint32); + if (isNegativ) + return (long)(multiplicator * uint32); + return (ulong)(multiplicator * uint32); + + case long int64: + if (isDezimal) + return (double)(multiplicator * int64); + if (isNegativ) + return (long)(multiplicator * int64); + return (ulong)(multiplicator * int64); + + case ulong uint64: + if (isDezimal) + return (double)(multiplicator * uint64); + if (isNegativ) + return (long)(multiplicator * uint64); + return (ulong)(multiplicator * uint64); + + default: + return raw; + } + throw new NotImplementedException(); + } + public override byte[] ParsePayloadToData(DataTree dataTree) { if (!string.Equals(dataTree.Name, this.Name)) throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); - - if(dataTree.Value is not T value) - throw new ArithmeticException($"The given Object from {nameof(dataTree.Value)} can't be parsed, it should be {typeof(T).Name}"); - validateType(Type, value); - var data = Tools.ValueToData(dataTree.Value); - - if (GetDataLength().IsValid(data.Length)) - throw new ArithmeticException($"Parsed DataLengt not fits Calculated DataLength"); + var rawValue = convertFormatedValueToRaw(dataTree.Value); + var data = Tools.ValueToData(rawValue); return data; } public override DataTree ParseDataToPayload(ref byte[] data) { List issueList = new List(); - if (data.Length < GetDataLength().Value) + uint pdl = GetDataLength().Value.Value; + + if (data.Length < pdl) + { issueList.Add(new DataTreeIssue("Given Data not fits PDL")); + byte[] cloneData = new byte[pdl]; + Array.Copy(data, cloneData, data.Length); + data = cloneData; + } object value = null; @@ -232,7 +343,7 @@ public override DataTree ParseDataToPayload(ref byte[] data) #endif } - return new DataTree(this.Name, 0, value, issueList.Count != 0 ? issueList.ToArray() : null); + return new DataTree(this.Name, 0, convertRawValueToFormated((T)value), issueList.Count != 0 ? issueList.ToArray() : null); } } } diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs index 62cbab7..cd339d3 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs @@ -119,7 +119,7 @@ public override byte[] ParsePayloadToData(DataTree dataTree) data.AddRange(ItemType.ParsePayloadToData(dataTree.Children[i])); } - if (GetDataLength().IsValid(data.Count)) + if (!GetDataLength().IsValid(data.Count)) throw new ArithmeticException($"Parsed DataLengt not fits Calculated DataLength"); return data.ToArray(); diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs index b86c842..d530f91 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs @@ -135,7 +135,7 @@ public byte[] ParsePayloadToData(DataTree dataTree) CommonPropertiesForNamed objectType = ObjectType ?? ReferenceType?.ReferencedObject; var data = objectType.ParsePayloadToData(dataTree); - if (GetDataLength().IsValid(data.Length)) + if (!GetDataLength().IsValid(data.Length)) throw new ArithmeticException($"Parsed Data.Lenght not fits Calculated DataLength"); return data; @@ -144,7 +144,7 @@ public DataTree ParseDataToPayload(ref byte[] data) { CommonPropertiesForNamed objectType = ObjectType ?? ReferenceType?.ReferencedObject; - if (GetDataLength().IsValid(data.Length)) + if (!GetDataLength().IsValid(data.Length)) throw new ArithmeticException($"Parsed Data.Lenght not fits Calculated DataLength"); return objectType.ParseDataToPayload(ref data); diff --git a/RDMSharpTests/Metadata/JSON/TestIntegerType.cs b/RDMSharpTests/Metadata/JSON/TestIntegerType.cs index d6e8628..84ec559 100644 --- a/RDMSharpTests/Metadata/JSON/TestIntegerType.cs +++ b/RDMSharpTests/Metadata/JSON/TestIntegerType.cs @@ -1,3 +1,4 @@ +using RDMSharp.Metadata; using RDMSharp.Metadata.JSON.OneOfTypes; using RDMSharp.RDM; @@ -18,6 +19,15 @@ public void TestManyInt8() }); Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)); + + Assert.Multiple(() => + { + DoParseDataTest(integerType, -71, new byte[] { 185 }); + DoParseDataTest(integerType, sbyte.MinValue, new byte[] { 128 }, nameof(sbyte.MinValue)); + DoParseDataTest(integerType, sbyte.MaxValue, new byte[] { 127 }, nameof(sbyte.MaxValue)); + DoParseDataTest(integerType, 0, new byte[] { 0 }, "Zero"); + DoParseDataTest(integerType, 1, new byte[] { 1 }, "One"); + }); } [Test] public void TestManyUInt8() @@ -32,6 +42,15 @@ public void TestManyUInt8() }); Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int8, null, null, null, null, null, null)); + + Assert.Multiple(() => + { + DoParseDataTest(integerType, 71, new byte[] { 71 }); + DoParseDataTest(integerType, byte.MinValue, new byte[] { 0 }, nameof(byte.MinValue)); + DoParseDataTest(integerType, byte.MaxValue, new byte[] { 255 }, nameof(byte.MaxValue)); + DoParseDataTest(integerType, 0, new byte[] { 0 }, "Zero"); + DoParseDataTest(integerType, 1, new byte[] { 1 }, "One"); + }); } [Test] public void TestManyInt16() @@ -46,6 +65,15 @@ public void TestManyInt16() }); Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt16, null, null, null, null, null, null)); + + Assert.Multiple(() => + { + DoParseDataTest(integerType, -13245, new byte[] { 204, 67 }); + DoParseDataTest(integerType, short.MinValue, new byte[] { 128, 0 }, nameof(short.MinValue)); + DoParseDataTest(integerType, short.MaxValue, new byte[] { 127,255 }, nameof(short.MaxValue)); + DoParseDataTest(integerType, 0, new byte[] { 0, 0 }, "Zero"); + DoParseDataTest(integerType, 1, new byte[] { 0, 1 }, "One"); + }); } [Test] public void TestManyUInt16() @@ -60,6 +88,15 @@ public void TestManyUInt16() }); Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int16, null, null, null, null, null, null)); + + Assert.Multiple(() => + { + DoParseDataTest(integerType, 65432, new byte[] { 255, 152 }); + DoParseDataTest(integerType, ushort.MinValue, new byte[] { 0, 0 }, nameof(ushort.MinValue)); + DoParseDataTest(integerType, ushort.MaxValue, new byte[] { 255, 255 }, nameof(ushort.MaxValue)); + DoParseDataTest(integerType, 0, new byte[] { 0, 0 }, "Zero"); + DoParseDataTest(integerType, 1, new byte[] { 0, 1 }, "One"); + }); } [Test] public void TestManyInt32() @@ -74,6 +111,15 @@ public void TestManyInt32() }); Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt32, null, null, null, null, null, null)); + + Assert.Multiple(() => + { + DoParseDataTest(integerType, -13243567, new byte[] { 255, 53, 235, 81 }); + DoParseDataTest(integerType, int.MinValue, new byte[] { 128, 0, 0, 0 }, nameof(int.MinValue)); + DoParseDataTest(integerType, int.MaxValue, new byte[] { 127, 255, 255, 255 }, nameof(int.MaxValue)); + DoParseDataTest(integerType, 0, new byte[] { 0, 0, 0, 0 }, "Zero"); + DoParseDataTest(integerType, 1, new byte[] { 0, 0, 0, 1 }, "One"); + }); } [Test] public void TestManyUInt32() @@ -88,6 +134,15 @@ public void TestManyUInt32() }); Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int32, null, null, null, null, null, null)); + + Assert.Multiple(() => + { + DoParseDataTest(integerType, 75643244, new byte[] { 4, 130, 57, 108 }); + DoParseDataTest(integerType, uint.MinValue, new byte[] { 0, 0, 0, 0 }, nameof(uint.MinValue)); + DoParseDataTest(integerType, uint.MaxValue, new byte[] { 255, 255, 255, 255 }, nameof(uint.MaxValue)); + DoParseDataTest(integerType, 0, new byte[] { 0, 0, 0, 0 }, "Zero"); + DoParseDataTest(integerType, 1, new byte[] { 0, 0, 0, 1 }, "One"); + }); } [Test] public void TestManyInt64() @@ -102,6 +157,15 @@ public void TestManyInt64() }); Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt64, null, null, null, null, null, null)); + + Assert.Multiple(() => + { + DoParseDataTest(integerType, -2136456776545, new byte[] { 255, 255, 254, 14, 145, 64, 180, 159 }); + DoParseDataTest(integerType, long.MinValue, new byte[] { 128, 0, 0, 0, 0, 0, 0, 0 }, nameof(long.MinValue)); + DoParseDataTest(integerType, long.MaxValue, new byte[] { 127, 255, 255, 255, 255, 255, 255, 255 }, nameof(long.MaxValue)); + DoParseDataTest(integerType, 0, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, "Zero"); + DoParseDataTest(integerType, 1, new byte[] { 0, 0, 0, 0, 0, 0, 0, 1 }, "One"); + }); } [Test] public void TestManyUInt64() @@ -116,6 +180,15 @@ public void TestManyUInt64() }); Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int64, null, null, null, null, null, null)); + + Assert.Multiple(() => + { + DoParseDataTest(integerType, 345676543456543, new byte[] { 0, 1, 58, 100, 23, 148, 117, 31 }); + DoParseDataTest(integerType, ulong.MinValue, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, nameof(ulong.MinValue)); + DoParseDataTest(integerType, ulong.MaxValue, new byte[] { 255, 255, 255, 255, 255, 255, 255, 255 }, nameof(ulong.MaxValue)); + DoParseDataTest(integerType, 0, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, "Zero"); + DoParseDataTest(integerType, 1, new byte[] { 0, 0, 0, 0, 0, 0, 0, 1 }, "One"); + }); } #if NET7_0_OR_GREATER [Test] @@ -131,6 +204,14 @@ public void TestManyInt128() }); Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt128, null, null, null, null, null, null)); + Assert.Multiple(() => + { + DoParseDataTest(integerType, new Int128(2725151552362626646, 5278987657876567), new byte[] { 37, 209, 174, 229, 253, 173, 190, 86, 0, 18, 193, 54, 24, 31, 20, 87 }); + DoParseDataTest(integerType, Int128.MinValue, new byte[] { 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, nameof(Int128.MinValue)); + DoParseDataTest(integerType, Int128.MaxValue, new byte[] { 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, nameof(Int128.MaxValue)); + DoParseDataTest(integerType, Int128.Zero, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, nameof(Int128.Zero)); + DoParseDataTest(integerType, Int128.One, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, nameof(Int128.One)); + }); } [Test] public void TestManyUInt128() @@ -145,7 +226,96 @@ public void TestManyUInt128() }); Assert.Throws(typeof(ArgumentException), () => integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int128, null, null, null, null, null, null)); + + Assert.Multiple(() => + { + DoParseDataTest(integerType, new UInt128(2725751552362626686, 5278987657876567), new byte[] { 37, 211, 208, 152, 96, 139, 62, 126, 0, 18, 193, 54, 24, 31, 20, 87 }); + DoParseDataTest(integerType, UInt128.MinValue, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, nameof(UInt128.MinValue)); + DoParseDataTest(integerType, UInt128.MaxValue, new byte[] { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }, nameof(UInt128.MaxValue)); + DoParseDataTest(integerType, UInt128.Zero, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, nameof(UInt128.Zero)); + DoParseDataTest(integerType, UInt128.One, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, nameof(UInt128.One)); + }); } #endif + + [Test] + public void TestPrefix1024() + { + var integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int32, null, null, null, null, 10, 2); + Assert.That(integerType.PrefixBase, Is.EqualTo(2)); + Assert.That(integerType.PrefixPower, Is.EqualTo(10)); + + Assert.Multiple(() => + { + var data = new byte[] { 0, 0, 0, 0 }; + var dataTree = integerType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(0)); + var parsedData = integerType.ParsePayloadToData(dataTree); + Assert.That(parsedData, Is.EqualTo(new byte[] { 0, 0, 0, 0 })); + + data = new byte[] { 0, 0, 0, 1 }; + dataTree = integerType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(1024)); + parsedData = integerType.ParsePayloadToData(dataTree); + Assert.That(parsedData, Is.EqualTo(new byte[] { 0, 0, 0, 1 })); + + data = new byte[] { 0, 0, 0, 100 }; + dataTree = integerType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(102400)); + parsedData = integerType.ParsePayloadToData(dataTree); + Assert.That(parsedData, Is.EqualTo(new byte[] { 0, 0, 0, 100 })); + }); + } + public void TestPrefix4Decimals() + { + var integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int32, null, null, null, null, -4, 10); + Assert.That(integerType.PrefixBase, Is.EqualTo(2)); + Assert.That(integerType.PrefixPower, Is.EqualTo(10)); + + Assert.Multiple(() => + { + var data = new byte[] { 0, 0, 0, 0 }; + var dataTree = integerType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(0)); + var parsedData = integerType.ParsePayloadToData(dataTree); + Assert.That(parsedData, Is.EqualTo(new byte[] { 0, 0, 0, 0 })); + + data = new byte[] { 0, 0, 0, 1 }; + dataTree = integerType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(0.0001)); + parsedData = integerType.ParsePayloadToData(dataTree); + Assert.That(parsedData, Is.EqualTo(new byte[] { 0, 0, 0, 1 })); + + data = new byte[] { 0, 0, 0, 100 }; + dataTree = integerType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(0.01)); + parsedData = integerType.ParsePayloadToData(dataTree); + Assert.That(parsedData, Is.EqualTo(new byte[] { 0, 0, 0, 100 })); + }); + } + + private void DoParseDataTest(IntegerType integerType, T value, byte[] expectedData, string message = null) + { + var dataTree = new DataTree(integerType.Name, 0, value); + var data = new byte[0]; + Assert.DoesNotThrow(() => data = integerType.ParsePayloadToData(dataTree), message); + Assert.That(data, Is.EqualTo(expectedData), message); + + byte[] clonaData = new byte[data.Length]; + Array.Copy(data, clonaData, clonaData.Length); + var parsedDataTree = integerType.ParseDataToPayload(ref clonaData); + Assert.That(clonaData, Has.Length.EqualTo(0), message); + + Assert.That(parsedDataTree, Is.EqualTo(dataTree), message); + + //Test for short Data & PDL Issue + clonaData = new byte[data.Length - 1]; + Array.Copy(data, clonaData, clonaData.Length); + Assert.DoesNotThrow(() => parsedDataTree = integerType.ParseDataToPayload(ref clonaData)); + Assert.That(parsedDataTree.Issues, Is.Not.Null); + Assert.That(parsedDataTree.Value, Is.Not.Null); + + Assert.Throws(typeof(ArithmeticException), () => data = integerType.ParsePayloadToData(new DataTree("Different Name", dataTree.Index, dataTree.Value)), message); + } } } \ No newline at end of file From 551e5d4824dcbf3b1eb5935e2d897f6333763999 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Tue, 24 Sep 2024 21:15:00 +0200 Subject: [PATCH 22/51] MInor Fix --- .../Metadata/JSON/OneOfTypes/IntegerType.cs | 72 +++++++++---------- .../Metadata/JSON/TestIntegerType.cs | 5 +- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs index 04bb01d..787e784 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs @@ -80,6 +80,9 @@ public class IntegerType : CommonPropertiesForNamed [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public int? PrefixBase { get; } = 10; + [JsonIgnore(Condition = JsonIgnoreCondition.Always)] + public double PrefixMultiplyer; + [JsonConstructor] public IntegerType(string name, string displayName, @@ -105,6 +108,8 @@ public IntegerType(string name, Units = units; PrefixPower = prefixPower; PrefixBase = prefixBase; + + PrefixMultiplyer = Math.Pow(PrefixBase ?? 10, PrefixPower ?? 0); } private static void validateType(EIntegerType type, T dummy = default) @@ -177,24 +182,20 @@ public override PDL GetDataLength() private T convertFormatedValueToRaw(object formated) { - int pBase = PrefixBase ?? 10; - int pPower = PrefixPower ?? 0; - if (pPower == 0) + if (PrefixMultiplyer == 1) return (T)formated; object rawValue = null; - - double multiplyer = (double)Math.Pow(pBase, pPower); switch (formated) { case double _double: - rawValue = _double / multiplyer; + rawValue = _double / PrefixMultiplyer; break; case long _long: - rawValue = _long / multiplyer; + rawValue = _long / PrefixMultiplyer; break; case ulong _ulong: - rawValue = _ulong / multiplyer; + rawValue = _ulong / PrefixMultiplyer; break; default: @@ -209,72 +210,69 @@ private T convertFormatedValueToRaw(object formated) private object convertRawValueToFormated(T raw) { - int pBase = PrefixBase ?? 10; - int pPower = PrefixPower ?? 0; - if (pPower == 0) + if (PrefixMultiplyer == 1) return raw; - double multiplicator = (long)Math.Pow(pBase, pPower); - bool isNegativ = Math.Sign(multiplicator) == -1; + bool isNegativ = Math.Sign(PrefixMultiplyer) == -1; bool isDezimal = PrefixPower < 0; switch (raw) { case sbyte int8: if (isDezimal) - return (double)(multiplicator * int8); + return (double)(PrefixMultiplyer * int8); if (isNegativ) - return (long)(multiplicator * int8); - return (ulong)(multiplicator * int8); + return (long)(PrefixMultiplyer * int8); + return (ulong)(PrefixMultiplyer * int8); case byte uint8: if (isDezimal) - return (double)(multiplicator * uint8); + return (double)(PrefixMultiplyer * uint8); if (isNegativ) - return (long)(multiplicator * uint8); - return (ulong)(multiplicator * uint8); + return (long)(PrefixMultiplyer * uint8); + return (ulong)(PrefixMultiplyer * uint8); case short int16: if (isDezimal) - return (double)(multiplicator * int16); + return (double)(PrefixMultiplyer * int16); if (isNegativ) - return (long)(multiplicator * int16); - return (ulong)(multiplicator * int16); + return (long)(PrefixMultiplyer * int16); + return (ulong)(PrefixMultiplyer * int16); case ushort uint16: if (isDezimal) - return (double)(multiplicator * uint16); + return (double)(PrefixMultiplyer * uint16); if (isNegativ) - return (long)(multiplicator * uint16); - return (ulong)(multiplicator * uint16); + return (long)(PrefixMultiplyer * uint16); + return (ulong)(PrefixMultiplyer * uint16); case int int32: if (isDezimal) - return (double)(multiplicator * int32); + return (double)(PrefixMultiplyer * int32); if (isNegativ) - return (long)(multiplicator * int32); - return (ulong)(multiplicator * int32); + return (long)(PrefixMultiplyer * int32); + return (ulong)(PrefixMultiplyer * int32); case uint uint32: if (isDezimal) - return (double)(multiplicator * uint32); + return (double)(PrefixMultiplyer * uint32); if (isNegativ) - return (long)(multiplicator * uint32); - return (ulong)(multiplicator * uint32); + return (long)(PrefixMultiplyer * uint32); + return (ulong)(PrefixMultiplyer * uint32); case long int64: if (isDezimal) - return (double)(multiplicator * int64); + return (double)(PrefixMultiplyer * int64); if (isNegativ) - return (long)(multiplicator * int64); - return (ulong)(multiplicator * int64); + return (long)(PrefixMultiplyer * int64); + return (ulong)(PrefixMultiplyer * int64); case ulong uint64: if (isDezimal) - return (double)(multiplicator * uint64); + return (double)(PrefixMultiplyer * uint64); if (isNegativ) - return (long)(multiplicator * uint64); - return (ulong)(multiplicator * uint64); + return (long)(PrefixMultiplyer * uint64); + return (ulong)(PrefixMultiplyer * uint64); default: return raw; diff --git a/RDMSharpTests/Metadata/JSON/TestIntegerType.cs b/RDMSharpTests/Metadata/JSON/TestIntegerType.cs index 84ec559..1691078 100644 --- a/RDMSharpTests/Metadata/JSON/TestIntegerType.cs +++ b/RDMSharpTests/Metadata/JSON/TestIntegerType.cs @@ -266,11 +266,12 @@ public void TestPrefix1024() Assert.That(parsedData, Is.EqualTo(new byte[] { 0, 0, 0, 100 })); }); } + [Test] public void TestPrefix4Decimals() { var integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int32, null, null, null, null, -4, 10); - Assert.That(integerType.PrefixBase, Is.EqualTo(2)); - Assert.That(integerType.PrefixPower, Is.EqualTo(10)); + Assert.That(integerType.PrefixBase, Is.EqualTo(10)); + Assert.That(integerType.PrefixPower, Is.EqualTo(-4)); Assert.Multiple(() => { From 978f3e78668edddeb69c935622d67a4c9a16759b Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Tue, 24 Sep 2024 21:50:06 +0200 Subject: [PATCH 23/51] Minor --- RDMSharp/Metadata/DataTree.cs | 8 +++++++- RDMSharp/Metadata/DataTreeValueLabel.cs | 14 ++++++++++++++ RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs | 12 +++++++++--- 3 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 RDMSharp/Metadata/DataTreeValueLabel.cs diff --git a/RDMSharp/Metadata/DataTree.cs b/RDMSharp/Metadata/DataTree.cs index ace3feb..e3fbca2 100644 --- a/RDMSharp/Metadata/DataTree.cs +++ b/RDMSharp/Metadata/DataTree.cs @@ -8,6 +8,8 @@ namespace RDMSharp.Metadata public readonly string Name; public readonly uint Index; public readonly object? Value; + public readonly string? Unit; + public readonly DataTreeValueLabel[]? Labels; public readonly DataTree[]? Children; public readonly DataTreeIssue[]? Issues; @@ -20,11 +22,15 @@ private DataTree(string name, uint index, DataTreeIssue[]? issues = null) public DataTree(DataTree dataTree, uint index) : this(dataTree.Name, index, dataTree.Issues) { Value = dataTree.Value; + Unit = dataTree.Unit; + Labels = dataTree.Labels; Children = dataTree.Children; } - public DataTree(string name, uint index, object value, DataTreeIssue[]? issues = null) : this(name, index, issues) + public DataTree(string name, uint index, object value, DataTreeIssue[]? issues = null, string unit = null, DataTreeValueLabel[] labels = null) : this(name, index, issues) { Value = value; + Unit = unit; + Labels = labels; } public DataTree(string name, uint index, DataTree[] children, DataTreeIssue[]? issues = null) : this(name, index, issues) diff --git a/RDMSharp/Metadata/DataTreeValueLabel.cs b/RDMSharp/Metadata/DataTreeValueLabel.cs new file mode 100644 index 0000000..8c0281f --- /dev/null +++ b/RDMSharp/Metadata/DataTreeValueLabel.cs @@ -0,0 +1,14 @@ +namespace RDMSharp.Metadata +{ + public readonly struct DataTreeValueLabel + { + public readonly object Value; + public readonly string Label; + + public DataTreeValueLabel(object value, string label) + { + Value = value; + Label = label; + } + } +} diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs index 787e784..9a567fd 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs @@ -340,8 +340,14 @@ public override DataTree ParseDataToPayload(ref byte[] data) break; #endif } - - return new DataTree(this.Name, 0, convertRawValueToFormated((T)value), issueList.Count != 0 ? issueList.ToArray() : null); + string unit = null; + if (Units.HasValue) + unit = Tools.GetUnitSymbol(Units.Value); + DataTreeValueLabel[] labels = null; + if ((Labels?.Length ?? 0) != 0) + labels = Labels.Select(lb => new DataTreeValueLabel(lb.Value, (lb.DisplayName ?? lb.Name))).ToArray(); + + return new DataTree(this.Name, 0, convertRawValueToFormated((T)value), issueList.Count != 0 ? issueList.ToArray() : null, unit, labels); } } -} +} \ No newline at end of file From 769bd8002e866d991d763d43e445324c4e02a1e3 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 25 Sep 2024 00:42:05 +0200 Subject: [PATCH 24/51] WIP --- .../Metadata/JSON/CommonPropertiesForNamed.cs | 4 +- .../Metadata/JSON/OneOfTypes/EIntegerType.cs | 30 +++ .../Metadata/JSON/OneOfTypes/IIntegerType.cs | 15 ++ .../Metadata/JSON/OneOfTypes/IntegerType.cs | 39 +--- RDMSharp/Metadata/JSON/OneOfTypes/Range.cs | 33 ++- .../Metadata/JSON/TestIntegerType.cs | 188 +++++++++++++----- 6 files changed, 229 insertions(+), 80 deletions(-) create mode 100644 RDMSharp/Metadata/JSON/OneOfTypes/EIntegerType.cs create mode 100644 RDMSharp/Metadata/JSON/OneOfTypes/IIntegerType.cs diff --git a/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs b/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs index 17f7e97..b305a65 100644 --- a/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs +++ b/RDMSharp/Metadata/JSON/CommonPropertiesForNamed.cs @@ -1,7 +1,5 @@ -using System; -using System.Linq; +using RDMSharp.RDM; using System.Text.Json.Serialization; -using RDMSharp.RDM; namespace RDMSharp.Metadata.JSON { diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/EIntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/EIntegerType.cs new file mode 100644 index 0000000..add763d --- /dev/null +++ b/RDMSharp/Metadata/JSON/OneOfTypes/EIntegerType.cs @@ -0,0 +1,30 @@ +using RDMSharp.Metadata.JSON.Converter; +using System.Text.Json.Serialization; + +namespace RDMSharp.Metadata.JSON.OneOfTypes +{ + [JsonConverter(typeof(CustomEnumConverter))] + public enum EIntegerType + { + [JsonPropertyName("int8")] + Int8, + [JsonPropertyName("int16")] + Int16, + [JsonPropertyName("int32")] + Int32, + [JsonPropertyName("int64")] + Int64, + [JsonPropertyName("int128")] + Int128, + [JsonPropertyName("uint8")] + UInt8, + [JsonPropertyName("uint16")] + UInt16, + [JsonPropertyName("uint32")] + UInt32, + [JsonPropertyName("uint64")] + UInt64, + [JsonPropertyName("uint128")] + UInt128 + } +} \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/IIntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/IIntegerType.cs new file mode 100644 index 0000000..bb19c9a --- /dev/null +++ b/RDMSharp/Metadata/JSON/OneOfTypes/IIntegerType.cs @@ -0,0 +1,15 @@ +namespace RDMSharp.Metadata.JSON.OneOfTypes +{ + public interface IIntegerType + { + string Name { get; } + string DisplayName { get; } + bool? RestrictToLabeled { get; } + string Notes { get; } + EIntegerType Type { get; } + ERDM_SensorUnit? Units { get; } + int? PrefixPower { get; } + int? PrefixBase { get; } + double PrefixMultiplyer { get; } + } +} \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs index 9a567fd..aa816b8 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs @@ -1,39 +1,12 @@ -using RDMSharp.Metadata.JSON.Converter; -using RDMSharp.RDM; +using RDMSharp.RDM; using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; -using System.Runtime; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes { - [JsonConverter(typeof(CustomEnumConverter))] - public enum EIntegerType - { - [JsonPropertyName("int8")] - Int8, - [JsonPropertyName("int16")] - Int16, - [JsonPropertyName("int32")] - Int32, - [JsonPropertyName("int64")] - Int64, - [JsonPropertyName("int128")] - Int128, - [JsonPropertyName("uint8")] - UInt8, - [JsonPropertyName("uint16")] - UInt16, - [JsonPropertyName("uint32")] - UInt32, - [JsonPropertyName("uint64")] - UInt64, - [JsonPropertyName("uint128")] - UInt128 - } - public class IntegerType : CommonPropertiesForNamed + public class IntegerType : CommonPropertiesForNamed, IIntegerType { [JsonPropertyName("name")] [JsonPropertyOrder(1)] @@ -81,7 +54,7 @@ public class IntegerType : CommonPropertiesForNamed public int? PrefixBase { get; } = 10; [JsonIgnore(Condition = JsonIgnoreCondition.Always)] - public double PrefixMultiplyer; + public double PrefixMultiplyer { get; } [JsonConstructor] public IntegerType(string name, @@ -340,6 +313,12 @@ public override DataTree ParseDataToPayload(ref byte[] data) break; #endif } + if (Ranges != null) + { + if (!Ranges.Any(r => r.IsInRange((T)value))) + issueList.Add(new DataTreeIssue("The Value is not in range of any Range")); + } + string unit = null; if (Units.HasValue) unit = Tools.GetUnitSymbol(Units.Value); diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/Range.cs b/RDMSharp/Metadata/JSON/OneOfTypes/Range.cs index fa230a1..f2ab053 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/Range.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/Range.cs @@ -1,4 +1,5 @@ -using System.Text.Json.Serialization; +using System; +using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes { @@ -17,6 +18,36 @@ public Range(T minimum, T maximum) Maximum = maximum; } + public bool IsInRange(T value) + { + switch (value) + { + case byte v when Minimum is byte min && Maximum is byte max: + return min <= v && v <= max; + case sbyte v when Minimum is sbyte min && Maximum is sbyte max: + return min <= v && v <= max; + case short v when Minimum is short min && Maximum is short max: + return min <= v && v <= max; + case ushort v when Minimum is ushort min && Maximum is ushort max: + return min <= v && v <= max; + case int v when Minimum is int min && Maximum is int max: + return min <= v && v <= max; + case uint v when Minimum is uint min && Maximum is uint max: + return min <= v && v <= max; + case long v when Minimum is long min && Maximum is long max: + return min <= v && v <= max; + case ulong v when Minimum is ulong min && Maximum is ulong max: + return min <= v && v <= max; +# if NET7_0_OR_GREATER + case Int128 v when Minimum is Int128 min && Maximum is Int128 max: + return min <= v && v <= max; + case UInt128 v when Minimum is UInt128 min && Maximum is UInt128 max: + return min <= v && v <= max; +#endif + } + return false; + } + public override string ToString() { return $"Range: {Minimum:X4} - {Maximum:X4}"; diff --git a/RDMSharpTests/Metadata/JSON/TestIntegerType.cs b/RDMSharpTests/Metadata/JSON/TestIntegerType.cs index 1691078..8974a5b 100644 --- a/RDMSharpTests/Metadata/JSON/TestIntegerType.cs +++ b/RDMSharpTests/Metadata/JSON/TestIntegerType.cs @@ -1,4 +1,5 @@ using RDMSharp.Metadata; +using RDMSharp.Metadata.JSON; using RDMSharp.Metadata.JSON.OneOfTypes; using RDMSharp.RDM; @@ -241,58 +242,153 @@ public void TestManyUInt128() [Test] public void TestPrefix1024() { - var integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int32, null, null, null, null, 10, 2); - Assert.That(integerType.PrefixBase, Is.EqualTo(2)); - Assert.That(integerType.PrefixPower, Is.EqualTo(10)); - - Assert.Multiple(() => + CommonPropertiesForNamed[] types = new CommonPropertiesForNamed[] { - var data = new byte[] { 0, 0, 0, 0 }; - var dataTree = integerType.ParseDataToPayload(ref data); - Assert.That(dataTree.Value, Is.EqualTo(0)); - var parsedData = integerType.ParsePayloadToData(dataTree); - Assert.That(parsedData, Is.EqualTo(new byte[] { 0, 0, 0, 0 })); - - data = new byte[] { 0, 0, 0, 1 }; - dataTree = integerType.ParseDataToPayload(ref data); - Assert.That(dataTree.Value, Is.EqualTo(1024)); - parsedData = integerType.ParsePayloadToData(dataTree); - Assert.That(parsedData, Is.EqualTo(new byte[] { 0, 0, 0, 1 })); - - data = new byte[] { 0, 0, 0, 100 }; - dataTree = integerType.ParseDataToPayload(ref data); - Assert.That(dataTree.Value, Is.EqualTo(102400)); - parsedData = integerType.ParsePayloadToData(dataTree); - Assert.That(parsedData, Is.EqualTo(new byte[] { 0, 0, 0, 100 })); - }); + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int8, null, null, null, null, 10, 2), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, 10, 2), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int16, null, null, null, null, 10, 2), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt16, null, null, null, null, 10, 2), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int32, null, null, null, null, 10, 2), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt32, null, null, null, null, 10, 2), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int64, null, null, null, null, 10, 2), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt64, null, null, null, null, 10, 2), + }; + foreach (CommonPropertiesForNamed integerType in types) + { + Assert.That(((IIntegerType)integerType).PrefixBase, Is.EqualTo(2)); + Assert.That(((IIntegerType)integerType).PrefixPower, Is.EqualTo(10)); + Assert.That(((IIntegerType)integerType).PrefixMultiplyer, Is.EqualTo(1024)); + + uint pdl = integerType.GetDataLength().Value.Value; + Assert.Multiple(() => + { + var data = new byte[pdl]; + var dataTree = integerType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(0)); + var parsedData = integerType.ParsePayloadToData(dataTree); + data = new byte[pdl]; + Assert.That(parsedData, Is.EqualTo(data)); + + data = new byte[pdl]; + data[data.Length - 1] = 1; + dataTree = integerType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(1024)); + parsedData = integerType.ParsePayloadToData(dataTree); + data = new byte[pdl]; + data[data.Length - 1] = 1; + Assert.That(parsedData, Is.EqualTo(data)); + + data = new byte[pdl]; + data[data.Length - 1] = 100; + dataTree = integerType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(102400)); + parsedData = integerType.ParsePayloadToData(dataTree); + data = new byte[pdl]; + data[data.Length - 1] = 100; + Assert.That(parsedData, Is.EqualTo(data)); + }); + } + } + [Test] + public void TestPrefix1024Negativ() + { + CommonPropertiesForNamed[] types = new CommonPropertiesForNamed[] + { + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int8, null, null, null, null, 1, -1024), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, 1, -1024), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int16, null, null, null, null, 1, -1024), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt16, null, null, null, null, 1, -1024), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int32, null, null, null, null, 1, -1024), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt32, null, null, null, null, 1, -1024), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int64, null, null, null, null, 1, -1024), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt64, null, null, null, null, 1, -1024), + }; + foreach (CommonPropertiesForNamed integerType in types) + { + Assert.That(((IIntegerType)integerType).PrefixBase, Is.EqualTo(-1024)); + Assert.That(((IIntegerType)integerType).PrefixPower, Is.EqualTo(1)); + Assert.That(((IIntegerType)integerType).PrefixMultiplyer, Is.EqualTo(-1024)); + + uint pdl = integerType.GetDataLength().Value.Value; + Assert.Multiple(() => + { + string message= ((IIntegerType)integerType).Type.ToString(); + var data = new byte[pdl]; + var dataTree = integerType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(0), message); + var parsedData = integerType.ParsePayloadToData(dataTree); + data = new byte[pdl]; + Assert.That(parsedData, Is.EqualTo(data), message); + + data = new byte[pdl]; + data[data.Length - 1] = 1; + dataTree = integerType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(-1024), message); + parsedData = integerType.ParsePayloadToData(dataTree); + data = new byte[pdl]; + data[data.Length - 1] = 1; + Assert.That(parsedData, Is.EqualTo(data), message); + + data = new byte[pdl]; + data[data.Length - 1] = 100; + dataTree = integerType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(-102400), message); + parsedData = integerType.ParsePayloadToData(dataTree); + data = new byte[pdl]; + data[data.Length - 1] = 100; + Assert.That(parsedData, Is.EqualTo(data), message); + }); + } } [Test] public void TestPrefix4Decimals() { - var integerType = new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int32, null, null, null, null, -4, 10); - Assert.That(integerType.PrefixBase, Is.EqualTo(10)); - Assert.That(integerType.PrefixPower, Is.EqualTo(-4)); - - Assert.Multiple(() => + CommonPropertiesForNamed[] types = new CommonPropertiesForNamed[] { - var data = new byte[] { 0, 0, 0, 0 }; - var dataTree = integerType.ParseDataToPayload(ref data); - Assert.That(dataTree.Value, Is.EqualTo(0)); - var parsedData = integerType.ParsePayloadToData(dataTree); - Assert.That(parsedData, Is.EqualTo(new byte[] { 0, 0, 0, 0 })); - - data = new byte[] { 0, 0, 0, 1 }; - dataTree = integerType.ParseDataToPayload(ref data); - Assert.That(dataTree.Value, Is.EqualTo(0.0001)); - parsedData = integerType.ParsePayloadToData(dataTree); - Assert.That(parsedData, Is.EqualTo(new byte[] { 0, 0, 0, 1 })); - - data = new byte[] { 0, 0, 0, 100 }; - dataTree = integerType.ParseDataToPayload(ref data); - Assert.That(dataTree.Value, Is.EqualTo(0.01)); - parsedData = integerType.ParsePayloadToData(dataTree); - Assert.That(parsedData, Is.EqualTo(new byte[] { 0, 0, 0, 100 })); - }); + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int8, null, null, null, null, -4, 10), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, -4, 10), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int16, null, null, null, null, -4, 10), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt16, null, null, null, null, -4, 10), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int32, null, null, null, null, -4, 10), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt32, null, null, null, null, -4, 10), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int64, null, null, null, null, -4, 10), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt64, null, null, null, null, -4, 10), + }; + foreach (CommonPropertiesForNamed integerType in types) + { + Assert.That(((IIntegerType)integerType).PrefixBase, Is.EqualTo(10)); + Assert.That(((IIntegerType)integerType).PrefixPower, Is.EqualTo(-4)); + Assert.That(((IIntegerType)integerType).PrefixMultiplyer, Is.EqualTo(0.0001)); + + uint pdl = integerType.GetDataLength().Value.Value; + Assert.Multiple(() => + { + var data = new byte[pdl]; + var dataTree = integerType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(0)); + var parsedData = integerType.ParsePayloadToData(dataTree); + data = new byte[pdl]; + Assert.That(parsedData, Is.EqualTo(data)); + + data = new byte[pdl]; + data[data.Length - 1] = 1; + dataTree = integerType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(0.0001)); + parsedData = integerType.ParsePayloadToData(dataTree); + data = new byte[pdl]; + data[data.Length - 1] = 1; + Assert.That(parsedData, Is.EqualTo(data)); + + data = new byte[pdl]; + data[data.Length - 1] = 100; + dataTree = integerType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(0.01)); + parsedData = integerType.ParsePayloadToData(dataTree); + data = new byte[pdl]; + data[data.Length - 1] = 100; + Assert.That(parsedData, Is.EqualTo(data)); + }); + } } private void DoParseDataTest(IntegerType integerType, T value, byte[] expectedData, string message = null) From f95c1ec1eb65a54c3582c8fbceb87f005fb79786 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 25 Sep 2024 15:54:58 +0200 Subject: [PATCH 25/51] Minor --- RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs index aa816b8..598090a 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/IntegerType.cs @@ -259,6 +259,11 @@ public override byte[] ParsePayloadToData(DataTree dataTree) throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); var rawValue = convertFormatedValueToRaw(dataTree.Value); + if (Ranges != null) + { + if (!Ranges.Any(r => r.IsInRange(rawValue))) + throw new ArithmeticException("The Value is not in range of any Range"); + } var data = Tools.ValueToData(rawValue); return data; From 67240aa67cb21f41ce247dbf65c29d5331ed1547 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 25 Sep 2024 16:33:15 +0200 Subject: [PATCH 26/51] WIP --- .../Metadata/JSON/OneOfTypes/BooleanType.cs | 22 ++++++++++--- .../JSON/OneOfTypes/LabeledBooleanType.cs | 3 ++ .../JSON/OneOfTypes/LabeledIntegerType.cs | 5 +++ RDMSharpTests/Metadata/JSON/TestBitType.cs | 4 +++ .../Metadata/JSON/TestBooleanType.cs | 33 ++++++++++++++++++- .../Metadata/JSON/TestIntegerType.cs | 4 ++- .../Metadata/JSON/TestLabeledBooleanType.cs | 4 +++ .../Metadata/JSON/TestLabeledIntegerType.cs | 4 +++ .../Metadata/JSON/TestPD_EnvelopeType.cs | 1 + 9 files changed, 74 insertions(+), 6 deletions(-) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs index 887a0b6..cb48fc2 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs @@ -95,11 +95,25 @@ public override byte[] ParsePayloadToData(DataTree dataTree) public override DataTree ParseDataToPayload(ref byte[] data) { List issueList = new List(); - if (data.Length != 1) - issueList.Add(new DataTreeIssue($"Data length is not 1")); + + uint pdl = GetDataLength().Value.Value; + if (data.Length < pdl) + { + issueList.Add(new DataTreeIssue("Given Data not fits PDL")); + byte[] cloneData = new byte[pdl]; + Array.Copy(data, cloneData, data.Length); + data = cloneData; + } + + + DataTreeValueLabel[] labels = null; + if ((Labels?.Length ?? 0) != 0) + labels = Labels.Select(lb => new DataTreeValueLabel(lb.Value, (lb.DisplayName ?? lb.Name))).ToArray(); + + bool value = false; + value = Tools.DataToBool(ref data); - data = data.Skip(1).ToArray(); - return new DataTree(this.Name, 0, Tools.DataToBool(ref data), issueList.Count != 0 ? issueList.ToArray() : null); + return new DataTree(this.Name, 0, value, issueList.Count != 0 ? issueList.ToArray() : null, labels: labels); } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs index 5ea6b4b..8ded8c2 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledBooleanType.cs @@ -40,6 +40,9 @@ public LabeledBooleanType(string name, Resources = resources; Value = value; } + public LabeledBooleanType(string name, bool value) : this(name, null, null, null, value) + { + } public override string ToString() { diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs index 7d33280..5f88836 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/LabeledIntegerType.cs @@ -41,6 +41,11 @@ public LabeledIntegerType(string name, Value = value; } + public LabeledIntegerType(string name, long value): this(name, null, null, null, value) + { + + } + public override string ToString() { return $"{Value} -> {Name}"; diff --git a/RDMSharpTests/Metadata/JSON/TestBitType.cs b/RDMSharpTests/Metadata/JSON/TestBitType.cs index 1a4730a..e0d2bd8 100644 --- a/RDMSharpTests/Metadata/JSON/TestBitType.cs +++ b/RDMSharpTests/Metadata/JSON/TestBitType.cs @@ -1,3 +1,4 @@ +using RDMSharp.Metadata; using RDMSharp.Metadata.JSON.OneOfTypes; namespace RDMSharpTests.Metadata.JSON @@ -10,6 +11,9 @@ public void TestMany() var bitType = new BitType("NAME", "DISPLAY_NAME", "NOTES", null, "bit", 1, true, false); Assert.That(bitType.Index, Is.EqualTo(1)); Assert.Throws(typeof(NotSupportedException), () => bitType.GetDataLength()); + byte[] bytes = new byte[0]; + Assert.Throws(typeof(NotSupportedException), () => bitType.ParseDataToPayload(ref bytes)); + Assert.Throws(typeof(NotSupportedException), () => bitType.ParsePayloadToData(new DataTree())); } } } \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestBooleanType.cs b/RDMSharpTests/Metadata/JSON/TestBooleanType.cs index 4ac0a76..c0fa405 100644 --- a/RDMSharpTests/Metadata/JSON/TestBooleanType.cs +++ b/RDMSharpTests/Metadata/JSON/TestBooleanType.cs @@ -1,3 +1,4 @@ +using RDMSharp.Metadata; using RDMSharp.Metadata.JSON.OneOfTypes; using RDMSharp.RDM; @@ -20,6 +21,13 @@ public void TestMany() Assert.That(pdl.Value, Is.EqualTo(1)); }); + DoParseDataTest(booleanType, false, new byte[] { 0x00 }); + DoParseDataTest(booleanType, true, new byte[] { 0x01 }); + + booleanType = new BooleanType("NAME", "DISPLAY_NAME", "NOTES", null, "boolean", null); + DoParseDataTest(booleanType, false, new byte[] { 0x00 }); + DoParseDataTest(booleanType, true, new byte[] { 0x01 }); + Assert.Throws(typeof(ArgumentException), () => booleanType = new BooleanType("NAME", "DISPLAY_NAME", "NOTES", null, "bolean", labeledBooleanType)); labeledBooleanType = new LabeledBooleanType[1]; @@ -27,7 +35,7 @@ public void TestMany() Assert.Throws(typeof(ArgumentException), () => booleanType = new BooleanType("NAME", "DISPLAY_NAME", "NOTES", null, "boolean", labeledBooleanType)); labeledBooleanType = new LabeledBooleanType[3]; - labeledBooleanType[0] = new LabeledBooleanType("NAME11", "DISPLAY_NAME11", "NOTES11", null, false); + labeledBooleanType[0] = new LabeledBooleanType("NAME11", false); labeledBooleanType[1] = new LabeledBooleanType("NAME22", "DISPLAY_NAME22", "NOTES22", null, true); labeledBooleanType[2] = new LabeledBooleanType("NAME33", "DISPLAY_NAME33", "NOTES33", null, false); Assert.Throws(typeof(ArgumentException), () => booleanType = new BooleanType("NAME", "DISPLAY_NAME", "NOTES", null, "boolean", labeledBooleanType)); @@ -37,5 +45,28 @@ public void TestMany() labeledBooleanType[1] = new LabeledBooleanType("NAME22", "DISPLAY_NAME22", "NOTES22", null, false); Assert.Throws(typeof(ArgumentException), () => booleanType = new BooleanType("NAME", "DISPLAY_NAME", "NOTES", null, "boolean", labeledBooleanType)); } + private void DoParseDataTest(BooleanType booleanType, bool value, byte[] expectedData, string message = null) + { + var dataTree = new DataTree(booleanType.Name, 0, value); + var data = new byte[0]; + Assert.DoesNotThrow(() => data = booleanType.ParsePayloadToData(dataTree), message); + Assert.That(data, Is.EqualTo(expectedData), message); + + byte[] clonaData = new byte[data.Length]; + Array.Copy(data, clonaData, clonaData.Length); + var parsedDataTree = booleanType.ParseDataToPayload(ref clonaData); + Assert.That(clonaData, Has.Length.EqualTo(0), message); + + Assert.That(parsedDataTree, Is.EqualTo(dataTree), message); + + //Test for short Data & PDL Issue + clonaData = new byte[data.Length - 1]; + Array.Copy(data, clonaData, clonaData.Length); + Assert.DoesNotThrow(() => parsedDataTree = booleanType.ParseDataToPayload(ref clonaData)); + Assert.That(parsedDataTree.Issues, Is.Not.Null); + Assert.That(parsedDataTree.Value, Is.Not.Null); + + Assert.Throws(typeof(ArithmeticException), () => data = booleanType.ParsePayloadToData(new DataTree("Different Name", dataTree.Index, dataTree.Value)), message); + } } } \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestIntegerType.cs b/RDMSharpTests/Metadata/JSON/TestIntegerType.cs index 8974a5b..6b2751c 100644 --- a/RDMSharpTests/Metadata/JSON/TestIntegerType.cs +++ b/RDMSharpTests/Metadata/JSON/TestIntegerType.cs @@ -242,6 +242,8 @@ public void TestManyUInt128() [Test] public void TestPrefix1024() { + LabeledIntegerType[] labeledIntegerType = new LabeledIntegerType[] { new LabeledIntegerType("Test 0", 0), new LabeledIntegerType("Test 1", 1), new LabeledIntegerType("Test 100", 100), }; + Range[] ranges = new Range[] { new Range(0, 100) }; CommonPropertiesForNamed[] types = new CommonPropertiesForNamed[] { new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int8, null, null, null, null, 10, 2), @@ -250,7 +252,7 @@ public void TestPrefix1024() new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt16, null, null, null, null, 10, 2), new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int32, null, null, null, null, 10, 2), new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt32, null, null, null, null, 10, 2), - new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int64, null, null, null, null, 10, 2), + new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int64, labeledIntegerType, null, ranges, ERDM_SensorUnit.BYTE, 10, 2), new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt64, null, null, null, null, 10, 2), }; foreach (CommonPropertiesForNamed integerType in types) diff --git a/RDMSharpTests/Metadata/JSON/TestLabeledBooleanType.cs b/RDMSharpTests/Metadata/JSON/TestLabeledBooleanType.cs index b7c0b68..f509997 100644 --- a/RDMSharpTests/Metadata/JSON/TestLabeledBooleanType.cs +++ b/RDMSharpTests/Metadata/JSON/TestLabeledBooleanType.cs @@ -1,3 +1,4 @@ +using RDMSharp.Metadata; using RDMSharp.Metadata.JSON.OneOfTypes; namespace RDMSharpTests.Metadata.JSON @@ -10,6 +11,9 @@ public void TestMany() var labeledBooleanType = new LabeledBooleanType("NAME", "DISPLAY_NAME", "NOTES", null, true); Assert.That(labeledBooleanType.Value, Is.True); Assert.Throws(typeof(NotSupportedException), () => labeledBooleanType.GetDataLength()); + byte[] bytes = new byte[0]; + Assert.Throws(typeof(NotSupportedException), () => labeledBooleanType.ParseDataToPayload(ref bytes)); + Assert.Throws(typeof(NotSupportedException), () => labeledBooleanType.ParsePayloadToData(new DataTree())); } } } \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestLabeledIntegerType.cs b/RDMSharpTests/Metadata/JSON/TestLabeledIntegerType.cs index 9008fba..6545873 100644 --- a/RDMSharpTests/Metadata/JSON/TestLabeledIntegerType.cs +++ b/RDMSharpTests/Metadata/JSON/TestLabeledIntegerType.cs @@ -1,3 +1,4 @@ +using RDMSharp.Metadata; using RDMSharp.Metadata.JSON.OneOfTypes; namespace RDMSharpTests.Metadata.JSON @@ -10,6 +11,9 @@ public void TestMany() var labeledIntegerType = new LabeledIntegerType("NAME", "DISPLAY_NAME", "NOTES", null, 3); Assert.That(labeledIntegerType.Value, Is.EqualTo(3)); Assert.Throws(typeof(NotSupportedException), () => labeledIntegerType.GetDataLength()); + byte[] bytes = new byte[0]; + Assert.Throws(typeof(NotSupportedException), () => labeledIntegerType.ParseDataToPayload(ref bytes)); + Assert.Throws(typeof(NotSupportedException), () => labeledIntegerType.ParsePayloadToData(new DataTree())); } } } \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs b/RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs index eb2cd33..aee4f82 100644 --- a/RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs +++ b/RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs @@ -18,6 +18,7 @@ public void TestMany() }); Assert.Throws(typeof(ArgumentException), () => pdEnvelopeType = new PD_EnvelopeType("NAME", "DISPLAY_NAME", "NOTES", null, "pdEnvelop", 2)); + } } } \ No newline at end of file From 4e9782d5cc8b9c709177f045e6192fc99ccc4dc1 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 25 Sep 2024 17:33:30 +0200 Subject: [PATCH 27/51] Fix BitFieldType-Parser and wrote tests for it --- RDMSharp/Metadata/DataTree.cs | 24 +++++- .../Metadata/JSON/OneOfTypes/BitFieldType.cs | 82 +++++++++++-------- RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs | 5 +- .../Metadata/JSON/TestBitFieldType.cs | 40 +++++++++ 4 files changed, 112 insertions(+), 39 deletions(-) diff --git a/RDMSharp/Metadata/DataTree.cs b/RDMSharp/Metadata/DataTree.cs index e3fbca2..f32f04a 100644 --- a/RDMSharp/Metadata/DataTree.cs +++ b/RDMSharp/Metadata/DataTree.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; namespace RDMSharp.Metadata { @@ -53,8 +54,27 @@ public bool Equals(DataTree other) return Name == other.Name && Index == other.Index && EqualityComparer.Default.Equals(Value, other.Value) && - EqualityComparer.Default.Equals(Children, other.Children) && - EqualityComparer.Default.Equals(Issues, other.Issues); + compairArrays(this, other); + + bool compairArrays(DataTree _this, DataTree other) + { + if (_this.Children != null) + { + if (!_this.Children.SequenceEqual(other.Children)) + return false; + } + else if (other.Children != null) + return false; + if (_this.Issues != null) + { + if (!_this.Issues.SequenceEqual(other.Issues)) + return false; + } + else if (other.Issues != null) + return false; + + return true; + } } public override int GetHashCode() diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs index 777c4d0..b295b2d 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs @@ -2,50 +2,27 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes { public class BitFieldType : CommonPropertiesForNamed { - [JsonConstructor] - public BitFieldType(string name, - string displayName, - string notes, - string[] resources, - string type, - ushort size, - bool? valueForUnspecified, - BitType[] bits) : base() - { - if (!"bitField".Equals(type)) - throw new ArgumentException($"Argument {nameof(type)} has to be \"bitField\""); - if (size % 8 != 0) - throw new ArgumentOutOfRangeException($"Argument {nameof(size)} has to be a multiple of 8"); - - Name = name; - DisplayName = displayName; - Notes = notes; - Resources = resources; - Type = type; - Size = size; - ValueForUnspecified = valueForUnspecified; - Bits = bits; - } - [JsonPropertyName("name")] [JsonPropertyOrder(1)] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public override string Name { get; } + [JsonPropertyName("displayName")] [JsonPropertyOrder(2)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public override string DisplayName { get; } + [JsonPropertyName("notes")] [JsonPropertyOrder(4)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public override string Notes { get; } + [JsonPropertyName("resources")] [JsonPropertyOrder(5)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] @@ -63,11 +40,40 @@ public BitFieldType(string name, [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyOrder(32)] public bool? ValueForUnspecified { get; } + [JsonPropertyName("bits")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyOrder(41)] public BitType[] Bits { get; } + [JsonConstructor] + public BitFieldType(string name, + string displayName, + string notes, + string[] resources, + string type, + ushort size, + bool? valueForUnspecified, + BitType[] bits) : base() + { + if (!"bitField".Equals(type)) + throw new ArgumentException($"Argument {nameof(type)} has to be \"bitField\""); + if (size % 8 != 0) + throw new ArgumentOutOfRangeException($"Argument {nameof(size)} has to be a multiple of 8"); + + Name = name; + DisplayName = displayName; + Notes = notes; + Resources = resources; + Type = type; + Size = size; + ValueForUnspecified = valueForUnspecified; + Bits = bits; + } + public BitFieldType(string name, ushort size, BitType[] bits) : this(name, null, null, null, "bitField", size, null, bits) + { + } + public override PDL GetDataLength() { return new PDL((uint)(Size / 8)); @@ -94,10 +100,10 @@ public override byte[] ParsePayloadToData(DataTree dataTree) BitType bit = Bits.FirstOrDefault(b=>b.Name== bitDataTree.Name); if (bit == null) throw new ArithmeticException($"Can't find matching BitType {bitDataTree.Name}"); - if (bitDataTree.Index != bit.Index) + if (Bits[bitDataTree.Index] != bit) throw new ArithmeticException($"The given DataTree {nameof(bitDataTree.Index)}({bitDataTree.Index}) not match BitType {nameof(bit.Index)}({bit.Index})"); if (bitDataTree.Value is not bool value) - throw new ArithmeticException($"DataTree VAlue is not bool"); + throw new ArithmeticException($"DataTree Value is not bool"); data[bit.Index] = value; } @@ -110,15 +116,19 @@ public override DataTree ParseDataToPayload(ref byte[] data) List issueList = new List(); int byteCount = (Size / 8); if (byteCount != data.Length) + { issueList.Add(new DataTreeIssue($"Data length not match given Size/8 ({byteCount})")); - + byte[] cloneData = new byte[byteCount]; + Array.Copy(data, cloneData, data.Length); + data = cloneData; + } bool[] bools = Tools.DataToBoolArray(ref data, this.Size); - foreach (BitType bitType in Bits) - bitDataTrees.Add(new DataTree(bitType.Name, bitType.Index, bools[bitType.Index])); - - data = data.Skip(byteCount).ToArray(); - - return new DataTree(this.Name, 0, bitDataTrees.OrderBy(b=>b.Index), issueList.Count != 0 ? issueList.ToArray() : null); + for (uint i = 0; i < Bits.Length; i++) + { + BitType bitType = Bits[i]; + bitDataTrees.Add(new DataTree(bitType.Name, i, bools[bitType.Index])); + } + return new DataTree(this.Name, 0, children: bitDataTrees.OrderBy(b=>b.Index).ToArray(), issueList.Count != 0 ? issueList.ToArray() : null); } } -} +} \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs index fb0b65f..82520bf 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BitType.cs @@ -24,9 +24,12 @@ public BitType(string name, Index = index; Reserved = reserved; ValueIfReserved = valueIfReserved; + } + public BitType(string name, ushort index) : this(name, null, null, null, "bit", index, null, null) + { } - [JsonPropertyName("name")] + [JsonPropertyName("name")] [JsonPropertyOrder(1)] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public override string Name { get; } diff --git a/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs b/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs index a5752ee..5fd30cd 100644 --- a/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs +++ b/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs @@ -1,3 +1,4 @@ +using RDMSharp.Metadata; using RDMSharp.Metadata.JSON.OneOfTypes; using RDMSharp.RDM; @@ -23,6 +24,45 @@ public void TestMany() Assert.Throws(typeof(ArgumentException), () => bitFieldType = new BitFieldType("NAME", "DISPLAY_NAME", "NOTES", null, "botField", 16, false, bitTypes)); Assert.Throws(typeof(ArgumentOutOfRangeException), () => bitFieldType = new BitFieldType("NAME", "DISPLAY_NAME", "NOTES", null, "bitField", 7, false, bitTypes)); + + + bitTypes = new BitType[3]; + bitTypes[0] = new BitType("NAME11", 2); + bitTypes[1] = new BitType("NAME22", 4); + bitTypes[2] = new BitType("NAME33", 15); + bitFieldType = new BitFieldType("NAME_BIT_FIELD", 16, bitTypes); + var dataTree= new DataTree(bitFieldType.Name,0,new DataTree[] { new DataTree(bitTypes[0].Name, 0, true), new DataTree(bitTypes[1].Name, 1, true), new DataTree(bitTypes[2].Name, 2, true), }); + + DoParseDataTest(bitFieldType, dataTree, new byte[] { 0b00010100, 0b10000000 }); + } + private void DoParseDataTest(BitFieldType bitFieldType, DataTree dataTree, byte[] expectedData, string message = null) + { + Assert.Multiple(() => + { + Assert.That(dataTree.Value, Is.Null); + Assert.That(dataTree.Children, Is.Not.Null); + var data = new byte[0]; + Assert.DoesNotThrow(() => data = bitFieldType.ParsePayloadToData(dataTree), message); + Assert.That(data, Is.EqualTo(expectedData), message); + + byte[] clonaData = new byte[data.Length]; + Array.Copy(data, clonaData, clonaData.Length); + var parsedDataTree = bitFieldType.ParseDataToPayload(ref clonaData); + Assert.That(clonaData, Has.Length.EqualTo(0), message); + + Assert.That(parsedDataTree, Is.EqualTo(dataTree), message); + Assert.That(parsedDataTree.Value, Is.Null); + + //Test for short Data & PDL Issue + clonaData = new byte[data.Length - 1]; + Array.Copy(data, clonaData, clonaData.Length); + Assert.DoesNotThrow(() => parsedDataTree = bitFieldType.ParseDataToPayload(ref clonaData)); + Assert.That(parsedDataTree.Issues, Is.Not.Null); + Assert.That(parsedDataTree.Value, Is.Null); + Assert.That(parsedDataTree.Children, Is.Not.Null); + + Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree("Different Name", dataTree.Index, dataTree.Value)), message); + }); } } } \ No newline at end of file From f2cee929e481199ed5e4a16a1a2fcfcc7bdd36f3 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 25 Sep 2024 17:48:07 +0200 Subject: [PATCH 28/51] Minor --- .../Metadata/JSON/OneOfTypes/BitFieldType.cs | 16 +++++++++++++--- RDMSharpTests/Metadata/JSON/TestBitFieldType.cs | 5 +++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs index b295b2d..b4cc648 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs @@ -70,7 +70,7 @@ public BitFieldType(string name, ValueForUnspecified = valueForUnspecified; Bits = bits; } - public BitFieldType(string name, ushort size, BitType[] bits) : this(name, null, null, null, "bitField", size, null, bits) + public BitFieldType(string name, ushort size, BitType[] bits, bool valueForUnspecified = false) : this(name, null, null, null, "bitField", size, valueForUnspecified, bits) { } @@ -91,9 +91,9 @@ public override byte[] ParsePayloadToData(DataTree dataTree) throw new ArithmeticException($"The given {nameof(dataTree.Children)}.{nameof(dataTree.Children.Length)}({dataTree.Children.Length}) not match {nameof(Bits)}.{nameof(Bits.Length)}({Bits.Length})"); bool[] data = new bool[Size]; - if (ValueForUnspecified.HasValue) + if (ValueForUnspecified == true) for (int i = 0; i < Size; i++) - data[i] = ValueForUnspecified.Value; + data[i] = true; foreach (DataTree bitDataTree in dataTree.Children) { @@ -128,6 +128,16 @@ public override DataTree ParseDataToPayload(ref byte[] data) BitType bitType = Bits[i]; bitDataTrees.Add(new DataTree(bitType.Name, i, bools[bitType.Index])); } + bool valueForUnspecified = ValueForUnspecified == true; + for(int i = 0; i < bools.Length; i++) + { + if (Bits.Any(b => b.Index == i)) + continue; + + bool bit= bools[i]; + if (bit != valueForUnspecified) + issueList.Add(new DataTreeIssue($"The Bit at Index {i} is Unspecified, but the Value is not {valueForUnspecified} as defined for Unspecified Bits")); + } return new DataTree(this.Name, 0, children: bitDataTrees.OrderBy(b=>b.Index).ToArray(), issueList.Count != 0 ? issueList.ToArray() : null); } } diff --git a/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs b/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs index 5fd30cd..076eceb 100644 --- a/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs +++ b/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs @@ -34,6 +34,11 @@ public void TestMany() var dataTree= new DataTree(bitFieldType.Name,0,new DataTree[] { new DataTree(bitTypes[0].Name, 0, true), new DataTree(bitTypes[1].Name, 1, true), new DataTree(bitTypes[2].Name, 2, true), }); DoParseDataTest(bitFieldType, dataTree, new byte[] { 0b00010100, 0b10000000 }); + + bitFieldType = new BitFieldType("NAME_BIT_FIELD", 16, bitTypes, true); + dataTree = new DataTree(bitFieldType.Name, 0, new DataTree[] { new DataTree(bitTypes[0].Name, 0, false), new DataTree(bitTypes[1].Name, 1, false), new DataTree(bitTypes[2].Name, 2, false), }); + Assert.That(bitFieldType.ValueForUnspecified, Is.True); + DoParseDataTest(bitFieldType, dataTree, new byte[] { 0b11101011, 0b01111111 }); } private void DoParseDataTest(BitFieldType bitFieldType, DataTree dataTree, byte[] expectedData, string message = null) { From 40311a634de77790147d3d9de8558562b16c7ea7 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 25 Sep 2024 18:11:08 +0200 Subject: [PATCH 29/51] MOOOOOOR TESTS --- .../Metadata/JSON/OneOfTypes/BitFieldType.cs | 2 +- .../Metadata/JSON/TestBitFieldType.cs | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs index b4cc648..426428d 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BitFieldType.cs @@ -100,7 +100,7 @@ public override byte[] ParsePayloadToData(DataTree dataTree) BitType bit = Bits.FirstOrDefault(b=>b.Name== bitDataTree.Name); if (bit == null) throw new ArithmeticException($"Can't find matching BitType {bitDataTree.Name}"); - if (Bits[bitDataTree.Index] != bit) + if (Bits.Length <= bitDataTree.Index || Bits[bitDataTree.Index] != bit) throw new ArithmeticException($"The given DataTree {nameof(bitDataTree.Index)}({bitDataTree.Index}) not match BitType {nameof(bit.Index)}({bit.Index})"); if (bitDataTree.Value is not bool value) throw new ArithmeticException($"DataTree Value is not bool"); diff --git a/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs b/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs index 076eceb..f95bf1b 100644 --- a/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs +++ b/RDMSharpTests/Metadata/JSON/TestBitFieldType.cs @@ -66,7 +66,24 @@ private void DoParseDataTest(BitFieldType bitFieldType, DataTree dataTree, byte[ Assert.That(parsedDataTree.Value, Is.Null); Assert.That(parsedDataTree.Children, Is.Not.Null); - Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree("Different Name", dataTree.Index, dataTree.Value)), message); + Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree("Different Name", dataTree.Index, children: dataTree.Children)), message); + Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, children: dataTree.Children?.Take(2).ToArray())), message); + + var children = dataTree.Children!.ToArray(); + children[1] = new DataTree("Other Name", children[1].Index, children[1].Value); + Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, children: children)), message); + + children = dataTree.Children!.ToArray(); + children[1] = new DataTree(children[1].Name, 3, children[1].Value); + Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, children: children)), message); + + children = dataTree.Children!.ToArray(); + children[1] = new DataTree(children[1].Name, 0, children[1].Value); + Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, children: children)), message); + + children = dataTree.Children!.ToArray(); + children[1] = new DataTree(children[1].Name, children[1].Index, 3); + Assert.Throws(typeof(ArithmeticException), () => data = bitFieldType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, children: children)), message); }); } } From ea070dfee327db9e4268517fd7c69ca6a87248a5 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 25 Sep 2024 18:17:28 +0200 Subject: [PATCH 30/51] Moooore Tests --- RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs | 1 - RDMSharpTests/Metadata/JSON/TestBooleanType.cs | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs index cb48fc2..b0dc5fd 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BooleanType.cs @@ -1,7 +1,6 @@ using RDMSharp.RDM; using System; using System.Collections.Generic; -using System.Drawing; using System.Linq; using System.Text.Json.Serialization; diff --git a/RDMSharpTests/Metadata/JSON/TestBooleanType.cs b/RDMSharpTests/Metadata/JSON/TestBooleanType.cs index c0fa405..79fa755 100644 --- a/RDMSharpTests/Metadata/JSON/TestBooleanType.cs +++ b/RDMSharpTests/Metadata/JSON/TestBooleanType.cs @@ -10,7 +10,7 @@ public class TestBooleanType public void TestMany() { var labeledBooleanType = new LabeledBooleanType[2]; - labeledBooleanType[0] = new LabeledBooleanType("NAME11", "DISPLAY_NAME11", "NOTES11", null, false); + labeledBooleanType[0] = new LabeledBooleanType("NAME11", null, "NOTES11", null, false); labeledBooleanType[1] = new LabeledBooleanType("NAME22", "DISPLAY_NAME22", "NOTES22", null, true); var booleanType = new BooleanType("NAME", "DISPLAY_NAME", "NOTES", null, "boolean", labeledBooleanType); Assert.That(booleanType.Labels, Has.Length.EqualTo(2)); @@ -67,6 +67,7 @@ private void DoParseDataTest(BooleanType booleanType, bool value, byte[] expecte Assert.That(parsedDataTree.Value, Is.Not.Null); Assert.Throws(typeof(ArithmeticException), () => data = booleanType.ParsePayloadToData(new DataTree("Different Name", dataTree.Index, dataTree.Value)), message); + Assert.Throws(typeof(ArithmeticException), () => data = booleanType.ParsePayloadToData(new DataTree(dataTree.Name, dataTree.Index, 234)), message); } } } \ No newline at end of file From 87c4171cecae0c5bb47ef2beee1cbb02242f5511 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 25 Sep 2024 21:21:26 +0200 Subject: [PATCH 31/51] Implement Parser for ByteType and wrote Tests --- .../Metadata/JSON/OneOfTypes/BytesType.cs | 156 ++++++++++- RDMSharpTests/Metadata/JSON/TestBytesType.cs | 253 ++++++++++++++++++ 2 files changed, 403 insertions(+), 6 deletions(-) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs index 87fd190..2e3e4f4 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Text.Json.Serialization; namespace RDMSharp.Metadata.JSON.OneOfTypes @@ -81,23 +82,166 @@ public override string ToString() public override PDL GetDataLength() { + switch (Format) + { + case "mac-address": + case "uid": + return new PDL(6); + case "ipv4": + case "float": + return new PDL(4); + case "ipv6": + case "uuid": + case "guid": + return new PDL(16); + case "double": + return new PDL(8); + case "pid": + return new PDL(2); + } return new PDL((uint)(MinLength ?? 1), (uint)(MaxLength ?? PDL.MAX_LENGTH)); } public override byte[] ParsePayloadToData(DataTree dataTree) { if (!string.Equals(dataTree.Name, this.Name)) throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); - - /// ToDo - - throw new ArithmeticException($"The given Object from {nameof(dataTree.Value)} can't be parsed"); + + switch (Format) + { + //Known from E1.37-5 (2024) + case "uid" when dataTree.Value is UID uid: + return uid.ToBytes().ToArray(); + case "ipv4" when dataTree.Value is IPv4Address ipv4: + return (byte[])ipv4; + case "ipv6" when dataTree.Value is IPv6Address ipv6: + return (byte[])ipv6; + case "mac-address" when dataTree.Value is MACAddress macAddress: + return (byte[])macAddress; + + //Known from E1.37-5 (2024) as uuid + case "uuid" when dataTree.Value is Guid uuid: + return uuid.ToByteArray(); + case "guid" when dataTree.Value is Guid guid: + return guid.ToByteArray(); + + //Additional added, because there is no fancy way to di this with E1.37-5 (2024) + case "pid" when dataTree.Value is ERDM_Parameter pid: + return Tools.ValueToData(pid); + + //Additional added, because there is no fancy way to di this with E1.37-5 (2024) + case "double" when dataTree.Value is double _double: + return BitConverter.GetBytes(_double); + case "float" when dataTree.Value is float _float: + return BitConverter.GetBytes(_float); + + + //Additional added, because there is no fancy way to di this with E1.37-5 (2024) + case "ascii" when dataTree.Value is string ascii: + return Encoding.ASCII.GetBytes(ascii); + case "utf8" when dataTree.Value is string utf8: + return Encoding.UTF8.GetBytes(utf8); + case "utf32" when dataTree.Value is string utf32: + return Encoding.UTF32.GetBytes(utf32); + case "unicode" when dataTree.Value is string unicode: + return Encoding.Unicode.GetBytes(unicode); + case "big_edian_unicode" when dataTree.Value is string big_edian_unicode: + return Encoding.BigEndianUnicode.GetBytes(big_edian_unicode); + case "latin1" when dataTree.Value is string latin1: + return Encoding.Latin1.GetBytes(latin1); + + //Fallback + default: + if (dataTree.Value is string str) + return Encoding.UTF8.GetBytes(str); + if (dataTree.Value is string[] strArray) + return Encoding.UTF8.GetBytes(string.Join((char)0, strArray)); + if (dataTree.Value is byte[] byteArray) + return byteArray; + break; + } + + throw new ArithmeticException($"The given Object of {nameof(Format)}: \"{Format}\" can't be parsed from {nameof(dataTree.Value)}: {dataTree.Value}"); } public override DataTree ParseDataToPayload(ref byte[] data) { List issueList = new List(); + object value = null; + switch (Format) + { + //Known from E1.37-5 (2024) + case "uid": + value = new UID(Tools.DataToUShort(ref data), Tools.DataToUInt(ref data)); + break; + case "ipv4": + value = new IPv4Address(data.Take(4)); + data = data.Skip(4).ToArray(); + break; + case "ipv6": + value = new IPv6Address(data.Take(16)); + data = data.Skip(16).ToArray(); + break; + case "mac-address": + value = new MACAddress(data.Take(16)); + data = data.Skip(6).ToArray(); + break; + + //Known from E1.37-5 (2024) as uuid + case "uuid": + case "guid": + value = new Guid(data.Take(16).ToArray()); + data = data.Skip(16).ToArray(); + break; + + //Additional added, because there is no fancy way to di this with E1.37-5 (2024) + case "pid": + value = Tools.DataToEnum(ref data); + break; + + //Additional added, because there is no fancy way to di this with E1.37-5 (2024) + case "double": + value = BitConverter.ToDouble(data, 0); + data = data.Skip(8).ToArray(); + break; + case "float": + value = BitConverter.ToSingle(data, 0); + data = data.Skip(4).ToArray(); + break; + + + //Additional added, because there is no fancy way to di this with E1.37-5 (2024) + case "ascii": + value = Encoding.ASCII.GetString(data); + data = data.Skip(data.Length).ToArray(); + break; + case "utf8": + value = Encoding.UTF8.GetString(data); + data = data.Skip(data.Length).ToArray(); + break; + case "utf32": + value = Encoding.UTF32.GetString(data); + data = data.Skip(data.Length).ToArray(); + break; + case "unicode": + value = Encoding.Unicode.GetString(data); + data = data.Skip(data.Length).ToArray(); + break; + case "big_edian_unicode": + value = Encoding.BigEndianUnicode.GetString(data); + data = data.Skip(data.Length).ToArray(); + break; + case "latin1": + value=Encoding.Latin1.GetString(data); + data = data.Skip(data.Length).ToArray(); + break; - data = data.Skip(data.Length).ToArray(); - return new DataTree(this.Name, 0, data, issueList.Count != 0 ? issueList.ToArray() : null); + //Fallback + default: + value = data; + data = data.Skip(data.Length).ToArray(); + issueList.Add(new DataTreeIssue($"No Parser found for {nameof(Format)}: \"{Format}\"")); + break; + } + return new DataTree(this.Name, 0, value, issueList.Count != 0 ? issueList.ToArray() : null); } } } diff --git a/RDMSharpTests/Metadata/JSON/TestBytesType.cs b/RDMSharpTests/Metadata/JSON/TestBytesType.cs index 6b05b3a..7fbbc54 100644 --- a/RDMSharpTests/Metadata/JSON/TestBytesType.cs +++ b/RDMSharpTests/Metadata/JSON/TestBytesType.cs @@ -1,3 +1,4 @@ +using RDMSharp.Metadata; using RDMSharp.Metadata.JSON.OneOfTypes; using RDMSharp.RDM; @@ -41,5 +42,257 @@ public void TestMany() Assert.Throws(typeof(ArgumentOutOfRangeException), () => bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 4294567890, null)); Assert.Throws(typeof(ArgumentOutOfRangeException), () => bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, 2, 4294567890)); } + [Test] + public void TestParseUID() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "uid", null, null); + Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(6)); + var uid = new UID(0x4646, 0x12345678); + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, uid)); + Assert.That(data, Is.EqualTo(new byte[] { 0x46, 0x46, 0x12, 0x34, 0x56, 0x78 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(uid)); + + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "uid", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } + + [Test] + public void TestParseIPv4() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "ipv4", null, null); + Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(4)); + var ipv4 = new IPv4Address(192,168,178,254); + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, ipv4)); + Assert.That(data, Is.EqualTo(new byte[] { 192, 168, 178, 254 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(ipv4)); + + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "ipv4", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseIPv6() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "ipv6", null, null); + Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(16)); + var ipv6 = IPv6Address.LocalHost; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, ipv6)); + Assert.That(data, Is.EqualTo(new byte[] { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(ipv6)); + + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "ipv6", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseMAC() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "mac-address", null, null); + Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(6)); + var mac = new MACAddress(new byte[] { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC }); + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, mac)); + Assert.That(data, Is.EqualTo(new byte[] { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(mac)); + + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "mac-address", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseGUID() + { + string[] formates = new string[] { "uuid", "guid" }; + foreach (var formate in formates) + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", formate, null, null); + Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(16)); + var guid = new Guid(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }); + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, guid)); + Assert.That(data, Is.EqualTo(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(guid)); + + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", formate, null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } + } + [Test] + public void TestParseDouble() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "double", null, null); + Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(8)); + var _double = 0.252536d; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, _double)); + Assert.That(data, Is.EqualTo(new byte[] { 142, 2, 68, 193, 140, 41, 208, 63 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(_double)); + + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "double", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseFloat() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "float", null, null); + Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(4)); + var _float = 0.252536f; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, _float)); + Assert.That(data, Is.EqualTo(new byte[] { 102, 76, 129, 62 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(_float)); + + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "float", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParsePID() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "pid", null, null); + Assert.That(bytesType.GetDataLength().Value, Is.EqualTo(2)); + var pid = ERDM_Parameter.CURVE; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, pid)); + Assert.That(data, Is.EqualTo(new byte[] { 0x03, 0x043 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(pid)); + + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "pid", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseASCII() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "ascii", null, null); + var ascii = "This is ASCII"; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, ascii)); + Assert.That(data, Is.EqualTo(new byte[] { 84, 104, 105, 115, 32, 105, 115, 32, 65, 83, 67, 73, 73 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(ascii)); + + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "ascii", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseUTF8() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "utf8", null, null); + var utf8 = "äöü߀!"; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, utf8)); + Assert.That(data, Is.EqualTo(new byte[] { 195, 164, 195, 182, 195, 188, 195, 159, 226, 130, 172, 33 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(utf8)); + + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "utf8", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseUTF32() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "utf32", null, null); + var utf32 = "😊🚀🌍💡📚✈️"; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, utf32)); + Assert.That(data, Is.EqualTo(new byte[] { 10, 246, 1, 0, 128, 246, 1, 0, 13, 243, 1, 0, 161, 244, 1, 0, 218, 244, 1, 0, 8, 39, 0, 0, 15, 254, 0, 0 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(utf32)); + + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "utf32", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseUnicode() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "unicode", null, null); + var unicode = "ÄÖÜß😊"; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, unicode)); + Assert.That(data, Is.EqualTo(new byte[] { 196, 0, 214, 0, 220, 0, 223, 0, 61, 216, 10, 222 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(unicode)); + + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "unicode", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseBigEndianUnicode() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "big_edian_unicode", null, null); + var big_edian_unicode = "ÄÖÜß😊"; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, big_edian_unicode)); + Assert.That(data, Is.EqualTo(new byte[] { 0, 196, 0, 214, 0, 220, 0, 223, 216, 61, 222, 10 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(big_edian_unicode)); + + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "big_edian_unicode", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseLatin1() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "latin1", null, null); + var latin1 = "Café"; ; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, latin1)); + Assert.That(data, Is.EqualTo(new byte[] { 67, 97, 102, 233 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(latin1)); + + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "latin1", null, null).ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseFallbackString() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, null, null); + var utf8 = "äöü߀!"; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, utf8)); + Assert.That(data, Is.EqualTo(new byte[] { 195, 164, 195, 182, 195, 188, 195, 159, 226, 130, 172, 33 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + } + [Test] + public void TestParseFallbackStringArray() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, null, null); + var utf8 = "äöü߀!"; + var array = new string[] { utf8, utf8 }; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, array)); + Assert.That(data, Is.EqualTo(new byte[] { 195, 164, 195, 182, 195, 188, 195, 159, 226, 130, 172, 33, 0, 195, 164, 195, 182, 195, 188, 195, 159, 226, 130, 172, 33 })); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + } + [Test] + public void TestParseFallbackByteArray() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, null, null); + var bytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, bytes)); + Assert.That(data, Is.EqualTo(bytes)); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(bytes)); + } } } \ No newline at end of file From 5094b6a9f7b3d4418237d1de795abbfa571dd862 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 25 Sep 2024 21:23:25 +0200 Subject: [PATCH 32/51] minor --- RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs index 16eb863..f200df2 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs @@ -1,9 +1,8 @@ using RDMSharp.RDM; -using System.Collections.Generic; using System; +using System.Collections.Generic; using System.Linq; using System.Text.Json.Serialization; -using System.Drawing; namespace RDMSharp.Metadata.JSON.OneOfTypes { From 1aabd78309d48439863f02bb4f8cbf6be3d06261 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 2 Oct 2024 15:33:47 +0200 Subject: [PATCH 33/51] Wip Parse StringType --- .../Metadata/JSON/OneOfTypes/StringType.cs | 105 +++++++++++--- RDMSharpTests/Metadata/JSON/TestStringType.cs | 136 +++++++++++++++++- 2 files changed, 219 insertions(+), 22 deletions(-) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs index 698a660..b5faec7 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs @@ -89,7 +89,28 @@ public StringType(string name, MaxBytes = maxBytes; RestrictToASCII = restrictToASCII; } - + public StringType( + string name, + string displayName, + string notes, + string format, + string pattern, + uint length, + bool? restrictToASCII = null) : this( + name, + displayName, + notes, + null, + "string", + format, + pattern, + minLength: length, + maxLength: length, + null, + null, + restrictToASCII) + { + } public override string ToString() { return base.ToString(); @@ -120,13 +141,25 @@ public override byte[] ParsePayloadToData(DataTree dataTree) if (dataTree.Value is string @string) { - if (MaxLength.HasValue) - @string = @string.Substring(0, (int)MaxLength); + if (MinLength.HasValue && MinLength.Value > @string.Length) + throw new ArithmeticException($"The given String is smaller then {nameof(MinLength)}: {MinLength}"); + if (MaxLength.HasValue && MaxLength.Value < @string.Length) + throw new ArithmeticException($"The given String is larger then {nameof(MaxLength)}: {MaxLength}"); + Encoding encoder = null; if (RestrictToASCII == true) - Encoding.ASCII.GetBytes(@string); + encoder = Encoding.ASCII; else - Encoding.UTF8.GetBytes(@string); + encoder = Encoding.UTF8; + + var data = encoder.GetBytes(@string); + + if (MinBytes.HasValue && MinBytes.Value > data.Length) + throw new ArithmeticException($"The given String encoded is smaller then {nameof(MinBytes)}: {MinBytes}"); + if (MaxBytes.HasValue && MaxBytes.Value < data.Length) + throw new ArithmeticException($"The given String encoded is larger then {nameof(MaxBytes)}: {MaxBytes}"); + + return data; } throw new ArithmeticException($"The given Object from {nameof(dataTree.Value)} can't be parsed"); @@ -135,32 +168,62 @@ public override byte[] ParsePayloadToData(DataTree dataTree) public override DataTree ParseDataToPayload(ref byte[] data) { List issueList = new List(); - if (MaxBytes.HasValue && data.Length > MaxBytes) + if (MaxBytes.HasValue && data.Length > MaxBytes.Value) issueList.Add(new DataTreeIssue($"Data length exceeds {nameof(MaxBytes)}, the Data has {data.Length}, but {nameof(MaxBytes)} is {MaxBytes}")); - if (MinBytes.HasValue && data.Length < MinBytes) + if (MinBytes.HasValue && data.Length < MinBytes.Value) issueList.Add(new DataTreeIssue($"Data length falls shorts of {nameof(MinBytes)}, the Data has {data.Length}, but {nameof(MinBytes)} is {MinBytes}")); string str = null; - uint length = (uint)data.Length; - if (MaxLength.HasValue) - length = MaxLength.Value; - if (MaxBytes.HasValue) - length = MaxBytes.Value; - - if (data.Any(c => c == 0)) - length = (uint)data.TakeWhile(c => c != 0).Count() + 1; - + byte[] dataBytes = data; + int charLength = 0; + int byteLength = 0; + int takenBytesCount = 0; if (RestrictToASCII == true) - str = Encoding.ASCII.GetString(data, 0, (int)length); + parse(Encoding.ASCII); else - str = Encoding.UTF8.GetString(data, 0, (int)length); + parse(Encoding.UTF8); + + void parse(Encoding encoder) + { + str = encoder.GetString(dataBytes); + takenBytesCount = dataBytes.Length; + + string[] strings = str.Split((char)0); + if (strings.Where(s => string.IsNullOrEmpty(s)).Count() > 1) + issueList.Add(new DataTreeIssue("More then one Null-Delimiter")); + if (strings.Skip(1).Any(s => !string.IsNullOrEmpty(s))) + issueList.Add(new DataTreeIssue("Trailing Characters")); + + str = strings.First(); + byteLength = encoder.GetBytes(str).Length; + takenBytesCount = byteLength; + charLength = str.Length; + bool repeatParse = false; + if (MaxLength.HasValue && MaxLength < charLength) + { + charLength = (int)MaxLength.Value; + repeatParse = true; + } + if (MaxBytes.HasValue && MaxBytes < byteLength) + { + byteLength = (int)MaxBytes.Value; + repeatParse = true; + } + if (repeatParse) + { + dataBytes = dataBytes.Take(byteLength).ToArray(); + str = encoder.GetString(dataBytes); + takenBytesCount = dataBytes.Length; + } + + } - if (MaxLength.HasValue && str.Length > MaxLength) + if (MaxLength.HasValue && str.Length > MaxLength.Value) issueList.Add(new DataTreeIssue($"String length exceeds {nameof(MaxLength)}, the Data has {str.Length}, but {nameof(MaxLength)} is {MaxLength}")); - if (MinLength.HasValue && str.Length < MinLength) + if (MinLength.HasValue && str.Length < MinLength.Value) issueList.Add(new DataTreeIssue($"String length falls shorts of {nameof(MinLength)}, the Data has {str.Length}, but {nameof(MinLength)} is {MinLength}")); - data = data.Skip((int)length).ToArray(); + data = data.Skip(takenBytesCount).ToArray(); return new DataTree(this.Name, 0, str, issueList.Count != 0 ? issueList.ToArray() : null); } } diff --git a/RDMSharpTests/Metadata/JSON/TestStringType.cs b/RDMSharpTests/Metadata/JSON/TestStringType.cs index 734a5c1..642ce18 100644 --- a/RDMSharpTests/Metadata/JSON/TestStringType.cs +++ b/RDMSharpTests/Metadata/JSON/TestStringType.cs @@ -1,3 +1,4 @@ +using RDMSharp.Metadata; using RDMSharp.Metadata.JSON.OneOfTypes; using RDMSharp.RDM; @@ -8,7 +9,7 @@ public class TestStringType [Test] public void TestMany() { - var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null,null,null,null,null,null,null); + var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, null, null, null, null, null); Assert.That(stringType.MinLength, Is.Null); Assert.That(stringType.MaxLength, Is.Null); @@ -41,5 +42,138 @@ public void TestMany() Assert.Throws(typeof(ArgumentException), () => stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "sting", null, null, null, null, null, null, null)); } + [Test] + public void TestParseFixedLengthASCII() + { + var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, null, 5, true); + string str = "qwert"; + DataTree dataTree = new DataTree("NAME", 0, str); + byte[] data = stringType.ParsePayloadToData(dataTree); + Assert.That(data, Is.EqualTo(new byte[] { 113, 119, 101, 114, 116 })); + DataTree reverseDataTree = stringType.ParseDataToPayload(ref data); + Assert.Multiple(() => + { + Assert.That(data, Has.Length.Zero); + Assert.That(reverseDataTree, Is.EqualTo(dataTree)); + }); + } + [Test] + public void TestParseFixedLengthInBytesUTF8() + { + var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, null, null, minBytes: 8, maxBytes: 8, null); + string str = ""; + DataTree dataTree = new DataTree("NAME", 0, str); + byte[] data = stringType.ParsePayloadToData(dataTree); + Assert.That(data, Is.EqualTo(new byte[] { 195, 132, 195, 156, 195, 150, 195, 159 })); + DataTree reverseDataTree = stringType.ParseDataToPayload(ref data); + Assert.Multiple(() => + { + Assert.That(data, Has.Length.Zero); + Assert.That(reverseDataTree, Is.EqualTo(dataTree)); + }); + } + [Test] + public void TestParseRangedLengthUTF8() + { + var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, 4, 6, null, null, null); + string str = ""; + DataTree dataTree = new DataTree("NAME", 0, str); + byte[] data = stringType.ParsePayloadToData(dataTree); + Assert.That(data, Is.EqualTo(new byte[] { 195, 132, 195, 156, 195, 150, 195, 159 })); + DataTree reverseDataTree = stringType.ParseDataToPayload(ref data); + Assert.Multiple(() => + { + Assert.That(data, Has.Length.Zero); + Assert.That(reverseDataTree, Is.EqualTo(dataTree)); + }); + } + [Test] + public void TestParseRangedLengthUTF8Mixed() + { + var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, 4, 6, 4, 8, null); + string str = "US"; + DataTree dataTree = new DataTree("NAME", 0, str); + byte[] data = stringType.ParsePayloadToData(dataTree); + Assert.That(data, Is.EqualTo(new byte[] { 195, 132, 85, 195, 150, 83 })); + DataTree reverseDataTree = stringType.ParseDataToPayload(ref data); + Assert.Multiple(() => + { + Assert.That(data, Has.Length.Zero); + Assert.That(reverseDataTree, Is.EqualTo(dataTree)); + }); + } + + [Test] + public void TestParseExceptions() + { + var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, 3, 6, 5, 8, null); + string str = "12"; + DataTree dataTree = new DataTree("NAME FAIL", 0, str); + Assert.Throws(typeof(ArithmeticException), () => stringType.ParsePayloadToData(dataTree)); + dataTree = new DataTree("NAME", 0, str); + Assert.Throws(typeof(ArithmeticException), () => stringType.ParsePayloadToData(dataTree)); + str = "1234"; + dataTree = new DataTree("NAME", 0, str); + Assert.Throws(typeof(ArithmeticException), () => stringType.ParsePayloadToData(dataTree)); + str = "1234567"; + dataTree = new DataTree("NAME", 0, str); + Assert.Throws(typeof(ArithmeticException), () => stringType.ParsePayloadToData(dataTree)); + + stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, null, null, 5, 8, null); + + str = "4567"; + dataTree = new DataTree("NAME", 0, str); + Assert.Throws(typeof(ArithmeticException), () => stringType.ParsePayloadToData(dataTree)); + str = ""; + dataTree = new DataTree("NAME", 0, str); + Assert.Throws(typeof(ArithmeticException), () => stringType.ParsePayloadToData(dataTree)); + str = null; + dataTree = new DataTree("NAME", 0, str); + Assert.Throws(typeof(ArithmeticException), () => stringType.ParsePayloadToData(dataTree)); + } + + [Test] + public void TestParseBadFormatedData1() + { + var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, null, null, 2, 8, null); + byte[] data = new byte[] { 195, 132, 0, 0, 0, 0 }; + var dataTree = stringType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo("")); + Assert.That(dataTree.Issues, Has.Length.EqualTo(1)); + + data = new byte[] { 195, 132, 0, 0, 119, 0 }; + dataTree = stringType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo("")); + Assert.That(dataTree.Issues, Has.Length.EqualTo(2)); + + data = new byte[] { 0, 0, 0, 0, 0, 0 }; + dataTree = stringType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(string.Empty)); + Assert.That(dataTree.Issues, Has.Length.EqualTo(1)); + + data = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + dataTree = stringType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(string.Empty)); + Assert.That(dataTree.Issues, Has.Length.EqualTo(2)); + + data = new byte[] { }; + dataTree = stringType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo(string.Empty)); + Assert.That(dataTree.Issues, Has.Length.EqualTo(1)); + } + [Test] + public void TestParseBadFormatedData2() + { + var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, 2, 4, null, null, null); + byte[] data = new byte[] { 195, 132, 0, 0, 0, 0 }; + var dataTree = stringType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo("")); + Assert.That(dataTree.Issues, Has.Length.EqualTo(2)); + + data = new byte[] { 195, 132, 119, 119, 119, 119, 0 }; + dataTree = stringType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo("wwww")); + Assert.That(dataTree.Issues, Has.Length.EqualTo(1)); + } } } \ No newline at end of file From 5ecf37a7c844ae9465d21e5e3df95453d76d2fbf Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Wed, 2 Oct 2024 15:50:05 +0200 Subject: [PATCH 34/51] Minor --- RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs | 4 ++-- RDMSharpTests/Metadata/JSON/TestStringType.cs | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs index b5faec7..978ac03 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/StringType.cs @@ -199,12 +199,12 @@ void parse(Encoding encoder) takenBytesCount = byteLength; charLength = str.Length; bool repeatParse = false; - if (MaxLength.HasValue && MaxLength < charLength) + if (MaxLength.HasValue && MaxLength.Value < charLength) { charLength = (int)MaxLength.Value; repeatParse = true; } - if (MaxBytes.HasValue && MaxBytes < byteLength) + if (MaxBytes.HasValue && MaxBytes.Value < byteLength) { byteLength = (int)MaxBytes.Value; repeatParse = true; diff --git a/RDMSharpTests/Metadata/JSON/TestStringType.cs b/RDMSharpTests/Metadata/JSON/TestStringType.cs index 642ce18..51704c7 100644 --- a/RDMSharpTests/Metadata/JSON/TestStringType.cs +++ b/RDMSharpTests/Metadata/JSON/TestStringType.cs @@ -160,6 +160,15 @@ public void TestParseBadFormatedData1() dataTree = stringType.ParseDataToPayload(ref data); Assert.That(dataTree.Value, Is.EqualTo(string.Empty)); Assert.That(dataTree.Issues, Has.Length.EqualTo(1)); + + data = new byte[] { 195, 132, 195, 132, 195, 132, 195, 132, 0 }; + dataTree = stringType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo("")); + Assert.That(dataTree.Issues, Has.Length.EqualTo(1)); + data = new byte[] { 195, 132, 195, 132, 195, 132, 195, 132, 119, 119, 0 }; + dataTree = stringType.ParseDataToPayload(ref data); + Assert.That(dataTree.Value, Is.EqualTo("")); + Assert.That(dataTree.Issues, Has.Length.EqualTo(1)); } [Test] public void TestParseBadFormatedData2() From 1a791d40b1c0d6297b838f4ea593604619f055e8 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 3 Oct 2024 20:34:23 +0200 Subject: [PATCH 35/51] Implement Array Format for BytesType --- .../Metadata/JSON/OneOfTypes/BytesType.cs | 356 +++++++++++------- RDMSharpTests/Metadata/JSON/TestBytesType.cs | 47 ++- 2 files changed, 274 insertions(+), 129 deletions(-) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs index 2e3e4f4..8cedeb7 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/BytesType.cs @@ -82,23 +82,41 @@ public override string ToString() public override PDL GetDataLength() { - switch (Format) + uint length = 0; + string format = Format; + bool noFixedSize = false; + if (!string.IsNullOrWhiteSpace(Format) && Format.EndsWith("[]")) + format = Format.Replace("[]", ""); + switch (format) { case "mac-address": case "uid": - return new PDL(6); + length = 6; + break; case "ipv4": case "float": - return new PDL(4); + length = 4; + break; case "ipv6": case "uuid": case "guid": - return new PDL(16); + length = 16; + break; case "double": - return new PDL(8); + length = 8; + break; case "pid": - return new PDL(2); + length = 2; + break; + default: + noFixedSize = true; + break; } + if (!string.IsNullOrWhiteSpace(Format) && Format.EndsWith("[]")) + return new PDL(0, (uint)(Math.Truncate((double)PDL.MAX_LENGTH / length) * length)); + else if (!noFixedSize) + return new PDL(length); + return new PDL((uint)(MinLength ?? 1), (uint)(MaxLength ?? PDL.MAX_LENGTH)); } public override byte[] ParsePayloadToData(DataTree dataTree) @@ -106,142 +124,228 @@ public override byte[] ParsePayloadToData(DataTree dataTree) if (!string.Equals(dataTree.Name, this.Name)) throw new ArithmeticException($"The given Name from {nameof(dataTree.Name)}({dataTree.Name}) not match this Name({this.Name})"); - switch (Format) + if (!string.IsNullOrWhiteSpace(Format) && Format.EndsWith("[]") && dataTree.Value is Array typedArray) { - //Known from E1.37-5 (2024) - case "uid" when dataTree.Value is UID uid: - return uid.ToBytes().ToArray(); - case "ipv4" when dataTree.Value is IPv4Address ipv4: - return (byte[])ipv4; - case "ipv6" when dataTree.Value is IPv6Address ipv6: - return (byte[])ipv6; - case "mac-address" when dataTree.Value is MACAddress macAddress: - return (byte[])macAddress; - - //Known from E1.37-5 (2024) as uuid - case "uuid" when dataTree.Value is Guid uuid: - return uuid.ToByteArray(); - case "guid" when dataTree.Value is Guid guid: - return guid.ToByteArray(); - - //Additional added, because there is no fancy way to di this with E1.37-5 (2024) - case "pid" when dataTree.Value is ERDM_Parameter pid: - return Tools.ValueToData(pid); - - //Additional added, because there is no fancy way to di this with E1.37-5 (2024) - case "double" when dataTree.Value is double _double: - return BitConverter.GetBytes(_double); - case "float" when dataTree.Value is float _float: - return BitConverter.GetBytes(_float); - - - //Additional added, because there is no fancy way to di this with E1.37-5 (2024) - case "ascii" when dataTree.Value is string ascii: - return Encoding.ASCII.GetBytes(ascii); - case "utf8" when dataTree.Value is string utf8: - return Encoding.UTF8.GetBytes(utf8); - case "utf32" when dataTree.Value is string utf32: - return Encoding.UTF32.GetBytes(utf32); - case "unicode" when dataTree.Value is string unicode: - return Encoding.Unicode.GetBytes(unicode); - case "big_edian_unicode" when dataTree.Value is string big_edian_unicode: - return Encoding.BigEndianUnicode.GetBytes(big_edian_unicode); - case "latin1" when dataTree.Value is string latin1: - return Encoding.Latin1.GetBytes(latin1); - - //Fallback - default: - if (dataTree.Value is string str) - return Encoding.UTF8.GetBytes(str); - if (dataTree.Value is string[] strArray) - return Encoding.UTF8.GetBytes(string.Join((char)0, strArray)); - if (dataTree.Value is byte[] byteArray) - return byteArray; - break; + List bytes = new List(); + string format = Format.Replace("[]", ""); + for (int i = 0; i < typedArray.Length; i++) + { + object value = typedArray.GetValue(i); + bytes.AddRange(parseData(format, value)); + if (value is string) + bytes.Add(0); //Null-Delimiter + } + return bytes.ToArray(); } + else + return parseData(Format, dataTree.Value); + + byte[] parseData(string format, object value) + { + Exception e = null; + try + { + switch (format) + { + //Known from E1.37-5 (2024) + case "uid" when value is UID uid: + return uid.ToBytes().ToArray(); + case "ipv4" when value is IPv4Address ipv4: + return (byte[])ipv4; + case "ipv6" when value is IPv6Address ipv6: + return (byte[])ipv6; + case "mac-address" when value is MACAddress macAddress: + return (byte[])macAddress; + + //Known from E1.37-5 (2024) as uuid + case "uuid" when value is Guid uuid: + return uuid.ToByteArray(); + case "guid" when value is Guid guid: + return guid.ToByteArray(); + + //Additional added, because there is no fancy way to di this with E1.37-5 (2024) + case "pid" when value is ERDM_Parameter pid: + return Tools.ValueToData(pid); - throw new ArithmeticException($"The given Object of {nameof(Format)}: \"{Format}\" can't be parsed from {nameof(dataTree.Value)}: {dataTree.Value}"); + //Additional added, because there is no fancy way to di this with E1.37-5 (2024) + case "double" when value is double _double: + return BitConverter.GetBytes(_double); + case "float" when value is float _float: + return BitConverter.GetBytes(_float); + + + //Additional added, because there is no fancy way to di this with E1.37-5 (2024) + case "ascii" when value is string ascii: + return Encoding.ASCII.GetBytes(ascii); + case "utf8" when value is string utf8: + return Encoding.UTF8.GetBytes(utf8); + case "utf32" when value is string utf32: + return Encoding.UTF32.GetBytes(utf32); + case "unicode" when value is string unicode: + return Encoding.Unicode.GetBytes(unicode); + case "big_edian_unicode" when value is string big_edian_unicode: + return Encoding.BigEndianUnicode.GetBytes(big_edian_unicode); + case "latin1" when value is string latin1: + return Encoding.Latin1.GetBytes(latin1); + + //Fallback + default: + if (value is string str) + return Encoding.UTF8.GetBytes(str); + if (value is byte[] byteArray) + return byteArray; + throw new NotImplementedException($"There is no implementation for {nameof(Format)}: {Format} and Value: {value}"); + } + } + catch (Exception ex) + { + e = ex; + } + throw new ArithmeticException($"The given Object of {nameof(Format)}: \"{Format}\" can't be parsed from {nameof(value)}: {value}", e); + } } public override DataTree ParseDataToPayload(ref byte[] data) { List issueList = new List(); object value = null; - switch (Format) + if (!string.IsNullOrWhiteSpace(Format) && Format.EndsWith("[]")) { - //Known from E1.37-5 (2024) - case "uid": - value = new UID(Tools.DataToUShort(ref data), Tools.DataToUInt(ref data)); - break; - case "ipv4": - value = new IPv4Address(data.Take(4)); - data = data.Skip(4).ToArray(); - break; - case "ipv6": - value = new IPv6Address(data.Take(16)); - data = data.Skip(16).ToArray(); - break; - case "mac-address": - value = new MACAddress(data.Take(16)); - data = data.Skip(6).ToArray(); - break; + List list = new List(); + while (data.Length > 0) + { + try + { + string format = Format.Replace("[]", ""); + list.Add(parseData(format, ref data)); + } + catch(Exception e) + { + issueList.Add(new DataTreeIssue(e.Message)); + break; + } + } + if (data.Length > 0) + issueList.Add(new DataTreeIssue("Data Length is not 0")); - //Known from E1.37-5 (2024) as uuid - case "uuid": - case "guid": - value = new Guid(data.Take(16).ToArray()); - data = data.Skip(16).ToArray(); - break; + if (list.Count == 0) + value = null; + else + { + Type targetType=list.First().GetType(); + var array = Array.CreateInstance(targetType,list.Count); + for (int i = 0; i < list.Count; i++) + array.SetValue(Convert.ChangeType(list[i], targetType), i); - //Additional added, because there is no fancy way to di this with E1.37-5 (2024) - case "pid": - value = Tools.DataToEnum(ref data); - break; + value = array; + } + } + else + value = parseData(Format, ref data); - //Additional added, because there is no fancy way to di this with E1.37-5 (2024) - case "double": - value = BitConverter.ToDouble(data, 0); - data = data.Skip(8).ToArray(); - break; - case "float": - value = BitConverter.ToSingle(data, 0); - data = data.Skip(4).ToArray(); - break; + return new DataTree(this.Name, 0, value, issueList.Count != 0 ? issueList.ToArray() : null); - //Additional added, because there is no fancy way to di this with E1.37-5 (2024) - case "ascii": - value = Encoding.ASCII.GetString(data); - data = data.Skip(data.Length).ToArray(); - break; - case "utf8": - value = Encoding.UTF8.GetString(data); - data = data.Skip(data.Length).ToArray(); - break; - case "utf32": - value = Encoding.UTF32.GetString(data); - data = data.Skip(data.Length).ToArray(); - break; - case "unicode": - value = Encoding.Unicode.GetString(data); - data = data.Skip(data.Length).ToArray(); - break; - case "big_edian_unicode": - value = Encoding.BigEndianUnicode.GetString(data); - data = data.Skip(data.Length).ToArray(); - break; - case "latin1": - value=Encoding.Latin1.GetString(data); - data = data.Skip(data.Length).ToArray(); - break; + object parseData(string format, ref byte[] data) + { + void validateDataLength(int length, ref byte[] data) + { + if (data.Length < length) + throw new ArithmeticException("Data to short"); + } + object value = null; + switch (format) + { + //Known from E1.37-5 (2024) + case "uid": + validateDataLength(6, ref data); + value = new UID(Tools.DataToUShort(ref data), Tools.DataToUInt(ref data)); + break; + case "ipv4": + validateDataLength(4, ref data); + value = new IPv4Address(data.Take(4)); + data = data.Skip(4).ToArray(); + break; + case "ipv6": + validateDataLength(16, ref data); + value = new IPv6Address(data.Take(16)); + data = data.Skip(16).ToArray(); + break; + case "mac-address": + validateDataLength(6, ref data); + value = new MACAddress(data.Take(6)); + data = data.Skip(6).ToArray(); + break; - //Fallback - default: - value = data; - data = data.Skip(data.Length).ToArray(); - issueList.Add(new DataTreeIssue($"No Parser found for {nameof(Format)}: \"{Format}\"")); - break; + //Known from E1.37-5 (2024) as uuid + case "uuid": + case "guid": + validateDataLength(16, ref data); + value = new Guid(data.Take(16).ToArray()); + data = data.Skip(16).ToArray(); + break; + + //Additional added, because there is no fancy way to di this with E1.37-5 (2024) + case "pid": + validateDataLength(2, ref data); + value = Tools.DataToEnum(ref data); + break; + + //Additional added, because there is no fancy way to di this with E1.37-5 (2024) + case "double": + validateDataLength(8, ref data); + value = BitConverter.ToDouble(data.Take(8).ToArray(), 0); + data = data.Skip(8).ToArray(); + break; + case "float": + validateDataLength(4, ref data); + value = BitConverter.ToSingle(data.Take(4).ToArray(), 0); + data = data.Skip(4).ToArray(); + break; + + + //Additional added, because there is no fancy way to di this with E1.37-5 (2024) + case "ascii": + value = getNullDelimitetData(Encoding.ASCII, ref data); + break; + case "utf8": + value = getNullDelimitetData(Encoding.UTF8, ref data); + break; + case "utf32": + value = getNullDelimitetData(Encoding.UTF32, ref data); + break; + case "unicode": + value = getNullDelimitetData(Encoding.Unicode, ref data); + break; + case "big_edian_unicode": + value = getNullDelimitetData(Encoding.BigEndianUnicode, ref data); + break; + case "latin1": + value = getNullDelimitetData(Encoding.Latin1,ref data); + break; + + //Fallback + default: + value = data; + data = data.Skip(data.Length).ToArray(); + issueList.Add(new DataTreeIssue($"No Parser found for {nameof(Format)}: \"{Format}\"")); + break; + } + return value; + + string getNullDelimitetData(Encoding encoding, ref byte[] data) + { + string res = encoding.GetString(data); + if (res.Contains('\0')) + { + res = res.Split('\0')[0]; + int count = encoding.GetByteCount(res + "\0"); + data = data.Skip(count).ToArray(); + } + else + data = new byte[0]; + return res; + } } - return new DataTree(this.Name, 0, value, issueList.Count != 0 ? issueList.ToArray() : null); } } } diff --git a/RDMSharpTests/Metadata/JSON/TestBytesType.cs b/RDMSharpTests/Metadata/JSON/TestBytesType.cs index 7fbbc54..2aad6f7 100644 --- a/RDMSharpTests/Metadata/JSON/TestBytesType.cs +++ b/RDMSharpTests/Metadata/JSON/TestBytesType.cs @@ -58,6 +58,41 @@ public void TestParseUID() Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "uid", null, null).ParsePayloadToData(dataTree)); Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); } + [Test] + public void TestParseUIDArrayEmpty() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "uid[]", null, null); + Assert.That(bytesType.GetDataLength().MinLength, Is.EqualTo(0)); + var uidArray = new UID[0]; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, uidArray)); + Assert.That(data, Is.EqualTo(new byte[0])); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Null); + } + [Test] + public void TestParseUIDArray() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "uid[]", null, null); + Assert.That(bytesType.GetDataLength().MinLength, Is.EqualTo(0)); + var uidArray = new UID[] { new UID(0x4646, 0x12345678) , new UID(0x4646, 0x12345678) }; + var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, uidArray)); + Assert.That(data, Is.EqualTo(new byte[] { 0x46, 0x46, 0x12, 0x34, 0x56, 0x78, 0x46, 0x46, 0x12, 0x34, 0x56, 0x78 })); + var corrupData = new List(); + corrupData.AddRange(data); + var dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.EqualTo(uidArray)); + + corrupData.Add(1); + corrupData.Add(2); + data= corrupData.ToArray(); + dataTree = bytesType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(2)); + Assert.That(data, Is.EqualTo(new byte[] { 1, 2 })); + Assert.That(dataTree.Value, Is.EqualTo(uidArray)); + Assert.That(dataTree.Issues, Has.Length.EqualTo(2)); + } [Test] public void TestParseIPv4() @@ -271,13 +306,13 @@ public void TestParseFallbackString() Assert.That(dataTree.Value, Is.Not.Null); } [Test] - public void TestParseFallbackStringArray() + public void TestParseFallbackUTF8Array() { - var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", null, null, null); + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "utf8[]", null, null); var utf8 = "äöü߀!"; var array = new string[] { utf8, utf8 }; var data = bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, array)); - Assert.That(data, Is.EqualTo(new byte[] { 195, 164, 195, 182, 195, 188, 195, 159, 226, 130, 172, 33, 0, 195, 164, 195, 182, 195, 188, 195, 159, 226, 130, 172, 33 })); + Assert.That(data, Is.EqualTo(new byte[] { 195, 164, 195, 182, 195, 188, 195, 159, 226, 130, 172, 33, 0, 195, 164, 195, 182, 195, 188, 195, 159, 226, 130, 172, 33, 0 })); var dataTree = bytesType.ParseDataToPayload(ref data); Assert.That(data, Has.Length.EqualTo(0)); Assert.That(dataTree.Value, Is.Not.Null); @@ -294,5 +329,11 @@ public void TestParseFallbackByteArray() Assert.That(dataTree.Value, Is.Not.Null); Assert.That(dataTree.Value, Is.EqualTo(bytes)); } + [Test] + public void TestParseFallbackUnknownType() + { + var bytesType = new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "UNKNOWN", null, null); + Assert.Throws(typeof(ArithmeticException), () => bytesType.ParsePayloadToData(new DataTree(bytesType.Name, 0, DateTime.Now))); + } } } \ No newline at end of file From 0239ca325ded1ee27db02fd4b50b381fe725fd22 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 3 Oct 2024 22:15:57 +0200 Subject: [PATCH 36/51] Test CompoundType Parser Stuff --- RDMSharp/Metadata/DataTree.cs | 4 ++ .../Metadata/JSON/OneOfTypes/CompoundType.cs | 22 ++++-- RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs | 19 ++++- .../Metadata/JSON/OneOfTypes/OneOfTypes.cs | 11 +-- .../Metadata/JSON/TestCompoundType.cs | 71 +++++++++++++++++++ RDMSharpTests/Metadata/JSON/TestListType.cs | 5 ++ 6 files changed, 115 insertions(+), 17 deletions(-) diff --git a/RDMSharp/Metadata/DataTree.cs b/RDMSharp/Metadata/DataTree.cs index f32f04a..b4fd069 100644 --- a/RDMSharp/Metadata/DataTree.cs +++ b/RDMSharp/Metadata/DataTree.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection.Metadata; namespace RDMSharp.Metadata { @@ -29,6 +30,9 @@ public DataTree(DataTree dataTree, uint index) : this(dataTree.Name, index, data } public DataTree(string name, uint index, object value, DataTreeIssue[]? issues = null, string unit = null, DataTreeValueLabel[] labels = null) : this(name, index, issues) { + if (value is IEnumerable || value is DataTree[] children) + throw new ArgumentException($"Use other Constructor if you use {nameof(Children)}"); + Value = value; Unit = unit; Labels = labels; diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs index f200df2..353703f 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs @@ -2,8 +2,11 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Text.Json.Serialization; +[assembly: InternalsVisibleTo("RDMSharpTests")] + namespace RDMSharp.Metadata.JSON.OneOfTypes { public class CompoundType : CommonPropertiesForNamed @@ -76,23 +79,34 @@ public override byte[] ParsePayloadToData(DataTree dataTree) data.AddRange(Subtypes[i].ParsePayloadToData(dataTree.Children[i])); } - if (!GetDataLength().IsValid(data.Count)) - throw new ArithmeticException($"Parsed DataLengt not fits Calculated DataLength"); + validateDataLength(data.Count); return data.ToArray(); } public override DataTree ParseDataToPayload(ref byte[] data) { List subTypeDataTree = new List(); - List issueList = new List(); + + int dataLength = data.Length; for (int i = 0; i < Subtypes.Length; i++) { OneOfTypes subType = Subtypes[i]; subTypeDataTree.Add(new DataTree(subType.ParseDataToPayload(ref data), (uint)i)); } + dataLength -= data.Length; + + validateDataLength(dataLength); + + return new DataTree(this.Name, 0, children: subTypeDataTree.OrderBy(b => b.Index).ToArray()); + } + + internal bool validateDataLength(int dataLength) + { + if (!GetDataLength().IsValid(dataLength)) + throw new ArithmeticException($"Parsed DataLength not fits Calculated DataLength"); - return new DataTree(this.Name, 0, subTypeDataTree.OrderBy(b => b.Index), issueList.Count != 0 ? issueList.ToArray() : null); + return true; } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs index cd339d3..3e50d8c 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs @@ -1,8 +1,11 @@ using RDMSharp.RDM; using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Text.Json.Serialization; +[assembly: InternalsVisibleTo("RDMSharpTests")] + namespace RDMSharp.Metadata.JSON.OneOfTypes { public class ListType : CommonPropertiesForNamed @@ -119,8 +122,7 @@ public override byte[] ParsePayloadToData(DataTree dataTree) data.AddRange(ItemType.ParsePayloadToData(dataTree.Children[i])); } - if (!GetDataLength().IsValid(data.Count)) - throw new ArithmeticException($"Parsed DataLengt not fits Calculated DataLength"); + validateDataLength(data.Count); return data.ToArray(); } @@ -131,13 +133,17 @@ public override DataTree ParseDataToPayload(ref byte[] data) List issueList = new List(); uint index = 0; + int dataLength = data.Length; while (_continue(ref data)) { dataTrees.Add(new DataTree(ItemType.ParseDataToPayload(ref data), index)); index++; } + dataLength -= data.Length; + + validateDataLength(dataLength); - return new DataTree(Name, 0, dataTrees, issueList.Count != 0 ? issueList.ToArray() : null); + return new DataTree(Name, 0, children: dataTrees.ToArray(), issueList.Count != 0 ? issueList.ToArray() : null); bool _continue(ref byte[] data) { @@ -159,5 +165,12 @@ bool _continue(ref byte[] data) return true; } } + internal bool validateDataLength(int dataLength) + { + if (!GetDataLength().IsValid(dataLength)) + throw new ArithmeticException($"Parsed DataLength not fits Calculated DataLength"); + + return true; + } } } \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs index d530f91..65c0844 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs @@ -133,20 +133,11 @@ public PDL GetDataLength() public byte[] ParsePayloadToData(DataTree dataTree) { CommonPropertiesForNamed objectType = ObjectType ?? ReferenceType?.ReferencedObject; - var data = objectType.ParsePayloadToData(dataTree); - - if (!GetDataLength().IsValid(data.Length)) - throw new ArithmeticException($"Parsed Data.Lenght not fits Calculated DataLength"); - - return data; + return objectType.ParsePayloadToData(dataTree); } public DataTree ParseDataToPayload(ref byte[] data) { CommonPropertiesForNamed objectType = ObjectType ?? ReferenceType?.ReferencedObject; - - if (!GetDataLength().IsValid(data.Length)) - throw new ArithmeticException($"Parsed Data.Lenght not fits Calculated DataLength"); - return objectType.ParseDataToPayload(ref data); } diff --git a/RDMSharpTests/Metadata/JSON/TestCompoundType.cs b/RDMSharpTests/Metadata/JSON/TestCompoundType.cs index 3090f79..4b869d0 100644 --- a/RDMSharpTests/Metadata/JSON/TestCompoundType.cs +++ b/RDMSharpTests/Metadata/JSON/TestCompoundType.cs @@ -1,3 +1,4 @@ +using RDMSharp.Metadata; using RDMSharp.Metadata.JSON.OneOfTypes; using RDMSharp.RDM; @@ -24,6 +25,76 @@ public void TestMany() Assert.Throws(typeof(ArgumentException), () => compoundType = new CompoundType("NAME", "DISPLAY_NAME", "NOTES", null, "kompound", oneOf)); Assert.Throws(typeof(ArgumentException), () => compoundType = new CompoundType("NAME", "DISPLAY_NAME", "NOTES", null, "compound", null)); Assert.Throws(typeof(ArgumentException), () => compoundType = new CompoundType("NAME", "DISPLAY_NAME", "NOTES", null, "compound", new OneOfTypes[0])); + + Assert.Throws(typeof(ArithmeticException), () => compoundType.validateDataLength(1)); + Assert.Throws(typeof(ArithmeticException), () => compoundType.validateDataLength(3)); + Assert.DoesNotThrow(() => compoundType.validateDataLength(2)); + } + + [Test] + public void TestParseData1() + { + OneOfTypes[] oneOf = new OneOfTypes[2]; + oneOf[0] = new OneOfTypes(new IntegerType("NAME1", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)); + oneOf[1] = new OneOfTypes(new IntegerType("NAME2", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int8, null, null, null, null, null, null)); + + var compoundType = new CompoundType("NAME", "DISPLAY_NAME", "NOTES", null, "compound", oneOf); + + DataTree dataTree = new DataTree(compoundType.Name, 0, new DataTree[] { new DataTree(oneOf[0].ObjectType.Name, 0, (byte)33), new DataTree(oneOf[1].ObjectType.Name, 1, (sbyte)-22) }); + byte[] data = compoundType.ParsePayloadToData(dataTree); + Assert.That(data, Is.EqualTo(new byte[] { 33, 234 })); + + DataTree dataTreeResult = compoundType.ParseDataToPayload(ref data); + Assert.That(dataTreeResult, Is.EqualTo(dataTree)); + } + + [Test] + public void TestParseDataInvalidName() + { + OneOfTypes[] oneOf = new OneOfTypes[2]; + oneOf[0] = new OneOfTypes(new IntegerType("NAME1", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)); + oneOf[1] = new OneOfTypes(new IntegerType("NAME2", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int8, null, null, null, null, null, null)); + + var compoundType = new CompoundType("NAME", "DISPLAY_NAME", "NOTES", null, "compound", oneOf); + + DataTree dataTree = new DataTree(compoundType.Name+"INVALID", 0, new DataTree[] { new DataTree(oneOf[0].ObjectType.Name, 0, (byte)33), new DataTree(oneOf[1].ObjectType.Name, 1, (sbyte)-22) }); + Assert.Throws(typeof(ArithmeticException), () => compoundType.ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseDataInvalidNameOnChildren() + { + OneOfTypes[] oneOf = new OneOfTypes[2]; + oneOf[0] = new OneOfTypes(new IntegerType("NAME1", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)); + oneOf[1] = new OneOfTypes(new IntegerType("NAME2", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int8, null, null, null, null, null, null)); + + var compoundType = new CompoundType("NAME", "DISPLAY_NAME", "NOTES", null, "compound", oneOf); + + DataTree dataTree = new DataTree(compoundType.Name, 0, new DataTree[] { new DataTree(oneOf[0].ObjectType.Name+ "INVALID", 0, (byte)33), new DataTree(oneOf[1].ObjectType.Name, 1, (sbyte)-22) }); + Assert.Throws(typeof(ArithmeticException), () => compoundType.ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseDataMissingChildrenDataTree() + { + OneOfTypes[] oneOf = new OneOfTypes[2]; + oneOf[0] = new OneOfTypes(new IntegerType("NAME1", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)); + oneOf[1] = new OneOfTypes(new IntegerType("NAME2", "DISPLAY_NAME", "NOTES", null, EIntegerType.Int8, null, null, null, null, null, null)); + + var compoundType = new CompoundType("NAME", "DISPLAY_NAME", "NOTES", null, "compound", oneOf); + + DataTree dataTree = new DataTree(compoundType.Name, 0, new DataTree[] { new DataTree(oneOf[0].ObjectType.Name, 0, (byte)33) }); + Assert.Throws(typeof(ArithmeticException), () => compoundType.ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseSubItemIsEmpty() + { + OneOfTypes[] oneOf = new OneOfTypes[2]; + oneOf[0] = new OneOfTypes(new IntegerType("NAME1", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)); + oneOf[1] = new OneOfTypes(); + + var compoundType = new CompoundType("NAME", "DISPLAY_NAME", "NOTES", null, "compound", oneOf); + + DataTree dataTree = new DataTree(compoundType.Name, 0, new DataTree[] { new DataTree(oneOf[0].ObjectType.Name, 0, (byte)33), new DataTree(null, 1, (sbyte)-22) }); + Assert.Throws(typeof(ArithmeticException), () => compoundType.ParsePayloadToData(dataTree)); } } } \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestListType.cs b/RDMSharpTests/Metadata/JSON/TestListType.cs index f5f73ff..ed6216d 100644 --- a/RDMSharpTests/Metadata/JSON/TestListType.cs +++ b/RDMSharpTests/Metadata/JSON/TestListType.cs @@ -60,6 +60,11 @@ public void TestMany() Assert.That(pdl.MinLength, Is.EqualTo(32)); Assert.That(pdl.MaxLength, Is.EqualTo(PDL.MAX_LENGTH)); }); + + Assert.Throws(typeof(ArithmeticException), () => listType.validateDataLength(0)); + Assert.Throws(typeof(ArithmeticException), () => listType.validateDataLength(3)); + Assert.DoesNotThrow(() => listType.validateDataLength(32)); + Assert.DoesNotThrow(() => listType.validateDataLength(58905)); } } } \ No newline at end of file From ba00e598a1fe15d9d183938016e7a599659addd4 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 3 Oct 2024 22:38:57 +0200 Subject: [PATCH 37/51] Minor --- RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs | 16 +++++++++------- RDMSharpTests/Metadata/JSON/TestOneOfTypes.cs | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs index 65c0844..270c068 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/OneOfTypes.cs @@ -124,26 +124,28 @@ public OneOfTypes(PD_EnvelopeType pdEnvelopeType) public bool IsEmpty() { - return ObjectType == null && ReferenceType == null; + return getObjectType() == null; } public PDL GetDataLength() { - return ObjectType?.GetDataLength() ?? ReferenceType?.GetDataLength() ?? new PDL(); + return getObjectType()?.GetDataLength() ?? new PDL(); } public byte[] ParsePayloadToData(DataTree dataTree) { - CommonPropertiesForNamed objectType = ObjectType ?? ReferenceType?.ReferencedObject; - return objectType.ParsePayloadToData(dataTree); + return getObjectType().ParsePayloadToData(dataTree); } public DataTree ParseDataToPayload(ref byte[] data) { - CommonPropertiesForNamed objectType = ObjectType ?? ReferenceType?.ReferencedObject; - return objectType.ParseDataToPayload(ref data); + return getObjectType().ParseDataToPayload(ref data); + } + private CommonPropertiesForNamed getObjectType() + { + return ObjectType ?? ReferenceType?.ReferencedObject; } public override string ToString() { - return ObjectType?.ToString() ?? ReferenceType.ToString(); + return getObjectType()?.ToString(); } } } \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestOneOfTypes.cs b/RDMSharpTests/Metadata/JSON/TestOneOfTypes.cs index 26e05ed..119e648 100644 --- a/RDMSharpTests/Metadata/JSON/TestOneOfTypes.cs +++ b/RDMSharpTests/Metadata/JSON/TestOneOfTypes.cs @@ -9,6 +9,7 @@ public void TestMany() { var oneOfTypes = new OneOfTypes(); Assert.That(oneOfTypes.IsEmpty, Is.True); + Assert.That(oneOfTypes.ToString(), Is.Null); Assert.DoesNotThrow(() => { Assert.That(oneOfTypes.GetDataLength().Value, Is.EqualTo(0)); From e3522d28f5344c2a94120c3c7a120639af66e2d8 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 3 Oct 2024 23:20:55 +0200 Subject: [PATCH 38/51] Add Tests for ListType Parser --- .../Metadata/JSON/OneOfTypes/CompoundType.cs | 12 +++- RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs | 31 +++++----- RDMSharpTests/Metadata/JSON/TestListType.cs | 58 ++++++++++++++++++- 3 files changed, 83 insertions(+), 18 deletions(-) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs index 353703f..0f964f5 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/CompoundType.cs @@ -86,6 +86,7 @@ public override byte[] ParsePayloadToData(DataTree dataTree) public override DataTree ParseDataToPayload(ref byte[] data) { List subTypeDataTree = new List(); + List issueList = new List(); int dataLength = data.Length; @@ -96,9 +97,16 @@ public override DataTree ParseDataToPayload(ref byte[] data) } dataLength -= data.Length; - validateDataLength(dataLength); + try + { + validateDataLength(dataLength); + } + catch (Exception e) + { + issueList.Add(new DataTreeIssue(e.Message)); + } - return new DataTree(this.Name, 0, children: subTypeDataTree.OrderBy(b => b.Index).ToArray()); + return new DataTree(this.Name, 0, children:subTypeDataTree.OrderBy(b => b.Index).ToArray(), issueList.Count != 0 ? issueList.ToArray() : null); } internal bool validateDataLength(int dataLength) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs index 3e50d8c..7c30ba2 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/ListType.cs @@ -100,8 +100,7 @@ public override PDL GetDataLength() if (max == 0) if (!MaxItems.HasValue) - if (MinItems.HasValue) - max = PDL.MAX_LENGTH; + max = PDL.MAX_LENGTH; if (min == max) return new PDL(min); @@ -115,12 +114,7 @@ public override byte[] ParsePayloadToData(DataTree dataTree) List data = new List(); for (int i = 0; i < dataTree.Children.Length; i++) - { - if(ItemType.IsEmpty()) - throw new ArithmeticException($"The given Object from {nameof(ItemType)} is Empty"); - data.AddRange(ItemType.ParsePayloadToData(dataTree.Children[i])); - } validateDataLength(data.Count); @@ -141,19 +135,19 @@ public override DataTree ParseDataToPayload(ref byte[] data) } dataLength -= data.Length; - validateDataLength(dataLength); + try + { + validateDataLength(dataLength); + } + catch (Exception e) + { + issueList.Add(new DataTreeIssue(e.Message)); + } return new DataTree(Name, 0, children: dataTrees.ToArray(), issueList.Count != 0 ? issueList.ToArray() : null); bool _continue(ref byte[] data) { - if (data.Length == 0) - { - if (MinItems.HasValue) - if (dataTrees.Count < MinItems.Value) - issueList.Add(new DataTreeIssue($"Given data falls shorts of {nameof(MinItems)}")); - return false; - } if (MaxItems.HasValue) if (dataTrees.Count > MaxItems.Value) { @@ -161,6 +155,13 @@ bool _continue(ref byte[] data) issueList.Add(new DataTreeIssue($"Given data exceeds {nameof(MaxItems)}")); return false; } + if (data.Length == 0) + { + if (MinItems.HasValue) + if (dataTrees.Count < MinItems.Value) + issueList.Add(new DataTreeIssue($"Given data falls shorts of {nameof(MinItems)}")); + return false; + } return true; } diff --git a/RDMSharpTests/Metadata/JSON/TestListType.cs b/RDMSharpTests/Metadata/JSON/TestListType.cs index ed6216d..1d5295d 100644 --- a/RDMSharpTests/Metadata/JSON/TestListType.cs +++ b/RDMSharpTests/Metadata/JSON/TestListType.cs @@ -1,3 +1,4 @@ +using RDMSharp.Metadata; using RDMSharp.Metadata.JSON.OneOfTypes; using RDMSharp.RDM; @@ -15,7 +16,7 @@ public void TestMany() Assert.DoesNotThrow(() => { PDL pdl = listType.GetDataLength(); - Assert.That(pdl.Value, Is.EqualTo(0)); + Assert.That(pdl.MaxLength, Is.EqualTo(PDL.MAX_LENGTH)); }); Assert.Throws(typeof(ArgumentException), () => listType = new ListType("NAME", "DISPLAY_NAME", "NOTES", null, "lost", new OneOfTypes(new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)), null, null)); @@ -66,5 +67,60 @@ public void TestMany() Assert.DoesNotThrow(() => listType.validateDataLength(32)); Assert.DoesNotThrow(() => listType.validateDataLength(58905)); } + + [Test] + public void TestParseData1() + { + var listType = new ListType("NAME", "DISPLAY_NAME", "NOTES", null, "list", new OneOfTypes(new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)), 1, 5); + var dataTree = new DataTree(listType.Name, 0, children: new DataTree[] { new DataTree("NAME", 0, (byte)11), new DataTree("NAME", 1, (byte)22), new DataTree("NAME", 2, (byte)33) }); + var data = listType.ParsePayloadToData(dataTree); + Assert.That(data, Is.EqualTo(new byte[] { 11, 22, 33 })); + + var dataTreeResult = listType.ParseDataToPayload(ref data); + Assert.That(dataTreeResult, Is.EqualTo(dataTree)); + + listType = new ListType("NAME", "DISPLAY_NAME", "NOTES", null, "list", new OneOfTypes(new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)), 3, 3); + data = listType.ParsePayloadToData(dataTree); + Assert.That(data, Is.EqualTo(new byte[] { 11, 22, 33 })); + + dataTreeResult = listType.ParseDataToPayload(ref data); + Assert.That(dataTreeResult, Is.EqualTo(dataTree)); + } + [Test] + public void TestParseDataShortMin() + { + var listType = new ListType("NAME", "DISPLAY_NAME", "NOTES", null, "list", new OneOfTypes(new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)), 4, 5); + var dataTree = new DataTree(listType.Name, 0, children: new DataTree[] { new DataTree("NAME", 0, (byte)11), new DataTree("NAME", 1, (byte)22), new DataTree("NAME", 2, (byte)33) }); + + var data = new byte[] { 11, 22, 33 }; + var dataTreeResult = listType.ParseDataToPayload(ref data); + Assert.That(dataTreeResult.Issues, Has.Length.EqualTo(2)); + } + [Test] + public void TestParseDataExceedMax() + { + var listType = new ListType("NAME", "DISPLAY_NAME", "NOTES", null, "list", new OneOfTypes(new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)), 1, 2); + var dataTree = new DataTree(listType.Name, 0, children: new DataTree[] { new DataTree("NAME", 0, (byte)11), new DataTree("NAME", 1, (byte)22), new DataTree("NAME", 2, (byte)33) }); + + var data = new byte[] { 11, 22, 33 }; + var dataTreeResult = listType.ParseDataToPayload(ref data); + Assert.That(dataTreeResult.Issues, Has.Length.EqualTo(2)); + } + [Test] + public void TestParseDataNameInvalid() + { + var listType = new ListType("NAME", "DISPLAY_NAME", "NOTES", null, "list", new OneOfTypes(new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)), 1, 2); + var dataTree = new DataTree(listType.Name+"INVALID", 0, children: new DataTree[] { new DataTree("NAME", 0, (byte)11), new DataTree("NAME", 1, (byte)22), new DataTree("NAME", 2, (byte)33) }); + + Assert.Throws(typeof(ArithmeticException), () => listType.ParsePayloadToData(dataTree)); + } + [Test] + public void TestParseDataChildNameInvalid() + { + var listType = new ListType("NAME", "DISPLAY_NAME", "NOTES", null, "list", new OneOfTypes(new IntegerType("NAME", "DISPLAY_NAME", "NOTES", null, EIntegerType.UInt8, null, null, null, null, null, null)), 1, 2); + var dataTree = new DataTree(listType.Name, 0, children: new DataTree[] { new DataTree("NAME" + "INVALID", 0, (byte)11), new DataTree("NAME", 1, (byte)22), new DataTree("NAME", 2, (byte)33) }); + + Assert.Throws(typeof(ArithmeticException), () => listType.ParsePayloadToData(dataTree)); + } } } \ No newline at end of file From 9d084b4f09b04c9be6e6ace85c5e79b8f16f0eaa Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 3 Oct 2024 23:31:28 +0200 Subject: [PATCH 39/51] More Tests --- RDMSharpTests/Metadata/JSON/TestRange.cs | 81 ++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 RDMSharpTests/Metadata/JSON/TestRange.cs diff --git a/RDMSharpTests/Metadata/JSON/TestRange.cs b/RDMSharpTests/Metadata/JSON/TestRange.cs new file mode 100644 index 0000000..45ae1f0 --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestRange.cs @@ -0,0 +1,81 @@ +using RDMSharp.Metadata.JSON; +using RDMSharp.Metadata.JSON.OneOfTypes; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestRange + { + [Test] + public void TestByte() + { + Range range = new Range(1, 7); + Assert.That(range.IsInRange(2), Is.True); + Assert.That(range.IsInRange(0), Is.False); + } + [Test] + public void TestSByte() + { + Range range = new Range(1, 7); + Assert.That(range.IsInRange(2), Is.True); + Assert.That(range.IsInRange(-3), Is.False); + } + [Test] + public void TestShort() + { + Range range = new Range(1, 7); + Assert.That(range.IsInRange(2), Is.True); + Assert.That(range.IsInRange(0), Is.False); + } + [Test] + public void TestUShort() + { + Range range = new Range(1, 7); + Assert.That(range.IsInRange(2), Is.True); + Assert.That(range.IsInRange(0), Is.False); + } + [Test] + public void TestInt() + { + Range range = new Range(1, 7); + Assert.That(range.IsInRange(2), Is.True); + Assert.That(range.IsInRange(0), Is.False); + } + [Test] + public void TestUInt() + { + Range range = new Range(1, 7); + Assert.That(range.IsInRange(2), Is.True); + Assert.That(range.IsInRange(0), Is.False); + } + [Test] + public void TestLong() + { + Range range = new Range(1, 7); + Assert.That(range.IsInRange(2), Is.True); + Assert.That(range.IsInRange(0), Is.False); + } + [Test] + public void TestULong() + { + Range range = new Range(1, 7); + Assert.That(range.IsInRange(2), Is.True); + Assert.That(range.IsInRange(0), Is.False); + } +#if NET7_0_OR_GREATER + [Test] + public void TestInt128() + { + Range range = new Range(1, 7); + Assert.That(range.IsInRange(2), Is.True); + Assert.That(range.IsInRange(0), Is.False); + } + [Test] + public void TestUInt128() + { + Range range = new Range(1, 7); + Assert.That(range.IsInRange(2), Is.True); + Assert.That(range.IsInRange(0), Is.False); + } +#endif + } +} \ No newline at end of file From 52314a511f131a80b61c640c082166f866435f92 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Thu, 3 Oct 2024 23:44:17 +0200 Subject: [PATCH 40/51] More Tests and Coverage --- RDMSharp/Metadata/JSON/OneOfTypes/Range.cs | 22 ++++++++++++++++++- .../Metadata/JSON/TestPD_EnvelopeType.cs | 14 ++++++++++++ RDMSharpTests/Metadata/JSON/TestRange.cs | 19 ++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/Range.cs b/RDMSharp/Metadata/JSON/OneOfTypes/Range.cs index f2ab053..78cb338 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/Range.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/Range.cs @@ -50,7 +50,27 @@ public bool IsInRange(T value) public override string ToString() { - return $"Range: {Minimum:X4} - {Maximum:X4}"; + switch (Minimum) + { + case byte: + case sbyte: + return $"Range: {Minimum:X2} - {Maximum:X2}"; + case short: + case ushort: + return $"Range: {Minimum:X4} - {Maximum:X4}"; + case int: + case uint: + return $"Range: {Minimum:X8} - {Maximum:X8}"; + case long: + case ulong: + return $"Range: {Minimum:X16} - {Maximum:X16}"; +#if NET7_0_OR_GREATER + case Int128: + case UInt128: + return $"Range: {Minimum:X32} - {Maximum:X32}"; +#endif + } + return $"Range: {Minimum} - {Maximum}"; } } } diff --git a/RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs b/RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs index aee4f82..4cde081 100644 --- a/RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs +++ b/RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs @@ -1,3 +1,4 @@ +using RDMSharp.Metadata; using RDMSharp.Metadata.JSON.OneOfTypes; using RDMSharp.RDM; @@ -20,5 +21,18 @@ public void TestMany() Assert.Throws(typeof(ArgumentException), () => pdEnvelopeType = new PD_EnvelopeType("NAME", "DISPLAY_NAME", "NOTES", null, "pdEnvelop", 2)); } + + [Test] + public void TestParseData1() + { + + var pdEnvelopeType = new PD_EnvelopeType("NAME", "DISPLAY_NAME", "NOTES", null, "pdEnvelope", 2); + var dataTree = new DataTree(pdEnvelopeType.Name, 0, null); + var data = pdEnvelopeType.ParsePayloadToData(dataTree); + Assert.That(data, Is.EqualTo(new byte[] { })); + + var dataTreeResult = pdEnvelopeType.ParseDataToPayload(ref data); + Assert.That(dataTreeResult, Is.EqualTo(dataTree)); + } } } \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestRange.cs b/RDMSharpTests/Metadata/JSON/TestRange.cs index 45ae1f0..d9af436 100644 --- a/RDMSharpTests/Metadata/JSON/TestRange.cs +++ b/RDMSharpTests/Metadata/JSON/TestRange.cs @@ -11,6 +11,7 @@ public void TestByte() Range range = new Range(1, 7); Assert.That(range.IsInRange(2), Is.True); Assert.That(range.IsInRange(0), Is.False); + Assert.That(range.ToString(), Is.EqualTo("Range: 01 - 07")); } [Test] public void TestSByte() @@ -18,6 +19,7 @@ public void TestSByte() Range range = new Range(1, 7); Assert.That(range.IsInRange(2), Is.True); Assert.That(range.IsInRange(-3), Is.False); + Assert.That(range.ToString(), Is.EqualTo("Range: 01 - 07")); } [Test] public void TestShort() @@ -25,6 +27,7 @@ public void TestShort() Range range = new Range(1, 7); Assert.That(range.IsInRange(2), Is.True); Assert.That(range.IsInRange(0), Is.False); + Assert.That(range.ToString(), Is.EqualTo("Range: 0001 - 0007")); } [Test] public void TestUShort() @@ -32,6 +35,7 @@ public void TestUShort() Range range = new Range(1, 7); Assert.That(range.IsInRange(2), Is.True); Assert.That(range.IsInRange(0), Is.False); + Assert.That(range.ToString(), Is.EqualTo("Range: 0001 - 0007")); } [Test] public void TestInt() @@ -39,6 +43,7 @@ public void TestInt() Range range = new Range(1, 7); Assert.That(range.IsInRange(2), Is.True); Assert.That(range.IsInRange(0), Is.False); + Assert.That(range.ToString(), Is.EqualTo("Range: 00000001 - 00000007")); } [Test] public void TestUInt() @@ -46,6 +51,7 @@ public void TestUInt() Range range = new Range(1, 7); Assert.That(range.IsInRange(2), Is.True); Assert.That(range.IsInRange(0), Is.False); + Assert.That(range.ToString(), Is.EqualTo("Range: 00000001 - 00000007")); } [Test] public void TestLong() @@ -53,6 +59,7 @@ public void TestLong() Range range = new Range(1, 7); Assert.That(range.IsInRange(2), Is.True); Assert.That(range.IsInRange(0), Is.False); + Assert.That(range.ToString(), Is.EqualTo("Range: 0000000000000001 - 0000000000000007")); } [Test] public void TestULong() @@ -60,6 +67,7 @@ public void TestULong() Range range = new Range(1, 7); Assert.That(range.IsInRange(2), Is.True); Assert.That(range.IsInRange(0), Is.False); + Assert.That(range.ToString(), Is.EqualTo("Range: 0000000000000001 - 0000000000000007")); } #if NET7_0_OR_GREATER [Test] @@ -68,6 +76,7 @@ public void TestInt128() Range range = new Range(1, 7); Assert.That(range.IsInRange(2), Is.True); Assert.That(range.IsInRange(0), Is.False); + Assert.That(range.ToString(), Is.EqualTo("Range: 00000000000000000000000000000001 - 00000000000000000000000000000007")); } [Test] public void TestUInt128() @@ -75,7 +84,17 @@ public void TestUInt128() Range range = new Range(1, 7); Assert.That(range.IsInRange(2), Is.True); Assert.That(range.IsInRange(0), Is.False); + Assert.That(range.ToString(), Is.EqualTo("Range: 00000000000000000000000000000001 - 00000000000000000000000000000007")); } #endif + + [Test] + public void TestStringInvalid() + { + Range range = new Range("1", "7"); + Assert.That(range.IsInRange("2"), Is.False); + Assert.That(range.IsInRange("0"), Is.False); + Assert.That(range.ToString(), Is.EqualTo("Range: 1 - 7")); + } } } \ No newline at end of file From f89fd52508f9876a8c2c1f968e78a4583acf1b63 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Fri, 4 Oct 2024 00:01:50 +0200 Subject: [PATCH 41/51] Add Test for debugFailing Linux Tests --- RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs | 3 +-- RDMSharpTests/Metadata/JSON/TestStringType.cs | 10 ++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs b/RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs index 4cde081..374cf87 100644 --- a/RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs +++ b/RDMSharpTests/Metadata/JSON/TestPD_EnvelopeType.cs @@ -24,8 +24,7 @@ public void TestMany() [Test] public void TestParseData1() - { - + { var pdEnvelopeType = new PD_EnvelopeType("NAME", "DISPLAY_NAME", "NOTES", null, "pdEnvelope", 2); var dataTree = new DataTree(pdEnvelopeType.Name, 0, null); var data = pdEnvelopeType.ParsePayloadToData(dataTree); diff --git a/RDMSharpTests/Metadata/JSON/TestStringType.cs b/RDMSharpTests/Metadata/JSON/TestStringType.cs index 51704c7..39d7cb6 100644 --- a/RDMSharpTests/Metadata/JSON/TestStringType.cs +++ b/RDMSharpTests/Metadata/JSON/TestStringType.cs @@ -1,11 +1,21 @@ using RDMSharp.Metadata; using RDMSharp.Metadata.JSON.OneOfTypes; using RDMSharp.RDM; +using System.Text; namespace RDMSharpTests.Metadata.JSON { public class TestStringType { + [Test] + public void TestUTF8_Works() + { + string originalString = ""; + byte[] byteArray = Encoding.UTF8.GetBytes(originalString); + string resultString = Encoding.UTF8.GetString(byteArray); + + Assert.That(resultString, Is.EqualTo(originalString)); + } [Test] public void TestMany() { From 514a5738413c56e9218ced656647d456a03ee62d Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Fri, 4 Oct 2024 00:07:42 +0200 Subject: [PATCH 42/51] try fix Tests --- RDMSharpTests/Metadata/JSON/TestStringType.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/RDMSharpTests/Metadata/JSON/TestStringType.cs b/RDMSharpTests/Metadata/JSON/TestStringType.cs index 39d7cb6..ec3644e 100644 --- a/RDMSharpTests/Metadata/JSON/TestStringType.cs +++ b/RDMSharpTests/Metadata/JSON/TestStringType.cs @@ -7,9 +7,15 @@ namespace RDMSharpTests.Metadata.JSON { public class TestStringType { + [TearDown] + public void Teardown() + { + Console.OutputEncoding = Encoding.Default; + } [Test] public void TestUTF8_Works() { + Console.OutputEncoding = Encoding.UTF8; string originalString = ""; byte[] byteArray = Encoding.UTF8.GetBytes(originalString); string resultString = Encoding.UTF8.GetString(byteArray); @@ -55,6 +61,7 @@ public void TestMany() [Test] public void TestParseFixedLengthASCII() { + Console.OutputEncoding = Encoding.ASCII; var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, null, 5, true); string str = "qwert"; DataTree dataTree = new DataTree("NAME", 0, str); @@ -70,6 +77,7 @@ public void TestParseFixedLengthASCII() [Test] public void TestParseFixedLengthInBytesUTF8() { + Console.OutputEncoding = Encoding.UTF8; var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, null, null, minBytes: 8, maxBytes: 8, null); string str = ""; DataTree dataTree = new DataTree("NAME", 0, str); @@ -85,6 +93,7 @@ public void TestParseFixedLengthInBytesUTF8() [Test] public void TestParseRangedLengthUTF8() { + Console.OutputEncoding = Encoding.UTF8; var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, 4, 6, null, null, null); string str = ""; DataTree dataTree = new DataTree("NAME", 0, str); @@ -100,6 +109,7 @@ public void TestParseRangedLengthUTF8() [Test] public void TestParseRangedLengthUTF8Mixed() { + Console.OutputEncoding = Encoding.UTF8; var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, 4, 6, 4, 8, null); string str = "US"; DataTree dataTree = new DataTree("NAME", 0, str); @@ -116,6 +126,7 @@ public void TestParseRangedLengthUTF8Mixed() [Test] public void TestParseExceptions() { + Console.OutputEncoding = Encoding.UTF8; var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, 3, 6, 5, 8, null); string str = "12"; DataTree dataTree = new DataTree("NAME FAIL", 0, str); @@ -145,6 +156,7 @@ public void TestParseExceptions() [Test] public void TestParseBadFormatedData1() { + Console.OutputEncoding = Encoding.UTF8; var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, null, null, 2, 8, null); byte[] data = new byte[] { 195, 132, 0, 0, 0, 0 }; var dataTree = stringType.ParseDataToPayload(ref data); @@ -183,6 +195,7 @@ public void TestParseBadFormatedData1() [Test] public void TestParseBadFormatedData2() { + Console.OutputEncoding = Encoding.UTF8; var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, 2, 4, null, null, null); byte[] data = new byte[] { 195, 132, 0, 0, 0, 0 }; var dataTree = stringType.ParseDataToPayload(ref data); From aaeba4a2b0669b1ddd28a8f6487c0293858ecc05 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Fri, 4 Oct 2024 00:13:23 +0200 Subject: [PATCH 43/51] try fix tests --- RDMSharpTests/Metadata/JSON/TestStringType.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/RDMSharpTests/Metadata/JSON/TestStringType.cs b/RDMSharpTests/Metadata/JSON/TestStringType.cs index ec3644e..98e0e51 100644 --- a/RDMSharpTests/Metadata/JSON/TestStringType.cs +++ b/RDMSharpTests/Metadata/JSON/TestStringType.cs @@ -1,4 +1,4 @@ -using RDMSharp.Metadata; +using RDMSharp.Metadata; using RDMSharp.Metadata.JSON.OneOfTypes; using RDMSharp.RDM; using System.Text; @@ -16,7 +16,7 @@ public void Teardown() public void TestUTF8_Works() { Console.OutputEncoding = Encoding.UTF8; - string originalString = ""; + string originalString = "Ä"; byte[] byteArray = Encoding.UTF8.GetBytes(originalString); string resultString = Encoding.UTF8.GetString(byteArray); @@ -79,7 +79,7 @@ public void TestParseFixedLengthInBytesUTF8() { Console.OutputEncoding = Encoding.UTF8; var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, null, null, minBytes: 8, maxBytes: 8, null); - string str = ""; + string str = "ÄÜÖß"; DataTree dataTree = new DataTree("NAME", 0, str); byte[] data = stringType.ParsePayloadToData(dataTree); Assert.That(data, Is.EqualTo(new byte[] { 195, 132, 195, 156, 195, 150, 195, 159 })); @@ -95,7 +95,7 @@ public void TestParseRangedLengthUTF8() { Console.OutputEncoding = Encoding.UTF8; var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, 4, 6, null, null, null); - string str = ""; + string str = "ÄÜÖß"; DataTree dataTree = new DataTree("NAME", 0, str); byte[] data = stringType.ParsePayloadToData(dataTree); Assert.That(data, Is.EqualTo(new byte[] { 195, 132, 195, 156, 195, 150, 195, 159 })); @@ -111,7 +111,7 @@ public void TestParseRangedLengthUTF8Mixed() { Console.OutputEncoding = Encoding.UTF8; var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, 4, 6, 4, 8, null); - string str = "US"; + string str = "ÄUÖS"; DataTree dataTree = new DataTree("NAME", 0, str); byte[] data = stringType.ParsePayloadToData(dataTree); Assert.That(data, Is.EqualTo(new byte[] { 195, 132, 85, 195, 150, 83 })); @@ -142,10 +142,10 @@ public void TestParseExceptions() stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, null, null, 5, 8, null); - str = "4567"; + str = "ÄÖÜ4567"; dataTree = new DataTree("NAME", 0, str); Assert.Throws(typeof(ArithmeticException), () => stringType.ParsePayloadToData(dataTree)); - str = ""; + str = "ÄÖÜÜÖÄ"; dataTree = new DataTree("NAME", 0, str); Assert.Throws(typeof(ArithmeticException), () => stringType.ParsePayloadToData(dataTree)); str = null; @@ -160,12 +160,12 @@ public void TestParseBadFormatedData1() var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, null, null, 2, 8, null); byte[] data = new byte[] { 195, 132, 0, 0, 0, 0 }; var dataTree = stringType.ParseDataToPayload(ref data); - Assert.That(dataTree.Value, Is.EqualTo("")); + Assert.That(dataTree.Value, Is.EqualTo("Ä")); Assert.That(dataTree.Issues, Has.Length.EqualTo(1)); data = new byte[] { 195, 132, 0, 0, 119, 0 }; dataTree = stringType.ParseDataToPayload(ref data); - Assert.That(dataTree.Value, Is.EqualTo("")); + Assert.That(dataTree.Value, Is.EqualTo("Ä")); Assert.That(dataTree.Issues, Has.Length.EqualTo(2)); data = new byte[] { 0, 0, 0, 0, 0, 0 }; @@ -185,11 +185,11 @@ public void TestParseBadFormatedData1() data = new byte[] { 195, 132, 195, 132, 195, 132, 195, 132, 0 }; dataTree = stringType.ParseDataToPayload(ref data); - Assert.That(dataTree.Value, Is.EqualTo("")); + Assert.That(dataTree.Value, Is.EqualTo("ÄÄÄÄ")); Assert.That(dataTree.Issues, Has.Length.EqualTo(1)); data = new byte[] { 195, 132, 195, 132, 195, 132, 195, 132, 119, 119, 0 }; dataTree = stringType.ParseDataToPayload(ref data); - Assert.That(dataTree.Value, Is.EqualTo("")); + Assert.That(dataTree.Value, Is.EqualTo("ÄÄÄÄ")); Assert.That(dataTree.Issues, Has.Length.EqualTo(1)); } [Test] @@ -199,12 +199,12 @@ public void TestParseBadFormatedData2() var stringType = new StringType("NAME", "DISPLAY_NAME", "NOTES", null, "string", null, null, 2, 4, null, null, null); byte[] data = new byte[] { 195, 132, 0, 0, 0, 0 }; var dataTree = stringType.ParseDataToPayload(ref data); - Assert.That(dataTree.Value, Is.EqualTo("")); + Assert.That(dataTree.Value, Is.EqualTo("Ä")); Assert.That(dataTree.Issues, Has.Length.EqualTo(2)); data = new byte[] { 195, 132, 119, 119, 119, 119, 0 }; dataTree = stringType.ParseDataToPayload(ref data); - Assert.That(dataTree.Value, Is.EqualTo("wwww")); + Assert.That(dataTree.Value, Is.EqualTo("Äwwww")); Assert.That(dataTree.Issues, Has.Length.EqualTo(1)); } } From 87d9186c5b5fec0ef500a07bc00519763905cc6c Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Fri, 4 Oct 2024 00:16:42 +0200 Subject: [PATCH 44/51] MInor --- RDMSharpTests/Metadata/JSON/TestStringType.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/RDMSharpTests/Metadata/JSON/TestStringType.cs b/RDMSharpTests/Metadata/JSON/TestStringType.cs index 98e0e51..bc4aa2b 100644 --- a/RDMSharpTests/Metadata/JSON/TestStringType.cs +++ b/RDMSharpTests/Metadata/JSON/TestStringType.cs @@ -17,10 +17,15 @@ public void TestUTF8_Works() { Console.OutputEncoding = Encoding.UTF8; string originalString = "Ä"; + byte[] originalBytes = new byte[] { 195, 132 }; byte[] byteArray = Encoding.UTF8.GetBytes(originalString); string resultString = Encoding.UTF8.GetString(byteArray); + byte[] resultByteArray = Encoding.UTF8.GetBytes(originalString); + Assert.That(resultString, Is.EqualTo(originalString)); + Assert.That(byteArray, Is.EqualTo(originalBytes)); + Assert.That(resultByteArray, Is.EqualTo(originalBytes)); } [Test] public void TestMany() From 7c8c941917c3a14afb7171e8f2d82b7a069e2085 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Fri, 4 Oct 2024 00:29:23 +0200 Subject: [PATCH 45/51] Wrote Parse Tests for ReferenceType --- .../Metadata/JSON/TestReferenceType.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/RDMSharpTests/Metadata/JSON/TestReferenceType.cs b/RDMSharpTests/Metadata/JSON/TestReferenceType.cs index 9b10362..1fe16b6 100644 --- a/RDMSharpTests/Metadata/JSON/TestReferenceType.cs +++ b/RDMSharpTests/Metadata/JSON/TestReferenceType.cs @@ -1,3 +1,4 @@ +using RDMSharp.Metadata; using RDMSharp.Metadata.JSON; using RDMSharp.Metadata.JSON.OneOfTypes; using RDMSharp.RDM; @@ -23,5 +24,21 @@ public void TestMany() Assert.Throws(typeof(ArgumentException), () => referenceType = new ReferenceType("%/get_request/0")); } + [Test] + public void TestParse() + { + var referenceType = new ReferenceType("#/get_request/0", new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "uid", null, null)); + Assert.That(referenceType.GetDataLength().Value, Is.EqualTo(6)); + var uid = new UID(0x4646, 0x12345678); + var data = referenceType.ParsePayloadToData(new DataTree(referenceType.ReferencedObject.Name, 0, uid)); + Assert.That(data, Is.EqualTo(new byte[] { 0x46, 0x46, 0x12, 0x34, 0x56, 0x78 })); + var dataTree = referenceType.ParseDataToPayload(ref data); + Assert.That(data, Has.Length.EqualTo(0)); + Assert.That(dataTree.Value, Is.Not.Null); + Assert.That(dataTree.Value, Is.EqualTo(uid)); + + Assert.Throws(typeof(ArithmeticException), () => new BytesType("Other Name", "DISPLAY_NAME", "NOTES", null, "bytes", "uid", null, null).ParsePayloadToData(dataTree)); + Assert.Throws(typeof(ArithmeticException), () => new BytesType("NAME", "DISPLAY_NAME", "NOTES", null, "bytes", "xyz", null, null).ParsePayloadToData(dataTree)); + } } } \ No newline at end of file From 7523afe0162c64b9fda96291bef9d4c41397412c Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Tue, 15 Oct 2024 10:55:43 +0200 Subject: [PATCH 46/51] Add more Tests --- RDMSharp/Metadata/DataTree.cs | 3 +- RDMSharp/Metadata/DataTreeIssue.cs | 10 ++- RDMSharpTests/Metadata/JSON/TestDataTree.cs | 85 +++++++++++++++++++ .../JSON/TestDataTreeIssue - Kopieren.cs | 19 +++++ .../Metadata/JSON/TestDataTreeIssue.cs | 21 +++++ 5 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 RDMSharpTests/Metadata/JSON/TestDataTree.cs create mode 100644 RDMSharpTests/Metadata/JSON/TestDataTreeIssue - Kopieren.cs create mode 100644 RDMSharpTests/Metadata/JSON/TestDataTreeIssue.cs diff --git a/RDMSharp/Metadata/DataTree.cs b/RDMSharp/Metadata/DataTree.cs index b4fd069..4e6a3fa 100644 --- a/RDMSharp/Metadata/DataTree.cs +++ b/RDMSharp/Metadata/DataTree.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection.Metadata; namespace RDMSharp.Metadata { @@ -45,7 +44,7 @@ public DataTree(string name, uint index, DataTree[] children, DataTreeIssue[]? i public override string ToString() { - return $"{Name}: {Value}"; + return $"[{Index}] {Name}: {Value}"; } public override bool Equals(object obj) diff --git a/RDMSharp/Metadata/DataTreeIssue.cs b/RDMSharp/Metadata/DataTreeIssue.cs index 6947e41..b9f3fef 100644 --- a/RDMSharp/Metadata/DataTreeIssue.cs +++ b/RDMSharp/Metadata/DataTreeIssue.cs @@ -1,4 +1,6 @@ -namespace RDMSharp.Metadata +using System; + +namespace RDMSharp.Metadata { public readonly struct DataTreeIssue { @@ -6,7 +8,13 @@ public readonly struct DataTreeIssue public DataTreeIssue(string description) { + if (string.IsNullOrWhiteSpace(description)) + throw new ArgumentNullException($"{nameof(description)} has to be a vaild String"); Description = description; } + public override string ToString() + { + return Description; + } } } diff --git a/RDMSharpTests/Metadata/JSON/TestDataTree.cs b/RDMSharpTests/Metadata/JSON/TestDataTree.cs new file mode 100644 index 0000000..66e7d4b --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestDataTree.cs @@ -0,0 +1,85 @@ +using RDMSharp.Metadata; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestDataTree + { + [Test] + public void TestMany() + { + Assert.Multiple(() => + { + var dataTree = new DataTree(); + Assert.That(dataTree.ToString(), Is.Not.Null); + Assert.Throws(typeof(ArgumentException), () => new DataTree("name", 1, value: new DataTree[0].ToList())); + + Assert.That(new DataTree() == new DataTree(), Is.True); + Assert.That(new DataTree() != new DataTree(), Is.False); + Assert.That(new DataTree().Equals(new DataTree()), Is.True); + Assert.That(((object)new DataTree()).Equals(new DataTree()), Is.True); + Assert.That(((object)new DataTree()).Equals((object)new DataTree()), Is.True); + Assert.That(((object)new DataTree()).Equals(1), Is.False); + + Assert.That(new DataTree("Test", 3, true) == new DataTree("Test", 3, true), Is.True); + Assert.That(new DataTree("Test", 3, true) != new DataTree("Test", 3, true), Is.False); + Assert.That(new DataTree("Test", 3, true).Equals(new DataTree("Test", 3, true)), Is.True); + + Assert.That(new DataTree("Test", 3, true) == new DataTree("Test", 31, true), Is.False); + Assert.That(new DataTree("Test", 3, true) != new DataTree("Test", 31, true), Is.True); + Assert.That(new DataTree("Test", 3, true).Equals(new DataTree("Test", 31, true)), Is.False); + Assert.That(new DataTree("Test", 3, true) == new DataTree("Test", 3, false), Is.False); + Assert.That(new DataTree("Test", 3, true) != new DataTree("Test", 3, false), Is.True); + Assert.That(new DataTree("Test", 3, true).Equals(new DataTree("Test", 3, false)), Is.False); + Assert.That(new DataTree("Test", 3, true) == new DataTree("Test2", 3, true), Is.False); + Assert.That(new DataTree("Test", 3, true) != new DataTree("Test3", 3, true), Is.True); + Assert.That(new DataTree("Test", 3, true).Equals(new DataTree("Test4", 3, true)), Is.False); + Assert.That(new DataTree("Test", 3, true) == new DataTree("Test", 3, null), Is.False); + Assert.That(new DataTree("Test", 3, true) != new DataTree("Test", 3, null), Is.True); + Assert.That(new DataTree("Test", 3, true).Equals(new DataTree("Test", 3, null)), Is.False); + }); + + HashSet dict1 = new HashSet(); + HashSet dict2 = new HashSet(); + HashSet dict3 = new HashSet(); + + dict1.Add(new DataTree()); + dict2.Add(new DataTree()); + dict3.Add(new DataTree()); + + dict1.Add(new DataTree("Test", 1, false)); + dict2.Add(new DataTree("Test", 1, false)); + dict3.Add(new DataTree("Test", 1, true)); + + dict1.Add(new DataTree("Test2", 2, 33)); + dict2.Add(new DataTree("Test2", 2, 33)); + dict3.Add(new DataTree("Test2", 2, 33)); + + Assert.Multiple(() => + { + Assert.That(new DataTree("Test", 3, children: dict1.ToArray()) == new DataTree("Test", 3, children: dict2.ToArray()), Is.True); + Assert.That(new DataTree("Test", 3, children: dict1.ToArray()) != new DataTree("Test", 3, children: dict2.ToArray()), Is.False); + Assert.That(new DataTree("Test", 3, children: dict1.ToArray()).Equals(new DataTree("Test", 3, children: dict2.ToArray())), Is.True); + + Assert.That(new DataTree("Test", 3, children: null) == new DataTree("Test", 3, children: dict3.ToArray()), Is.False); + Assert.That(new DataTree("Test", 3, children: dict1.ToArray()) == new DataTree("Test", 3, children: dict3.ToArray()), Is.False); + Assert.That(new DataTree("Test", 3, children: dict1.ToArray()) != new DataTree("Test", 3, children: dict3.ToArray()), Is.True); + Assert.That(new DataTree("Test", 3, children: dict1.ToArray()).Equals(new DataTree("Test", 3, children: dict3.ToArray())), Is.False); + }); + + DataTreeIssue[] issues1 = new DataTreeIssue[] { new DataTreeIssue("Test Issue") }; + DataTreeIssue[] issues2 = new DataTreeIssue[] { new DataTreeIssue("Test Issue"), new DataTreeIssue("Test Issue2") }; + + Assert.Multiple(() => + { + Assert.That(new DataTree("Test", 3, true, issues1) == new DataTree("Test", 3, true, issues1.ToList().ToArray()), Is.True); + Assert.That(new DataTree("Test", 3, true, issues1) != new DataTree("Test", 3, true, issues1.ToList().ToArray()), Is.False); + Assert.That(new DataTree("Test", 3, true, issues1).Equals(new DataTree("Test", 3, true, issues1.ToList().ToArray())), Is.True); + + Assert.That(new DataTree("Test", 3, true) == new DataTree("Test", 3, true, issues2), Is.False); + Assert.That(new DataTree("Test", 3, true, issues1) == new DataTree("Test", 3, true, issues2), Is.False); + Assert.That(new DataTree("Test", 3, true, issues1) != new DataTree("Test", 3, true, issues2), Is.True); + Assert.That(new DataTree("Test", 3, true, issues1).Equals(new DataTree("Test", 3, true, issues2)), Is.False); + }); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestDataTreeIssue - Kopieren.cs b/RDMSharpTests/Metadata/JSON/TestDataTreeIssue - Kopieren.cs new file mode 100644 index 0000000..d2cf3a7 --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestDataTreeIssue - Kopieren.cs @@ -0,0 +1,19 @@ +using RDMSharp.Metadata; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestDefineNotFoundException + { + [Test] + public void TestMany() + { + Assert.Multiple(() => + { + var exception = new DefineNotFoundException(); + Assert.That(exception.Message, Is.Not.Null); + exception = new DefineNotFoundException("Test"); + Assert.That(exception.Message, Is.EqualTo("Test")); + }); + } + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/JSON/TestDataTreeIssue.cs b/RDMSharpTests/Metadata/JSON/TestDataTreeIssue.cs new file mode 100644 index 0000000..e536fdc --- /dev/null +++ b/RDMSharpTests/Metadata/JSON/TestDataTreeIssue.cs @@ -0,0 +1,21 @@ +using RDMSharp.Metadata; + +namespace RDMSharpTests.Metadata.JSON +{ + public class TestDataTreeIssue + { + [Test] + public void TestMany() + { + Assert.Multiple(() => + { + var issue = new DataTreeIssue(); + Assert.That(issue.ToString(), Is.Null); + issue = new DataTreeIssue("Test"); + Assert.That(issue.ToString(), Is.EqualTo("Test")); + Assert.Throws(typeof(ArgumentNullException), () => new DataTreeIssue("")); + Assert.Throws(typeof(ArgumentNullException), () => new DataTreeIssue(null)); + }); + } + } +} \ No newline at end of file From d2d30304abe3b5b10d4767a3021fe5f08df48012 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Tue, 15 Oct 2024 10:56:06 +0200 Subject: [PATCH 47/51] Grrr --- ...DataTreeIssue - Kopieren.cs => TestDefineNotFoundException.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename RDMSharpTests/Metadata/JSON/{TestDataTreeIssue - Kopieren.cs => TestDefineNotFoundException.cs} (100%) diff --git a/RDMSharpTests/Metadata/JSON/TestDataTreeIssue - Kopieren.cs b/RDMSharpTests/Metadata/JSON/TestDefineNotFoundException.cs similarity index 100% rename from RDMSharpTests/Metadata/JSON/TestDataTreeIssue - Kopieren.cs rename to RDMSharpTests/Metadata/JSON/TestDefineNotFoundException.cs From 6520c4781ae1052a3149eeb344c204667bf2f426 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Tue, 22 Oct 2024 20:03:09 +0200 Subject: [PATCH 48/51] More Tests --- RDMSharp/Metadata/ParameterBag.cs | 5 +- RDMSharpTests/Metadata/TestParameterBag.cs | 99 ++++++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 RDMSharpTests/Metadata/TestParameterBag.cs diff --git a/RDMSharp/Metadata/ParameterBag.cs b/RDMSharp/Metadata/ParameterBag.cs index fc0df97..c9df038 100644 --- a/RDMSharp/Metadata/ParameterBag.cs +++ b/RDMSharp/Metadata/ParameterBag.cs @@ -8,7 +8,10 @@ namespace RDMSharp.Metadata public readonly ushort ManufacturerID { get; } public readonly ushort? DeviceModelID { get; } public readonly uint? SoftwareVersionID { get; } - + public ParameterBag() + { + throw new NotSupportedException("Its not allowed to have an default of this Type"); + } public ParameterBag(ERDM_Parameter pid, ushort manufacturerID = 0, ushort? deviceModelID = null, uint? softwareVersionID = null) { if ((ushort)pid >= 0x8000) diff --git a/RDMSharpTests/Metadata/TestParameterBag.cs b/RDMSharpTests/Metadata/TestParameterBag.cs new file mode 100644 index 0000000..bb49cc0 --- /dev/null +++ b/RDMSharpTests/Metadata/TestParameterBag.cs @@ -0,0 +1,99 @@ +using RDMSharp.Metadata; + +namespace RDMSharpTests.Metadata +{ + public class TestParameterBag + { + + [Test] + public void TestMany() + { + Assert.Throws(typeof(NotSupportedException), () => new ParameterBag()); + HashSet parameterBags = new HashSet(); + Assert.DoesNotThrow(() => parameterBags.Add(new ParameterBag(ERDM_Parameter.CURVE))); + + + ERDM_Parameter pid = ERDM_Parameter.ADD_TAG; + ParameterBag bag = new ParameterBag(pid); + parameterBags.Add(bag); + Assert.Multiple(() => + { + Assert.That(bag, Is.Not.Default); + Assert.That(bag.PID, Is.EqualTo(pid)); + Assert.That(bag.ManufacturerID, Is.EqualTo(0)); + Assert.That(bag.DeviceModelID, Is.EqualTo(null)); + Assert.That(bag.SoftwareVersionID, Is.EqualTo(null)); + Assert.That(bag.ToString(), Is.EqualTo(pid.ToString())); + }); + + pid = (ERDM_Parameter)0x8943; + bag = new ParameterBag(pid, 432, 678, 42); + parameterBags.Add(bag); + Assert.Multiple(() => + { + Assert.That(bag, Is.Not.Default); + Assert.That(bag.PID, Is.EqualTo(pid)); + Assert.That(bag.ManufacturerID, Is.EqualTo(432)); + Assert.That(bag.DeviceModelID, Is.EqualTo(678)); + Assert.That(bag.SoftwareVersionID, Is.EqualTo(42)); + Assert.That(bag.ToString(), Is.EqualTo($"{pid} ManufacturerID: {432}, DeviceModelID: {678}, SoftwareVersionID: {42}")); + }); + + bag = new ParameterBag(pid, 432, 678); + parameterBags.Add(bag); + Assert.Multiple(() => + { + Assert.That(bag, Is.Not.Default); + Assert.That(bag.PID, Is.EqualTo(pid)); + Assert.That(bag.ManufacturerID, Is.EqualTo(432)); + Assert.That(bag.DeviceModelID, Is.EqualTo(678)); + Assert.That(bag.SoftwareVersionID, Is.EqualTo(null)); + Assert.That(bag.ToString(), Is.EqualTo($"{pid} ManufacturerID: {432}, DeviceModelID: {678}")); + }); + + bag = new ParameterBag(pid, 432); + parameterBags.Add(bag); + Assert.Multiple(() => + { + Assert.That(bag, Is.Not.Default); + Assert.That(bag.PID, Is.EqualTo(pid)); + Assert.That(bag.ManufacturerID, Is.EqualTo(432)); + Assert.That(bag.DeviceModelID, Is.EqualTo(null)); + Assert.That(bag.SoftwareVersionID, Is.EqualTo(null)); + Assert.That(bag.ToString(), Is.EqualTo($"{pid} ManufacturerID: {432}")); + }); + + Assert.Throws(typeof(ArgumentNullException), () => new ParameterBag(pid)); + } + + + [Test] + public void TestEqualMethodes() + { + Assert.Multiple(() => + { + Assert.That(new ParameterBag(ERDM_Parameter.CURVE) == new ParameterBag(ERDM_Parameter.CURVE), Is.True); + Assert.That(new ParameterBag(ERDM_Parameter.CURVE) == new ParameterBag(ERDM_Parameter.DIMMER_INFO), Is.False); + + Assert.That(new ParameterBag(ERDM_Parameter.CURVE) != new ParameterBag(ERDM_Parameter.CURVE), Is.False); + Assert.That(new ParameterBag(ERDM_Parameter.CURVE) != new ParameterBag(ERDM_Parameter.DIMMER_INFO), Is.True); + + Assert.That(new ParameterBag(ERDM_Parameter.CURVE).Equals(new ParameterBag(ERDM_Parameter.CURVE)), Is.True); + Assert.That(new ParameterBag(ERDM_Parameter.CURVE).Equals(new ParameterBag(ERDM_Parameter.DIMMER_INFO)), Is.False); + + Assert.That(new ParameterBag(ERDM_Parameter.CURVE).Equals((object)new ParameterBag(ERDM_Parameter.CURVE)), Is.True); + Assert.That(new ParameterBag(ERDM_Parameter.CURVE).Equals((object)new ParameterBag(ERDM_Parameter.DIMMER_INFO)), Is.False); + + Assert.That(new ParameterBag(ERDM_Parameter.CURVE).Equals(null), Is.False); + + ERDM_Parameter pid = (ERDM_Parameter)0x8555; + Assert.That(new ParameterBag(pid, 1), Is.Not.EqualTo(new ParameterBag(pid, 2))); + Assert.That(new ParameterBag(pid, 1), Is.Not.EqualTo(new ParameterBag(pid, 1, 444))); + Assert.That(new ParameterBag(pid, 1, 444), Is.Not.EqualTo(new ParameterBag(pid, 1, 444, 5))); +#pragma warning disable NUnit2009 + Assert.That(new ParameterBag(pid, 1, 444, 5), Is.EqualTo(new ParameterBag(pid, 1, 444, 5))); +#pragma warning restore NUnit2009 + }); + } + } +} \ No newline at end of file From 35f941f87b05f784f3af7188923bc65d3928dd90 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Tue, 22 Oct 2024 22:55:05 +0200 Subject: [PATCH 49/51] Work on PeerToPeerProcess and Tests --- RDMSharp/Metadata/MetadataFactory.cs | 36 +++++-- RDMSharp/RDM/AbstractSendReceivePipeline.cs | 10 ++ RDMSharp/RDM/AsyncRDMRequestHelper.cs | 4 +- RDMSharp/RDM/Device/AbstractRDMDevice.cs | 4 +- RDMSharp/RDM/Device/RDMDeviceModel.cs | 4 +- .../RDM/Discovery/AbstractDiscoveryTool.cs | 6 +- RDMSharp/RDM/PeerToPeerProcess.cs | 101 +++++++++++++++++- .../Metadata/TestPeerToPeerProcess.cs | 55 ++++++++++ 8 files changed, 202 insertions(+), 18 deletions(-) create mode 100644 RDMSharp/RDM/AbstractSendReceivePipeline.cs create mode 100644 RDMSharpTests/Metadata/TestPeerToPeerProcess.cs diff --git a/RDMSharp/Metadata/MetadataFactory.cs b/RDMSharp/Metadata/MetadataFactory.cs index 9e33ba9..76b7bcc 100644 --- a/RDMSharp/Metadata/MetadataFactory.cs +++ b/RDMSharp/Metadata/MetadataFactory.cs @@ -102,6 +102,8 @@ internal static MetadataJSONObjectDefine GetDefine(ParameterBag parameter) private static MetadataJSONObjectDefine getDefine(ParameterBag parameter) { var version = GetMetadataSchemaVersions().First(); + if (metadataVersionDefinesBagDictionary == null) + fillDefaultMetadataVersionList(); var possibleDefines = metadataVersionDefinesBagDictionary[version].FindAll(d => d.PID == (ushort)parameter.PID && d.ManufacturerID == parameter.ManufacturerID); if (possibleDefines.Count == 1) return possibleDefines[0]; @@ -142,14 +144,20 @@ internal static byte[] ParsePayloadToData(MetadataJSONObjectDefine define, Comma if (_command is not Command command) throw new InvalidOperationException(); - if (payload is DataTree dataTree) - { - OneOfTypes[] oneofTypes = null; - if (command.SingleField.HasValue) - oneofTypes = new OneOfTypes[] { command.SingleField.Value }; - else if (command.ListOfFields.Length != 0) - oneofTypes = command.ListOfFields; + if (command.GetIsEmpty()) + return new byte[0]; + + if (payload is DataTree dataTree && command.SingleField.HasValue) + return command.SingleField.Value.ParsePayloadToData(dataTree); + if (payload is DataTree[] dataTreeArray && command.ListOfFields.Length != 0) + { + if (dataTreeArray.Length != command.ListOfFields.Length) + throw new IndexOutOfRangeException(); + List data = new List(); + for (int i = 0; i < command.ListOfFields.Length; i++) + data.AddRange(command.ListOfFields[i].ParsePayloadToData(dataTreeArray[i])); + return data.ToArray(); } throw new ArithmeticException(); @@ -160,6 +168,20 @@ internal static object ParseDataToPayload(MetadataJSONObjectDefine define, Comma if (_command is not Command command) throw new InvalidOperationException(); + if (command.GetIsEmpty()) + return new byte[0]; + + if (command.SingleField.HasValue) + return command.SingleField.Value.ParseDataToPayload(ref data); + + if (command.ListOfFields.Length != 0) + { + List tree = new List(); + for (int i = 0; i < command.ListOfFields.Length; i++) + tree.Add(command.ListOfFields[i].ParseDataToPayload(ref data)); + return tree.ToArray(); + } + throw new ArithmeticException(); } internal static byte[] GetRequestMessageData(ParameterBag parameter, object payloadData) diff --git a/RDMSharp/RDM/AbstractSendReceivePipeline.cs b/RDMSharp/RDM/AbstractSendReceivePipeline.cs new file mode 100644 index 0000000..5e02022 --- /dev/null +++ b/RDMSharp/RDM/AbstractSendReceivePipeline.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; + +namespace RDMSharp.RDM +{ + public abstract class AbstractSendReceivePipeline + { + public abstract Task SendMesage(RDMMessage message); + public abstract Task ReceiveMesage(RDMMessage message); + } +} diff --git a/RDMSharp/RDM/AsyncRDMRequestHelper.cs b/RDMSharp/RDM/AsyncRDMRequestHelper.cs index 9041b17..109da03 100644 --- a/RDMSharp/RDM/AsyncRDMRequestHelper.cs +++ b/RDMSharp/RDM/AsyncRDMRequestHelper.cs @@ -33,7 +33,7 @@ public void Dispose() this.IsDisposing= false; } - public bool ReceiveMethode(RDMMessage rdmMessage) + public bool ReceiveMessage(RDMMessage rdmMessage) { if (this.IsDisposing || this.IsDisposed) return false; @@ -67,7 +67,7 @@ public bool ReceiveMethode(RDMMessage rdmMessage) } - public async Task RequestParameter(RDMMessage requerst) + public async Task RequestMessage(RDMMessage requerst) { try { diff --git a/RDMSharp/RDM/Device/AbstractRDMDevice.cs b/RDMSharp/RDM/Device/AbstractRDMDevice.cs index c2453fc..7928d62 100644 --- a/RDMSharp/RDM/Device/AbstractRDMDevice.cs +++ b/RDMSharp/RDM/Device/AbstractRDMDevice.cs @@ -169,7 +169,7 @@ protected async Task ReceiveRDMMessage(RDMMessage rdmMessage) LastSeen = DateTime.UtcNow; - if (asyncRDMRequestHelper.ReceiveMethode(rdmMessage)) + if (asyncRDMRequestHelper.ReceiveMessage(rdmMessage)) return; if ((rdmMessage.NackReason?.Length ?? 0) != 0) @@ -183,7 +183,7 @@ protected async Task ReceiveRDMMessage(RDMMessage rdmMessage) } private async Task requestParameter(RDMMessage rdmMessage) { - return await asyncRDMRequestHelper.RequestParameter(rdmMessage); + return await asyncRDMRequestHelper.RequestMessage(rdmMessage); } private async void DeviceModel_Initialized(object sender, EventArgs e) { diff --git a/RDMSharp/RDM/Device/RDMDeviceModel.cs b/RDMSharp/RDM/Device/RDMDeviceModel.cs index 3a73af9..519f0d0 100644 --- a/RDMSharp/RDM/Device/RDMDeviceModel.cs +++ b/RDMSharp/RDM/Device/RDMDeviceModel.cs @@ -225,7 +225,7 @@ internal async Task ReceiveRDMMessage(RDMMessage rdmMessage) if (!rdmMessage.Command.HasFlag(ERDM_Command.RESPONSE)) return; - if (asyncRDMRequestHelper.ReceiveMethode(rdmMessage)) + if (asyncRDMRequestHelper.ReceiveMessage(rdmMessage)) return; await processMessage(rdmMessage); @@ -233,7 +233,7 @@ internal async Task ReceiveRDMMessage(RDMMessage rdmMessage) private async Task requestParameter(RDMMessage rdmMessage) { - return await asyncRDMRequestHelper.RequestParameter(rdmMessage); + return await asyncRDMRequestHelper.RequestMessage(rdmMessage); } private async Task processMessage(RequestResult result) diff --git a/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs b/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs index 8c18351..826bdee 100644 --- a/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs +++ b/RDMSharp/RDM/Discovery/AbstractDiscoveryTool.cs @@ -34,7 +34,7 @@ public AbstractDiscoveryTool() protected void ReceiveRDMMessage(RDMMessage rdmMessage) { - asyncRDMRequestHelper.ReceiveMethode(rdmMessage); + asyncRDMRequestHelper.ReceiveMessage(rdmMessage); } public async Task> PerformDiscovery(IProgress progress = null, bool full = true) @@ -99,7 +99,7 @@ private async Task DiscoverDevicesBinarySearch(UID uidStart, UID uidEnd, RDMDisc ParameterData = new DiscUniqueBranchRequest(uidStart, uidEnd).ToPayloadData() }; context.IncreaseMessageCounter(); - var res = await asyncRDMRequestHelper.RequestParameter(m); + var res = await asyncRDMRequestHelper.RequestMessage(m); if (res.Success) { success = res.Success; @@ -202,7 +202,7 @@ private async Task DiscoverDevicesBinarySearch(UID uidStart, UID uidEnd, RDMDisc Parameter = ERDM_Parameter.DISC_MUTE, DestUID = uid }; - var res = await asyncRDMRequestHelper.RequestParameter(n); + var res = await asyncRDMRequestHelper.RequestMessage(n); if (res.Success) { muted = res.Success; diff --git a/RDMSharp/RDM/PeerToPeerProcess.cs b/RDMSharp/RDM/PeerToPeerProcess.cs index f75fb01..6fb16e0 100644 --- a/RDMSharp/RDM/PeerToPeerProcess.cs +++ b/RDMSharp/RDM/PeerToPeerProcess.cs @@ -1,18 +1,115 @@ using RDMSharp.Metadata; using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using static RDMSharp.Metadata.JSON.Command; namespace RDMSharp { internal class PeerToPeerProcess { - public PeerToPeerProcess(ERDM_Command command, ERDM_Parameter parameter, object payloadObject = null) + internal enum EPeerToPeerProcessState + { + Waiting, + Running, + Finished, + Failed + } + public readonly ERDM_Command Command; + public readonly UID UID; + public readonly SubDevice SubDevice; + public readonly ParameterBag ParameterBag; + public readonly object RequestPayloadObject; + public object ResponsePayloadObject { get; private set; } + + public MetadataJSONObjectDefine Define { get; private set; } + public EPeerToPeerProcessState State { get; private set; } = EPeerToPeerProcessState.Waiting; + + private RDMMessage request = null; + private RDMMessage response = null; + public PeerToPeerProcess(ERDM_Command command, UID uid, SubDevice subDevice, ParameterBag parameterBag, object payloadObject = null) { if (command != ERDM_Command.GET_COMMAND) if (command != ERDM_Command.SET_COMMAND) throw new ArgumentException($"{nameof(command)} should be {ERDM_Command.GET_COMMAND} or {ERDM_Command.SET_COMMAND}"); + Command = command; + UID = uid; + SubDevice = subDevice; + ParameterBag = parameterBag; + RequestPayloadObject = payloadObject; + + Define = MetadataFactory.GetDefine(ParameterBag); + } + + public void Run(AsyncRDMRequestHelper asyncRDMRequestHelper) + { + _ = run(asyncRDMRequestHelper); + } + + private async Task run(AsyncRDMRequestHelper asyncRDMRequestHelper) + { + try + { + if (State != EPeerToPeerProcessState.Waiting) + return; + + if (asyncRDMRequestHelper == null) + throw new ArgumentNullException(nameof(asyncRDMRequestHelper)); + + State = EPeerToPeerProcessState.Running; + + ECommandDublicte commandRequest = ECommandDublicte.GetRequest; + if (Command == ERDM_Command.SET_COMMAND) + commandRequest = ECommandDublicte.SetRequest; + + ECommandDublicte commandResponse = ECommandDublicte.GetResponse; + if (Command == ERDM_Command.SET_COMMAND) + commandResponse = ECommandDublicte.SetResponse; - //MetadataFactory. + byte[] parameterData = MetadataFactory.ParsePayloadToData(Define, commandRequest, RequestPayloadObject); + request = new RDMMessage() + { + Command = Command, + DestUID = UID, + SubDevice = SubDevice, + Parameter = ParameterBag.PID, + ParameterData = parameterData + }; + List bytes = new List(); + while (State == EPeerToPeerProcessState.Running) + { + var responseResult = await asyncRDMRequestHelper.RequestMessage(request); + if (!responseResult.Success) + { + State = EPeerToPeerProcessState.Failed; + return; + } + response = responseResult.Response; + bytes.AddRange(response.ParameterData); + if (response.ResponseType == ERDM_ResponseType.ACK) + { + ResponsePayloadObject = MetadataFactory.ParseDataToPayload(Define, commandResponse, bytes.ToArray()); + State = EPeerToPeerProcessState.Finished; + return; + } + else if (response.ResponseType == ERDM_ResponseType.ACK_OVERFLOW) + { + //Do nothing else send another Request + //Send Message on next loop + } + else if (response.ResponseType == ERDM_ResponseType.ACK_TIMER && response.Value is AcknowledgeTimer timer) + { + await Task.Delay(timer.EstimidatedResponseTime); + request.Parameter = ERDM_Parameter.QUEUED_MESSAGE; + //Send Message on next loop + } + } + } + catch (Exception e) + { + State = EPeerToPeerProcessState.Failed; + } } } } \ No newline at end of file diff --git a/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs b/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs new file mode 100644 index 0000000..f3c369b --- /dev/null +++ b/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs @@ -0,0 +1,55 @@ +using RDMSharp.Metadata; + +namespace RDMSharpTests.Metadata +{ + public class TestPeerToPeerProcess + { + + [Test] + public async Task Test_Get_DMX_START_ADDRESS() + { + var command = ERDM_Command.GET_COMMAND; + var uid = new UID(1234, 123456); + var subdevice = SubDevice.Root; + var parameterBag = new ParameterBag(ERDM_Parameter.DMX_START_ADDRESS); + const ushort DMX_ADDRESS = 33; + PeerToPeerProcess peerToPeerProcess = new PeerToPeerProcess(command, uid, subdevice, parameterBag); + + Assert.That(peerToPeerProcess.Define, Is.Not.Null); + Assert.That(peerToPeerProcess.State, Is.EqualTo(PeerToPeerProcess.EPeerToPeerProcessState.Waiting)); + Assert.That(peerToPeerProcess.RequestPayloadObject, Is.Null); + Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.Null); + + AsyncRDMRequestHelper helper = null; + helper = new AsyncRDMRequestHelper(sendMessage); + peerToPeerProcess.Run(helper); + + while (peerToPeerProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Running) + await Task.Delay(100); + + Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTree[]))); + Assert.That(((DataTree[])peerToPeerProcess.ResponsePayloadObject)[0].Value, Is.EqualTo(DMX_ADDRESS)); + + async Task sendMessage(RDMMessage message) + { + Assert.That(message.Command, Is.EqualTo(command)); + Assert.That(message.DestUID, Is.EqualTo(uid)); + Assert.That(message.SubDevice, Is.EqualTo(subdevice)); + Assert.That(message.Parameter, Is.EqualTo(parameterBag.PID)); + + RDMMessage response = new RDMMessage() + { + Command= message.Command | ERDM_Command.RESPONSE, + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter= message.Parameter, + SubDevice= message.SubDevice, + ParameterData= MetadataFactory.GetResponseMessageData(parameterBag, new DataTree[] { new DataTree("dmx_address", 0, DMX_ADDRESS) }) + }; + + await Task.Delay(10); + helper.ReceiveMessage(response); + } + } + } +} \ No newline at end of file From e636b0543aaa89106aedd6d41e6c09027819c8dd Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Fri, 25 Oct 2024 23:52:27 +0200 Subject: [PATCH 50/51] More Tests --- RDMSharp/Metadata/MetadataFactory.cs | 2 +- .../RDM/PayloadObject/AcknowledgeTimer.cs | 4 +- RDMSharp/RDM/PeerToPeerProcess.cs | 16 +-- .../Metadata/TestPeerToPeerProcess.cs | 111 ++++++++++++++++++ .../RDM/PayloadObject/AcknowledgeTimerTest.cs | 2 +- 5 files changed, 124 insertions(+), 11 deletions(-) diff --git a/RDMSharp/Metadata/MetadataFactory.cs b/RDMSharp/Metadata/MetadataFactory.cs index 76b7bcc..bae4442 100644 --- a/RDMSharp/Metadata/MetadataFactory.cs +++ b/RDMSharp/Metadata/MetadataFactory.cs @@ -169,7 +169,7 @@ internal static object ParseDataToPayload(MetadataJSONObjectDefine define, Comma throw new InvalidOperationException(); if (command.GetIsEmpty()) - return new byte[0]; + return null; if (command.SingleField.HasValue) return command.SingleField.Value.ParseDataToPayload(ref data); diff --git a/RDMSharp/RDM/PayloadObject/AcknowledgeTimer.cs b/RDMSharp/RDM/PayloadObject/AcknowledgeTimer.cs index 702611b..6880491 100644 --- a/RDMSharp/RDM/PayloadObject/AcknowledgeTimer.cs +++ b/RDMSharp/RDM/PayloadObject/AcknowledgeTimer.cs @@ -7,7 +7,7 @@ public class AcknowledgeTimer : AbstractRDMPayloadObject { [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2208")] public AcknowledgeTimer( - TimeSpan estimidatedResponseTime = default) : this((ushort)(estimidatedResponseTime.TotalSeconds / 10)) + TimeSpan estimidatedResponseTime = default) : this((ushort)(estimidatedResponseTime.TotalSeconds * 10.0)) { if (estimidatedResponseTime.TotalSeconds / 10 > ushort.MaxValue) throw new ArgumentOutOfRangeException("The Timer is to long for the Resolution of 16-bit ushort"); @@ -16,7 +16,7 @@ private AcknowledgeTimer( ushort _estimidatedResponseTimeRaw = default) { this.estimidatedResponseTimeRaw = _estimidatedResponseTimeRaw; - this.EstimidatedResponseTime = TimeSpan.FromSeconds(this.estimidatedResponseTimeRaw * 10); + this.EstimidatedResponseTime = TimeSpan.FromSeconds(this.estimidatedResponseTimeRaw / 10.0); } public TimeSpan EstimidatedResponseTime { get; private set; } diff --git a/RDMSharp/RDM/PeerToPeerProcess.cs b/RDMSharp/RDM/PeerToPeerProcess.cs index 6fb16e0..c390597 100644 --- a/RDMSharp/RDM/PeerToPeerProcess.cs +++ b/RDMSharp/RDM/PeerToPeerProcess.cs @@ -86,6 +86,13 @@ private async Task run(AsyncRDMRequestHelper asyncRDMRequestHelper) return; } response = responseResult.Response; + if (response.ResponseType == ERDM_ResponseType.ACK_TIMER && response.Value is AcknowledgeTimer timer) + { + await Task.Delay(timer.EstimidatedResponseTime); + request.Parameter = ERDM_Parameter.QUEUED_MESSAGE; + //Send Message on next loop + continue; + } bytes.AddRange(response.ParameterData); if (response.ResponseType == ERDM_ResponseType.ACK) { @@ -93,16 +100,11 @@ private async Task run(AsyncRDMRequestHelper asyncRDMRequestHelper) State = EPeerToPeerProcessState.Finished; return; } - else if (response.ResponseType == ERDM_ResponseType.ACK_OVERFLOW) + if (response.ResponseType == ERDM_ResponseType.ACK_OVERFLOW) { //Do nothing else send another Request //Send Message on next loop - } - else if (response.ResponseType == ERDM_ResponseType.ACK_TIMER && response.Value is AcknowledgeTimer timer) - { - await Task.Delay(timer.EstimidatedResponseTime); - request.Parameter = ERDM_Parameter.QUEUED_MESSAGE; - //Send Message on next loop + continue; } } } diff --git a/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs b/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs index f3c369b..24bd898 100644 --- a/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs +++ b/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs @@ -51,5 +51,116 @@ async Task sendMessage(RDMMessage message) helper.ReceiveMessage(response); } } + + + [Test] + public async Task Test_Get_PROXIED_DEVICES() + { + var command = ERDM_Command.GET_COMMAND; + var uid = new UID(1234, 123456); + var subdevice = SubDevice.Root; + var parameterBag = new ParameterBag(ERDM_Parameter.PROXIED_DEVICES); + DataTree[] children = new DataTree[500]; + Random rnd = new Random(); + for (int i = 0; i < children.Length; i++) + children[i] = new DataTree("device_uid", (uint)i, new UID(0x1234, (uint)rnd.Next(1, int.MaxValue))); + + PeerToPeerProcess peerToPeerProcess = new PeerToPeerProcess(command, uid, subdevice, parameterBag); + + Assert.That(peerToPeerProcess.Define, Is.Not.Null); + Assert.That(peerToPeerProcess.State, Is.EqualTo(PeerToPeerProcess.EPeerToPeerProcessState.Waiting)); + Assert.That(peerToPeerProcess.RequestPayloadObject, Is.Null); + Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.Null); + + AsyncRDMRequestHelper helper = null; + byte[] parameterData = MetadataFactory.GetResponseMessageData(parameterBag, new DataTree[] { new DataTree("device_uids", 0, children: children) }); + helper = new AsyncRDMRequestHelper(sendMessage); + peerToPeerProcess.Run(helper); + + while (peerToPeerProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Running) + await Task.Delay(100); + + Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTree[]))); + Assert.That(((DataTree[])peerToPeerProcess.ResponsePayloadObject)[0].Children, Is.EqualTo(children)); + + + async Task sendMessage(RDMMessage message) + { + Assert.That(message.Command, Is.EqualTo(command)); + Assert.That(message.DestUID, Is.EqualTo(uid)); + Assert.That(message.SubDevice, Is.EqualTo(subdevice)); + Assert.That(message.Parameter, Is.EqualTo(parameterBag.PID)); + + var count = Math.Min(parameterData.Length, 0xE4); + var _parameterData = parameterData.Take(count).ToArray(); + parameterData= parameterData.Skip(count).ToArray(); + RDMMessage response = new RDMMessage() + { + Command = message.Command | ERDM_Command.RESPONSE, + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = message.Parameter, + SubDevice = message.SubDevice, + ParameterData = _parameterData, + PortID_or_Responsetype = parameterData.Length == 0 ? (byte)ERDM_ResponseType.ACK : (byte)ERDM_ResponseType.ACK_OVERFLOW + }; + + await Task.Delay(10); + helper.ReceiveMessage(response); + } + } + [Test] + public async Task Test_Get_LAMP_STRIKES() + { + var command = ERDM_Command.GET_COMMAND; + var uid = new UID(1234, 123456); + var subdevice = SubDevice.Root; + var parameterBag = new ParameterBag(ERDM_Parameter.LAMP_STRIKES); + const uint LAMP_STRIKES = 33; + PeerToPeerProcess peerToPeerProcess = new PeerToPeerProcess(command, uid, subdevice, parameterBag); + + Assert.That(peerToPeerProcess.Define, Is.Not.Null); + Assert.That(peerToPeerProcess.State, Is.EqualTo(PeerToPeerProcess.EPeerToPeerProcessState.Waiting)); + Assert.That(peerToPeerProcess.RequestPayloadObject, Is.Null); + Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.Null); + + AsyncRDMRequestHelper helper = null; + byte count = 0; + helper = new AsyncRDMRequestHelper(sendMessage); + peerToPeerProcess.Run(helper); + + while (peerToPeerProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Running) + await Task.Delay(100); + + Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTree[]))); + Assert.That(((DataTree[])peerToPeerProcess.ResponsePayloadObject)[0].Value, Is.EqualTo(LAMP_STRIKES)); + + async Task sendMessage(RDMMessage message) + { + Assert.That(count, Is.LessThan(2)); + if(count==0) + Assert.That(message.Parameter, Is.EqualTo(parameterBag.PID)); + else if(count==1) + Assert.That(message.Parameter, Is.EqualTo(ERDM_Parameter.QUEUED_MESSAGE)); + Assert.That(message.Command, Is.EqualTo(command)); + Assert.That(message.DestUID, Is.EqualTo(uid)); + Assert.That(message.SubDevice, Is.EqualTo(subdevice)); + + RDMMessage response = new RDMMessage() + { + Command = message.Command | ERDM_Command.RESPONSE, + DestUID = message.SourceUID, + SourceUID = message.DestUID, + Parameter = parameterBag.PID, + SubDevice = message.SubDevice, + ParameterData = count == 0 ? new AcknowledgeTimer(TimeSpan.FromSeconds(3)).ToPayloadData() : MetadataFactory.GetResponseMessageData(parameterBag, new DataTree[] { new DataTree("strikes", 0, LAMP_STRIKES) }), + PortID_or_Responsetype = count == 0 ? (byte)ERDM_ResponseType.ACK_TIMER : (byte)ERDM_ResponseType.ACK + }; + + await Task.Delay(10); + count++; + helper.ReceiveMessage(response); + } + } } } \ No newline at end of file diff --git a/RDMSharpTests/RDM/PayloadObject/AcknowledgeTimerTest.cs b/RDMSharpTests/RDM/PayloadObject/AcknowledgeTimerTest.cs index 2be1428..49b5ede 100644 --- a/RDMSharpTests/RDM/PayloadObject/AcknowledgeTimerTest.cs +++ b/RDMSharpTests/RDM/PayloadObject/AcknowledgeTimerTest.cs @@ -10,7 +10,7 @@ public void Setup() [Test] public void ToPayloadAndFromMessageTest() { - var time = TimeSpan.FromSeconds(360000); + var time = TimeSpan.FromSeconds(3); AcknowledgeTimer acknowledgeTimer = new AcknowledgeTimer(time); byte[] data = acknowledgeTimer.ToPayloadData(); From 820675a0fce9f1cbf87ede7333362b2e288b7772 Mon Sep 17 00:00:00 2001 From: Patrick Grote Date: Fri, 1 Nov 2024 23:56:12 +0100 Subject: [PATCH 51/51] Work on Parse DataTree to known Objects --- RDMSharp/Metadata/DataTreeBranch.cs | 122 +++++++++++++ RDMSharp/Metadata/DataTreeObjectAttribute.cs | 17 ++ .../DataTreeObjectConstructorAttribute.cs | 11 ++ .../DataTreeObjectParameterAttribute.cs | 14 ++ .../Metadata/JSON/OneOfTypes/ReferenceType.cs | 2 - RDMSharp/Metadata/MetadataFactory.cs | 54 ++++-- RDMSharp/RDM/Enum/ERDM_DisplayInvert.cs | 7 +- RDMSharp/RDM/Enum/ERDM_Status.cs | 6 +- .../RDM/PayloadObject/RDMDMXPersonality.cs | 14 +- .../RDMDMXPersonalityDescription.cs | 16 +- RDMSharp/RDM/PayloadObject/RDMDeviceInfo.cs | 32 +++- .../RDM/PayloadObject/RDMSlotDescription.cs | 10 +- RDMSharp/RDM/PeerToPeerProcess.cs | 8 +- RDMSharp/RDM/Tools.cs | 8 + .../Parser/TestDefinedDataTreeObjects.cs | 168 ++++++++++++++++++ .../Metadata/TestMetadataFactoryStuff.cs | 20 +-- .../Metadata/TestPeerToPeerProcess.cs | 39 ++-- RDMSharpTests/RDMSharpTests.csproj | 3 - 18 files changed, 486 insertions(+), 65 deletions(-) create mode 100644 RDMSharp/Metadata/DataTreeBranch.cs create mode 100644 RDMSharp/Metadata/DataTreeObjectAttribute.cs create mode 100644 RDMSharp/Metadata/DataTreeObjectConstructorAttribute.cs create mode 100644 RDMSharp/Metadata/DataTreeObjectParameterAttribute.cs create mode 100644 RDMSharpTests/Metadata/Parser/TestDefinedDataTreeObjects.cs diff --git a/RDMSharp/Metadata/DataTreeBranch.cs b/RDMSharp/Metadata/DataTreeBranch.cs new file mode 100644 index 0000000..306e364 --- /dev/null +++ b/RDMSharp/Metadata/DataTreeBranch.cs @@ -0,0 +1,122 @@ +using RDMSharp.Metadata.JSON; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace RDMSharp.Metadata +{ + public readonly struct DataTreeBranch : IEquatable + { + public static readonly DataTreeBranch Empty = new DataTreeBranch(); + public static readonly DataTreeBranch Unset = new DataTreeBranch(true); + + public readonly DataTree[] Children; + public readonly bool IsEmpty; + public readonly bool IsUnset; + + public readonly object ParsedObject; + public DataTreeBranch() + { + IsEmpty = true; + } + private DataTreeBranch(bool isUnset) + { + IsUnset = true; + } + public DataTreeBranch(params DataTree[] children) + { + if (children.Length == 0) + IsEmpty = true; + + Children = children; + } + public DataTreeBranch(MetadataJSONObjectDefine define, Command.ECommandDublicte commandType, params DataTree[] children): this(children) + { + if (define == null) + throw new ArgumentNullException(); + + ParsedObject = this.getParsedObject(define, commandType); + } + + private object getParsedObject(MetadataJSONObjectDefine define, Command.ECommandDublicte commandType) + { + if (IsEmpty || IsUnset) + return null; + + var definedDataTreeObjectType = MetadataFactory.GetDefinedDataTreeObjectType(define, commandType); + if (definedDataTreeObjectType != null) + { + if (definedDataTreeObjectType.IsEnum) + return Enum.ToObject(definedDataTreeObjectType, Children.Single().Value); + + ConstructorInfo[] constructors = definedDataTreeObjectType.GetConstructors(); + + foreach (var constructor in constructors) + { + if (constructor.GetCustomAttribute() is DataTreeObjectConstructorAttribute cAttribute) + { + var parameters = new List(); + foreach (var param in constructor.GetParameters()) + if (param.GetCustomAttribute() is DataTreeObjectParameterAttribute pAttribute) + { + if (Children.FirstOrDefault(c => string.Equals(c.Name, pAttribute.Name)) is DataTree child) + parameters.Add(child.Value); + else + throw new ArgumentException($"No matching Value found for '{pAttribute.Name}'"); + } + + var instance = constructor.Invoke(parameters.ToArray()); + return instance; + } + } + } + + if (Children.Length == 1) + { + DataTree dataTree = Children[0]; + + if (dataTree.Value != null) + return dataTree.Value; + + if (dataTree.Children.GroupBy(c => c.Name).Count() == 1) + { + var list = dataTree.Children.Select(c => c.Value).ToList(); + Type targetType = list.First().GetType(); + var array = Array.CreateInstance(targetType, list.Count); + for (int i = 0; i < list.Count; i++) + array.SetValue(Convert.ChangeType(list[i], targetType), i); + + return array; + } + } + + throw new NotImplementedException(); + } + + public override bool Equals(object obj) + { + return obj is DataTreeBranch branch && Equals(branch); + } + + public bool Equals(DataTreeBranch other) + { + return EqualityComparer.Default.Equals(Children, other.Children); + } + + public override int GetHashCode() + { + return HashCode.Combine(Children); + } + + public static bool operator ==(DataTreeBranch left, DataTreeBranch right) + { + return left.Equals(right); + } + + public static bool operator !=(DataTreeBranch left, DataTreeBranch right) + { + return !(left == right); + } + } +} \ No newline at end of file diff --git a/RDMSharp/Metadata/DataTreeObjectAttribute.cs b/RDMSharp/Metadata/DataTreeObjectAttribute.cs new file mode 100644 index 0000000..5f16cea --- /dev/null +++ b/RDMSharp/Metadata/DataTreeObjectAttribute.cs @@ -0,0 +1,17 @@ +using RDMSharp.Metadata.JSON; +using System; + +namespace RDMSharp.Metadata; + +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum, AllowMultiple = true)] +public class DataTreeObjectAttribute : Attribute +{ + public readonly ERDM_Parameter Parameter; + public readonly Command.ECommandDublicte Command; + + public DataTreeObjectAttribute(ERDM_Parameter parameter, Command.ECommandDublicte command) + { + Parameter = parameter; + Command = command; + } +} \ No newline at end of file diff --git a/RDMSharp/Metadata/DataTreeObjectConstructorAttribute.cs b/RDMSharp/Metadata/DataTreeObjectConstructorAttribute.cs new file mode 100644 index 0000000..55bc0ad --- /dev/null +++ b/RDMSharp/Metadata/DataTreeObjectConstructorAttribute.cs @@ -0,0 +1,11 @@ +using System; + +namespace RDMSharp.Metadata; + +[AttributeUsage(AttributeTargets.Constructor)] +public class DataTreeObjectConstructorAttribute : Attribute +{ + public DataTreeObjectConstructorAttribute() + { + } +} \ No newline at end of file diff --git a/RDMSharp/Metadata/DataTreeObjectParameterAttribute.cs b/RDMSharp/Metadata/DataTreeObjectParameterAttribute.cs new file mode 100644 index 0000000..12de6d9 --- /dev/null +++ b/RDMSharp/Metadata/DataTreeObjectParameterAttribute.cs @@ -0,0 +1,14 @@ +using System; + +namespace RDMSharp.Metadata; + +[AttributeUsage(AttributeTargets.Parameter)] +public class DataTreeObjectParameterAttribute : Attribute +{ + public readonly string Name; + + public DataTreeObjectParameterAttribute(string name) + { + Name = name; + } +} \ No newline at end of file diff --git a/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs b/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs index 542b17d..c3d58ac 100644 --- a/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs +++ b/RDMSharp/Metadata/JSON/OneOfTypes/ReferenceType.cs @@ -1,8 +1,6 @@ using RDMSharp.RDM; using System; -using System.Collections.Generic; using System.Text.Json.Serialization; -using System.Xml.Linq; namespace RDMSharp.Metadata.JSON.OneOfTypes { diff --git a/RDMSharp/Metadata/MetadataFactory.cs b/RDMSharp/Metadata/MetadataFactory.cs index bae4442..b91dc74 100644 --- a/RDMSharp/Metadata/MetadataFactory.cs +++ b/RDMSharp/Metadata/MetadataFactory.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Runtime.CompilerServices; using System.Text.Json; using System.Text.Json.Nodes; @@ -20,6 +21,7 @@ public static class MetadataFactory private static List metadataVersionList; private static Dictionary> metadataVersionDefinesBagDictionary; private static ConcurrentDictionary parameterBagDefineCache; + public static IReadOnlyCollection MetadataVersionList { get @@ -138,7 +140,7 @@ private static MetadataJSONObjectDefine getDefine(ParameterBag parameter) throw new DefineNotFoundException($"{parameter}"); } - internal static byte[] ParsePayloadToData(MetadataJSONObjectDefine define, Command.ECommandDublicte commandType, object payload) + internal static byte[] ParsePayloadToData(MetadataJSONObjectDefine define, Command.ECommandDublicte commandType, DataTreeBranch payload) { define.GetCommand(commandType, out Command? _command); if (_command is not Command command) @@ -147,10 +149,10 @@ internal static byte[] ParsePayloadToData(MetadataJSONObjectDefine define, Comma if (command.GetIsEmpty()) return new byte[0]; - if (payload is DataTree dataTree && command.SingleField.HasValue) + if (payload.Children.SingleOrDefault() is DataTree dataTree && command.SingleField.HasValue) return command.SingleField.Value.ParsePayloadToData(dataTree); - if (payload is DataTree[] dataTreeArray && command.ListOfFields.Length != 0) + if (payload.Children is DataTree[] dataTreeArray && command.ListOfFields.Length != 0) { if (dataTreeArray.Length != command.ListOfFields.Length) throw new IndexOutOfRangeException(); @@ -162,43 +164,73 @@ internal static byte[] ParsePayloadToData(MetadataJSONObjectDefine define, Comma throw new ArithmeticException(); } - internal static object ParseDataToPayload(MetadataJSONObjectDefine define, Command.ECommandDublicte commandType, byte[] data) + internal static DataTreeBranch ParseDataToPayload(MetadataJSONObjectDefine define, Command.ECommandDublicte commandType, byte[] data) { define.GetCommand(commandType, out Command? _command); if (_command is not Command command) throw new InvalidOperationException(); if (command.GetIsEmpty()) - return null; + return DataTreeBranch.Empty; if (command.SingleField.HasValue) - return command.SingleField.Value.ParseDataToPayload(ref data); + return new DataTreeBranch(define, commandType, command.SingleField.Value.ParseDataToPayload(ref data)); if (command.ListOfFields.Length != 0) { List tree = new List(); for (int i = 0; i < command.ListOfFields.Length; i++) tree.Add(command.ListOfFields[i].ParseDataToPayload(ref data)); - return tree.ToArray(); + return new DataTreeBranch(define, commandType, tree.ToArray()); } throw new ArithmeticException(); } - internal static byte[] GetRequestMessageData(ParameterBag parameter, object payloadData) + internal static byte[] GetRequestMessageData(ParameterBag parameter, DataTreeBranch payloadData) { return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicte.GetRequest, payloadData); } - internal static byte[] GetResponseMessageData(ParameterBag parameter, object payloadData) + internal static byte[] GetResponseMessageData(ParameterBag parameter, DataTreeBranch payloadData) { return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicte.GetResponse, payloadData); } - internal static byte[] SetRequestMessageData(ParameterBag parameter, object payloadData) + internal static byte[] SetRequestMessageData(ParameterBag parameter, DataTreeBranch payloadData) { return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicte.SetRequest, payloadData); } - internal static byte[] SetResponseMessageData(ParameterBag parameter, object payloadData) + internal static byte[] SetResponseMessageData(ParameterBag parameter, DataTreeBranch payloadData) { return ParsePayloadToData(GetDefine(parameter), Command.ECommandDublicte.SetResponse, payloadData); } + + private static List definedDataTreeObjects; + public static IReadOnlyCollection DefinedDataTreeObjects + { + get + { + fillDefinedDataTreeObjects(); + return definedDataTreeObjects; + } + } + + private static void fillDefinedDataTreeObjects() + { + if (definedDataTreeObjects != null) + return; + + definedDataTreeObjects = new List(); + + definedDataTreeObjects.AddRange(Tools.FindClassesWithAttribute()); + } + + public static Type GetDefinedDataTreeObjectType(MetadataJSONObjectDefine define, Command.ECommandDublicte commandType) + { + return DefinedDataTreeObjects.Where(t => + { + if (t.GetCustomAttributes().Any(attribute => (ushort)attribute.Parameter == define.PID && attribute.Command == commandType)) + return true; + return false; + }).FirstOrDefault(); + } } } diff --git a/RDMSharp/RDM/Enum/ERDM_DisplayInvert.cs b/RDMSharp/RDM/Enum/ERDM_DisplayInvert.cs index 2a58318..1303d45 100644 --- a/RDMSharp/RDM/Enum/ERDM_DisplayInvert.cs +++ b/RDMSharp/RDM/Enum/ERDM_DisplayInvert.cs @@ -1,5 +1,10 @@ -namespace RDMSharp +using RDMSharp.Metadata; +using RDMSharp.Metadata.JSON; + +namespace RDMSharp { + [DataTreeObject(ERDM_Parameter.DISPLAY_INVERT, Command.ECommandDublicte.GetResponse)] + [DataTreeObject(ERDM_Parameter.DISPLAY_INVERT, Command.ECommandDublicte.SetRequest)] public enum ERDM_DisplayInvert : byte { OFF = 0x00, diff --git a/RDMSharp/RDM/Enum/ERDM_Status.cs b/RDMSharp/RDM/Enum/ERDM_Status.cs index 0607316..53db912 100644 --- a/RDMSharp/RDM/Enum/ERDM_Status.cs +++ b/RDMSharp/RDM/Enum/ERDM_Status.cs @@ -1,5 +1,9 @@ -namespace RDMSharp +using RDMSharp.Metadata; +using RDMSharp.Metadata.JSON; + +namespace RDMSharp { + [DataTreeObject(ERDM_Parameter.STATUS_MESSAGES, Command.ECommandDublicte.GetRequest)] public enum ERDM_Status : byte { NONE = 0x00, diff --git a/RDMSharp/RDM/PayloadObject/RDMDMXPersonality.cs b/RDMSharp/RDM/PayloadObject/RDMDMXPersonality.cs index 01025b2..c558cdd 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDMXPersonality.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDMXPersonality.cs @@ -1,13 +1,17 @@ -using System; +using RDMSharp.Metadata; +using RDMSharp.Metadata.JSON; +using System; using System.Collections.Generic; namespace RDMSharp -{ +{ + [DataTreeObject(ERDM_Parameter.DMX_PERSONALITY, Command.ECommandDublicte.GetResponse)] public class RDMDMXPersonality : AbstractRDMPayloadObjectOneOf - { + { + [DataTreeObjectConstructor] public RDMDMXPersonality( - byte currentPersonality = 1, - byte ofPersonalities = 0) + [DataTreeObjectParameter("personality")] byte currentPersonality = 1, + [DataTreeObjectParameter("personality_count")] byte ofPersonalities = 0) { this.CurrentPersonality = currentPersonality; this.OfPersonalities = ofPersonalities; diff --git a/RDMSharp/RDM/PayloadObject/RDMDMXPersonalityDescription.cs b/RDMSharp/RDM/PayloadObject/RDMDMXPersonalityDescription.cs index 9b4c2e5..78c1168 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDMXPersonalityDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDMXPersonalityDescription.cs @@ -1,13 +1,17 @@ -using System.Collections.Generic; +using RDMSharp.Metadata; +using RDMSharp.Metadata.JSON; +using System.Collections.Generic; namespace RDMSharp -{ +{ + [DataTreeObject(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION, Command.ECommandDublicte.GetResponse)] public class RDMDMXPersonalityDescription : AbstractRDMPayloadObject, IRDMPayloadObjectIndex - { + { + [DataTreeObjectConstructor] public RDMDMXPersonalityDescription( - byte personalityId = 1, - ushort slots = 0, - string description = "") + [DataTreeObjectParameter("personality")] byte personalityId = 1, + [DataTreeObjectParameter("dmx_slots_required")] ushort slots = 0, + [DataTreeObjectParameter("description")] string description = "") { this.PersonalityId = personalityId; this.Slots = slots; diff --git a/RDMSharp/RDM/PayloadObject/RDMDeviceInfo.cs b/RDMSharp/RDM/PayloadObject/RDMDeviceInfo.cs index a720f27..4166f07 100644 --- a/RDMSharp/RDM/PayloadObject/RDMDeviceInfo.cs +++ b/RDMSharp/RDM/PayloadObject/RDMDeviceInfo.cs @@ -1,8 +1,11 @@ -using System.Collections.Generic; +using RDMSharp.Metadata; +using RDMSharp.Metadata.JSON; +using System.Collections.Generic; using System.Text; namespace RDMSharp { + [DataTreeObject(ERDM_Parameter.DEVICE_INFO, Command.ECommandDublicte.GetResponse)] public class RDMDeviceInfo : AbstractRDMPayloadObject { public RDMDeviceInfo( @@ -32,6 +35,33 @@ public RDMDeviceInfo( SubDeviceCount = subDeviceCount; SensorCount = sensorCount; } + [DataTreeObjectConstructor] + public RDMDeviceInfo( + [DataTreeObjectParameter("protocol_major")] byte rdmProtocolVersionMajor, + [DataTreeObjectParameter("protocol_minor")] byte rdmProtocolVersionMinor, + [DataTreeObjectParameter("device_model_id")] ushort deviceModelId, + [DataTreeObjectParameter("product_category")] ushort productCategory, + [DataTreeObjectParameter("software_version_id")] uint softwareVersionId, + [DataTreeObjectParameter("dmx_footprint")] ushort dmx512Footprint, + [DataTreeObjectParameter("current_personality")] byte dmx512CurrentPersonality, + [DataTreeObjectParameter("personality_count")] byte dmx512NumberOfPersonalities, + [DataTreeObjectParameter("dmx_start_address")] ushort dmx512StartAddress, + [DataTreeObjectParameter("sub_device_count")] ushort subDeviceCount, + [DataTreeObjectParameter("sensor_count")] byte sensorCount): + this(rdmProtocolVersionMajor, + rdmProtocolVersionMinor, + deviceModelId, + (ERDM_ProductCategoryCoarse)(byte)(productCategory >> 8), + (ERDM_ProductCategoryFine)productCategory, + softwareVersionId, + dmx512Footprint, + dmx512CurrentPersonality, + dmx512NumberOfPersonalities, + dmx512StartAddress, + subDeviceCount, + sensorCount) + { + } public byte RdmProtocolVersionMajor { get; private set; } public byte RdmProtocolVersionMinor { get; private set; } diff --git a/RDMSharp/RDM/PayloadObject/RDMSlotDescription.cs b/RDMSharp/RDM/PayloadObject/RDMSlotDescription.cs index 400da5a..73a7a25 100644 --- a/RDMSharp/RDM/PayloadObject/RDMSlotDescription.cs +++ b/RDMSharp/RDM/PayloadObject/RDMSlotDescription.cs @@ -1,12 +1,16 @@ -using System.Collections.Generic; +using RDMSharp.Metadata; +using RDMSharp.Metadata.JSON; +using System.Collections.Generic; namespace RDMSharp { + [DataTreeObject(ERDM_Parameter.SLOT_DESCRIPTION, Command.ECommandDublicte.GetResponse)] public class RDMSlotDescription : AbstractRDMPayloadObject { + [DataTreeObjectConstructor] public RDMSlotDescription( - ushort slotId = 0, - string description = "") + [DataTreeObjectParameter("slot")] ushort slotId = 0, + [DataTreeObjectParameter("description")] string description = "") { this.SlotId = slotId; diff --git a/RDMSharp/RDM/PeerToPeerProcess.cs b/RDMSharp/RDM/PeerToPeerProcess.cs index c390597..52d6734 100644 --- a/RDMSharp/RDM/PeerToPeerProcess.cs +++ b/RDMSharp/RDM/PeerToPeerProcess.cs @@ -19,15 +19,15 @@ internal enum EPeerToPeerProcessState public readonly UID UID; public readonly SubDevice SubDevice; public readonly ParameterBag ParameterBag; - public readonly object RequestPayloadObject; - public object ResponsePayloadObject { get; private set; } + public readonly DataTreeBranch RequestPayloadObject; + public DataTreeBranch ResponsePayloadObject { get; private set; } = DataTreeBranch.Unset; public MetadataJSONObjectDefine Define { get; private set; } public EPeerToPeerProcessState State { get; private set; } = EPeerToPeerProcessState.Waiting; private RDMMessage request = null; private RDMMessage response = null; - public PeerToPeerProcess(ERDM_Command command, UID uid, SubDevice subDevice, ParameterBag parameterBag, object payloadObject = null) + public PeerToPeerProcess(ERDM_Command command, UID uid, SubDevice subDevice, ParameterBag parameterBag, DataTreeBranch? payloadObject = null) { if (command != ERDM_Command.GET_COMMAND) if (command != ERDM_Command.SET_COMMAND) @@ -37,7 +37,7 @@ public PeerToPeerProcess(ERDM_Command command, UID uid, SubDevice subDevice, Par UID = uid; SubDevice = subDevice; ParameterBag = parameterBag; - RequestPayloadObject = payloadObject; + RequestPayloadObject = payloadObject ?? DataTreeBranch.Unset; Define = MetadataFactory.GetDefine(ParameterBag); } diff --git a/RDMSharp/RDM/Tools.cs b/RDMSharp/RDM/Tools.cs index 35ed6c8..a4b94dd 100644 --- a/RDMSharp/RDM/Tools.cs +++ b/RDMSharp/RDM/Tools.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Net; using System.Net.Sockets; +using System.Reflection; using System.Text; namespace RDMSharp @@ -82,6 +83,13 @@ public static TAttribute GetAttribute(this Enum value) .GetCustomAttributes(false) .OfType() .SingleOrDefault(); + } + public static List FindClassesWithAttribute() where TAttribute : Attribute + { + Assembly assembly = Assembly.GetExecutingAssembly(); + return assembly.GetTypes() + .Where(t => (t.IsClass || t.IsEnum) && t.GetCustomAttributes() != null) + .ToList(); } public static byte[] ValueToData(params bool[] bits) diff --git a/RDMSharpTests/Metadata/Parser/TestDefinedDataTreeObjects.cs b/RDMSharpTests/Metadata/Parser/TestDefinedDataTreeObjects.cs new file mode 100644 index 0000000..dab8421 --- /dev/null +++ b/RDMSharpTests/Metadata/Parser/TestDefinedDataTreeObjects.cs @@ -0,0 +1,168 @@ +using RDMSharp.Metadata; + +namespace RDMSharpTests.Metadata.Parser; + +public class TestDefinedDataTreeObjects +{ + [Test] + public async Task Test_DeviceInfo() + { + byte[] data = { + 0x01, 0x00, 0x00, 0x05, 0x06, 0x01, 0x02, 0x00, + 0x01, 0x01, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, + 0x00, 0x04, 0x00 + }; + + var parameterBag = new ParameterBag(ERDM_Parameter.DEVICE_INFO); + var define = MetadataFactory.GetDefine(parameterBag); + + var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicte.GetResponse, data); + + Assert.Multiple(() => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDeviceInfo))); + + var obj = dataTreeBranch.ParsedObject as RDMDeviceInfo; + Assert.That(obj.RdmProtocolVersionMajor, Is.EqualTo(1)); + Assert.That(obj.RdmProtocolVersionMinor, Is.EqualTo(0)); + Assert.That(obj.DeviceModelId, Is.EqualTo(0x0005)); + Assert.That(obj.ProductCategoryCoarse, Is.EqualTo(ERDM_ProductCategoryCoarse.POWER)); + Assert.That(obj.ProductCategoryFine, Is.EqualTo(ERDM_ProductCategoryFine.POWER_CONTROL)); + Assert.That(obj.SoftwareVersionId, Is.EqualTo(0x02000101)); + Assert.That(obj.Dmx512Footprint, Is.EqualTo(1)); + Assert.That(obj.Dmx512CurrentPersonality, Is.EqualTo(1)); + Assert.That(obj.Dmx512NumberOfPersonalities, Is.EqualTo(3)); + Assert.That(obj.Dmx512StartAddress, Is.EqualTo(1)); + Assert.That(obj.SubDeviceCount, Is.EqualTo(4)); + Assert.That(obj.SensorCount, Is.EqualTo(0)); + }); + } + + [Test] + public async Task Test_Personality() + { + byte[] data = { + 0x01, 0x03 + }; + + var parameterBag = new ParameterBag(ERDM_Parameter.DMX_PERSONALITY); + var define = MetadataFactory.GetDefine(parameterBag); + + var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicte.GetResponse, data); + + Assert.Multiple(() => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDMXPersonality))); + + var obj = dataTreeBranch.ParsedObject as RDMDMXPersonality; + Assert.That(obj.CurrentPersonality, Is.EqualTo(1)); + Assert.That(obj.OfPersonalities, Is.EqualTo(3)); + }); + } + + [Test] + public async Task Test_Personality_Description() + { + byte[] data = { + 0x01, 0x00, 0x01, 0x53, 0x45, 0x51, 0x55, 0x45, + 0x4e, 0x43, 0x45 + }; + + var parameterBag = new ParameterBag(ERDM_Parameter.DMX_PERSONALITY_DESCRIPTION); + var define = MetadataFactory.GetDefine(parameterBag); + + var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicte.GetResponse, data); + + Assert.Multiple(() => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMDMXPersonalityDescription))); + + var obj = dataTreeBranch.ParsedObject as RDMDMXPersonalityDescription; + Assert.That(obj.PersonalityId, Is.EqualTo(1)); + Assert.That(obj.Slots, Is.EqualTo(1)); + Assert.That(obj.Description, Is.EqualTo("SEQUENCE")); + }); + } + + [Test] + public async Task Test_Slot_Description() + { + byte[] data = { + 0x00, 0x00, 0x53, 0x41, 0x46, 0x45, 0x54, 0x59 + }; + + var parameterBag = new ParameterBag(ERDM_Parameter.SLOT_DESCRIPTION); + var define = MetadataFactory.GetDefine(parameterBag); + + var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicte.GetResponse, data); + + Assert.Multiple(() => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(RDMSlotDescription))); + + var obj = dataTreeBranch.ParsedObject as RDMSlotDescription; + Assert.That(obj.SlotId, Is.EqualTo(0)); + Assert.That(obj.Description, Is.EqualTo("SAFETY")); + }); + } + + [Test] + public async Task Test_Display_Invert() + { + byte[] data = { + 0x01 + }; + + var parameterBag = new ParameterBag(ERDM_Parameter.DISPLAY_INVERT); + var define = MetadataFactory.GetDefine(parameterBag); + + var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicte.SetRequest, data); + + Assert.Multiple(() => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_DisplayInvert))); + + var obj = (ERDM_DisplayInvert)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(ERDM_DisplayInvert.ON)); + }); + } + + [Test] + public async Task Test_Status_Messages() + { + byte[] data = { + 0x02 + }; + + var parameterBag = new ParameterBag(ERDM_Parameter.STATUS_MESSAGES); + var define = MetadataFactory.GetDefine(parameterBag); + + var dataTreeBranch = MetadataFactory.ParseDataToPayload(define, RDMSharp.Metadata.JSON.Command.ECommandDublicte.GetRequest, data); + + Assert.Multiple(() => + { + Assert.That(dataTreeBranch.IsUnset, Is.False); + Assert.That(dataTreeBranch.IsEmpty, Is.False); + Assert.That(dataTreeBranch.ParsedObject, Is.Not.Null); + Assert.That(dataTreeBranch.ParsedObject, Is.TypeOf(typeof(ERDM_Status))); + + var obj = (ERDM_Status)dataTreeBranch.ParsedObject; + Assert.That(obj, Is.EqualTo(ERDM_Status.ADVISORY)); + }); + } +} \ No newline at end of file diff --git a/RDMSharpTests/Metadata/TestMetadataFactoryStuff.cs b/RDMSharpTests/Metadata/TestMetadataFactoryStuff.cs index 4bfbfa0..c318669 100644 --- a/RDMSharpTests/Metadata/TestMetadataFactoryStuff.cs +++ b/RDMSharpTests/Metadata/TestMetadataFactoryStuff.cs @@ -15,16 +15,16 @@ public void Teardown() Console.OutputEncoding = System.Text.Encoding.Default; } - [Test] - public void TestMetadataFactory() - { - var schemas = MetadataFactory.GetMetadataSchemaVersions(); - Assert.That(schemas, Has.Count.EqualTo(1)); - var defines = MetadataFactory.GetMetadataDefineVersions(); - Assert.That(defines, Has.Count.EqualTo(122)); - foreach (var define in defines) - testString(define.ToString()); - } + //[Test] + //public void TestMetadataFactory() + //{ + // var schemas = MetadataFactory.GetMetadataSchemaVersions(); + // Assert.That(schemas, Has.Count.EqualTo(1)); + // var defines = MetadataFactory.GetMetadataDefineVersions(); + // Assert.That(defines, Has.Count.EqualTo(122)); + // foreach (var define in defines) + // testString(define.ToString()); + //} [Test] public void TestMetadataVersion() diff --git a/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs b/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs index 24bd898..b44dc51 100644 --- a/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs +++ b/RDMSharpTests/Metadata/TestPeerToPeerProcess.cs @@ -17,8 +17,8 @@ public async Task Test_Get_DMX_START_ADDRESS() Assert.That(peerToPeerProcess.Define, Is.Not.Null); Assert.That(peerToPeerProcess.State, Is.EqualTo(PeerToPeerProcess.EPeerToPeerProcessState.Waiting)); - Assert.That(peerToPeerProcess.RequestPayloadObject, Is.Null); - Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.Null); + Assert.That(peerToPeerProcess.RequestPayloadObject.IsUnset, Is.True); + Assert.That(peerToPeerProcess.ResponsePayloadObject.IsUnset, Is.True); AsyncRDMRequestHelper helper = null; helper = new AsyncRDMRequestHelper(sendMessage); @@ -27,8 +27,9 @@ public async Task Test_Get_DMX_START_ADDRESS() while (peerToPeerProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Running) await Task.Delay(100); - Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTree[]))); - Assert.That(((DataTree[])peerToPeerProcess.ResponsePayloadObject)[0].Value, Is.EqualTo(DMX_ADDRESS)); + Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTreeBranch))); + Assert.That(peerToPeerProcess.ResponsePayloadObject.Children[0].Value, Is.EqualTo(DMX_ADDRESS)); + Assert.That(peerToPeerProcess.ResponsePayloadObject.ParsedObject, Is.EqualTo(DMX_ADDRESS)); async Task sendMessage(RDMMessage message) { @@ -39,12 +40,12 @@ async Task sendMessage(RDMMessage message) RDMMessage response = new RDMMessage() { - Command= message.Command | ERDM_Command.RESPONSE, + Command = message.Command | ERDM_Command.RESPONSE, DestUID = message.SourceUID, SourceUID = message.DestUID, - Parameter= message.Parameter, - SubDevice= message.SubDevice, - ParameterData= MetadataFactory.GetResponseMessageData(parameterBag, new DataTree[] { new DataTree("dmx_address", 0, DMX_ADDRESS) }) + Parameter = message.Parameter, + SubDevice = message.SubDevice, + ParameterData = MetadataFactory.GetResponseMessageData(parameterBag, new DataTreeBranch(new DataTree[] { new DataTree("dmx_address", 0, DMX_ADDRESS) })) }; await Task.Delay(10); @@ -69,19 +70,20 @@ public async Task Test_Get_PROXIED_DEVICES() Assert.That(peerToPeerProcess.Define, Is.Not.Null); Assert.That(peerToPeerProcess.State, Is.EqualTo(PeerToPeerProcess.EPeerToPeerProcessState.Waiting)); - Assert.That(peerToPeerProcess.RequestPayloadObject, Is.Null); - Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.Null); + Assert.That(peerToPeerProcess.RequestPayloadObject.IsUnset, Is.True); + Assert.That(peerToPeerProcess.ResponsePayloadObject.IsUnset, Is.True); AsyncRDMRequestHelper helper = null; - byte[] parameterData = MetadataFactory.GetResponseMessageData(parameterBag, new DataTree[] { new DataTree("device_uids", 0, children: children) }); + byte[] parameterData = MetadataFactory.GetResponseMessageData(parameterBag, new DataTreeBranch(new DataTree[] { new DataTree("device_uids", 0, children: children) })); helper = new AsyncRDMRequestHelper(sendMessage); peerToPeerProcess.Run(helper); while (peerToPeerProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Running) await Task.Delay(100); - Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTree[]))); - Assert.That(((DataTree[])peerToPeerProcess.ResponsePayloadObject)[0].Children, Is.EqualTo(children)); + Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTreeBranch))); + Assert.That(peerToPeerProcess.ResponsePayloadObject.Children[0].Children, Is.EqualTo(children)); + Assert.That(peerToPeerProcess.ResponsePayloadObject.ParsedObject, Is.EqualTo(children.Select(dt => dt.Value).ToList())); async Task sendMessage(RDMMessage message) @@ -121,8 +123,8 @@ public async Task Test_Get_LAMP_STRIKES() Assert.That(peerToPeerProcess.Define, Is.Not.Null); Assert.That(peerToPeerProcess.State, Is.EqualTo(PeerToPeerProcess.EPeerToPeerProcessState.Waiting)); - Assert.That(peerToPeerProcess.RequestPayloadObject, Is.Null); - Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.Null); + Assert.That(peerToPeerProcess.RequestPayloadObject.IsUnset, Is.True); + Assert.That(peerToPeerProcess.ResponsePayloadObject.IsUnset, Is.True); AsyncRDMRequestHelper helper = null; byte count = 0; @@ -132,8 +134,9 @@ public async Task Test_Get_LAMP_STRIKES() while (peerToPeerProcess.State == PeerToPeerProcess.EPeerToPeerProcessState.Running) await Task.Delay(100); - Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTree[]))); - Assert.That(((DataTree[])peerToPeerProcess.ResponsePayloadObject)[0].Value, Is.EqualTo(LAMP_STRIKES)); + Assert.That(peerToPeerProcess.ResponsePayloadObject, Is.TypeOf(typeof(DataTreeBranch))); + Assert.That(peerToPeerProcess.ResponsePayloadObject.Children[0].Value, Is.EqualTo(LAMP_STRIKES)); + Assert.That(peerToPeerProcess.ResponsePayloadObject.ParsedObject, Is.EqualTo(LAMP_STRIKES)); async Task sendMessage(RDMMessage message) { @@ -153,7 +156,7 @@ async Task sendMessage(RDMMessage message) SourceUID = message.DestUID, Parameter = parameterBag.PID, SubDevice = message.SubDevice, - ParameterData = count == 0 ? new AcknowledgeTimer(TimeSpan.FromSeconds(3)).ToPayloadData() : MetadataFactory.GetResponseMessageData(parameterBag, new DataTree[] { new DataTree("strikes", 0, LAMP_STRIKES) }), + ParameterData = count == 0 ? new AcknowledgeTimer(TimeSpan.FromSeconds(3)).ToPayloadData() : MetadataFactory.GetResponseMessageData(parameterBag, new DataTreeBranch(new DataTree[] { new DataTree("strikes", 0, LAMP_STRIKES) })), PortID_or_Responsetype = count == 0 ? (byte)ERDM_ResponseType.ACK_TIMER : (byte)ERDM_ResponseType.ACK }; diff --git a/RDMSharpTests/RDMSharpTests.csproj b/RDMSharpTests/RDMSharpTests.csproj index e847399..81eccf2 100644 --- a/RDMSharpTests/RDMSharpTests.csproj +++ b/RDMSharpTests/RDMSharpTests.csproj @@ -49,8 +49,5 @@ - - -