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

entry_to_string function implemented #465

Open
wants to merge 5 commits into
base: latest
Choose a base branch
from
Open
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
28 changes: 28 additions & 0 deletions include/stumpless/entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,34 @@ struct stumpless_entry {
# endif
};

/**
* Returns the entry as a formatted string.
* The character buffer should be freed when no longer is needed by the caller
* to avoid memory leaks.
*
* **Thread Safety: MT-Safe**
* This function is thread safe. A mutex is used to coordinate changes to the
* entry while it is being modified.
*
* **Async Signal Safety: AS-Unsafe lock heap**
* This function is not safe to call from signal handlers due to the use of a
* non-reentrant lock to coordinate changes and the use of memory management
* functions.
*
* **Async Cancel Safety: AC-Unsafe lock heap**
* This function is not safe to call from threads that may be asynchronously
* cancelled, due to the use of a lock that could be left locked as well as
* memory management functions.
*
* @param entry The entry whose string is returned.
*
* @return The string if no error was encountered. If an error is
* encountered, then NULL is returned and an error code is set appropriately.
*/
STUMPLESS_PUBLIC_FUNCTION
const char *
stumpless_entry_to_string ( const struct stumpless_entry *entry );

/**
* Adds an element to an entry. The element is appended to the end of the list
* of elements in this entry.
Expand Down
56 changes: 56 additions & 0 deletions src/entry.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* limitations under the License.
*/

#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
Expand Down Expand Up @@ -48,6 +49,61 @@

static struct cache *entry_cache = NULL;

const char *
stumpless_entry_to_string ( const struct stumpless_entry* entry ) {

VALIDATE_ARG_NOT_NULL ( entry );
lock_entry ( entry );

struct strbuilder* entry_string_strbuilder = strbuilder_new ();
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, "prival=\"", 8);
entry_string_strbuilder = strbuilder_append_positive_int(entry_string_strbuilder, entry->prival);
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, "\", ", 3);
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, "hostname=\"", 10);
if ( entry->hostname_length > 0 )
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, entry->hostname , entry->hostname_length);
else
entry_string_strbuilder = strbuilder_append_char(entry_string_strbuilder, '-');
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, "\", ", 3);
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, "app_name=\"", 10);
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, entry->app_name, entry->app_name_length );
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, "\", ", 3);
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, "procid=\"", 8);
if (entry -> procid_length > 0)
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, entry->procid , strlen( entry->procid ) );
else
entry_string_strbuilder = strbuilder_append_procid( entry_string_strbuilder );
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, "\", ", 3);
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, "msgid=\"", 7);
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, entry->msgid, entry->msgid_length);
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, "\", ", 3);

for (size_t element_index = 0; element_index < (entry -> element_count) ; element_index++)
{
const char* element_str = stumpless_element_to_string ( entry->elements[element_index] );
entry_string_strbuilder = strbuilder_append_buffer (entry_string_strbuilder, element_str, strlen(element_str));
entry_string_strbuilder = strbuilder_append_buffer (entry_string_strbuilder, ", ", 2);
free_mem ( element_str );
}

if ( entry->message != NULL )
{
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, "message=\"", 9);
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, entry->message, entry->message_length);
entry_string_strbuilder = strbuilder_append_buffer(entry_string_strbuilder, "\", ", 3);
}

const char* final_entry_string = strbuilder_to_string( entry_string_strbuilder );
strbuilder_destroy( entry_string_strbuilder );
unlock_entry ( entry );
clear_error(); //not sure about what this does
return final_entry_string;

fail:
unlock_entry ( entry );
return NULL; //Change this before commit
}

struct stumpless_entry *
stumpless_add_element( struct stumpless_entry *entry,
struct stumpless_element *element ) {
Expand Down
78 changes: 78 additions & 0 deletions test/function/entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,84 @@ namespace {
}
};

TEST_F( EntryTest, SimpleTestToString ) {
struct stumpless_entry *
stump_entry = stumpless_new_entry_str( STUMPLESS_FACILITY_USER,
STUMPLESS_SEVERITY_INFO,
basic_app_name,
basic_msgid,
basic_message );
const char* stump_as_str = stumpless_entry_to_string( stump_entry );
const char* basic_stump_str =
"prival=\"14\", hostname=\"\", app_name=\"basic-app-name\", procid=\"\", msgid=\"basic-msgid\", message=\"basic message\"";

EXPECT_STREQ(stump_as_str, basic_stump_str);
free ( (void *) stump_as_str );
stumpless_destroy_entry_and_contents( stump_entry );
}

TEST_F( EntryTest, ToStringAddOneElement ) {
struct stumpless_entry *
stump_entry = stumpless_new_entry_str( STUMPLESS_FACILITY_USER,
STUMPLESS_SEVERITY_INFO,
basic_app_name,
basic_msgid,
basic_message );
struct stumpless_element *
element = stumpless_new_element( "test-new-element" );
EXPECT_NO_ERROR;
ASSERT_NOT_NULL( element );

stump_entry = stumpless_add_element( stump_entry, element );

const char* stump_as_str = stumpless_entry_to_string( stump_entry );
const char* basic_stump_str =
"prival=\"14\", hostname=\"\", app_name=\"basic-app-name\", procid=\"\", msgid=\"basic-msgid\", test-new-element, message=\"basic message\"";

EXPECT_STREQ(stump_as_str, basic_stump_str);
free ( (void *) stump_as_str );
stumpless_destroy_entry_and_contents( stump_entry );
}

TEST_F( EntryTest, ToStringAddOneElementWithParams ) {
struct stumpless_entry *
stump_entry = stumpless_new_entry_str( STUMPLESS_FACILITY_USER,
STUMPLESS_SEVERITY_INFO,
basic_app_name,
basic_msgid,
basic_message );
struct stumpless_element *
element_with_params = stumpless_new_element( "element-with-params" );
EXPECT_NO_ERROR;
ASSERT_NOT_NULL( element_with_params );
struct stumpless_param *
param_1 = stumpless_new_param( "param1", "val1" );
struct stumpless_param *
param_2 = stumpless_new_param( "param2", "val2" );

stumpless_add_param( element_with_params, param_1 );
stumpless_add_param( element_with_params, param_2 );

stump_entry = stumpless_add_element( stump_entry, element_with_params );

const char* stump_as_str = stumpless_entry_to_string( stump_entry );
const char* basic_stump_str =
"prival=\"14\", hostname=\"\", app_name=\"basic-app-name\", procid=\"\", msgid=\"basic-msgid\", element-with-params=[param1=\"val1\",param2=\"val2\"], message=\"basic message\"";

EXPECT_STREQ(stump_as_str, basic_stump_str);
free ( (void *) stump_as_str );
stumpless_destroy_entry_and_contents( stump_entry );
}

TEST_F( EntryTest, NullEntryToString ) {
struct stumpless_entry *
stump_entry = NULL;
const char* stump_as_str = stumpless_entry_to_string( stump_entry );

EXPECT_ERROR_ID_EQ( STUMPLESS_ARGUMENT_EMPTY );
EXPECT_NULL(stump_as_str);
}

TEST_F( EntryTest, AddElement ) {
struct stumpless_entry *entry;
struct stumpless_element *element;
Expand Down
Loading