Skip to content

Commit

Permalink
We have voodoo'd the free
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Redington and Jon Distad committed Apr 15, 2011
1 parent 16db6b2 commit c262721
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 45 deletions.
85 changes: 46 additions & 39 deletions ext/bamfcsv/bamfcsv_ext.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include <stdlib.h>
#include "bamfcsv_ext.h"

struct s_Cell *alloc_cell(struct s_Row *row, struct s_Cell *prev_cell) {
struct bamfcsv_Cell *bamfcsv_alloc_cell(struct bamfcsv_Row *row, struct bamfcsv_Cell *prev_cell) {

struct s_Cell *new_cell = malloc(sizeof(struct s_Cell));
struct bamfcsv_Cell *new_cell = malloc(sizeof(struct bamfcsv_Cell));

new_cell -> start = NULL;
new_cell -> len = 0;
Expand All @@ -16,47 +16,54 @@ struct s_Cell *alloc_cell(struct s_Row *row, struct s_Cell *prev_cell) {

}

struct s_Row *alloc_row(struct s_Row *prev_row) {
struct bamfcsv_Row *bamfcsv_alloc_row(struct bamfcsv_Row *prev_row) {

struct s_Row *new_row = malloc(sizeof(struct s_Row));
struct bamfcsv_Row *new_row = malloc(sizeof(struct bamfcsv_Row));

new_row -> next_row = NULL;
new_row -> cell_count = 0;
new_row -> first_cell = alloc_cell(new_row, NULL);
new_row -> first_cell = bamfcsv_alloc_cell(new_row, NULL);
if (prev_row != NULL) prev_row->next_row = new_row;

return new_row;

}

void free_cell(struct s_Cell *cell) {
void bamfcsv_free_rows(struct bamfcsv_Row *row, unsigned long num_rows) {

if (cell != NULL) {
free_cell(cell->next_cell);
free(cell);
unsigned long i, j;
struct bamfcsv_Row **rows = calloc(sizeof(struct bamfcsv_Row*), num_rows);
struct bamfcsv_Row *cur_row = row;
struct bamfcsv_Cell *cur_cell;
for (i = 0; i < num_rows; i++) {
rows[i] = cur_row;
struct bamfcsv_Cell **cells = calloc(sizeof(struct bamfcsv_Cell*), cur_row->cell_count);
cur_cell = cur_row -> first_cell;
for(j = 0; j < cur_row -> cell_count; j++) {
cells[j] = cur_cell;
cur_cell = cur_cell -> next_cell;
}
for (j = 0; j < cur_row -> cell_count; j++) {
free(cells[j]);
}
free(cells);
cur_row = cur_row -> next_row;
}

}

void free_row(struct s_Row *row) {

if (row != NULL) {

free_row(row->next_row);
free_cell(row->first_cell);
free(row);


for (i = 0; i < num_rows; i++) {
free(rows[i]);
}
free(rows);

}

VALUE build_matrix_from_pointer_tree(struct s_Row *first_row, int num_rows) {
VALUE bamfcsv_build_matrix_from_pointer_tree(struct bamfcsv_Row *first_row, unsigned long num_rows) {
VALUE matrix;
VALUE row;
VALUE new_string;
int i,j;
struct s_Row *cur_row;
struct s_Cell *cur_cell;
unsigned long i,j;
struct bamfcsv_Row *cur_row;
struct bamfcsv_Cell *cur_cell;

cur_row = first_row;
matrix = rb_ary_new2(num_rows);
Expand Down Expand Up @@ -90,7 +97,7 @@ VALUE build_matrix_from_pointer_tree(struct s_Row *first_row, int num_rows) {
return matrix;
}

void finalize_cell(struct s_Cell *cell, char *cur, int quote_count) {
void bamfcsv_finalize_cell(struct bamfcsv_Cell *cell, char *cur, int quote_count) {
if (*(cur-1) == '\r')
cell->len = (int)(cur-(cell->start)-1);
else
Expand All @@ -99,14 +106,14 @@ void finalize_cell(struct s_Cell *cell, char *cur, int quote_count) {
if (quote_count) cell->has_quotes = 1;
}

VALUE build_matrix(char *buf, int bufsize) {
VALUE bamfcsv_build_matrix(char *buf, int bufsize) {
int str_start = 0;
int num_rows = 1;
int quote_count = 0, quotes_matched = 1;

struct s_Row *first_row = alloc_row(NULL);
struct s_Row *cur_row = first_row;
struct s_Cell *cur_cell = cur_row->first_cell;
struct bamfcsv_Row *first_row = bamfcsv_alloc_row(NULL);
struct bamfcsv_Row *cur_row = first_row;
struct bamfcsv_Cell *cur_cell = cur_row->first_cell;
cur_cell->start = buf;

VALUE matrix;
Expand Down Expand Up @@ -136,8 +143,8 @@ VALUE build_matrix(char *buf, int bufsize) {
if (quote_count && *(cur-1) != '"')
rb_raise(BAMFCSV_MalformedCSVError_class, "Unclosed quoted field on line %d, cell %d.", num_rows, cur_row->cell_count);

finalize_cell(cur_cell, cur, quote_count);
cur_cell = alloc_cell(cur_row, cur_cell);
bamfcsv_finalize_cell(cur_cell, cur, quote_count);
cur_cell = bamfcsv_alloc_cell(cur_row, cur_cell);
cur_cell->start = cur+1;
quote_count = 0;

Expand All @@ -146,8 +153,8 @@ VALUE build_matrix(char *buf, int bufsize) {
if (quote_count && !(*(cur-1) == '"' || *(cur-1) == '\r' && *(cur-2) == '"'))
rb_raise(BAMFCSV_MalformedCSVError_class, "Unclosed quoted field on line %d, cell %d: EOL", num_rows, cur_row->cell_count);

finalize_cell(cur_cell, cur, quote_count);
cur_row = alloc_row(cur_row);
bamfcsv_finalize_cell(cur_cell, cur, quote_count);
cur_row = bamfcsv_alloc_row(cur_row);
cur_cell = cur_row->first_cell;
cur_cell->start = cur+1;
quote_count = 0;
Expand All @@ -166,27 +173,27 @@ VALUE build_matrix(char *buf, int bufsize) {
else if (quote_count && *(cur-1) != '"') /* Quotes closed before end of final cell */
rb_raise(BAMFCSV_MalformedCSVError_class, "Unclosed quoted field on line %d, cell %d: EOF", num_rows, cur_row->cell_count);

finalize_cell(cur_cell, cur, quote_count);
bamfcsv_finalize_cell(cur_cell, cur, quote_count);

matrix = build_matrix_from_pointer_tree(first_row, num_rows);
matrix = bamfcsv_build_matrix_from_pointer_tree(first_row, num_rows);

free_row(first_row);
bamfcsv_free_rows(first_row, num_rows);

return matrix;

}

VALUE parse_string(VALUE self, VALUE string) {
VALUE bamfcsv_parse_string(VALUE self, VALUE string) {

return build_matrix(RSTRING_PTR(string), NUM2INT(rb_str_length(string)));
return bamfcsv_build_matrix(RSTRING_PTR(string), NUM2INT(rb_str_length(string)));

}

void Init_bamfcsv() {

BAMFCSV_module = rb_define_module("BAMFCSV");
VALUE bamfcsv_singleton_class = rb_singleton_class(BAMFCSV_module);
rb_define_private_method(bamfcsv_singleton_class, "__parse_string", parse_string, 1);
rb_define_private_method(bamfcsv_singleton_class, "__parse_string", bamfcsv_parse_string, 1);

BAMFCSV_MalformedCSVError_class = rb_define_class_under(BAMFCSV_module, "MalformedCSVError", rb_eRuntimeError);
}
12 changes: 6 additions & 6 deletions ext/bamfcsv/bamfcsv_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
VALUE BAMFCSV_module;
VALUE BAMFCSV_MalformedCSVError_class;

struct s_Row {
struct s_Cell *first_cell;
struct s_Row *next_row;
int cell_count;
struct bamfcsv_Row {
struct bamfcsv_Cell *first_cell;
struct bamfcsv_Row *next_row;
unsigned long cell_count;
};

struct s_Cell {
struct bamfcsv_Cell {
char *start;
int len;
int has_quotes;
struct s_Cell *next_cell;
struct bamfcsv_Cell *next_cell;
};

void Init_bamfcsv();
Expand Down

0 comments on commit c262721

Please sign in to comment.