1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
/**
* See aws/testing/compression/huffman.h for docs.
*/
#define AWS_UNSTABLE_TESTING_API
#include <aws/compression/private/huffman_testing.h>
#include <aws/common/byte_buf.h>
#include <aws/common/common.h>
int huffman_test_transitive(
struct aws_huffman_symbol_coder *coder,
const char *input,
size_t size,
size_t encoded_size,
const char **error_string) {
struct aws_huffman_encoder encoder;
aws_huffman_encoder_init(&encoder, coder);
struct aws_huffman_decoder decoder;
aws_huffman_decoder_init(&decoder, coder);
const size_t intermediate_buffer_size = size * 2;
AWS_VARIABLE_LENGTH_ARRAY(uint8_t, intermediate_buffer, intermediate_buffer_size);
memset(intermediate_buffer, 0, intermediate_buffer_size);
AWS_VARIABLE_LENGTH_ARRAY(char, output_buffer, size);
memset(output_buffer, 0, size);
struct aws_byte_cursor to_encode = aws_byte_cursor_from_array((uint8_t *)input, size);
struct aws_byte_buf intermediate_buf = aws_byte_buf_from_empty_array(intermediate_buffer, intermediate_buffer_size);
struct aws_byte_buf output_buf = aws_byte_buf_from_empty_array(output_buffer, size);
int result = aws_huffman_encode(&encoder, &to_encode, &intermediate_buf);
if (result != AWS_OP_SUCCESS) {
*error_string = "aws_huffman_encode failed";
return AWS_OP_ERR;
}
if (to_encode.len != 0) {
*error_string = "not all data encoded";
return AWS_OP_ERR;
}
if (encoded_size && intermediate_buf.len != encoded_size) {
*error_string = "encoded length is incorrect";
return AWS_OP_ERR;
}
struct aws_byte_cursor intermediate_cur = aws_byte_cursor_from_buf(&intermediate_buf);
result = aws_huffman_decode(&decoder, &intermediate_cur, &output_buf);
if (result != AWS_OP_SUCCESS) {
*error_string = "aws_huffman_decode failed";
return AWS_OP_ERR;
}
if (intermediate_cur.len != 0) {
*error_string = "not all encoded data was decoded";
return AWS_OP_ERR;
}
if (output_buf.len != size) {
*error_string = "decode output size incorrect";
return AWS_OP_ERR;
}
if (memcmp(input, output_buffer, size) != 0) {
*error_string = "decoded data does not match input data";
return AWS_OP_ERR;
}
return AWS_OP_SUCCESS;
}
int huffman_test_transitive_chunked(
struct aws_huffman_symbol_coder *coder,
const char *input,
size_t size,
size_t encoded_size,
size_t output_chunk_size,
const char **error_string) {
struct aws_huffman_encoder encoder;
aws_huffman_encoder_init(&encoder, coder);
struct aws_huffman_decoder decoder;
aws_huffman_decoder_init(&decoder, coder);
const size_t intermediate_buffer_size = size * 2;
AWS_VARIABLE_LENGTH_ARRAY(uint8_t, intermediate_buffer, intermediate_buffer_size);
memset(intermediate_buffer, 0, intermediate_buffer_size);
AWS_VARIABLE_LENGTH_ARRAY(char, output_buffer, size);
memset(output_buffer, 0, size);
struct aws_byte_cursor to_encode = aws_byte_cursor_from_array(input, size);
struct aws_byte_buf intermediate_buf = aws_byte_buf_from_empty_array(intermediate_buffer, (size_t)-1);
intermediate_buf.capacity = 0;
struct aws_byte_buf output_buf = aws_byte_buf_from_empty_array(output_buffer, (size_t)-1);
output_buf.capacity = 0;
int result = AWS_OP_SUCCESS;
{
do {
const size_t previous_intermediate_len = intermediate_buf.len;
intermediate_buf.capacity += output_chunk_size;
result = aws_huffman_encode(&encoder, &to_encode, &intermediate_buf);
if (intermediate_buf.len == previous_intermediate_len) {
*error_string = "encode didn't write any data";
return AWS_OP_ERR;
}
if (result != AWS_OP_SUCCESS && aws_last_error() != AWS_ERROR_SHORT_BUFFER) {
*error_string = "encode returned wrong error code";
return AWS_OP_ERR;
}
} while (result != AWS_OP_SUCCESS);
}
if (result != AWS_OP_SUCCESS) {
*error_string = "aws_huffman_encode failed";
return AWS_OP_ERR;
}
if (intermediate_buf.len > intermediate_buffer_size) {
*error_string = "too much data encoded";
return AWS_OP_ERR;
}
if (encoded_size && intermediate_buf.len != encoded_size) {
*error_string = "encoded length is incorrect";
return AWS_OP_ERR;
}
struct aws_byte_cursor intermediate_cur = aws_byte_cursor_from_buf(&intermediate_buf);
{
do {
const size_t previous_output_len = output_buf.len;
output_buf.capacity += output_chunk_size;
if (output_buf.capacity > size) {
output_buf.capacity = size;
}
result = aws_huffman_decode(&decoder, &intermediate_cur, &output_buf);
if (output_buf.len == previous_output_len) {
*error_string = "decode didn't write any data";
return AWS_OP_ERR;
}
if (result != AWS_OP_SUCCESS && aws_last_error() != AWS_ERROR_SHORT_BUFFER) {
*error_string = "decode returned wrong error code";
return AWS_OP_ERR;
}
} while (result != AWS_OP_SUCCESS);
}
if (result != AWS_OP_SUCCESS) {
*error_string = "aws_huffman_decode failed";
return AWS_OP_ERR;
}
if (output_buf.len != size) {
*error_string = "decode output size incorrect";
return AWS_OP_ERR;
}
if (memcmp(input, output_buffer, size) != 0) {
*error_string = "decoded data does not match input data";
return AWS_OP_ERR;
}
return AWS_OP_SUCCESS;
}
|