/* Tests the libcsplit_wide_string_split function * Returns 1 if successful or 0 if not */ int csplit_test_wide_string_split( void ) { libcerror_error_t *error = NULL; libcsplit_wide_split_string_t *split_string = NULL; int result = 0; /* Test regular cases */ result = libcsplit_wide_string_split( L"1 2 3 4 5", 10, (wchar_t) ' ', &split_string, &error ); CSPLIT_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); CSPLIT_TEST_ASSERT_IS_NOT_NULL( "split_string", split_string ); CSPLIT_TEST_ASSERT_IS_NULL( "error", error ); result = libcsplit_wide_split_string_free( &split_string, &error ); CSPLIT_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); CSPLIT_TEST_ASSERT_IS_NULL( "split_string", split_string ); CSPLIT_TEST_ASSERT_IS_NULL( "error", error ); /* Test string that does not need splitting */ result = libcsplit_wide_string_split( L"1 2 3 4 5", 10, (wchar_t) '\n', &split_string, &error ); CSPLIT_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); CSPLIT_TEST_ASSERT_IS_NOT_NULL( "split_string", split_string ); CSPLIT_TEST_ASSERT_IS_NULL( "error", error ); result = libcsplit_wide_split_string_free( &split_string, &error ); CSPLIT_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); CSPLIT_TEST_ASSERT_IS_NULL( "split_string", split_string ); CSPLIT_TEST_ASSERT_IS_NULL( "error", error ); /* Test empty string */ result = libcsplit_wide_string_split( L"", 1, (wchar_t) ' ', &split_string, &error ); CSPLIT_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); CSPLIT_TEST_ASSERT_IS_NULL( "split_string", split_string ); CSPLIT_TEST_ASSERT_IS_NULL( "error", error ); result = libcsplit_wide_string_split( L"1 2 3 4 5", 0, (wchar_t) ' ', &split_string, &error ); CSPLIT_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); CSPLIT_TEST_ASSERT_IS_NULL( "split_string", split_string ); CSPLIT_TEST_ASSERT_IS_NULL( "error", error ); /* Test error cases */ result = libcsplit_wide_string_split( NULL, 10, (wchar_t) ' ', &split_string, &error ); CSPLIT_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); CSPLIT_TEST_ASSERT_IS_NULL( "split_string", split_string ); CSPLIT_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); split_string = (libcsplit_wide_split_string_t *) 0x12345678UL; result = libcsplit_wide_string_split( L"1 2 3 4 5", 10, (wchar_t) ' ', &split_string, &error ); CSPLIT_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); CSPLIT_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); split_string = NULL; result = libcsplit_wide_string_split( L"1 2 3 4 5", (size_t) SSIZE_MAX + 1, (wchar_t) ' ', &split_string, &error ); CSPLIT_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); CSPLIT_TEST_ASSERT_IS_NULL( "split_string", split_string ); CSPLIT_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); result = libcsplit_wide_string_split( L"1 2 3 4 5", 10, (wchar_t) ' ', NULL, &error ); CSPLIT_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); CSPLIT_TEST_ASSERT_IS_NULL( "split_string", split_string ); CSPLIT_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); #if defined( HAVE_CSPLIT_TEST_MEMORY ) /* Test csplit_test_wide_string_split with malloc failing in libcsplit_wide_split_string_initialize */ csplit_test_malloc_attempts_before_fail = 0; result = libcsplit_wide_string_split( L"1 2 3 4 5", 10, (wchar_t) ' ', &split_string, &error ); if( csplit_test_malloc_attempts_before_fail != -1 ) { csplit_test_malloc_attempts_before_fail = -1; if( split_string != NULL ) { libcsplit_wide_split_string_free( &split_string, NULL ); } } else { CSPLIT_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); CSPLIT_TEST_ASSERT_IS_NULL( "split_string", split_string ); CSPLIT_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); } #endif /* defined( HAVE_CSPLIT_TEST_MEMORY ) */ return( 1 ); on_error: if( error != NULL ) { libcerror_error_free( &error ); } return( 0 ); }
/* Splits a wide character string * Returns 1 if successful or -1 on error */ int libcsplit_wide_string_split( const wchar_t *string, size_t string_size, wchar_t delimiter, libcsplit_wide_split_string_t **split_string, libcerror_error_t **error ) { wchar_t *segment_start = NULL; wchar_t *segment_end = NULL; wchar_t *string_end = NULL; static char *function = "libcsplit_wide_string_split"; ssize_t segment_length = 0; int number_of_segments = 0; int segment_index = 0; if( string == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid string.", function ); return( -1 ); } if( string_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid string size value exceeds maximum.", function ); return( -1 ); } if( split_string == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid split string.", function ); return( -1 ); } if( *split_string != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid split string already set.", function ); return( -1 ); } /* An empty string has no segments */ if( ( string_size == 0 ) || ( string[ 0 ] == 0 ) ) { return( 1 ); } /* Determine the number of segments */ segment_start = (wchar_t *) string; string_end = (wchar_t *) &( string[ string_size - 1 ] ); do { segment_end = segment_start; while( segment_end <= string_end ) { if( ( segment_end == string_end ) || ( *segment_end == 0 ) ) { segment_end = NULL; break; } else if( *segment_end == delimiter ) { break; } segment_end++; } if( segment_end > string_end ) { break; } segment_index++; if( segment_end == NULL ) { break; } if( segment_end == segment_start ) { segment_start++; } else if( segment_end != string ) { segment_start = segment_end + 1; } } while( segment_end != NULL ); number_of_segments = segment_index; if( libcsplit_wide_split_string_initialize( split_string, string, string_size, number_of_segments, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to intialize split string.", function ); goto on_error; } if( *split_string == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing split string.", function ); goto on_error; } /* Do not bother splitting empty strings */ if( number_of_segments == 0 ) { return( 1 ); } /* Determine the segments * empty segments are stored as strings only containing the end of character */ if( libcsplit_wide_split_string_get_string( *split_string, &segment_start, &string_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve split string.", function ); goto on_error; } if( segment_start == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing segment start.", function ); goto on_error; } if( string_size < 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid string size value out of bounds.", function ); goto on_error; } segment_end = segment_start; string_end = &( segment_start[ string_size - 1 ] ); for( segment_index = 0; segment_index < number_of_segments; segment_index++ ) { segment_end = segment_start; while( segment_end <= string_end ) { if( ( segment_end == string_end ) || ( *segment_end == 0 ) ) { segment_end = NULL; break; } else if( *segment_end == delimiter ) { break; } segment_end++; } if( segment_end == NULL ) { segment_length = (ssize_t) ( string_end - segment_start ); } else { segment_length = (ssize_t) ( segment_end - segment_start ); } if( segment_length >= 0 ) { segment_start[ segment_length ] = 0; if( libcsplit_wide_split_string_set_segment_by_index( *split_string, segment_index, segment_start, segment_length + 1, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set split string segment: %d.", function, segment_index ); goto on_error; } } if( segment_end == NULL ) { break; } if( segment_end == ( (libcsplit_internal_wide_split_string_t *) *split_string )->string ) { segment_start++; } if( segment_end != ( (libcsplit_internal_wide_split_string_t *) *split_string )->string ) { segment_start = segment_end + 1; } } return( 1 ); on_error: if( *split_string != NULL ) { libcsplit_wide_split_string_free( split_string, NULL ); } return( -1 ); }