NEOERR *wdbr_find (WDB *wdb, WDBCursor *cursor, const char *key, WDBRow **row) { DBT dkey, data; WDBRow *my_row; NEOERR *err = STATUS_OK; int r; *row = NULL; if (wdb->table_version != cursor->table_version) { return nerr_raise (NERR_ASSERT, "Cursor doesn't match database"); } memset(&dkey, 0, sizeof(dkey)); memset(&data, 0, sizeof(data)); dkey.flags = DB_DBT_USERMEM; data.flags = DB_DBT_MALLOC; dkey.data = (void *)key; dkey.size = strlen(key); r = cursor->db_cursor->c_get (cursor->db_cursor, &dkey, &data, DB_SET_RANGE); if (r == DB_NOTFOUND) return STATUS_OK; else if (r) return nerr_raise (r, "Unable to get find item for key %s", key); /* allocate row */ err = alloc_row (wdb, &my_row); if (err) { free (data.data); return nerr_pass(err); } my_row->key_value = (char *) malloc (dkey.size + 1); if (my_row->key_value == NULL) { free (data.data); free (my_row); return nerr_raise (NERR_NOMEM, "No memory for new row"); } memcpy (my_row->key_value, dkey.data, dkey.size); my_row->key_value[dkey.size] = '\0'; /* unpack row */ err = unpack_row (wdb, data.data, data.size, my_row); free (data.data); if (err) { free (my_row); return nerr_pass(err); } *row = my_row; return STATUS_OK; }
NEOERR *wdbr_lookup (WDB *wdb, const char *key, WDBRow **row) { DBT dkey, data; NEOERR *err = STATUS_OK; WDBRow *my_row; int r; *row = NULL; memset(&dkey, 0, sizeof(dkey)); memset(&data, 0, sizeof(data)); dkey.flags = DB_DBT_USERMEM; data.flags = DB_DBT_MALLOC; dkey.data = (void *)key; dkey.size = strlen(key); r = wdb->db->get (wdb->db, NULL, &dkey, &data, 0); if (r == DB_NOTFOUND) return nerr_raise (NERR_NOT_FOUND, "Unable to find key %s", key); else if (r) return nerr_raise (NERR_DB, "Error retrieving key %s: %d", key, r); /* allocate row */ err = alloc_row (wdb, &my_row); if (err != STATUS_OK) { free (data.data); return nerr_pass(err); } my_row->key_value = strdup(key); if (my_row->key_value == NULL) { free (data.data); free (my_row); return nerr_raise (NERR_NOMEM, "No memory for new row"); } /* unpack row */ err = unpack_row (wdb, data.data, data.size, my_row); free (data.data); if (err) { free (my_row); return nerr_pass(err); } *row = my_row; return STATUS_OK; }
NEOERR *wdbr_create (WDB *wdb, const char *key, WDBRow **row) { WDBRow *my_row; NEOERR *err = STATUS_OK; *row = NULL; /* allocate row */ err = alloc_row (wdb, &my_row); if (err) return nerr_pass(err); my_row->key_value = strdup(key); if (my_row->key_value == NULL) { wdbr_destroy (wdb, &my_row); return nerr_raise (NERR_NOMEM, "No memory for new row"); } *row = my_row; return STATUS_OK; }
NEOERR *wdbr_next (WDB *wdb, WDBCursor *cursor, WDBRow **row, int flags) { DBT dkey, data; WDBRow *my_row; NEOERR *err = STATUS_OK; int r; *row = NULL; if (wdb->table_version != cursor->table_version) { return nerr_raise (NERR_ASSERT, "Cursor doesn't match database"); } memset(&dkey, 0, sizeof(dkey)); memset(&data, 0, sizeof(data)); dkey.flags = DB_DBT_MALLOC; data.flags = DB_DBT_MALLOC; /* First call */ if (flags & WDBC_FIRST) { r = cursor->db_cursor->c_get (cursor->db_cursor, &dkey, &data, DB_FIRST); if (r == DB_NOTFOUND) return nerr_raise (NERR_NOT_FOUND, "Cursor empty"); else if (r) return nerr_raise (NERR_DB, "Unable to get first item from cursor: %d", r); } else { r = cursor->db_cursor->c_get (cursor->db_cursor, &dkey, &data, DB_NEXT); if (r == DB_NOTFOUND) return STATUS_OK; else if (r) return nerr_raise (NERR_DB, "Unable to get next item from cursor: %d", r); } /* allocate row */ err = alloc_row (wdb, &my_row); if (err) { free (data.data); return nerr_pass(err); } my_row->key_value = (char *) malloc (dkey.size + 1); if (my_row->key_value == NULL) { free (data.data); free (my_row); return nerr_raise (NERR_NOMEM, "No memory for new row"); } memcpy (my_row->key_value, dkey.data, dkey.size); my_row->key_value[dkey.size] = '\0'; /* unpack row */ err = unpack_row (wdb, data.data, data.size, my_row); free (data.data); free (dkey.data); if (err) { free (my_row); return nerr_pass(err); } *row = my_row; return STATUS_OK; }
VALUE 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(0); struct s_Row *cur_row = first_row; struct s_Cell *cur_cell = cur_row->first_cell; cur_cell->start = buf; VALUE matrix; char *cur; if (bufsize > 0 && *(buf+bufsize-1) == '\n') { *(buf+bufsize-1) = 0; --bufsize; } for (cur = buf; cur < buf+bufsize; cur++) { if (*cur == '"') { if (0 == quote_count && cur_cell->start != cur) /* Quotes begin past opening of cell */ rb_raise(BAMFCSV_MalformedCSVError_class, "Illegal quoting on line %d, cell %d: Quoted cell must open with '\"'", num_rows, cur_row->cell_count); else ++quote_count; } quotes_matched = !(quote_count & 1); /* count is even */ if (quotes_matched) { if (*cur == ',') { 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); cur_cell->start = cur+1; quote_count = 0; } else if (*cur == '\n') { 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); cur_cell = cur_row->first_cell; cur_cell->start = cur+1; quote_count = 0; num_rows++; } else if (quote_count && *cur != '\r' && *cur != '"') rb_raise(BAMFCSV_MalformedCSVError_class, "Illegal quoting on line %d, cell %d", num_rows, cur_row->cell_count); } } if (!quotes_matched) /* Reached EOF without matching quotes */ rb_raise(BAMFCSV_MalformedCSVError_class, "Illegal quoting on line %d, cell %d: File ends without closing '\"'", num_rows, cur_row->cell_count); 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); matrix = build_matrix_from_pointer_tree(first_row, num_rows); free_row(first_row); return matrix; }