Files
FantasyPvP 00042ea092 done
2024-12-05 02:09:18 +00:00

161 lines
4.4 KiB
C

/// dynamic array class
/// written by: Harry Irving
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
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;
}