diff --git a/src/char_stream_req/char_stream_req.cpp b/src/char_stream_req/char_stream_req.cpp new file mode 100644 index 0000000..32b781d --- /dev/null +++ b/src/char_stream_req/char_stream_req.cpp @@ -0,0 +1,55 @@ +/* + * char_stream_req.cpp + * + * Created on: Nov 14, 2014 + * Author: edwardh + */ + +#include + +#include "char_stream_req.h" + + +CharStreamReq::CharStreamReq() +{ + this->max_num_of_unique_chars = (unsigned char)~0 + 1; + this->char_occurrence_count = new unsigned int[max_num_of_unique_chars]; + + clearRecv(); +} + +CharStreamReq::~CharStreamReq() +{ + delete []this->char_occurrence_count; +} + + +void CharStreamReq::recv(unsigned char in_char) +{ + char_occurrence_count[in_char]++; +} + + +void CharStreamReq::printRecvSorted(char *outbuffer, size_t buf_size) +{ + size_t char_out_itr = 0; + + for(unsigned int char_in_itr = 0; char_in_itr < max_num_of_unique_chars; ++char_in_itr) + { + int num_of_chars_to_output = char_occurrence_count[char_in_itr]; + for(int duplicate_char_out_itr = 0; + (duplicate_char_out_itr < num_of_chars_to_output) && (char_out_itr < buf_size-1); + ++duplicate_char_out_itr) + { + outbuffer[char_out_itr] = char_in_itr; + char_out_itr++; + } + } + + outbuffer[char_out_itr] = '\0'; +} + +void CharStreamReq::clearRecv() +{ + std::memset(this->char_occurrence_count, 0 ,max_num_of_unique_chars * sizeof(*char_occurrence_count)); +} diff --git a/src/char_stream_req/char_stream_req.h b/src/char_stream_req/char_stream_req.h new file mode 100644 index 0000000..5a03014 --- /dev/null +++ b/src/char_stream_req/char_stream_req.h @@ -0,0 +1,40 @@ +/* + * char_stream_req.h + * + * Description: + * Receive a stream of characters (ASCII), accumulate them and + * provide the means to output them in an acceding sorted manner. + * + * Limitations: + * - Sorted based on the ASCII table, no special care has been done to handle upper and lower characters. + * - It can accumulate between 2^(sizeof(int)) to 256 * (2^(sizeof(int))) characters. + * + * Note: It is up to the application that uses this module to specify how many characters to recv + * until a print is performed, followed by a clear to reset the data. + * + * + * Created on: Nov 14, 2014 + * Author: edwardh + */ + +#ifndef CHAR_STREAM_REQ_H_ +#define CHAR_STREAM_REQ_H_ + + +class CharStreamReq +{ +public: + CharStreamReq(); + ~CharStreamReq(); + + void recv(unsigned char in_char); + void printRecvSorted(char *outbuffer, size_t buf_size); + void clearRecv(); + +private: + unsigned int *char_occurrence_count; + unsigned int max_num_of_unique_chars; +}; + + +#endif /* CHAR_STREAM_REQ_H_ */ diff --git a/unit_tester/build/mk_common/utest_config_production_path.mk b/unit_tester/build/mk_common/utest_config_production_path.mk index d23f027..9a18c2e 100755 --- a/unit_tester/build/mk_common/utest_config_production_path.mk +++ b/unit_tester/build/mk_common/utest_config_production_path.mk @@ -1,16 +1,18 @@ -# -# -# - -# When all source files in a folder are under tests, it is prefered to add the folder instead of adding individual source files. -SRC_DIRS = \ - $(PRODUCTION_SOURCES)/llist -# - -SRC_FILES = \ -# $(PRODUCTION_SOURCES)/source_file.cpp -# - -INCLUDE_DIRS +=\ - $(PRODUCTION_SOURCES)/ +# +# +# + +# When all source files in a folder are under tests, it is prefered to add the folder instead of adding individual source files. +SRC_DIRS = \ + $(PRODUCTION_SOURCES)/llist\ + $(PRODUCTION_SOURCES)/char_stream_req\ +# + +SRC_FILES = \ +# $(PRODUCTION_SOURCES)/source_file.cpp +# + +INCLUDE_DIRS +=\ + $(PRODUCTION_SOURCES)/\ + $(PRODUCTION_SOURCES)/char_stream_req\ # \ No newline at end of file diff --git a/unit_tester/build/mk_common/utest_config_test_path.mk b/unit_tester/build/mk_common/utest_config_test_path.mk index 6fa1005..be9bf9e 100755 --- a/unit_tester/build/mk_common/utest_config_test_path.mk +++ b/unit_tester/build/mk_common/utest_config_test_path.mk @@ -1,19 +1,20 @@ -# -# -# - -INCLUDE_DIRS =\ - .\ - $(TEST_ROOT)/helpers/include\ - $(TEST_ROOT)/mocks/include\ - /usr/include\ - $(CPPUTEST_HOME)/include\ - -TEST_SRC_DIRS = \ - $(TEST_ROOT)/helpers/src\ - $(TEST_ROOT)/tests\ - $(TEST_ROOT)/tests/llist_test\ -# - -MOCKS_SRC_DIRS =\ +# +# +# + +INCLUDE_DIRS =\ + .\ + $(TEST_ROOT)/helpers/include\ + $(TEST_ROOT)/mocks/include\ + /usr/include\ + $(CPPUTEST_HOME)/include\ + +TEST_SRC_DIRS = \ + $(TEST_ROOT)/helpers/src\ + $(TEST_ROOT)/tests\ + $(TEST_ROOT)/tests/llist_test\ + $(TEST_ROOT)/tests/char_stream_req_test\ +# + +MOCKS_SRC_DIRS =\ $(TEST_ROOT)/mocks/src\ \ No newline at end of file diff --git a/unit_tester/tests/char_stream_req_test/char_stream_req_test.cpp b/unit_tester/tests/char_stream_req_test/char_stream_req_test.cpp new file mode 100644 index 0000000..f94782e --- /dev/null +++ b/unit_tester/tests/char_stream_req_test/char_stream_req_test.cpp @@ -0,0 +1,98 @@ +/* + * char_stream_req_test.cpp + * + * Created on: Nov 14, 2014 + * Author: edwardh + */ + +#include "CppUTest/TestHarness.h" + +#include "char_stream_req.h" + + +TEST_GROUP(char_stream_req) +{ + static const int bulk_size = 100000; + + void setup() + { + } + + void teardown() + { + } +}; + +TEST(char_stream_req, unique_input_alphanumeric) +{ + + const char *cstream_in = "abc123"; + const char *cstream_expected = "123abc"; + char cstream_out[bulk_size]; + + CharStreamReq csr; + + for(char *ch_itr = (char*)cstream_in; (*ch_itr != '\0'); ++ch_itr) + csr.recv(*ch_itr); + + csr.printRecvSorted(cstream_out, bulk_size); + + STRCMP_EQUAL(cstream_expected, cstream_out); +} + +TEST(char_stream_req, non_unique_input_alphanumeric) +{ + + const char *cstream_in = "abbc13b213"; + const char *cstream_expected = "11233abbbc"; + char cstream_out[bulk_size]; + + CharStreamReq csr; + + for(char *ch_itr = (char*)cstream_in; (*ch_itr != '\0'); ++ch_itr) + csr.recv(*ch_itr); + + csr.printRecvSorted(cstream_out, bulk_size); + + STRCMP_EQUAL(cstream_expected, cstream_out); +} + +/* + * Current implementation assumes that the output is sorted based on the + * ASCII table (For alphanumeric: Numbers, Upper chars and lastly Lower chars. + */ +TEST(char_stream_req, non_unique_input_alphanumeric_w_low_and_up_chars) +{ + + const char *cstream_in = "abBc13Ab213"; + const char *cstream_expected = "11233ABabbc"; + char cstream_out[bulk_size]; + + CharStreamReq csr; + + for(char *ch_itr = (char*)cstream_in; (*ch_itr != '\0'); ++ch_itr) + csr.recv(*ch_itr); + + csr.printRecvSorted(cstream_out, bulk_size); + + STRCMP_EQUAL(cstream_expected, cstream_out); +} + +TEST(char_stream_req, input_larger_than_outbuffer__output_only_4_chars) +{ + + const char *cstream_in = "a1b3c2"; + const char *cstream_expected = "123"; + + const int small_bulk_size = 4; + char cstream_out[small_bulk_size]; + + CharStreamReq csr; + + for(char *ch_itr = (char*)cstream_in; (*ch_itr != '\0'); ++ch_itr) + csr.recv(*ch_itr); + + csr.printRecvSorted(cstream_out, small_bulk_size); + + STRCMP_EQUAL(cstream_expected, cstream_out); +}