Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(chatffi): better message metadata parsing #5820

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 102 additions & 7 deletions base_layer/chat_ffi/chat.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ struct ChatByteVector;

struct ChatClientFFI;

struct ChatMessageMetadataVector;

struct ChatMessages;

struct Message;
Expand All @@ -35,6 +37,8 @@ struct ChatFFIMessage {
const char *from_address;
uint64_t stored_at;
const char *message_id;
struct ChatMessageMetadataVector metadata;
int metadata_len;
};

typedef void (*CallbackMessageReceived)(struct ChatFFIMessage*);
Expand Down Expand Up @@ -139,7 +143,11 @@ void add_chat_contact(struct ChatClientFFI *client, struct TariAddress *address,
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `()` - Does not return a value, equivalent to void in C
* `status` - Returns an int representing of the online status
* Online = 1,
* Offline = 2,
* NeverSeen = 3,
* Banned = 4,
*
* # Safety
* The ```address``` should be destroyed after use
Expand All @@ -165,18 +173,18 @@ struct Message *create_chat_message(struct TariAddress *receiver,
int *error_out);

/**
* Frees memory for messages
* Frees memory for message
*
* ## Arguments
* `messages_ptr` - The pointer of a Vec<Message>
* `messages_ptr` - The pointer of a Message
*
* ## Returns
* `()` - Does not return a value, equivalent to void in C
*
* # Safety
* None
*/
void destroy_chat_messages(struct ChatMessages *messages_ptr);
void destroy_chat_message(struct Message *messages_ptr);

/**
* Sends a message over a client
Expand Down Expand Up @@ -213,10 +221,24 @@ void send_chat_message(struct ChatClientFFI *client, struct Message *message, in
*/
struct ChatMessages *get_chat_messages(struct ChatClientFFI *client,
struct TariAddress *address,
int *limit,
int *page,
int limit,
int page,
int *error_out);

/**
* Frees memory for messages
*
* ## Arguments
* `ptr` - The pointer of a Message
*
* ## Returns
* `()` - Does not return a value, equivalent to void in C
*
* # Safety
* None
*/
void destroy_chat_messages(struct ChatMessages *ptr);

/**
* Creates message metadata and appends it to a Message
*
Expand All @@ -236,7 +258,7 @@ struct ChatMessages *get_chat_messages(struct ChatClientFFI *client,
*/
void add_chat_message_metadata(struct Message *message,
int metadata_type,
const char *data,
struct ChatByteVector *data,
int *error_out);

/**
Expand Down Expand Up @@ -338,6 +360,79 @@ void destroy_chat_ffi_liveness_data(struct ChatFFIContactsLivenessData *address)
*/
void destroy_chat_ffi_message(struct ChatFFIMessage *address);

/**
* Creates a ChatByteVector
*
* ## Arguments
* `byte_array` - The pointer to the byte array
* `element_count` - The number of elements in byte_array
* `error_out` - Pointer to an int which will be modified to an error code should one occur, may not be null. Functions
* as an out parameter.
*
* ## Returns
* `*mut ChatByteVector` - Pointer to the created ChatByteVector. Note that it will be ptr::null_mut()
* if the byte_array pointer was null or if the elements in the byte_vector don't match
* element_count when it is created
*
* # Safety
* The ```byte_vector_destroy``` function must be called when finished with a ChatByteVector to prevent a memory leak
*/
struct ChatByteVector *chat_byte_vector_create(const unsigned char *byte_array,
unsigned int element_count,
int *error_out);

/**
* Frees memory for a ChatByteVector
*
* ## Arguments
* `bytes` - The pointer to a ChatByteVector
*
* ## Returns
* `()` - Does not return a value, equivalent to void in C
*
* # Safety
* None
*/
void chat_byte_vector_destroy(struct ChatByteVector *bytes);

/**
* Gets a c_uchar at position in a ChatByteVector
*
* ## Arguments
* `ptr` - The pointer to a ChatByteVector
* `position` - The integer position
* `error_out` - Pointer to an int which will be modified to an error code should one occur, may not be null. Functions
* as an out parameter.
*
* ## Returns
* `c_uchar` - Returns a character. Note that the character will be a null terminator (0) if ptr
* is null or if the position is invalid
*
* # Safety
* None
*/
unsigned char chat_byte_vector_get_at(struct ChatByteVector *ptr,
unsigned int position,
int *error_out);

/**
* Gets the number of elements in a ChatByteVector
*
* ## Arguments
* `ptr` - The pointer to a ChatByteVector
* `error_out` - Pointer to an int which will be modified to an error code should one occur, may not be null. Functions
* as an out parameter.
*
* ## Returns
* `c_uint` - Returns the integer number of elements in the ChatByteVector. Note that it will be zero
* if ptr is null
*
* # Safety
* None
*/
unsigned int chat_byte_vector_get_length(const struct ChatByteVector *vec,
int *error_out);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
6 changes: 5 additions & 1 deletion base_layer/chat_ffi/src/contacts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,11 @@ pub unsafe extern "C" fn add_chat_contact(
/// `error_out` - Pointer to an int which will be modified
///
/// ## Returns
/// `()` - Does not return a value, equivalent to void in C
/// `status` - Returns an int representing of the online status
/// Online = 1,
/// Offline = 2,
/// NeverSeen = 3,
/// Banned = 4,
///
/// # Safety
/// The ```address``` should be destroyed after use
Expand Down
12 changes: 12 additions & 0 deletions base_layer/chat_ffi/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ pub enum InterfaceError {
TokioError(String),
#[error("Something about the argument is invalid: `{0}`")]
InvalidArgument(String),
#[error("An error has occurred when checking the length of the allocated object")]
AllocationError,
#[error("An error because the supplied position was out of range")]
PositionInvalidError,
}

/// This struct is meant to hold an error for use by FFI client applications. The error has an integer code and string
Expand All @@ -54,6 +58,14 @@ impl From<InterfaceError> for LibChatError {
code: 4,
message: format!("{:?}", v),
},
InterfaceError::AllocationError => Self {
code: 5,
message: format!("{:?}", v),
},
InterfaceError::PositionInvalidError => Self {
code: 6,
message: format!("{:?}", v),
},
InterfaceError::InvalidArgument(_) => Self {
code: 7,
message: format!("{:?}", v),
Expand Down
31 changes: 24 additions & 7 deletions base_layer/chat_ffi/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,18 @@ pub unsafe extern "C" fn create_chat_message(
Box::into_raw(Box::new(message_out))
}

/// Frees memory for messages
/// Frees memory for message
///
/// ## Arguments
/// `messages_ptr` - The pointer of a Vec<Message>
/// `messages_ptr` - The pointer of a Message
///
/// ## Returns
/// `()` - Does not return a value, equivalent to void in C
///
/// # Safety
/// None
#[no_mangle]
pub unsafe extern "C" fn destroy_chat_messages(messages_ptr: *mut ChatMessages) {
pub unsafe extern "C" fn destroy_chat_message(messages_ptr: *mut Message) {
if !messages_ptr.is_null() {
drop(Box::from_raw(messages_ptr))
}
Expand Down Expand Up @@ -147,8 +147,8 @@ pub unsafe extern "C" fn send_chat_message(client: *mut ChatClientFFI, message:
pub unsafe extern "C" fn get_chat_messages(
client: *mut ChatClientFFI,
address: *mut TariAddress,
limit: *mut c_int,
page: *mut c_int,
limit: c_int,
page: c_int,
error_out: *mut c_int,
) -> *mut ChatMessages {
let mut error = 0;
Expand All @@ -164,8 +164,8 @@ pub unsafe extern "C" fn get_chat_messages(
ptr::swap(error_out, &mut error as *mut c_int);
}

let mlimit = u64::try_from(*limit).unwrap_or(DEFAULT_MESSAGE_LIMIT);
let mpage = u64::try_from(*page).unwrap_or(DEFAULT_MESSAGE_PAGE);
let mlimit = u64::try_from(limit).unwrap_or(DEFAULT_MESSAGE_LIMIT);
let mpage = u64::try_from(page).unwrap_or(DEFAULT_MESSAGE_PAGE);

let mut messages = Vec::new();

Expand All @@ -176,3 +176,20 @@ pub unsafe extern "C" fn get_chat_messages(

Box::into_raw(Box::new(ChatMessages(messages)))
}

/// Frees memory for messages
///
/// ## Arguments
/// `ptr` - The pointer of a Message
///
/// ## Returns
/// `()` - Does not return a value, equivalent to void in C
///
/// # Safety
/// None
#[no_mangle]
pub unsafe extern "C" fn destroy_chat_messages(ptr: *mut ChatMessages) {
if !ptr.is_null() {
drop(Box::from_raw(ptr))
}
}
Loading