Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/vis12/src/lib/common/dyn-seq.c
ViewVC logotype

View of /branches/vis12/src/lib/common/dyn-seq.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1906 - (download) (as text) (annotate)
Sun Jun 3 07:01:19 2012 UTC (8 years, 5 months ago) by jhr
File size: 2152 byte(s)
  fix bug in dynamic sequence append
/*! \file dyn-seq.c
 *
 * \author John Reppy
 *
 * An implementation of dynamic sequences.
 */

/*
 * COPYRIGHT (c) 2012 The Diderot Project (http://diderot-language.cs.uchicago.edu)
 * All rights reserved.
 */

#include "Diderot/diderot.h"

// compute the address of the i'th element in the sequence
STATIC_INLINE void* ElemAddr(void *base, size_t elemSz, unsigned int i)
{
    return (void *)((char *)base + i*elemSz);
}

//! append an element to a sequence
Diderot_DynSeq_t *Diderot_DynSeqAppend (size_t elemSz, Diderot_DynSeq_t *seq, void *item)
{
    if (seq->nElems == seq->size) {
      // grow the data array
	unsigned int newSize = (seq->size < 64) ? seq->size + 8 : seq->size + 64;
	void *newData = CheckedAlloc (elemSz * newSize);
	Diderot_DynSeqCopy (elemSz, newData, seq);
	seq->size = newSize;
	seq->base = 0;
	FREE(seq->data);
	seq->data = newData;
    }
    unsigned int i = (seq->base + seq->nElems) % seq->size;
    seq->nElems++;
    memcpy(ElemAddr(seq->data, elemSz, i), item, elemSz);
    return seq;
}

//! prepend an element to a sequence
//Diderot_DynSeq_t *Diderot_DynSeqPrepend (size_t elemSz, void *, Diderot_DynSeq_t *);

//! concatenate two sequences
//Diderot_DynSeq_t *Diderot_DynSeqConcat (size_t elemSz, Diderot_DynSeq_t *, Diderot_DynSeq_t *);

//! \brief copy the elements of a sequence to an array
//! \param elemSz the size of the sequence elements in bytes
//! \param dst the destination array
//! \param seq the source sequence
//! \return the address of the element that follows the array
void *Diderot_DynSeqCopy (size_t elemSz, void *dst, Diderot_DynSeq_t *seq)
{
    unsigned int n = seq->nElems;
    if (seq->base + n > seq->size) {
      // sequence wraps around, so we need to copy it in two steps
	n = seq->size - seq->base;
	memcpy (dst, ElemAddr(seq->data, elemSz, seq->base), n*elemSz);
	dst = (void *)((char *)dst + n*elemSz);
	n = seq->nElems - n;
	memcpy (dst, ElemAddr(seq->data, elemSz, 0), n*elemSz);
	return (void *)((char *)dst + n*elemSz);
    }
    else {
	size_t cpySz = n*elemSz;
	memcpy (dst, ElemAddr(seq->data, elemSz, seq->base), cpySz);
	return (void *)((char *)dst + cpySz);
    }
}

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0