int sp_compute_checksum(SP_FILE *sp, SP_CHECKSUM *comp_chksum){ char *proc = "sp_compute_checksum"; void *buff; SP_INTEGER cur_pos; if (sp == SPNULL) return_err(proc,101,101,"Null SPFILE structure"); if (sp->open_mode != SP_mode_read) return_err(proc,102,102,"File must be opened for read"); if (! sp->read_spifr->status->is_disk_file) return_err(proc,103,103,"File must be a disk file"); if (sp_error(sp) != 0) return_err(proc,104,104,"Sphere file already has an error"); /* save the current position so we can go back to it */ if ((cur_pos = sp_tell(sp)) < 0) return_err(proc,110,110, rsprintf("sp_tell() failed, returning: %s", get_return_status_message())); /* rewind the file */ if (sp_seek(sp,0,0) != 0) return_err(proc,111,111, rsprintf("sp_seek() to sample 0 failed, returning: %s", get_return_status_message())); /* allocate some memory */ if ((buff = (void *)sp_data_alloc(sp,4096)) == (void *)0) return_err(proc,112,112, rsprintf("can not alloc waveform buffer, returning: %s", get_return_status_message())); /* read in the data */ while (sp_read_data(buff,4096,sp) > 0) ; /* dealloc memory */ sp_data_free(sp,buff); if (sp_error(sp) != 0) return_err(proc,120,120, rsprintf("sp_error() indicates an error, returning: %s", get_return_status_message())); *comp_chksum = sp->read_spifr->waveform->checksum; if (sp_seek(sp,cur_pos,0) != 0) return_err(proc,130,130, rsprintf("sp_seek() to return the file to it's initial" "state failed, returning: %s", get_return_status_message())); return_success(proc,0,0,"ok"); }
static PyObject * sophia_db_get(SophiaDB *db, PyObject *args) { char *key; PyObject *pkey, *pvalue = NULL; void *value; Py_ssize_t ksize; size_t vsize; ensure_is_opened(db, NULL); if (!PyArg_UnpackTuple(args, "get", 1, 2, &pkey, &pvalue) || PyBytes_AsStringAndSize(pkey, &key, &ksize) == -1) return NULL; int rv = sp_get(db->db, key, (size_t)ksize, &value, &vsize); switch (rv) { case 1: pvalue = PyBytes_FromStringAndSize(value, (Py_ssize_t)vsize); free(value); return pvalue; case 0: if (pvalue) return pvalue; Py_RETURN_NONE; default: PyErr_SetString(SophiaError, sp_error(db->db)); return NULL; } }
/* Attach a python comparison function to the database instance. * Passing `None` resets the comparison function to the original * default one. */ static PyObject * sophia_db_set_cmp_fun(SophiaDB *db, PyObject *fun) { int rv; if (fun == Py_None) { if (!db->cmp_fun) return 0; Py_DECREF(db->cmp_fun); db->cmp_fun = NULL; rv = sp_ctl(db->env, SPCMP, sophia_compare_default, NULL); } else if (PyCallable_Check(fun)) { if (db->cmp_fun) Py_DECREF(db->cmp_fun); Py_INCREF(fun); db->cmp_fun = fun; rv = sp_ctl(db->env, SPCMP, sophia_compare_custom, fun); } else { PyErr_SetString(PyExc_TypeError, "expected either a callable or None"); return NULL; } if (rv == -1) { PyErr_SetString(SophiaError, sp_error(db->env)); return NULL; } Py_RETURN_NONE; }
static int getrand(int n) { int rc; int i; for (i = 0; i < n; i++) { uint32_t k = rand(); memcpy(key, &k, sizeof(k)); k = rand(); memcpy(key + 4, &k, sizeof(k)); k = rand(); memcpy(key + 8, &k, sizeof(k)); k = rand(); memcpy(key + 12, &k, sizeof(k)); void *v = NULL; size_t vsize = 0; rc = sp_get(db, key, sizeof(key), &v, &vsize); if (rc <= 0) { printf("get: %s\n", sp_error(db)); break; } free(v); print_current(i); } return 0; }
/* Open (or reopen) the underlying sophia database iff no cursors * are still in use. */ static PyObject * sophia_db_open(SophiaDB *db, PyObject *args) { char *path; if (!PyArg_ParseTuple(args, "s:open", &path)) return NULL; if (db->db) { int status = sophia_db_close_internal(db); if (status == 0) { db->close_me = 1; Py_RETURN_FALSE; } else if (status == -1) return NULL; } if (sp_ctl(db->env, SPDIR, SPO_CREAT | SPO_RDWR, path) == -1 || (!db->cmp_fun && sp_ctl(db->env, SPCMP, sophia_compare_default, NULL) == -1)) return PyErr_NoMemory(); db->db = sp_open(db->env); if (!db->db) { PyErr_SetString(SophiaError, sp_error(db->env)); return NULL; } db->cursors = 0; db->close_me = 0; Py_RETURN_TRUE; }
static PyObject * sophia_cursor_new(SophiaDB *db, PyTypeObject *cursortype, PyObject *args, PyObject *kwargs) { SophiaCursor *pcur; int order = SPGTE; char *begin = NULL; PyObject *pbegin = NULL; Py_ssize_t bsize = 0; static char *keywords[] = {"start_key", "order", NULL}; ensure_is_opened(db, NULL); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi", keywords, &pbegin, &order) || (pbegin && pbegin != Py_None && PyBytes_AsStringAndSize(pbegin, &begin, &bsize) == -1)) return NULL; pcur = PyObject_New(SophiaCursor, cursortype); if (!pcur) return NULL; void *cursor = sp_cursor(db->db, order, begin, (size_t)bsize); if (!cursor) { PyObject_Del(pcur); PyErr_SetString(SophiaError, sp_error(db->db)); return NULL; } Py_INCREF(db); db->cursors++; pcur->db = db; pcur->cursor = cursor; return (PyObject *)pcur; }
todo_db_t * todo_db_new (char *path) { int rc; void *env; todo_db_t *db = malloc(sizeof(todo_db_t)); // bail if failed to allocate memoery if (NULL == db) return NULL; env = sp_env(); // error in memoery allocation if (NULL == env) return NULL; // create if not exists in read-write mode rc = sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, path); // turn on garbage collection sp_ctl(env, SPGC, 1); if (-1 == rc) { todo_ferror("%s\n", sp_error(env)); sp_destroy(env); return NULL; } db->env = env; db->path = path; return db; }
static PyObject * sophia_db_set_option(SophiaDB *db, PyObject *args) { int rv, option; PyObject *pvalue, *pvalue2 = NULL; if (!PyArg_ParseTuple(args, "iO|O:setopt", &option, &pvalue, &pvalue2)) return NULL; if (option == SPCMP) { return sophia_db_set_cmp_fun(db, pvalue); } else if (option == SPPAGE || option == SPMERGEWM) { uint32_t value; if (pylong_to_uint32_t(pvalue, &value) == -1) return NULL; rv = sp_ctl(db->env, option, value); } else if (option == SPGC || option == SPMERGE) { int value = PyObject_IsTrue(pvalue); if (value == -1) return NULL; rv = sp_ctl(db->env, option, value); } else if (option == SPGCF) { double value; if (pyfloat_to_double(pvalue, &value) == -1) return NULL; rv = sp_ctl(db->env, option, value); } else if (option == SPGROW) { if (pvalue2 == NULL) { PyErr_SetString(PyExc_ValueError, "expected a third argument"); return NULL; } uint32_t new_size; double resize; if (pylong_to_uint32_t(pvalue, &new_size) == -1 || pyfloat_to_double(pvalue2, &resize) == -1) return NULL; rv = sp_ctl(db->env, option, new_size, resize); } else { PyErr_SetString(PyExc_ValueError, "unknown option"); return NULL; } if (rv == -1) { PyErr_SetString(SophiaError, sp_error(db->env)); return NULL; } Py_RETURN_NONE; }
static void error_nonfatal(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); void *db = sp_open(env); t( db != NULL ); uint32_t k = 1, v = 1; t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); t( sp_set(db, &k, UINT16_MAX + 1 , &v, sizeof(v)) == -1); t( sp_error(db) != NULL ); t( sp_set(db, &k, sizeof(k), &v, sizeof(v)) == 0); t( sp_error(db) == NULL ); t( sp_destroy(db) == 0 ); t( sp_destroy(env) == 0 ); t( rmrf(dbrep) == 0 ); }
static PyObject * sophia_db_rollback(SophiaDB *db) { ensure_is_opened(db, NULL); if (sp_rollback(db->db) == -1) { PyErr_SetString(SophiaError, sp_error(db->db)); return NULL; } Py_RETURN_NONE; }
int todo_db_open (todo_db_t *db) { db->dbh = sp_open(db->env); if (NULL == db->dbh) { todo_ferror("%s\n", sp_error(db->env)); sp_destroy(db->env); return -1; } return 0; }
/* Destroy the underlying sophia database iff no cursors are still in use, * as it would be impossible to destroy them afterwards (trying to do so results * in a segfault). If a cursor is still in use, mark the python database as * "to be closed", and effectively close it when the last remaining cursor * has been destroyed. A call to `Database.open()` sets the marker "to be closed" * to false. */ static int sophia_db_close_internal(SophiaDB *db) { if (!db->db) return 1; if (db->cursors > 0) { return 0; } if (sp_destroy(db->db) == -1) { PyErr_SetString(SophiaError, sp_error(db->env)); return -1; } db->db = NULL; return 1; }
static void limit_value(void) { void *env = sp_env(); t( env != NULL ); t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 ); t( sp_ctl(env, SPCMP, cmp, NULL) == 0 ); void *db = sp_open(env); t( db != NULL ); char buf[1]; t( sp_set(db, buf, sizeof(buf), buf, UINT32_MAX + 1ULL) == -1 ); t( sp_error(db) != NULL ); t( sp_destroy(db) == 0 ); t( sp_destroy(env) == 0 ); rmrf(dbrep); }
int main(int argc, char * argv[]) { if (argc != 3) usage(argv[0]); int n = atol(argv[2]); srand(701888); env = sp_env(); sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, "./sophia_bench_data"); db = sp_open(env); if (db == NULL) { printf("open: %s\n", sp_error(env)); return 1; } int rc = 0; unsigned long long start = now(); switch (benchof(argv[1])) { case SETSEQ: rc = setseq(n); break; case SETRAND: rc = setrand(n); break; case GETSEQ:rc = getseq(n); break; case GETRAND: rc = getrand(n); break; case RANGEFWD: rc = rangefwd(n); break; case UNKNOWN: printf("unknown operation\n"); } if (rc == 0) { unsigned long long diff = now() - start; float rps = n / (diff / 1000.0); printf("%d rps\n", (int)rps); } if (keytraversed > 0 && keytraversed != n) printf("(%d keys traversed)\n", keytraversed); sp_destroy(db); sp_destroy(env); return rc; }
int todo_db_set (todo_db_t *db, char *key, char *value) { if (NULL == db->dbh) { todo_ferror("Attempting set on unopened database at '%s'\n", db->path); return -1; } int rc = sp_set(db->dbh, strdup(key), strlen(key), strdup(value), strlen(value)); if (-1 == rc) { todo_ferror("Error setting '%s'. sophia: '%s'\n", key, sp_error(db->dbh)); return rc; } return 0; }
static int setseq(int n) { int rc; int i; for (i = 0; i < n; i++) { memcpy(key + 8, &keyseq, sizeof(keyseq)); keyseq++; rc = sp_set(db, key, sizeof(key), value, sizeof(value)); if (rc == -1) { printf("sp_set: %s\n", sp_error(db)); return 1; } print_current(i); } return 0; }
static int rangefwd(int n) { void *c = sp_cursor(db, SPGTE, NULL, 0); if (c == NULL) { printf("cursor failed: %s\n", sp_error(db)); return 1; } while (sp_fetch(c)) { const char *k = sp_key(c); size_t sz = sp_valuesize(c); (void)k; (void)sz; keytraversed++; } sp_destroy(c); return 0; }
/* Count the number of records in the database. This is O(n) time, * and then absolutely inefficient, but keeping an up-to-date counter * of the records would require to check the existence of a record before * each insert or delete operation, which would be very costly at the end. */ static PyObject * sophia_db_count_records(SophiaDB *db) { size_t count = 0; ensure_is_opened(db, NULL); void *cur = sp_cursor(db->db, SPGT, NULL, 0); if (!cur) { PyErr_SetString(SophiaError, sp_error(db->db)); return NULL; } while ((sp_fetch(cur))) count++; sp_destroy(cur); return PyLong_FromSize_t(count); }
jint JNICALL Java_eu_unicredit_sophia_SophiaInterface_sp_1error (JNIEnv * env, jobject obj, jlongArray args) { jlong* array = (*env)->GetLongArrayElements(env, args,JNI_FALSE); jint size = (*env)->GetArrayLength(env, args); int ret = -1; switch(size) { case 0: printf("Not supported\n"); break; case 1: ret = sp_error((void*)array[0]); break; default: printf("Not supported\n"); break; }; return (jint)ret; }
static int getseq(int n) { int rc; int i; for (i = 0; i < n; i++) { memcpy(key + 8, &keyseq, sizeof(keyseq)); keyseq++; void *v = NULL; size_t vsize = 0; rc = sp_get(db, key, sizeof(key), &v, &vsize); if (rc <= 0) { printf("get: %s\n", sp_error(db)); break; } free(v); print_current(i); } return 0; }
static PyObject * sophia_db_delete(SophiaDB *db, PyObject *args) { char *key; PyObject *pkey; Py_ssize_t ksize; ensure_is_opened(db, NULL); if (!PyArg_UnpackTuple(args, "delete", 1, 1, &pkey) || PyBytes_AsStringAndSize(pkey, &key, &ksize) == -1) return NULL; if (sp_delete(db->db, key, (size_t)ksize) == -1) { PyErr_SetString(SophiaError, sp_error(db->db)); return NULL; } Py_RETURN_NONE; }
static PyObject * sophia_db_set(SophiaDB *db, PyObject *args) { char *key, *value; PyObject *pkey, *pvalue; Py_ssize_t ksize, vsize; ensure_is_opened(db, NULL); if (!PyArg_UnpackTuple(args, "set", 2, 2, &pkey, &pvalue) || PyBytes_AsStringAndSize(pkey, &key, &ksize) == -1 || PyBytes_AsStringAndSize(pvalue, &value, &vsize) == -1) return NULL; if (sp_set(db->db, key, (size_t)ksize, value, (size_t)vsize) == -1) { PyErr_SetString(SophiaError, sp_error(db->db)); return NULL; } Py_RETURN_NONE; }
static int setrand(int n) { int rc; int i; for (i = 0; i < n; i++) { uint32_t k = rand(); memcpy(key, &k, sizeof(k)); k = rand(); memcpy(key + 4, &k, sizeof(k)); k = rand(); memcpy(key + 8, &k, sizeof(k)); k = rand(); memcpy(key + 12, &k, sizeof(k)); rc = sp_set(db, key, sizeof(key), value, sizeof(value)); if (rc == -1) { printf("sp_set: %s\n", sp_error(db)); return 1; } print_current(i); } return 0; }
static PyObject * sophia_db_contains(SophiaDB *db, PyObject *args) { char *key; PyObject *pkey; Py_ssize_t ksize; ensure_is_opened(db, NULL); if (!PyArg_UnpackTuple(args, "get", 1, 1, &pkey) || PyBytes_AsStringAndSize(pkey, &key, &ksize) == -1) return NULL; int rv = sp_get(db->db, key, (size_t)ksize, NULL, NULL); switch (rv) { case 1: Py_RETURN_TRUE; case 0: Py_RETURN_FALSE; default: PyErr_SetString(SophiaError, sp_error(db->db)); return NULL; } }
sophiadb_t* db_init(void * conf) { conf_t * pconf = (conf_t *)conf; printf("size of datatype = %d\n",pconf->max_num); sophiadb_t* db = (sophiadb_t*) calloc(pconf->max_num, sizeof(sophiadb_t)); if (!db) { printf("error alloc size=%lu\n", sizeof(sophiadb_t)); exit(1); } assert(db); datatype_t * p = (datatype_t *)pconf->list_datatypes; spcmpf fcmp ; while(p) { fcmp = cmp0; if (p->number <= 0) { printf("error config parametr: number=%d \n", p->number ); free(db); return NULL; } db[p->number-1].type = p->type; db[p->number-1].datadir = p->datadir; switch (p->type) { case SPHDB_INT : db[p->number-1].datalen = sizeof(int32_t); fcmp = cmp32; break; case SPHDB_LONG : db[p->number-1].datalen = sizeof(int64_t); fcmp = cmp64; break; case SPHDB_STRING : db[p->number-1].datalen = SPHDB_STRLEN; break; default: printf("error: undefined config datatype\n"); free(db); exit(1); } printf("fcmp: fcmp=%x\n", fcmp); db[p->number-1].env = sp_env(); if (db[p->number-1].env == NULL) { /* memory allocation error */ printf("env error\n"); free(db); exit(1); } int rc = sp_ctl(db[p->number-1].env, SPDIR, SPO_CREAT|SPO_RDWR, p->datadir); if (rc == -1) { /* memory allocation error */ printf("error: %s\n", sp_error(db[p->number-1].env)); sp_destroy(db[p->number-1].env); free(db); exit(1); } if (fcmp != cmp0) { printf("%s type=%d %x\n", p->datadir, p->type , fcmp); rc = sp_ctl(db[p->number-1].env, SPCMP, fcmp, NULL); if (rc == -1) { /* memory allocation error */ printf("error: %s\n", sp_error(db[p->number-1].env)); sp_destroy(db[p->number-1].env); free(db); exit(1); } } db[p->number-1].db = sp_open(db[p->number-1].env); if (db[p->number-1].db == NULL) { printf("sp_open: %s\n", sp_error(db[p->number-1].env)); sp_destroy(db[p->number-1].env); exit(1); } p = p->next; } printf("db is open %s\n", pconf->datadir ); return db; }
int sp_close(SP_FILE *sp) { char *proc="sp_close " SPHERE_VERSION_STR; char *write_name; char *read_name; SP_INTEGER lint=0, header_size=0, data_size=0; int header_changed=FALSE; SPIFR *spifr; SPSTATUS *w_spstat, *r_spstat; int ret, verify_checksum=FALSE; if (sp_verbose > 10) fprintf(spfp,"Proc %s:\n",proc); if (sp == SPNULL) return_err(proc,100,100,"Null SPFILE pointer"); w_spstat = sp->write_spifr->status; r_spstat = sp->read_spifr->status; write_name = (w_spstat->external_filename == CNULL) ? CNULL : mtrf_strdup(sp->write_spifr->status->external_filename); read_name = (r_spstat->external_filename == CNULL) ? CNULL : mtrf_strdup(r_spstat->external_filename); if (sp->open_mode == SP_mode_update) { if (sp_verbose > 10) fprintf(spfp,"Proc %s: Mode SP_update\n",proc); if (w_spstat->write_occured_flag) { /* if there has been a spwrite, then the waveform is written */ /* as if it were a file opened for write */ /* Step 1: recursively call sp_close, changing the mode to write */ /* Step 2: delete the previous file */ /* Step 3: rename the temporary file */ if (sp_verbose > 15) fprintf(spfp,"Proc %s: Overwriting the original waveform\n", proc); sp->open_mode = SP_mode_write; if ((ret=sp_close(sp)) != 0){ unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_child(proc,int,ret); } unlink(read_name); rename(write_name,read_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_success(proc,0,0,"ok"); } else { /* the header has been changed and the data mode of the waveform */ /* COULD BE CHANGED the waveform has not been modified in any */ /* way, only the header has changed */ /* Step 1: write the header into the temporary file */ /* Step 2: If the header changed in size OR the waveform */ /* format has changed */ /* A: copy the waveform into the temp file */ /* B: close the files */ /* C: delete the old file in favor of the new file */ /* Else the header has not changed in size. */ /* A: write the header into the original file */ /* B: Close both files */ /* C: delete the temporary file */ FILE *fp; int samples_read, samples_written; /* Step 1: */ spifr = sp->write_spifr; fp = ((spifr->waveform->sp_fp != FPNULL) ? (spifr->waveform->sp_fp) : ((spifr->waveform->sp_fob->fp != FPNULL) ? (spifr->waveform->sp_fob->fp) : FPNULL)); if (sp_verbose > 15) fprintf(spfp, "Proc %s: Writing header to temp file. position %d\n", proc,ftell(fp)); if (fp == FPNULL){ free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3000,3000,"Internal Error"); } /* Write the header into the temporary file to compute the size */ /* of the header and then rewind back over the just written header*/ rewind(fp); if (sp_write_header(fp,spifr->status->file_header, &header_size,&data_size) < 0){ free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3001,3001, "Unable to update header in file"); } rewind(fp); /* Step 2 - - if the header size or waveform has changed */ if ((sp->read_spifr->waveform->header_data_size != header_size) || (w_spstat->file_encoding != r_spstat->file_encoding) || (w_spstat->file_compress != r_spstat->file_compress) || (w_spstat->file_sbf != r_spstat->file_sbf) || (w_spstat->channels != CHANNELSNULL)){ char *buff; int ns, nc, in_nspb, out_nspb; if (sp_verbose > 15) { fprintf(spfp,"Proc %s: output header and/or",proc); fprintf(spfp,"data has changed, copying file.\n"); fprintf(spfp,"Proc %s: from %d to %d\n",proc, sp->read_spifr->waveform->header_data_size, header_size); } ns = r_spstat->user_sample_count; nc = r_spstat->user_channel_count; in_nspb = r_spstat->user_sample_n_bytes * r_spstat->user_channel_count; out_nspb = w_spstat->user_sample_n_bytes * w_spstat->user_channel_count; if ((buff=mtrf_malloc(nc * in_nspb * 4096)) == CNULL) { free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3010,3010, "Unable to malloc transfer buffer space"); } /* A: */ do { sp->open_mode = SP_mode_read; samples_read = sp_read_data(buff,4096,sp); if (samples_read > 0) { sp->open_mode = SP_mode_write; samples_written = sp_write_data(buff,samples_read,sp); if (samples_written != samples_read){ free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3012,3012, "Copy of waveform data failed"); } } else { if (sp_eof(sp) == 0) { free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3013,3013, "Error: Zero samples read while not at EOF"); } if (sp_error(sp) >= 100) { /* a checksum error occured, close the sp and */ /* delete the temp file */ sp->open_mode = SP_mode_update; sp_print_return_status(spfp); free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); mtrf_free(buff); return_err(proc,3011,3011, "Error copying waveform data"); } } sp->open_mode = SP_mode_update; } while (samples_read > 0); mtrf_free(buff); /* make sure the file is at eof (as if it were opened for */ /* read) */ sp->open_mode = SP_mode_read; if (! sp_eof(sp)){ sp->open_mode = SP_mode_update; free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3012,3012,"Error copying waveform data"); } sp->open_mode = SP_mode_write; if ((ret=sp_close(sp)) != 0){ unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_child(proc,int,ret); } /* C: */ unlink(read_name); rename(write_name,read_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_success(proc,0,0,"ok"); } else { /* A: */ spifr = sp->read_spifr; fp = ((spifr->waveform->sp_fp != FPNULL) ? (spifr->waveform->sp_fp) : ((spifr->waveform->sp_fob->fp != FPNULL) ? (spifr->waveform->sp_fob->fp) : FPNULL)); if (fp == FPNULL) return_err(proc,3002,3002,"Internal Error"); rewind(fp); if (sp_verbose > 15) fprintf(spfp, "Proc %s: header size not changed. position %d\n", proc,ftell(fp)); if (sp_write_header(fp,w_spstat->file_header, &header_size,&data_size) < 0){ free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3003,3003, "Unable to update header in file"); } /* B: */ free_sphere_t(sp); /* C: */ unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_success(proc,0,0,"ok"); } } } /* END of update mode file */ if (sp->open_mode == SP_mode_write) { if (sp_verbose > 10) fprintf(spfp, "Proc %s: Mode SP_mode_write\n",proc); spifr = sp->write_spifr; /* flush the data to the file */ if (spifr->status->is_disk_file) fob_fflush(spifr->waveform->sp_fob); /* if the mode is write, update the sample_count and checksum */ /* field if needed. If the checksum field exists, verify it, */ /* and warn if it's not the same */ /************ ONLY UPDATE FIELDS IF THE FILE IS NOT A STREAM *********/ if (spifr->status->is_disk_file){ h_get_field(w_spstat->file_header, SAMPLE_COUNT_FIELD, T_INTEGER, (void *)&lint); if (spifr->waveform->samples_written != lint) { /* then update the field */ lint = (SP_INTEGER) spifr->waveform->samples_written; spifr->status->file_sample_count = lint; /* temporarily reset the write occured flag to allow header */ /* modifications */ w_spstat->write_occured_flag = FALSE; if (sp_h_set_field(sp,SAMPLE_COUNT_FIELD,T_INTEGER,&lint) !=0){ if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,200,200,"Unable to update sample_count"); } /* Reset the write occured flag */ w_spstat->write_occured_flag = TRUE; header_changed = TRUE; } if (h_get_field(spifr->status->file_header,SAMPLE_CHECKSUM_FIELD, T_INTEGER,(void *)&lint) != 0){ if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,201,201, "Unable to get sample_checksum for file on disk"); } if (lint != spifr->status->file_checksum) { /* then the checksum was just computed, so install it */ lint = (SP_INTEGER)spifr->waveform->checksum; /* temporarily reset the write occured flag to allow header */ /* modifications */ w_spstat->write_occured_flag = FALSE; if (sp_h_set_field(sp,SAMPLE_CHECKSUM_FIELD, T_INTEGER,&lint) >= 100){ if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,202,202,"Unable to update checksum"); } /* Reset the write occured flag */ w_spstat->write_occured_flag = TRUE; header_changed = TRUE; } else if (lint != spifr->waveform->checksum) { spifr->waveform->failed_checksum = TRUE; if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,203,203, rsprintf("Write verification of checksum failed on file %s", spifr->status->external_filename)); } } /* flush the updated header to the file */ if (header_changed) { FILE *fp; if (! spifr->status->is_disk_file) { if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,301,301, "Internal Error, header changed size on write to stdout"); } fp = ((spifr->waveform->sp_fp != FPNULL) ? (spifr->waveform->sp_fp) : ((spifr->waveform->sp_fob->fp != FPNULL) ? (spifr->waveform->sp_fob->fp) : FPNULL)); if (fp == FPNULL) { if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,300,300,"Internal Error"); } rewind(fp); if (sp_write_header(fp,spifr->status->file_header, &header_size,&data_size) < 0) { if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,204,204,"Unable to update header in file"); } } if ((spifr->status->is_temp_file == FALSE) && fob_is_fp(spifr->waveform->sp_fob)) { /* check to make sure the blocking has not changed */ if (header_changed) if (((data_size + PAD_MULT) / PAD_MULT) != ((spifr->waveform->header_data_size + PAD_MULT) /PAD_MULT)){ if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,205,205, "Header size has changed on update"); } } else { if (spifr->status->user_compress == spifr->status->file_compress){ if (fob_flush_to_fp(spifr->waveform->sp_fob, spifr->waveform->sp_fp) != 0){ if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,206,206,"Unable to flush data to disk"); } } else { /* do some compression */ FOB *comp_fob; /* 1. rewind the data */ /* 2. alloc FOB to compress into */ /* 3. compress the file */ /* 4. free the allocated FOB */ fob_rewind(spifr->waveform->sp_fob); if ((comp_fob = fob_create(spifr->waveform->sp_fp)) == FOBPNULL) { if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,207,207,"Unable to setup for compression"); } spifr->waveform->sp_fp = FPNULL; switch (spifr->status->file_compress){ char message[70]; case SP_wc_shorten: /* optimize the compression */ shorten_set_channel_count(spifr->status->file_channel_count); if (spifr->status->file_encoding == SP_se_ulaw) shorten_set_ftype("au"); else if (spifr->status->file_encoding == SP_se_pcm1) shorten_set_ftype("s8"); else if (spifr->status->file_encoding == SP_se_pcm2) if (spifr->status->file_sbf == SP_sbf_01) shorten_set_ftype("s16lh"); else shorten_set_ftype("s16hl"); if (sp_verbose > 15) shorten_dump_flags(spfp); if(setjmp(exitenv) == 0){ if (shorten_compress(spifr->waveform->sp_fob, comp_fob, message) < 0){ fob_destroy(comp_fob); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,208,208, rsprintf("Shorten Compression Failed - %s", message)); } } else return_err(proc,213,0,"Shorten Compression Aborted"); fob_fflush(comp_fob); break; case SP_wc_wavpack: if(setjmp(exitenv) == 0){ /* optimize the compression */ wavpack_set_progname( "wavpack" ); if (spifr->status->file_channel_count == 1) wavpack_set_monoflg(TRUE); else wavpack_set_monoflg(FALSE); wavpack_set_byteflg(spifr->status->file_sbf ==SP_sbf_1); if (sp_verbose > 15) wavpack_dump_interface(spfp); if (wavpack_pack(spifr->waveform->sp_fob, comp_fob)<0){ fob_destroy(comp_fob); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,209,209, "Wavpack Compression Failed"); } wavpack_free_progname(); fob_fflush(comp_fob); } else { return_err(proc,212,0,"Wavpack Compression Aborted"); } break; case SP_wc_shortpack: return_err(proc,211,211, "Unable to Compress using shortpack\n"); default: if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,210,210, "Unable to Compress the requested format\n"); } spifr->waveform->sp_fp = comp_fob->fp; fob_destroy(comp_fob); } } if ((sp->open_mode == SP_mode_write) || (sp->open_mode == SP_mode_update)) if (w_spstat->extra_checksum_verify) verify_checksum = TRUE; } free_sphere_t(sp); /*************************************************/ /* The file is now completely written and closed */ /*************************************************/ /**************************************************/ /* If the write verification is requested, do it */ if (verify_checksum) { if (strsame(write_name,"-")) { if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_warn(proc,1,1, "Unable to verify checksum, file went to STDOUT"); } if (verify_file_checksum(write_name) != 0){ sp_print_return_status(spfp); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,1000,1000, "Read Verification of written file failed"); } } if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_success(proc,0,0,"ok"); }