X-Git-Url: https://code.kerkeslager.com/?p=fur;a=blobdiff_plain;f=c%2Frope.c;fp=c%2Frope.c;h=716a5af76e999592bf1359812a0742d78b250ef2;hp=0000000000000000000000000000000000000000;hb=64ef22e135f7c790f0cd80956d8bdf7fa0268148;hpb=93ca0209c0daf4988ee1ceb509b043a80a8ac40e diff --git a/c/rope.c b/c/rope.c new file mode 100644 index 0000000..716a5af --- /dev/null +++ b/c/rope.c @@ -0,0 +1,90 @@ +#ifndef ROPE_C +#define ROPE_C + +#include +#include +#include +#include + +enum RopeType; +typedef enum RopeType RopeType; +enum RopeType { + ROPETYPE_CONCATENATION, + ROPETYPE_STRING +}; + +struct Concatenation; +typedef struct Concatenation Concatenation; +struct Concatenation { + Rope* r0; + Rope* r1; +}; + +struct String; +typedef struct String String; +struct String { + size_t length; + uint32_t* characters; +}; + +union RopeInstance; +typedef union RopeInstance RopeInstance; +union RopeInstance { + Concatenation concatenation; + String string; +}; + +struct Rope { + volatile size_t referenceCount; + RopeType type; + RopeInstance instance; +}; + +Rope* Rope_rereference(Rope* self) { + __sync_add_and_fetch(&(self->referenceCount), 1); + return self; +} + +void Rope_destruct(Rope* self) { + size_t referenceCount = __sync_sub_and_fetch(&(self->referenceCount), 1); + + if(referenceCount == 0) { + switch(self->type) { + case ROPETYPE_CONCATENATION: + Rope_destruct(self->instance.concatenation.r0); + Rope_destruct(self->instance.concatenation.r1); + break; + + case ROPETYPE_STRING: + free(self->instance.string.characters); + break; + + default: + assert(false); + } + + free(self); + } +} + +void Rope_write(Rope*, Encoding, FILE) { + // TODO Implement + printf("Not implemented"); +} + +Rope* Rope_read(Encoding, FILE) { + // TODO Implement + printf("Not implemented"); + return NULL; +} + +Rope* Rope_concatenate(Rope* r0, Rope* r1) { + Rope* result = malloc(sizeof(Rope)); + result->referenceCount = 0; + result->type = ROPETYPE_CONCATENATION; + result->instance.concatenation.r0 = Rope_rereference(r0); + result->instance.concatenation.r1 = Rope_rereference(r1); + return result; +} + +#endif