Skip to content

Instantly share code, notes, and snippets.

@philipheimboeck
Created January 24, 2015 09:52
Show Gist options
  • Save philipheimboeck/78e2ec0389aefd0ba197 to your computer and use it in GitHub Desktop.
Save philipheimboeck/78e2ec0389aefd0ba197 to your computer and use it in GitHub Desktop.
C Inheritance: Decorator Pattern

Decorator Pattern in C

  • Basic C Inheritance
  • No Destructor implemented
#include <stdlib.h>
#include <stdio.h>
#include <Kernel/string.h>
#include "decorator.h"
/** Constructors **/
Writer_t* create_writer() {
Writer_t* writer = (Writer_t*) malloc(sizeof(StarWriter_t));
if (writer == 0) return 0;
writer->base.print = writer_print;
writer->base.type.type = "Writer";
return writer;
}
EndlineWriter_t* create_endline_writer(WriterComponent_t* component) {
EndlineWriter_t* writer = (EndlineWriter_t*) malloc(sizeof(EndlineWriter_t));
if (writer == 0) return 0;
writer->base.base.print = endline_writer_print;
writer->base.base.type.type = "EndlineWriter";
writer->base.component = component;
return writer;
}
StarWriter_t* create_star_writer(WriterComponent_t* component) {
StarWriter_t* writer = (StarWriter_t*) malloc(sizeof(StarWriter_t));
if (writer == 0) return 0;
writer->base.base.print = star_writer_print;
writer->base.base.type.type = "StarWriter";
writer->base.component = component;
return writer;
}
/** Class Methods **/
int instance_of(WriterComponent_t* this, const char* instance) {
return (strcmp(this->type.type, instance));
}
/** Print Methods **/
char* writer_print(void* this, char* data, size_t max_size) {
printf(data);
return data;
};
char* endline_writer_print(void* this, char* data, size_t max_size) {
EndlineWriter_t* obj = (EndlineWriter_t*) this;
// Add \n to data
size_t length = strlen(data);
if (length < max_size - 1) {
data[length] = '\n';
data[length + 1] = '\0';
}
return obj->base.component->print(obj->base.component, data, max_size);
}
char* star_writer_print(void* this, char* data, size_t max_size) {
StarWriter_t* obj = (StarWriter_t*) this;
// Add * to data
size_t length = strlen(data);
if (length < max_size - 1) {
data[length] = '*';
data[length + 1] = '\0';
}
return obj->base.component->print(obj->base.component, data, max_size);
}
#ifndef _H_DECORATOR
#define _H_DECORATOR
#include <stdio.h>
/**
* Used to ask what type the object is:
* The string is the classname
*/
typedef struct Type {
char* type;
} Type_t;
/**
* Abstract Writer Component
*/
typedef struct WriterComponent {
Type_t type;
char* (* print)(void* this, char* data, size_t max_length);
} WriterComponent_t;
/**
* Abstract Writer Decorator
*/
typedef struct WriterDecorator {
WriterComponent_t base;
WriterComponent_t* component;
} WriterDecorator_t;
int instance_of(WriterComponent_t* this, const char* class);
/**
* Concrete Component: Writer
*/
typedef struct Writer {
WriterComponent_t base;
} Writer_t;
Writer_t* create_writer();
char* writer_print(void* this, char*, size_t);
/**
* Concrete Decorator: EndlineWriter
* Attach a new line at the end of the string
*/
typedef struct EndlineWriter {
WriterDecorator_t base;
} EndlineWriter_t;
EndlineWriter_t* create_endline_writer(WriterComponent_t* component);
char* endline_writer_print(void* this, char*, size_t);
/**
* Concrete Decorator: Star Writer
* Attach a * at the end of the string
*/
typedef struct StarWriter {
WriterDecorator_t base;
} StarWriter_t;
StarWriter_t* create_star_writer(WriterComponent_t* component);
char* star_writer_print(void* this, char*, size_t);
#endif
#include "decorator.h"
int main() {
char text[20] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '\0'};
WriterComponent_t* writer = (WriterComponent_t*) create_star_writer((WriterComponent_t*) create_endline_writer((WriterComponent_t*) create_writer()));
writer->print(writer, text, 20);
printf(writer->type.type); // Will print StarWriter
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment