Beispiel #1
0
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;
}
Beispiel #4
0
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;
}
Beispiel #7
0
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;
}
Beispiel #9
0
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;
}
Beispiel #11
0
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;
}
Beispiel #13
0
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);
}
Beispiel #14
0
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;
}
Beispiel #15
0
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;
}
Beispiel #16
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;
}
Beispiel #17
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);
}
Beispiel #19
0
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;
}
Beispiel #20
0
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;
}
Beispiel #23
0
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;
    }
}
Beispiel #25
0
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;
}
Beispiel #26
0
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");
}