/// dynamic array class /// written by: Harry Irving #include #include #include #include #include typedef enum LineState { UNMODIFIED, MODIFIED, ADDED, REMOVED, } LineState; typedef struct { uint32_t size; // Current number of elements uint32_t capacity; // Total capacity allocated LineState* data; // Array of LineState values } StateArray; StateArray arr_init(int capacity) { // creates a new array to store the state StateArray arr; arr.size = capacity; arr.capacity = capacity; arr.data = (LineState*)calloc(capacity, sizeof(LineState)); // Initialize all elements to UNMODIFIED for (int i = 0; i < capacity; i++) { arr.data[i] = UNMODIFIED; } return arr; } // prints the state of the array into a file // this method is for debug purposes! // void arr_print(StateArray* self) { // FILE* log_file = fopen("diff.txt", "w"); // if (log_file == NULL) { // fprintf(stderr, "Error: Could not open log file\n"); // } // for (int i = 0; i < self->size; i++) { // switch (self->data[i]) { // case UNMODIFIED: // fwrite("UNMODIFIED\n", sizeof(char), strlen("UNMODIFIED\n"), log_file); // break; // case MODIFIED: // fwrite("MODIFIED\n", sizeof(char), strlen("MODIFIED\n"), log_file); // break; // case ADDED: // fwrite("ADDED\n", sizeof(char), strlen("ADDED\n"), log_file); // break; // case REMOVED: // fwrite("REMOVED\n", sizeof(char), strlen("REMOVED\n"), log_file); // break; // } // } // fclose(log_file); // } // calculates an offset to use for indexing into the state relative to the buffer. // this is because some elements might not be aligned due to needing to insert the "REMOVED" element in some cases. int arr_added_or_removed_before(StateArray* self, int index) { int count = 0; for (int i = 0; i < index; i++) { // if (self->data[i] == ADDED || self->data[i] == REMOVED) { // if (self->data[i] == REMOVED) { // // every time a "REMOVED" element is found, we increase the index by 1 // index++; // } // count++; // } if (self->data[i] == REMOVED) { // every time a "REMOVED" element is found, we increase the index by 1 index++; count++; } } return count; } void arr_set(StateArray* self, int index, LineState state) { int offset = arr_added_or_removed_before(self, index); self->data[index] = state; } LineState arr_remove(StateArray* self, int index) { int offset = arr_added_or_removed_before(self, index); if (index >= self->size) { return -1; } LineState removed = self->data[index]; // Shift remaining elements left for (int i = index; i < self->size - 1; i++) { self->data[i] = self->data[i + 1]; } self->size--; return removed; } int arr_insert(StateArray* self, int index, LineState state) { int offset = arr_added_or_removed_before(self, index); if (index > self->size) { return -1; } self->size++; // Grow array if needed if (self->size > self->capacity) { self->capacity = (self->size) * sizeof(LineState); self->data = (LineState*)realloc(self->data, self->capacity * sizeof(LineState)); } // Shift elements right to make room for (int i = self->size - 1; i > index; i--) { self->data[i] = self->data[i - 1]; } self->data[index] = state; return 0; } LineState arr_get(StateArray* self, int index) { int offset = arr_added_or_removed_before(self, index); return self->data[index]; } int arr_original_offset(StateArray* self, int index) { int offset = 0; for (int i = 0; i < index; i++) { if (self->data[i] == ADDED) { offset--; } } return offset; } int arr_modified_offset(StateArray* self, int index) { int offset = 0; for (int i = 0; i < index; i++) { if (self->data[i] == REMOVED) { offset--; } } return offset; } int arr_dealloc(StateArray* self) { free(self->data); self->data = NULL; self->size = 0; self->capacity = 0; return 0; }