Skip to content

Conversation

@SageCreations
Copy link
Member

fixed send_raw and send_raw_client issue.

@SageCreations SageCreations merged commit efa51b7 into main Feb 19, 2025
@AlbertShown
Copy link
Member

Thank you for the update. I think @DocQuantic mentioned that my send_raw suggestion did not work for him, but actually your suggestion is working. So, I guess send_raw() should be something like:

def send_raw(self, function: str, raw: any) -> None:
    """
    Safely send raw data to the UI for all clients.

    This function sends a raw data buffer to a JavaScript function in the UI.
    The JavaScript function should be capable of handling raw binary data.

    Args:
        function (str): The JavaScript function that will receive the raw data.
        data (raw): The raw data buffer.

    Raises:
        ValueError: If `data` is `None`.

    Returns:
        None

    Example:
        send_raw("myJavaScriptFunc", bytearray([0x0A, 0x0B, 0x0C]))
        # Sends 3 bytes of raw data to the JavaScript function `myJavaScriptFunc`.
        # myJavaScriptFunc(myUint8Array)
    """
    if raw is None:
        raise ValueError("Invalid pointer: Cannot send a null pointer.")
    _raw.webui_send_raw(
            c_size_t(self._window),
            c_char_p(function.encode("utf-8")),
            cast(raw, c_void_p),
            len(raw)
        )

@AlbertShown
Copy link
Member

Also, example send_raw_to_javascript sounds more informative than sending-raw as people can know what example do before digging inside.

@SageCreations
Copy link
Member Author

SageCreations commented Feb 19, 2025

@AlbertShown May have missed. I had similar issues with your implementation. The issue was that the memoryview buffer was not writable causing an error. I fixed it with an extra check. I confirmed it only seem to error out when normal bytes are passed in.

The function looks like this now:

    # -- send_raw -----------------------------------
    def send_raw(self, function: str, data: Union[bytes, bytearray, memoryview, array.array]) -> None:
        """
        Safely send raw data to the UI for all clients.

        This function sends a raw data buffer to a JavaScript function in the UI.
        The JavaScript function should be capable of handling raw binary data.

        Args:
            function (str): The JavaScript function that will receive the raw data.
            data (Union[bytes, bytearray, memoryview, array.array]): The raw data buffer.

        Raises:
            ValueError: If `data` is `None` or empty.

        Returns:
            None

        Example:
            my_window.send_raw("myJavaScriptFunc", bytearray([0x01, 0x0A, 0xFF]))
            # Sends 3 bytes of raw data to the JavaScript function `myJavaScriptFunc`.
        """
        if data is None or len(data) == 0:
            raise ValueError("Data must not be None or empty.")

        # Ensure data is a memoryview for uniformity
        if not isinstance(data, memoryview):
            data = memoryview(data)

        # Ensure that data is a writable copy to obtain void pointer,
        # from_buffer will throw error if the buffer passed in is not writable.
        if data.readonly:
            data = memoryview(bytearray(data))

        # Obtain a c_void_p pointer to the data buffer
        ptr = c_void_p(addressof(c_char.from_buffer(data)))

        # Determine the size of the data
        size = len(data)

        # Call the underlying function to send the data
        _raw.webui_send_raw(
            c_size_t(self._window),
            c_char_p(function.encode("utf-8")),
            ptr,
            c_size_t(size)
        )

this section here I added should fix the issue:

# Ensure that data is a writable copy to obtain void pointer,
# from_buffer will throw error if the buffer passed in is not writable.
if data.readonly:
    data = memoryview(bytearray(data))

And just to be sure, I tested @DocQuantic example that they posted and confirmed it work with this implementation of send_raw. I added the same fix to send_raw_client as well.

@SageCreations
Copy link
Member Author

SageCreations commented Feb 19, 2025

Also, example send_raw_to_javascript sounds more informative than sending-raw as people can know what example do before digging inside.

I'll change the directory to that. I agree, it makes more sense that way.

@AlbertShown
Copy link
Member

Sounds good then, thank you for the fix and improvement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants