Skip to content

Commit

Permalink
feat(chatffi): better message metadata parsing (#5820)
Browse files Browse the repository at this point in the history
Description
---
- Change metadata adding to byte vectors from strings
- Adds Message Metadata byte vector reading
- Changes ptrs to uint for message paging params
- doc updates

Motivation and Context
---
Be able to parse metadata mo'betta

How Has This Been Tested?
---
CI

Breaking Changes
---

- [x] None
- [ ] Requires data directory on base node to be deleted
- [ ] Requires hard fork
- [ ] Other - Please specify
  • Loading branch information
brianp authored Sep 28, 2023
1 parent 468b4ce commit 9a43eab
Show file tree
Hide file tree
Showing 10 changed files with 448 additions and 48 deletions.
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

0 comments on commit 9a43eab

Please sign in to comment.