Skip to content

Introduce functions to read the values in the fst file. - #3

Open
strau0106 wants to merge 1 commit into
MaxXSoft:masterfrom
strau0106:master
Open

Introduce functions to read the values in the fst file.#3
strau0106 wants to merge 1 commit into
MaxXSoft:masterfrom
strau0106:master

Conversation

@strau0106

Copy link
Copy Markdown

This pull request introduces two functions to read the values of the opened fst file. The first just returns the value at a given time and the second gets the value, as soon as it changed.

Comment thread fstapi/src/reader.rs
/// If the variable is not found, returns `None`.
/// If the value is not found, returns `None`.
pub fn get_value_from_handle_at_time(&mut self, time: u64, handle: Handle) -> Option<String> {
let mut buf = vec![0; 1024]; // Allocate a buffer for the value

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The length of this buffer should be the length of the signal corresponding to the handle, rather than hardcoded, otherwise there is a risk of buffer overflow.

I checked the fstapi code, it seems that the signal lengths are stored in an array in the memory pointed to by the reader context, but there is no such API to read them, and unfortunately the memory layout of the context is opaque.

It would be better to add an API called fstReaderGetSignalLength to fstapi.c and fstapi.h, that returns xc->signal_lens[handle], and uses the the return value as the length to initialize the buffer.

Comment thread fstapi/src/reader.rs
capi::fstReaderGetValueFromHandleAtTime(self.ctx, time, handle.into(), buf.as_mut_ptr())
};

let value_str = unsafe { std::ffi::CStr::from_ptr(result as *const raw::c_char).to_str().ok()? };

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • The result should be checked, since fstReaderGetValueFromHandleAtTime may return a null pointer.
  • The return type of this method should be Box<[u8]> instead of String, to be consistent with the writer API of this Rust crate.

Comment thread fstapi/src/reader.rs
};

let value_str = unsafe { std::ffi::CStr::from_ptr(result as *const raw::c_char).to_str().ok()? };
return Some(value_str.to_owned());

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use return at the end of the function, just use the expression without the trailing semicolon.

Comment thread fstapi/src/reader.rs
///
/// If the variable is not found, returns `None`.
/// If the value is not found, returns `None`.
pub fn get_value_from_handle_at_time(&mut self, time: u64, handle: Handle) -> Option<String> {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method could have been named something simpler, like value_at_time.

Comment thread fstapi/src/reader.rs
}

/// Finds the next time at which a variable changes after a given time.
pub fn get_next_time_change(&mut self, start_time: u64, handle: Handle) -> Result<u64> {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name of this method could be find_next_time_change.

Comment thread fstapi/src/reader.rs
let mut time_table_len = 0;
let mut last_time = 0;

self.for_each_block(|time, current_handle, _val, _| {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.for_each_block(|time, current_handle, _val, _| {
self.for_each_block(|time, current_handle, _, _| {

Comment thread fstapi/src/reader.rs
Comment on lines +263 to +266
if time >= start_time && current_handle == handle {
time_table.push(time);
time_table_len += 1;
}

@MaxXSoft MaxXSoft Nov 19, 2024

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both time_table and time_table_len can be removed, since you only want to get the first time that meets the condition.

Try to define a variable let mut first_time = None; and rewrite with:

Suggested change
if time >= start_time && current_handle == handle {
time_table.push(time);
time_table_len += 1;
}
if first_time.is_none() && time >= start_time && current_handle == handle {
first_time = Some(time);
}

@MaxXSoft

Copy link
Copy Markdown
Owner

Thanks for your contribution!

I've added some comments to your changes, please check.

@strau0106

strau0106 commented Nov 19, 2024

Copy link
Copy Markdown
Author

Hi, thanks for your quick response and feeback. My first time doing things in rust...

Do you think it would make sense to PR GTKWave for the getFstReaderSignalLength, instead of branching in this repo?

I will update the small rust changes in the coming days.

@MaxXSoft

Copy link
Copy Markdown
Owner

Do you think it would make sense to PR GTKWave for the getFstReaderSignalLength, instead of branching in this repo?

Actually the fstapi in this repo is already a modified version, lol. In order to make the Rust binding work faster and more straightforward, I have modified some APIs and added some new. So feel free to change fstapi.c in this repo.

And IMO it's not make sense to add fstReaderGetSignalLength to GTKWave, the signal_lens array is not intended to be read by user most of the time, although user may want to read it to make the call of fstReaderGetValueFromHandleAtTime safer.

So the point is that fstReaderGetValueFromHandleAtTime should provide a safer interface than it currently does, like:

int fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx, char *buf, size_t buf_len);

Or allocate memory of sufficient length within the API:

char *fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx);

@strau0106

Copy link
Copy Markdown
Author

Ok, I will make the changes here then.

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.

2 participants