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

ddlog.h: Functions to pass non-C strings to DDlog. #518

Merged
merged 1 commit into from Feb 12, 2020

Conversation

ryzhyk
Copy link
Contributor

@ryzhyk ryzhyk commented Feb 12, 2020

ddlog.h can be used when invoking ddlog from other programming
languages. Such languages - such as Go - may not be able to easily /
cheaply generate a null-terminated string from their own string type.

For example Go provides _GoStringPtr (https://golang.org/cmd/cgo/)
which gives access to the underlying byte array (should be treated as
immutable), but that array may not be null-terminated. Which means that
in order to call ddlog_string, one has to make a copy of the string
first (e.g. with CString) and ensure it is null terminated. Given that
ddlog makes its own copy of the string when building the record, we are
up to 2 copies.

This commit adds three functions that accept non-null-terminated
strings:

/*
 * Create a string value.
 *
 * `s` - points to the start of a UTF8 string.  The string does not have to be
 *       NULL-terminated.
 * `length` - length of string in bytes.
 *
 * This function copies `s` to an internal buffer, so the caller is responsible for
 * deallocating `s` if it was dynamically allocated.
 *
 * Returns `NULL` if `s` is not a valid UTF8 string.
 */
extern ddlog_record* ddlog_string_with_length(const char * s, size_t len);

/*
 * Same as `ddlog_struct()`, but passes constructor name as
 * non-null-terminated string represented by its start address and length in
 * bytes.
 */
extern ddlog_record* ddlog_struct_with_length(const char* constructor,
                                              size_t constructor_len,
                                              ddlog_record ** args,
                                              size_t len);

/*
 * Same as ddlog_struct_static_cons(), but passes constructor name as
 * non-null-terminated string represented by its start address and length in
 * bytes.
 */
extern ddlog_record* ddlog_struct_static_cons_with_length(
        const char *constructor,
        size_t constructor_len,
        ddlog_record **args, size_t args_len);

In addition, ddlog_get_str_with_length() was modified to return string length
along with pointer, which may be more convenient than calling
ddlog_get_strlen() in some cases.

Resolves #515.

`ddlog.h` can be used when invoking ddlog from other programming
languages. Such languages - such as Go - may not be able to easily /
cheaply generate a null-terminated string from their own string type.

For example Go provides `_GoStringPtr` (https://golang.org/cmd/cgo/)
which gives access to the underlying byte array (should be treated as
immutable), but that array may not be null-terminated. Which means that
in order to call `ddlog_string`, one has to make a copy of the string
first (e.g. with `CString`) and ensure it is null terminated. Given that
ddlog makes its own copy of the string when building the record, we are
up to 2 copies.

This commit adds three functions that accept non-null-terminated
strings:

```
/*
 * Create a string value.
 *
 * `s` - points to the start of a UTF8 string.  The string does not have to be
 *       NULL-terminated.
 * `length` - length of string in bytes.
 *
 * This function copies `s` to an internal buffer, so the caller is responsible for
 * deallocating `s` if it was dynamically allocated.
 *
 * Returns `NULL` if `s` is not a valid UTF8 string.
 */
extern ddlog_record* ddlog_string_with_length(const char * s, size_t len);

/*
 * Same as `ddlog_struct()`, but passes constructor name as
 * non-null-terminated string represented by its start address and length in
 * bytes.
 */
extern ddlog_record* ddlog_struct_with_length(const char* constructor,
                                              size_t constructor_len,
                                              ddlog_record ** args,
                                              size_t len);

/*
 * Same as ddlog_struct_static_cons(), but passes constructor name as
 * non-null-terminated string represented by its start address and length in
 * bytes.
 */
extern ddlog_record* ddlog_struct_static_cons_with_length(
        const char *constructor,
        size_t constructor_len,
        ddlog_record **args, size_t args_len);
```

In addition, `ddlog_get_str_with_length()` was modified to return string length
along with pointer, which may be more convenient than calling
`ddlog_get_strlen()` in some cases.

Resolves vmware#515.
Copy link
Member

@antoninbas antoninbas left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for making this change

@ryzhyk ryzhyk merged commit 49fed75 into vmware:master Feb 12, 2020
@ryzhyk ryzhyk deleted the strings_with_length branch February 12, 2020 22:25
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.

Support non-null terminated strings in ddlog's C API
2 participants