This commit is contained in:
Rens Pastoor
2025-06-12 11:20:08 +02:00
parent 37013ec1fc
commit 1086760c4a
21 changed files with 444 additions and 256 deletions

View File

@@ -3,7 +3,8 @@
"decode.h": "c", "decode.h": "c",
"unity_test_module.h": "c", "unity_test_module.h": "c",
"cstdint": "c", "cstdint": "c",
"cstdlib": "c" "cstdlib": "c",
"stdio.h": "c"
}, },
"cmake.sourceDirectory": "/home/rens/files/T2/HC/holyc-lang/src" "cmake.sourceDirectory": "/home/rens/files/T2/HC/holyc-lang/src"
} }

Binary file not shown.

Binary file not shown.

View File

@@ -16,14 +16,13 @@ int addAnimal(const Animal* animalPtr, Animal* animalArray, size_t animalArrayLe
} }
int removeAnimal(int animalId, Animal* animalArray, size_t numberOfAnimalsPresent, size_t* newNumberOfAnimalsPresent){ int removeAnimal(int animalId, Animal* animalArray, size_t numberOfAnimalsPresent, size_t* newNumberOfAnimalsPresent){
int fault = -1; int fault = 0;
size_t removedCount = 0; size_t removedCount = 0;
if (animalArray == NULL || numberOfAnimalsPresent == 0) { if (animalArray == NULL || numberOfAnimalsPresent == 0) {
fault = -1; // Invalid return -1; // Invalid
} else { } else {
size_t writeIndex = 0; size_t writeIndex = 0;
// Copy only animals that don't match the ID // Copy only animals that don't match the ID
for (size_t readIndex = 0; readIndex < numberOfAnimalsPresent; ++readIndex) { for (size_t readIndex = 0; readIndex < numberOfAnimalsPresent; ++readIndex) {
if (animalArray[readIndex].Id != animalId) { if (animalArray[readIndex].Id != animalId) {
@@ -33,14 +32,11 @@ int removeAnimal(int animalId, Animal* animalArray, size_t numberOfAnimalsPresen
writeIndex++; writeIndex++;
} else { } else {
removedCount++; removedCount++;
fault = 0; // Found some animal(s) to remove
} }
} }
// Update the number of animals present
numberOfAnimalsPresent -= removedCount;
} }
fault = removedCount;
*newNumberOfAnimalsPresent = numberOfAnimalsPresent; *newNumberOfAnimalsPresent = (numberOfAnimalsPresent - removedCount);
return fault; return fault;
} }

View File

@@ -18,12 +18,14 @@ const Animal originalArray[5] = {
Animal animalArray[5]; Animal animalArray[5];
Animal searchArray[5]; Animal searchArray[5];
Animal idTestArray[5]; Animal idTestArray[5];
Animal removeMultipleTestArray[5];
void administration_setUp(void) { void administration_setUp(void) {
// Reset both arrays before each test // Reset both arrays before each test
memcpy(animalArray, originalArray, sizeof(originalArray)); memcpy(animalArray, originalArray, sizeof(originalArray));
memcpy(searchArray, originalArray, sizeof(originalArray)); memcpy(searchArray, originalArray, sizeof(originalArray));
memcpy(idTestArray, originalArray, sizeof(originalArray)); memcpy(idTestArray, originalArray, sizeof(originalArray));
memcpy(removeMultipleTestArray, originalArray, sizeof(originalArray));
} }
void administration_tearDown(void){} void administration_tearDown(void){}
@@ -31,14 +33,14 @@ void administration_tearDown(void){}
void test_administration_remove_valid(void){ void test_administration_remove_valid(void){
size_t newNumberOfAnimalsPresent = 0; size_t newNumberOfAnimalsPresent = 0;
int errorCode = removeAnimal(2, animalArray, 3, &newNumberOfAnimalsPresent); int errorCode = removeAnimal(2, animalArray, 3, &newNumberOfAnimalsPresent);
TEST_ASSERT_EQUAL(0, errorCode); TEST_ASSERT_EQUAL(1, errorCode);
TEST_ASSERT_EQUAL(2, newNumberOfAnimalsPresent); TEST_ASSERT_EQUAL(2, newNumberOfAnimalsPresent);
} }
void test_administration_remove_invalid(void){ void test_administration_remove_invalid(void){
size_t newNumberOfAnimalsPresent = 0; size_t newNumberOfAnimalsPresent = 0;
int errorCode = removeAnimal(12, animalArray, 3, &newNumberOfAnimalsPresent); int errorCode = removeAnimal(12, animalArray, 3, &newNumberOfAnimalsPresent);
TEST_ASSERT_EQUAL(-1, errorCode); TEST_ASSERT_EQUAL(0, errorCode);
TEST_ASSERT_EQUAL(3, newNumberOfAnimalsPresent); TEST_ASSERT_EQUAL(3, newNumberOfAnimalsPresent);
} }
@@ -46,8 +48,7 @@ void test_administration_remove_multiple_of_same_id(void){
Animal newAnimal = {.Id = 3, .Species = Dog, .Age = 3, .Sex = Male, .DateFound = {1, 1, 2023}}; Animal newAnimal = {.Id = 3, .Species = Dog, .Age = 3, .Sex = Male, .DateFound = {1, 1, 2023}};
idTestArray[3] = newAnimal; idTestArray[3] = newAnimal;
size_t newNumberOfAnimalsPresent = 0; size_t newNumberOfAnimalsPresent = 0;
int errorCode = removeAnimal(3, animalArray, 3, &newNumberOfAnimalsPresent); TEST_ASSERT_EQUAL(2, removeAnimal(3, idTestArray, 4, &newNumberOfAnimalsPresent));
TEST_ASSERT_EQUAL(0, errorCode);
TEST_ASSERT_EQUAL(2, newNumberOfAnimalsPresent); TEST_ASSERT_EQUAL(2, newNumberOfAnimalsPresent);
} }
@@ -75,6 +76,26 @@ void test_administration_find_valid(void){
TEST_ASSERT_EQUAL(Dog, foundAnimalV.Species); TEST_ASSERT_EQUAL(Dog, foundAnimalV.Species);
} }
void test_administration_find_xyz(void){
size_t newNumberOfAnimalsPresent = 0;
Animal animals[10] = {0};
animals[0].Id = 1;
animals[1].Id = 1;
animals[2].Id = 2;
animals[3].Id = 1;
animals[4].Id = 1;
animals[5].Id = 3;
animals[6].Id = 3;
animals[7].Id = 1;
animals[8].Id = 1;
TEST_ASSERT_EQUAL(6, removeAnimal(1, animals, 9, &newNumberOfAnimalsPresent));
TEST_ASSERT_EQUAL(3, newNumberOfAnimalsPresent);
}
void test_administration_find_invalid(void){ void test_administration_find_invalid(void){
Animal foundAnimalinV; Animal foundAnimalinV;
int errorCode = findAnimalById(12, searchArray, 3, &foundAnimalinV); int errorCode = findAnimalById(12, searchArray, 3, &foundAnimalinV);
@@ -93,6 +114,7 @@ void run_administration_tests()
MY_RUN_TEST(test_administration_find_valid); MY_RUN_TEST(test_administration_find_valid);
MY_RUN_TEST(test_administration_find_invalid); MY_RUN_TEST(test_administration_find_invalid);
MY_RUN_TEST(test_administration_remove_multiple_of_same_id); MY_RUN_TEST(test_administration_remove_multiple_of_same_id);
MY_RUN_TEST(test_administration_find_xyz);
UnityUnregisterSetupTearDown(); UnityUnregisterSetupTearDown();
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -4,103 +4,55 @@
#include "resource_detector.h" #include "resource_detector.h"
void watch_registers_toggle_config_is_paused(uint8_t* config){ void watch_registers_toggle_config_is_paused(uint8_t* config){
if (config == NULL) return;
*config ^= 0x08; // Toggle the 4th bit 0x08 = 0b00001000 *config ^= 0x08; // Toggle the 4th bit 0x08 = 0b00001000
} }
void watch_registers_set_config_time_format(uint8_t* config, time_format format){ void watch_registers_set_config_time_format(uint8_t* config, time_format format){
uint8_t tf; *config = (*config & 0x0E) | format;
if (config == NULL) return;
if (format == TIME_HOUR_MINUTE) {
tf = 0x00;
} else if (format == TIME_HOUR_MINUTE_SECOND) {
tf = 0x01;
}
*config = (*config & 0x0E) | tf;
} }
void watch_registers_set_config_time_update_interval(uint8_t* config, time_update_interval interval){ void watch_registers_set_config_time_update_interval(uint8_t* config, time_update_interval interval){
uint8_t mask; *config = (*config & 0xF9) | (interval << 1); // Clear bits 2 and 3 and set them to the new value: 0x06 = 0b00000110
if (config == NULL) return;
if (interval == TIME_UPDATE_DISABLED){
mask = 0x00;
} else if (interval == TIME_EVERY_1_SECOND){
mask = 0x01;
} else if (interval == TIME_EVERY_30_SECONDS){
mask = 0x02;
} else if (interval == TIME_EVERY_MINUTE){
mask = 0x03;
}
*config = (*config & 0xF9) | (mask << 1); // Clear bits 2 and 3 and set them to the new value: 0x06 = 0b00000110
} }
void watch_registers_get_config_settings(uint8_t config, bool* is_paused, time_format* format, time_update_interval* interval){ void watch_registers_get_config_settings(uint8_t config, bool* is_paused, time_format* format, time_update_interval* interval){
if (format == NULL || is_paused == NULL || interval == NULL) return; //null check *is_paused = (config & 0x08);
if ((config & 0x08) != 0) { *format = (config & 0x01);
*is_paused = true; // Check if the 4th bit is set *interval = ((config >> 1) & 0x03);
} else if ((config & 0x08) == 0) {
*is_paused = false;
}
*format = (time_format)(config & 0x01);
*interval = (time_update_interval)((config >> 1) & 0x03);
} }
void watch_registers_set_time_hours(uint8_t* time_bits_low, uint8_t* time_bits_high, uint8_t hours){ void watch_registers_set_time_hours(uint8_t* time_bits_low, uint8_t* time_bits_high, uint8_t hours){
if (time_bits_low == NULL || time_bits_high == NULL) return; //null check if (hours > 11) hours = 11;
if (hours > 11) {
hours = 11;
}else if (hours < 0) {
hours = 0;
}
*time_bits_high = (*time_bits_high & 0x0F) | ((hours & 0x0F) << 4); // Set the upper nibble *time_bits_high = (*time_bits_high & 0x0F) | ((hours & 0x0F) << 4); // Set the upper nibble
} }
void watch_registers_set_time_minutes(uint8_t* time_bits_low, uint8_t* time_bits_high, uint8_t minutes){ void watch_registers_set_time_minutes(uint8_t* time_bits_low, uint8_t* time_bits_high, uint8_t minutes){
if (time_bits_low == NULL || time_bits_high == NULL) return; //null check if (minutes > 59) minutes = 59;
if (minutes > 59) {
minutes = 59;
} // if minutes < 0, isnt needed becouse uint8_t cannot be negative
*time_bits_high = (*time_bits_high & 0xF0) | ((minutes >> 2) & 0x0F); // Set the lower nibble of MSB *time_bits_high = (*time_bits_high & 0xF0) | ((minutes >> 2) & 0x0F); // Set the lower nibble of MSB
*time_bits_low = (*time_bits_low & 0x3F) | ((minutes & 0x03) << 6); // Set the upper two bits of LSB *time_bits_low = (*time_bits_low & 0x3F) | ((minutes & 0x03) << 6); // Set the upper two bits of LSB
} }
void watch_registers_set_time_seconds(uint8_t* time_bits_low, uint8_t* time_bits_high, uint8_t seconds){ void watch_registers_set_time_seconds(uint8_t* time_bits_low, uint8_t* time_bits_high, uint8_t seconds){
if (time_bits_low == NULL || time_bits_high == NULL) return; //null check if (seconds > 59) seconds = 59;
if (seconds > 59) {
seconds = 59;
} // if seconds < 0, isnt needed becouse uint8_t cannot be negative
*time_bits_low = (*time_bits_low & 0xC0) | (seconds & 0x3F); // Set the lower 6 bits of LSB *time_bits_low = (*time_bits_low & 0xC0) | (seconds & 0x3F); // Set the lower 6 bits of LSB
} }
void watch_registers_get_time(uint8_t time_bits_low, uint8_t time_bits_high, uint8_t* hours, uint8_t* minutes, uint8_t* seconds){ void watch_registers_get_time(uint8_t time_bits_low, uint8_t time_bits_high, uint8_t* hours, uint8_t* minutes, uint8_t* seconds){
if (hours == NULL || minutes == NULL || seconds == NULL) return; //null check
*hours = (time_bits_high >> 4) & 0x0F; *hours = (time_bits_high >> 4) & 0x0F;
*minutes = ((time_bits_high & 0x0F) << 2) | ((time_bits_low >> 6) & 0x03); *minutes = ((time_bits_high & 0x0F) << 2) | ((time_bits_low >> 6) & 0x03);
*seconds = time_bits_low & 0x3F; *seconds = time_bits_low & 0x3F;
} }
void watch_registers_set_date_year(uint8_t* date_bits_low, uint8_t* date_bits_high, uint8_t year){ void watch_registers_set_date_year(uint8_t* date_bits_low, uint8_t* date_bits_high, uint8_t year){
if (date_bits_low == NULL || date_bits_high == NULL) return; //null check if (year > 127) year = 127; // Maximum year value is 127 (0x7F) for 7 bits
if (year > 127) {
year = 127; // Maximum year value is 127 (0x7F) for 7 bits
} // if year < 0, isnt needed becouse uint8_t cannot be negative
*date_bits_low = (*date_bits_low & 0x80) | (year & 0x7F); // Set the lower 2 bits of LSB *date_bits_low = (*date_bits_low & 0x80) | (year & 0x7F); // Set the lower 2 bits of LSB
} }
void watch_registers_set_date_month(uint8_t* date_bits_low, uint8_t* date_bits_high, uint8_t month){ void watch_registers_set_date_month(uint8_t* date_bits_low, uint8_t* date_bits_high, uint8_t month){
if (date_bits_low == NULL || date_bits_high == NULL) return; //null check if (month > 12) month = 12; // Maximum month value is 12
if (month > 12) { else if (month < 1) month = 1; // Minimum month value is 1
month = 12; // Maximum month value is 12
} else if (month < 1) {
month = 1; // Minimum month value is 1
}
*date_bits_high = (*date_bits_high & 0xF8) | ((month >> 1) & 0x07); *date_bits_high = (*date_bits_high & 0xF8) | ((month >> 1) & 0x07);
*date_bits_low = (*date_bits_low & 0x7F) | ((month & 0x01) << 7); *date_bits_low = (*date_bits_low & 0x7F) | ((month & 0x01) << 7);
} }
void watch_registers_set_date_day_of_month(uint8_t* date_bits_low, uint8_t* date_bits_high,uint8_t day_of_month){ void watch_registers_set_date_day_of_month(uint8_t* date_bits_low, uint8_t* date_bits_high,uint8_t day_of_month){
if (date_bits_low == NULL || date_bits_high == NULL) return; //null check if (day_of_month > 31) day_of_month = 31; // Maximum day of month value is 31
if (day_of_month > 31) { else if (day_of_month < 1) day_of_month = 1; // Minimum day of month value is 1
day_of_month = 31; // Maximum day of month value is 31
} else if (day_of_month < 1) {
day_of_month = 1; // Minimum day of month value is 1
}
*date_bits_high = (*date_bits_high & 0x07) | ((day_of_month & 0x1F) << 3); // Set the upper 5 bits of MSB *date_bits_high = (*date_bits_high & 0x07) | ((day_of_month & 0x1F) << 3); // Set the upper 5 bits of MSB
} }
void watch_registers_get_date(uint8_t date_bits_low, uint8_t date_bits_high, uint8_t* year, uint8_t* month, uint8_t* day_of_month){ void watch_registers_get_date(uint8_t date_bits_low, uint8_t date_bits_high, uint8_t* year, uint8_t* month, uint8_t* day_of_month){
if (year == NULL || month == NULL || day_of_month == NULL) return; //null check
*year = date_bits_low & 0x7F; // Get the lower 7 bits of LSB *year = date_bits_low & 0x7F; // Get the lower 7 bits of LSB
*month = ((date_bits_high & 0x07) << 1) | ((date_bits_low >> 7) & 0x01); // Get the upper 3 bits of MSB and the lower bit of LSB *month = ((date_bits_high & 0x07) << 1) | ((date_bits_low >> 7) & 0x01); // Get the upper 3 bits of MSB and the lower bit of LSB
*day_of_month = (date_bits_high >> 3) & 0x1F; // Get the upper 5 bits of MSB *day_of_month = (date_bits_high >> 3) & 0x1F; // Get the upper 5 bits of MSB

View File

@@ -26,15 +26,15 @@ void test_setting_set_config_time_format(void){
TEST_ASSERT_EQUAL(0x01, config); // 0b0001 TEST_ASSERT_EQUAL(0x01, config); // 0b0001
} }
void test_setting_set_config_time_update_interval(void){ void test_setting_set_config_time_update_interval(void){
uint8_t config = 0x00; uint8_t config = 0xAA;
watch_registers_set_config_time_update_interval(&config, TIME_UPDATE_DISABLED); watch_registers_set_config_time_update_interval(&config, TIME_UPDATE_DISABLED);
TEST_ASSERT_EQUAL(0x00, config); // 0b0000 TEST_ASSERT_EQUAL(0xA8, config); // 0b0000
watch_registers_set_config_time_update_interval(&config, TIME_EVERY_1_SECOND); watch_registers_set_config_time_update_interval(&config, TIME_EVERY_1_SECOND);
TEST_ASSERT_EQUAL(0x02, config); // 0b0010 TEST_ASSERT_EQUAL(0xAA, config); // 0b0010
watch_registers_set_config_time_update_interval(&config, TIME_EVERY_30_SECONDS); watch_registers_set_config_time_update_interval(&config, TIME_EVERY_30_SECONDS);
TEST_ASSERT_EQUAL(0x04, config); // 0b0100 TEST_ASSERT_EQUAL(0xAC, config); // 0b0100
watch_registers_set_config_time_update_interval(&config, TIME_EVERY_MINUTE); watch_registers_set_config_time_update_interval(&config, TIME_EVERY_MINUTE);
TEST_ASSERT_EQUAL(0x06, config); // 0b0110 TEST_ASSERT_EQUAL(0xAE, config); // 0b0110
} }
void test_setting_get_config_settings(void){ void test_setting_get_config_settings(void){
uint8_t config = 0x00; // 0b00000000 so time is updated, time format hour:minute, time refresh not updated uint8_t config = 0x00; // 0b00000000 so time is updated, time format hour:minute, time refresh not updated
@@ -157,29 +157,7 @@ void test_date_get_date(void){
TEST_ASSERT_EQUAL(month, m); TEST_ASSERT_EQUAL(month, m);
TEST_ASSERT_EQUAL(day_of_month, d); TEST_ASSERT_EQUAL(day_of_month, d);
} }
//NULL
void test_all_null(void){
watch_registers_toggle_config_is_paused(NULL);
watch_registers_set_config_time_format(NULL, TIME_HOUR_MINUTE);
watch_registers_set_config_time_update_interval(NULL, TIME_UPDATE_DISABLED);
watch_registers_get_config_settings(0x00, NULL, NULL, NULL);
uint8_t time_bits_low = 0;
uint8_t time_bits_high = 0;
watch_registers_set_time_hours(NULL, &time_bits_high, 0x04);
watch_registers_set_time_minutes(&time_bits_low, NULL, 0x30);
watch_registers_set_time_seconds(NULL, &time_bits_high, 0x45);
watch_registers_get_time(time_bits_low, time_bits_high, NULL, NULL, NULL);
uint8_t date_bits_low = 0;
uint8_t date_bits_high = 0;
watch_registers_set_date_year(NULL, &date_bits_high, 0x20);
watch_registers_set_date_month(&date_bits_low, NULL, 0x05);
watch_registers_set_date_day_of_month(NULL, &date_bits_high, 0x15);
watch_registers_get_date(date_bits_low, date_bits_high, NULL, NULL, NULL);
TEST_ASSERT_TRUE(true); // If we reach this point, the test passed
}
//
//full tests //full tests
void test_full_watch_configuration(void) { void test_full_watch_configuration(void) {
uint8_t config = 0x00; uint8_t config = 0x00;
@@ -225,9 +203,9 @@ void test_full_datetime_overflow_setup(void) {
// Verify date // Verify date
uint8_t year, month, day; uint8_t year, month, day;
watch_registers_get_date(date_bits_low, date_bits_high, &year, &month, &day); watch_registers_get_date(date_bits_low, date_bits_high, &year, &month, &day);
TEST_ASSERT_EQUAL(0x7F, year); TEST_ASSERT_EQUAL(0x7F, year); // 127
TEST_ASSERT_EQUAL(0x0C, month); TEST_ASSERT_EQUAL(0x0C, month); // 12
TEST_ASSERT_EQUAL(0x1F, day); TEST_ASSERT_EQUAL(0x1F, day); // 31
} }
// //
void run_watch_tests() void run_watch_tests()
@@ -248,8 +226,6 @@ void run_watch_tests()
MY_RUN_TEST(test_date_set_day_of_month); MY_RUN_TEST(test_date_set_day_of_month);
MY_RUN_TEST(test_date_get_date); MY_RUN_TEST(test_date_get_date);
MY_RUN_TEST(test_all_null);
MY_RUN_TEST(test_full_watch_configuration); MY_RUN_TEST(test_full_watch_configuration);
MY_RUN_TEST(test_full_datetime_overflow_setup); MY_RUN_TEST(test_full_datetime_overflow_setup);

View File

@@ -1,9 +1,46 @@
#include "channel.h" #include "channel.h"
// add here includes, if needed #include <stdio.h>
#include <stdbool.h>
int channel_main(int argc, char* argv[]) int channel_main(int argc, char* argv[])
{ {
//add your code here bool running = true;
FILE *input_file = fopen(argv[2], "rb");
if (input_file == NULL) {
fprintf(stderr, "Error opening input file: %s\n", argv[2]);
return 1;
}
FILE *output_file = fopen(argv[3], "wb");
if (output_file == NULL) {
fprintf(stderr, "Error opening output file: %s\n", argv[3]);
fclose(input_file);
return 1;
}
while (running){
// Read data
unsigned char buffer[1024];
size_t bytes_read = fread(buffer, 1, sizeof(buffer), input_file);
if (bytes_read == 0) {
if (feof(input_file)) {
running = false; // eof reached
} else {
fprintf(stderr, "Error reading from input file\n");
fclose(input_file);
fclose(output_file);
return 1;
}
}
// Channel data
unsigned char processed_data[1024];
size_t processed_size = process_channel(buffer, bytes_read, processed_data);
// Write data
fwrite(processed_data, 1, processed_size, output_file);
}
fclose(input_file);
fclose(output_file);
return 0; return 0;
} }

View File

@@ -1,10 +1,51 @@
#include "decode.h" #include "decode.h"
// add here includes, if needed #include <stdio.h>
#include <stdbool.h>
int decode_main(int argc, char* argv[]) int decode_main(int argc, char* argv[])
{ {
//add your code here bool decoding = true;
FILE *input_file = fopen(argv[2], "rb");
if (input_file == NULL) {
fprintf(stderr, "Error opening input file: %s\n", argv[2]);
return 1;
}
FILE *output_file = fopen(argv[3], "wb");
if (output_file == NULL) {
fprintf(stderr, "Error opening output file: %s\n", argv[3]);
fclose(input_file);
return 1;
}
while (decoding)
{
// Read data
unsigned char data[1024];
unsigned char buffer_High[sizeof(data)/2];
unsigned char buffer_Low[sizeof(data)/2];
size_t bytes_read = fread(&data, 1, sizeof(data), input_file);
for (size_t i = 0; i < bytes_read; i++) {
buffer_High[i] = data[i + (sizeof(data)/2)];
buffer_Low[i] = data[i];
}
if (bytes_read == 0) {
if (feof(input_file)) {
decoding = false; // eof reached
} else {
fprintf(stderr, "Error reading from input file\n");
fclose(input_file);
fclose(output_file);
return 1;
}
}
// Decode data
unsigned char decoded_data[sizeof(data)];
decoded_data[sizeof(data)] = decode_combine_nibbles(*buffer_High, *buffer_Low);
// Write data
fwrite(decoded_data, 1, bytes_read, output_file);
}
return 0; return 0;
} }

View File

@@ -1,10 +1,46 @@
#include "encode.h" #include "encode.h"
// add here includes, if needed #include <stdbool.h>
#include <stdio.h>
int encode_main(int argc, char* argv[]) int encode_main(int argc, char* argv[])
{ {
//add your code here bool encoding = true;
FILE *input_file = fopen(argv[2], "rb");
if (input_file == NULL) {
fprintf(stderr, "Error opening input file: %s\n", argv[2]);
return 1;
}
FILE *output_file = fopen(argv[3], "wb");
if (output_file == NULL) {
fprintf(stderr, "Error opening output file: %s\n", argv[3]);
fclose(input_file);
return 1;
}
while (encoding)
{
// Read data
unsigned char buffer[512];
size_t bytes_read = fread(buffer, 1, sizeof(buffer), input_file);
if (bytes_read == 0) {
if (feof(input_file)) {
encoding = false; // eof reached
} else {
fprintf(stderr, "Error reading from input file\n");
fclose(input_file);
fclose(output_file);
return 1;
}
}
// Encode data
unsigned char encoded_data_high[sizeof(buffer)];
unsigned char encoded_data_low[sizeof(buffer)];
encode_value(buffer, encoded_data_high, encoded_data_low);
// Write data
fwrite(encoded_data_high, 1, bytes_read, output_file);
fwrite(encoded_data_low, 1, bytes_read, output_file);
}
return 0; return 0;
} }

View File

@@ -23,7 +23,7 @@ void decode_byte(uint8_t in, uint8_t* nibble){
// Check parity bits // Check parity bits
uint8_t error = 0; uint8_t error = 0;
if ((p0 ^ d0 ^ d1 ^ d2) != 0) error |= 0x01; // Error in p0 group if ((p0 ^ d0 ^ d1 ^ d2) != 0) error |= 0x01; // Error in p0 group
if ((p1 ^ d0 ^ d1 ^ d3) != 0) error |= 0x02; // Error in p1 group if ((p1 ^ d0 ^ d1 ^ d3) != 0) error |= 0x02; // Error in p1 group // 0000111
if ((p2 ^ d0 ^ d2 ^ d3) != 0) error |= 0x04; // Error in p2 group if ((p2 ^ d0 ^ d2 ^ d3) != 0) error |= 0x04; // Error in p2 group
if (MSB == 0 && error != 0) { if (MSB == 0 && error != 0) {

Binary file not shown.

View File

@@ -18,101 +18,107 @@ using System.Threading.Tasks;
using System.IO; using System.IO;
using System.Windows.Forms; using System.Windows.Forms;
namespace PoloClubApp { namespace PoloClubApp
class Club { {
private string name; // the name of the club /// <summary>
private List<Device> devices; // a list of devices /// Represents a Polo Club that manages a collection of devices.
/// </summary>
class Club
{
private string name;
private List<Device> devices;
public Club(string name){ /// <summary>
/// Initializes a new instance of the Club class.
/// </summary>
/// <param name="name">The name of the club.</param>
public Club(string name)
{
this.name = name; this.name = name;
this.devices = new List<Device>(); this.devices = new List<Device>();
} }
public string Name { get { return this.name; } } // read only property for Name /// <summary>
/// Gets the name of the club (read-only).
/// </summary>
public string Name => this.name;
// ----- Graded Methods -----
//-----Provide your answers here----- /// <summary>
/// Retrieves all wearable devices (implementing IWearable interface).
public List<Device> GetAllWearables(){ /// </summary>
List<Device> wearables = new List<Device>(); /// <returns>List of wearable devices.</returns>
public List<Device> GetAllWearables()
foreach (Device dev in this.devices){ {
if (dev is SmartWatch || dev is FitTracker){ return devices.Where(d => d is IWearable).ToList();
wearables.Add(dev);
}
}
return wearables;
}
public void AssignDevice(int id, string playerName){
Device device = GetDeviceById(id);
if(device == null){
throw new Exception("Device not found");
}
if (!(device is IWearable)){
device.AssignDevice(playerName, null);
} else {
IWearable wearable = (IWearable)device;
device.AssignDevice(playerName, wearable.GetWaterResistanceMeters());
}
}
public bool ReturnDevice(int id){
Device device = GetDeviceById(id);
return device.ReturnDevice();
} }
public List<Device> GetAllAssignedDevicesByPlayer(string playerName){ /// <summary>
List<Device> assignedDevices = new List<Device>(); /// Assigns a device to a player.
foreach (Device dev in this.devices){ /// </summary>
if (dev.PlayerName == playerName){ /// <param name="id">Device ID.</param>
assignedDevices.Add(dev); /// <param name="playerName">Player's name.</param>
} /// <exception cref="Exception">Thrown if device is not found.</exception>
} public void AssignDevice(int id, string playerName)
return assignedDevices; {
var device = GetDeviceById(id) ?? throw new Exception("Device not found");
var waterResistance = (device as IWearable)?.GetWaterResistanceMeters();
device.AssignDevice(playerName, waterResistance);
} }
public List<String> GenerateReportPerPlayer(string playerName){ /// <summary>
string returnString = "List of devices assigned to " + playerName; /// Returns a device from a player.
List<String> lines = new List<String>(); /// </summary>
List<Device> assignedDevices = GetAllAssignedDevicesByPlayer(playerName); /// <param name="id">Device ID.</param>
/// <returns>True if successful, false if device not found.</returns>
lines.Add(returnString); public bool ReturnDevice(int id)
string currentDeviceType = "SmartPhone"; {
var device = GetDeviceById(id);
lines.Add("Phones"); return device?.ReturnDevice() ?? false;
lines.Add("-");
foreach (Device dev in assignedDevices){
if (dev is SmartPhone){
lines.Add(dev.GetDetails());
}
}
lines.Add("Wearables");
lines.Add("-");
foreach (Device dev in assignedDevices){
if (!(dev is SmartPhone)){
lines.Add(dev.GetDetails());
}
}
int phoneCount = 0;
int wearableCount = 0;
foreach (Device dev in assignedDevices){
if (dev is SmartPhone){
phoneCount++;
}
if (dev is IWearable){
wearableCount++;
}
}
lines.Add("Total: " + assignedDevices.Count + " devices, " + phoneCount + " phones and " + wearableCount + " wearables");
return lines;
} }
/// <summary>
/// Gets all devices assigned to a specific player.
/// </summary>
/// <param name="playerName">Player's name.</param>
/// <returns>List of assigned devices.</returns>
public List<Device> GetAllAssignedDevicesByPlayer(string playerName)
{
return devices.Where(d => d.PlayerName == playerName).ToList();
}
/// <summary>
/// Generates a formatted device report for a player.
/// </summary>
/// <param name="playerName">Player's name.</param>
/// <returns>Formatted report lines.</returns>
public List<string> GenerateReportPerPlayer(string playerName)
{
var assignedDevices = GetAllAssignedDevicesByPlayer(playerName);
var report = new List<string>
{
$"List of devices assigned to {playerName}",
"Phones",
"-"
};
report.AddRange(assignedDevices
.OfType<SmartPhone>()
.Select(d => d.GetDetails()));
report.AddRange(new[] { "Wearables", "-" });
report.AddRange(assignedDevices
.Where(d => d is IWearable)
.Select(d => d.GetDetails()));
report.Add($"Total: {assignedDevices.Count} devices, " +
$"{assignedDevices.Count(d => d is SmartPhone)} phones and " +
$"{assignedDevices.Count(d => d is IWearable)} wearables");
return report;
}
// -----The provided code below will not be graded, therefore should not be changed----- // -----The provided code below will not be graded, therefore should not be changed-----

View File

@@ -17,40 +17,81 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace PoloClubApp { namespace PoloClubApp {
internal abstract class Device { /// <summary>
/// Abstract base class representing a device in the Polo Club system.
/// </summary>
public abstract class Device {
/// <summary>
/// Gets the unique identifier of the device.
/// </summary>
public int Id { get; } public int Id { get; }
/// <summary>
/// Gets the name of the device.
/// </summary>
public string Name { get; } public string Name { get; }
/// <summary>
/// Gets or sets the name of the player the device is assigned to.
/// </summary>
public string PlayerName { get; set; } public string PlayerName { get; set; }
public Device(int id, string name, string playerName = null){
/// <summary>
/// Initializes a new instance of the Device class.
/// </summary>
/// <param name="id">The unique identifier for the device.</param>
/// <param name="name">The name of the device.</param>
/// <param name="playerName">The name of the player the device is assigned to (optional).</param>
protected Device(int id, string name, string playerName = null) {
Id = id; Id = id;
Name = name; Name = name;
PlayerName = playerName; PlayerName = playerName;
} }
/// <summary>
/// Gets detailed information about the device.
/// </summary>
/// <returns>Formatted string with device details.</returns>
public abstract string GetDetails(); public abstract string GetDetails();
/// <summary>
/// Checks if the device is currently assigned to a player.
/// </summary>
/// <returns>True if assigned, false otherwise.</returns>
public bool IsAssigned(){ public bool IsAssigned(){
return PlayerName != null; return !string.IsNullOrEmpty(PlayerName);
}
public Exception AssignDevice(string playerName, int? waterResistanceMeters){
if (IsAssigned()){
throw new Exception("Device is already assigned");
} else if (this is IWearable && waterResistanceMeters < 3){
throw new Exception("Water resistance meters should be 3 or more");
} else if (this.Id == null){
throw new Exception("Device Id is null");
} else {
PlayerName = playerName;
return null;
}
} }
/// <summary>
/// Assigns the device to a player.
/// </summary>
/// <param name="playerName">Name of the player to assign to.</param>
/// <param name="waterResistanceMeters">Water resistance for wearables (nullable).</param>
/// <exception cref="Exception">Throws when assignment fails.</exception>
public void AssignDevice(string playerName, int? waterResistanceMeters)
{
if (IsAssigned())
throw new Exception("Device is already assigned");
if (this is IWearable && waterResistanceMeters < 3)
throw new Exception("Water resistance must be 3 meters or more for wearables");
if (Id == 0)
throw new Exception("Invalid device ID");
PlayerName = playerName;
}
/// <summary>
/// Returns the device from a player.
/// </summary>
/// <returns>True if successful, false if device wasn't assigned.</returns>
public bool ReturnDevice(){ public bool ReturnDevice(){
if (!IsAssigned()){ if (!IsAssigned())
return false; return false;
}
PlayerName = null; PlayerName = null;
return true; return true;
} }
} }
} }

View File

@@ -17,27 +17,57 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace PoloClubApp { namespace PoloClubApp {
internal class FitTracker : Device, IWearable { /// <summary>
public string DeviceType = "FitTracker"; /// Represents a fitness tracker device that implements IWearable interface.
public int Id { get; } /// </summary>
public string Name { get; } public class FitTracker : Device, IWearable {
public string PlayerName { get; set; } /// <summary>
/// Gets the type of the device (always "FitTracker").
/// </summary>
public string DeviceType { get; } = "FitTracker";
/// <summary>
/// Gets the water resistance rating in meters.
/// </summary>
public int WaterResistanceMeters { get; } public int WaterResistanceMeters { get; }
/// <summary>
/// Gets the color of the fitness tracker.
/// </summary>
public string Color { get; } public string Color { get; }
public FitTracker(int id, string name, int waterResistanceMeters, string color) : base(id, name, null){ /// <summary>
Id = id; /// Initializes a new instance of the FitTracker class.
Name = name; /// </summary>
/// <param name="id">The unique device identifier.</param>
/// <param name="name">The name of the fitness tracker.</param>
/// <param name="waterResistanceMeters">Water resistance rating in meters.</param>
/// <param name="color">The color of the device.</param>
public FitTracker(int id, string name, int waterResistanceMeters, string color)
: base(id, name)
{
WaterResistanceMeters = waterResistanceMeters; WaterResistanceMeters = waterResistanceMeters;
Color = color; Color = color;
} }
public override string GetDetails(){ /// <summary>
return DeviceType + "Id: " + Id + ", Name: " + Name + ", Type: " + ", WaterResistanceMeters: " + WaterResistanceMeters + ", Color: " + Color; /// Gets detailed information about the fitness tracker.
/// </summary>
/// <returns>Formatted string with device details.</returns>
public override string GetDetails()
{
return $"{DeviceType} - Id: {Id}, Name: {Name}, " +
$"Water Resistance: {WaterResistanceMeters}m, " +
$"Color: {Color}";
} }
public int GetWaterResistanceMeters(){ /// <summary>
/// Gets the water resistance rating.
/// </summary>
/// <returns>Water resistance in meters.</returns>
public int GetWaterResistanceMeters()
{
return WaterResistanceMeters; return WaterResistanceMeters;
} }
} }
} }

View File

@@ -18,8 +18,14 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace PoloClubApp { namespace PoloClubApp {
interface IWearable { /// <summary>
///Returns the water resistance level of the wearable device in meters. /// Interface for wearable devices that have water resistance capability.
/// </summary>
public interface IWearable{
/// <summary>
/// Gets the water resistance rating of the wearable device.
/// </summary>
/// <returns>Water resistance in meters.</returns>
int GetWaterResistanceMeters(); int GetWaterResistanceMeters();
} }
} }

View File

@@ -17,18 +17,30 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace PoloClubApp { namespace PoloClubApp {
internal class SmartPhone : Device { /// <summary>
public string DeviceType = "SmartPhone"; /// Represents a smartphone device in the Polo Club system.
public int Id { get; } /// </summary>
public string Name { get; } public class SmartPhone : Device
public string PlayerName { get; set; } {
/// <summary>
public SmartPhone(int id, string name) : base(id, name, null){ /// Gets the type of the device (always "SmartPhone").
Id = id; /// </summary>
Name = name; public string DeviceType { get; } = "SmartPhone";
}
public override string GetDetails(){ /// <summary>
return DeviceType + "Id: " + Id + ", Name: " + Name; /// Initializes a new instance of the SmartPhone class.
/// </summary>
/// <param name="id">The unique identifier for the smartphone.</param>
/// <param name="name">The name of the smartphone.</param>
public SmartPhone(int id, string name) : base(id, name) { }
/// <summary>
/// Gets a formatted string with details about the smartphone.
/// </summary>
/// <returns>A string containing device details.</returns>
public override string GetDetails()
{
return $"{DeviceType} - Id: {Id}, Name: {Name}";
} }
} }
} }

View File

@@ -18,25 +18,57 @@ using System.Threading.Tasks;
using System.Xml.Linq; using System.Xml.Linq;
namespace PoloClubApp { namespace PoloClubApp {
internal class SmartWatch : Device, IWearable { /// <summary>
public string DeviceType = "Watch"; /// Represents a smartwatch device that implements IWearable interface.
/// </summary>
public class SmartWatch : Device, IWearable {
/// <summary>
/// Gets the type of the device (always "SmartWatch").
/// </summary>
public string DeviceType { get; } = "SmartWatch";
/// <summary>
/// Gets the water resistance rating in meters.
/// </summary>
public int WaterResistanceMeters { get; } public int WaterResistanceMeters { get; }
/// <summary>
/// Gets the screen size in millimeters.
/// </summary>
public int ScreenSize { get; } public int ScreenSize { get; }
/// Initializes a new SmartWatch with specified ID, name, player name, water resistance, and screen size. /// <summary>
public SmartWatch(int id, string name, int waterResistanceMeters, int screenSize) : base(id, name, null){ /// Initializes a new instance of the SmartWatch class.
WaterResistanceMeters = waterResistanceMeters; /// </summary>
ScreenSize = screenSize; /// <param name="id">The unique device identifier.</param>
/// <param name="name">The name of the smartwatch.</param>
/// <param name="waterResistanceMeters">Water resistance rating in meters.</param>
/// <param name="screenSize">Screen size in millimeters.</param>
public SmartWatch(int id, string name, int waterResistanceMeters, int screenSize)
: base(id, name)
{
WaterResistanceMeters = waterResistanceMeters;
ScreenSize = screenSize;
} }
/// Returns a string representation of the SmartWatch details. /// <summary>
public override string GetDetails(){ /// Gets detailed information about the smartwatch.
return DeviceType + "Id: " + Id + ", Name: " + Name + ", WaterResistanceMeters: " + WaterResistanceMeters + ", ScreenSize: " + ScreenSize; /// </summary>
/// <returns>Formatted string with device details.</returns>
public override string GetDetails()
{
return $"{DeviceType} - Id: {Id}, Name: {Name}, " +
$"Water Resistance: {WaterResistanceMeters}m, " +
$"Screen Size: {ScreenSize}mm";
} }
/// Returns the water resistance of the SmartWatch in meters. /// <summary>
public int GetWaterResistanceMeters(){ /// Gets the water resistance rating.
/// </summary>
/// <returns>Water resistance in meters.</returns>
public int GetWaterResistanceMeters()
{
return WaterResistanceMeters; return WaterResistanceMeters;
} }
} }
} }