예제 #1
0
void
stress_test_array(int amt)
{
	array arr; /* matey! */
	gendata x;
	int i;

	arr = array_create();
	assert(array_size(arr) == 0);

	printf("Adding %d items to an array...\n", amt);
	for (i = 0; i < amt; ++i) {
		x.num = i;
		arr = array_add(arr, x);
		assert(x.num == array_get_data(arr, (unsigned int)i).num);
		assert(array_size(arr) == (unsigned int)(i + 1));
	}

	printf("Shrinking an array of %d items...\n", amt);
	for (i = amt - 1; i >= 0; --i) {
		assert(array_get_data(arr, (unsigned int)i).num == i);
		arr = array_remove(arr);
		assert(array_size(arr) == (unsigned int)i);
	}

	printf("Filling a pre-grown array of %d items...\n", amt);
	array_grow(arr, amt);
	assert(array_size(arr) == (unsigned int)amt);
	for (i = 0; i < amt; ++i) {
		x.num = i;
		arr = array_set_data(arr, (unsigned int)i, x);
		assert(x.num == array_get_data(arr, (unsigned int)i).num);
	}

	printf("Shrinking an array of %d items...\n", amt);
	for (i = amt - 1; i >= 0; --i) {
		assert(array_get_data(arr, (unsigned int)i).num == i);
		arr = array_shrink(arr, 1);

		assert(array_size(arr) == (unsigned int)i);
		/* Compactise at funky points */
		if ((i % COMPACTISE_MODULO) == 0) {
			arr = array_compact(arr);
			/* Compactising should not change size */
			assert(array_size(arr) == (unsigned int)i);
		}
	}

	array_destroy(arr, NULL);
}
예제 #2
0
string stack_pop_string(object store, string name)
{
    // error checking
    if (!array_exists(store,name))
        return "";
    int size=array_get_int(store,name,0);
    if (size==0)
        return "";
    else
    {
        string popped=array_get_string(store,name,size);
        array_shrink(store,name,size);
        array_set_int(store,name,0,size-1);

        return popped;
    }
}
예제 #3
0
object stack_pop_object(object store, string name)
{
/* No error checking :(
    // error checking
    if (!array_exists(store,name))
        return SDL_ERROR_DOES_NOT_EXIST;
*/
    int size=array_get_int(store,name,0);

/* no error checking :(
    if (size==0)
        return "";
*/
    object popped=array_get_object(store,name,size);
    array_shrink(store,name,size);
    array_set_int(store,name,0,size-1);

    return popped;
}
예제 #4
0
static void shrink(Process *p, Eterm* ret) 
{
    unsigned int range = HASH_RANGE(p->dictionary);
    unsigned int steps = (range*3) / 10;
    Eterm hi, lo, tmp;
    unsigned int i;
    Eterm *hp;
#ifdef DEBUG
    Eterm *hp_limit;
#endif

    if (range - steps < INITIAL_SIZE) {
	steps = range - INITIAL_SIZE; 
    }

    for (i = 0; i < steps; ++i) {
	ProcDict *pd = p->dictionary;
	if (pd->splitPosition == 0) {
	    pd->homeSize /= 2;
	    pd->splitPosition = pd->homeSize;
	}
	--(pd->splitPosition);
	hi = ARRAY_GET(pd, (pd->splitPosition + pd->homeSize));
	lo = ARRAY_GET(pd, pd->splitPosition);
	if (hi != NIL) {
	    if (lo == NIL) {
		array_put(&(p->dictionary), pd->splitPosition, hi);
	    } else {
		int needed = 4;
		if (is_list(hi) && is_list(lo)) {
		    needed = 2*erts_list_length(hi);
		}
		if (HeapWordsLeft(p) < needed) {
		    BUMP_REDS(p, erts_garbage_collect(p, needed, ret, 1));
		    hi = pd->data[(pd->splitPosition + pd->homeSize)];
		    lo = pd->data[pd->splitPosition];
		}
#ifdef DEBUG
		hp_limit = p->htop + needed;
#endif
		if (is_tuple(lo)) {
		    if (is_tuple(hi)) {
			hp = HeapOnlyAlloc(p, 4);
			tmp = CONS(hp, hi, NIL);
			hp += 2;
			array_put(&(p->dictionary), pd->splitPosition, 
				  CONS(hp,lo,tmp));
			hp += 2;
			ASSERT(hp <= hp_limit);
		    } else { /* hi is a list */
			hp = HeapOnlyAlloc(p, 2);
			array_put(&(p->dictionary), pd->splitPosition, 
				  CONS(hp, lo, hi));
			hp += 2;
			ASSERT(hp <= hp_limit);
		    }
		} else { /* lo is a list */
		    if (is_tuple(hi)) {
			hp = HeapOnlyAlloc(p, 2);
			array_put(&(p->dictionary), pd->splitPosition, 
				  CONS(hp, hi, lo));
			hp += 2;
			ASSERT(hp <= hp_limit);

		    } else { /* Two lists */
			hp = HeapOnlyAlloc(p, needed);
			for (tmp = hi; tmp != NIL; tmp = TCDR(tmp)) {
			    lo = CONS(hp, TCAR(tmp), lo);
			    hp += 2;
			}
			ASSERT(hp <= hp_limit);
			array_put(&(p->dictionary), pd->splitPosition, lo);
		    }
		}
	    }
	}
	array_put(&(p->dictionary), (pd->splitPosition + pd->homeSize), NIL);
    }
    if (HASH_RANGE(p->dictionary) <= (p->dictionary->size / 4)) {
	array_shrink(&(p->dictionary), (HASH_RANGE(p->dictionary) * 3) / 2);
    }
}
예제 #5
0
파일: tech.c 프로젝트: s0be/naev
/**
 * @brief Loads the tech information.
 */
int tech_load (void)
{
   int i, ret, s;
   uint32_t bufsize;
   char *buf, *data;
   xmlNodePtr node, parent;
   xmlDocPtr doc;
   tech_group_t *tech;

   /* Load the data. */
   data = ndata_read( TECH_DATA, &bufsize );
   if (data == NULL)
      return -1;

   /* Load the document. */
   doc = xmlParseMemory( data, bufsize );
   if (doc == NULL) {
      WARN("'%s' is not a valid XML file.", TECH_DATA);
      return -1;
   }

   /* Load root element. */
   parent = doc->xmlChildrenNode;
   if (!xml_isNode(parent,XML_TECH_ID)) {
      WARN("Malformed "TECH_DATA" file: missing root element '"XML_TECH_ID"'");
      return -1;
   }

   /* Get first node. */
   node = parent->xmlChildrenNode;
   if (node == NULL) {
      WARN("Malformed "TECH_DATA" file: does not contain elements");
      return -1;
   }

   /* Create the array. */
   tech_groups = array_create( tech_group_t );

   /* First pass create the groups - needed to reference them later. */
   ret   = 0;
   tech  = NULL;
   do {
      xml_onlyNodes(node);
      /* Must match tag. */
      if (!xml_isNode(node, XML_TECH_TAG)) {
         WARN("'"XML_TECH_ID"' has unknown node '%s'.", node->name);
         continue;
      }
      if (ret==0) /* Write over failures. */
         tech = &array_grow( &tech_groups );
      ret = tech_parseNode( tech, node );
   } while (xml_nextNode(node));
   array_shrink( &tech_groups );

   /* Now we load the data. */
   node  = parent->xmlChildrenNode;
   s     = array_size( tech_groups );
   do {
      /* Must match tag. */
      if (!xml_isNode(node, XML_TECH_TAG))
         continue;

      /* Must avoid warning by checking explicit NULL. */
      xmlr_attr( node, "name", buf );
      if (buf == NULL)
         continue;

      /* Load next tech. */
      for (i=0; i<s; i++) {
         tech  = &tech_groups[i];
         if (strcmp(tech->name, buf)==0)
            tech_parseNodeData( tech, node );
      }

      /* Free memory. */
      free(buf);
   } while (xml_nextNode(node));

   /* Info. */
   DEBUG("Loaded %d tech group%s", s, (s == 1) ? "" : "s" );

   /* Free memory. */
   free(data);
   xmlFreeDoc(doc);

   return 0;
}
예제 #6
0
파일: load.c 프로젝트: dpt/MotionMasks
result_t motionmaskplayer_load(motionmaskplayer_t *player,
                               const char         *filename)
{
  result_t    err;
  FILE       *f       = NULL;
  stream_t   *s       = NULL;
  uint32_t    signature;
  frame_t    *frames  = NULL;
  int         start;
  int         i;
  int         totalheights;
  mmoffset_t *offsets = NULL;
  mmdata_t   *data    = NULL;
  int         dataused;
  int         dataallocated;

  if (player->flags & player_FLAGS_LOADED)
  {
    free(player->frames);
    free(player->offsets);
    free(player->data);

    player->flags &= ~player_FLAGS_LOADED;
  }

  f = fopen(filename, "rb");
  if (f == NULL)
  {
    err = result_FILE_NOT_FOUND;
    goto failure;
  }

  err = stream_stdio_create(f, 1024, &s);
  if (err)
    goto failure;

  f = NULL; /* 'f' is now owned by the stream code */

  /* read file header */
  
  err = unpackfromstream(s,
                         format_HEADER_SIZE,
                         "<i2hii",
                         &signature,
                         &player->width,
                         &player->height,
                         &player->nframes);
  if (err)
    goto failure;

  if (signature != format_ID)
  {
    logf_fatal("header has bad signature");
    err = result_MMPLAYER_BAD_SIGNATURE;
    goto failure;
  }

  logf_info("header: width x height = %d x %d, nframes = %d",
            player->width,
            player->height,
            player->nframes);

  if (player->width <= 0 || player->height <= 0 || player->nframes <= 0)
  {
    logf_fatal("header has invalid dimensions");
    err = result_MMPLAYER_INVALID_DIMENSIONS;
    goto failure;
  }

  /* read frames */

  frames = malloc(player->nframes * sizeof(*frames));
  if (frames == NULL)
    goto oom;

  start = 0;

  for (i = 0; i < player->nframes; i++)
  {
    frame_t *frame = &frames[i];

    err = unpackfromstream(s,
                           format_FRAME_SIZE,
                           "<4hiC",
                           &frame->width,
                           &frame->height,
                           &frame->x,
                           &frame->y,
                           &frame->source);
    if (err)
      goto failure;

    logf_info("frame %d: width x height = %d x %d, x,y = %d,%d, source = %x",
              i,
              frame->width,
              frame->height,
              frame->x,
              frame->y,
              frame->source);

    if (frame->width <= 0 || frame->height <= 0)
    {
      err = result_MMPLAYER_INVALID_FRAME_DIMENSIONS;
      goto failure;
    }

    // FIXME: Expand checks for x,y and source fields.

    frame->start = start;

    start += player->height;
  }

  totalheights = start;

  /* unpack offsets. we'll need to work over them again later. */

  offsets = malloc(totalheights * sizeof(*offsets));
  if (offsets == NULL)
    goto oom;

  {
    int consumedoffsets;

    for (i = 0; i < totalheights; i += consumedoffsets)
    {
      stream_size_t availablebytes;
      stream_size_t availableoffsets;
      int32_t       maxavailableoffsets;

      availablebytes = stream_remaining_need_and_fill(s, 2);
      if (availablebytes == stream_EOF || availablebytes < 2)
      {
        err = result_MMPLAYER_TRUNCATED_INPUT;
        goto failure;
      }

      availableoffsets = availablebytes / 2;

      /* read up to the limit of the size of data we're anticipating */
      maxavailableoffsets = availableoffsets > INT32_MAX ?
                            INT32_MAX : (int32_t) availableoffsets;

      consumedoffsets = MIN(totalheights - i, maxavailableoffsets);
      if (consumedoffsets < 1)
      {
        err = result_MMPLAYER_TRUNCATED_INPUT;
        goto failure;
      }

      s->buf += unpack(s->buf, "<*hP", consumedoffsets, offsets + i);
    }
  }

  /* read data chunk */

  data          = NULL;
  dataused      = 0;
  dataallocated = 0;

  for (;;)
  {
    stream_size_t remaining;  // stream returns a ptrdiff_t actually

    remaining = stream_remaining_and_fill(s);
    if (remaining == stream_EOF)
      break; /* EOF (we assume) */

    if (array_grow((void **) &data,
                   sizeof(*data),
                   dataused,
                   &dataallocated,
                   (int) remaining,
                   1))
      goto oom;

    memcpy(data + dataused, s->buf, remaining);
    dataused += remaining;
    s->buf   += remaining;
  }

  if (data == NULL)
  {
    err = result_MMPLAYER_TRUNCATED_INPUT;
    goto failure;
  }

  if (array_shrink((void **) &data,
                   sizeof(*data),
                   dataused,
                   &dataallocated))
    goto oom;

  /* fix up offsets table now we know where 'data' lives */

  for (i = 0; i < totalheights; i++)
  {
    mmoffset_t o;

    o = offsets[i];
    
    /* verify the offsets (since a truncated data chunk cannot be detected
     * earlier on) */
    if ((intptr_t) o >= dataused)
    {
      logf_fatal("offset %d out of range\n", i);
      err = result_MMPLAYER_BAD_OFFSET;
      goto failure;
    }
    
    offsets[i] = data + (ptrdiff_t) o;
  }

  stream_destroy(s);

  player->frames  = frames;
  player->offsets = offsets;
  player->data    = data;
  player->ndata   = dataused;

  player->flags |= player_FLAGS_LOADED;

  return result_OK;


oom:

  err = result_OOM;

failure:

  if (f)
    fclose(f);

  stream_destroy(s);

  free(frames);
  free(offsets);
  free(data);

  return err;
}
예제 #7
0
파일: tests.c 프로젝트: garettbass/c-array
int main(int argc, const char* argv[]) {
    array_t(int) a = NULL;
    test(array_size(a) == 0);
    test(array_capacity(a) == 0);

    array_alloc(a, 0, destructed_element_count_destructor);
    test(array_size(a) == 0);
    test(array_capacity(a) == 0);


    array_append(a, 1);
    test(array_size(a) == 1);
    test(array_capacity(a) >= 1);
    test(a[0] == 1);


    array_append(a, 2);
    test(array_size(a) == 2);
    test(array_capacity(a) >= 2);
    test(a[0] == 1);
    test(a[1] == 2);


    array_append(a, 3);
    test(array_size(a) == 3);
    test(array_capacity(a) >= 3);
    test(a[0] == 1);
    test(a[1] == 2);
    test(a[2] == 3);


    array_insert(a, 0, 0);
    test(array_size(a) == 4);
    test(array_capacity(a) >= 4);
    test(a[0] == 0);
    test(a[1] == 1);
    test(a[2] == 2);
    test(a[3] == 3);


    array_reserve(a, 16);
    test(array_size(a) == 4);
    test(array_capacity(a) == 16);
    test(a[0] == 0);
    test(a[1] == 1);
    test(a[2] == 2);
    test(a[3] == 3);


    array_shrink(a);
    test(array_size(a) == 4);
    test(array_capacity(a) == 4);
    test(a[0] == 0);
    test(a[1] == 1);
    test(a[2] == 2);
    test(a[3] == 3);


    array_remove(a, 0);
    test(array_size(a) == 3);
    test(array_capacity(a) == 4);
    test(a[0] == 1);
    test(a[1] == 2);
    test(a[2] == 3);
    test(destructed_element_count == 1);
    destructed_element_count = 0;


    array_remove_unordered(a,0);
    test(array_size(a) == 2);
    test(array_capacity(a) == 4);
    test(a[0] == 3);
    test(a[1] == 2);
    test(destructed_element_count == 1);
    destructed_element_count = 0;


    array_clear(a);
    test(array_size(a) == 0);
    test(array_capacity(a) >= 0);
    test(destructed_element_count == 2);
    destructed_element_count = 0;


    array_append(a, 0);
    array_append(a, 1);
    array_append(a, 2);
    test(array_size(a) == 3);
    test(array_capacity(a) >= 3);
    test(destructed_element_count == 0);


    array_free(a);
    test(a == NULL);
    test(array_size(a) == 0);
    test(array_capacity(a) == 0);
    test(destructed_element_count == 3);
    destructed_element_count = 0;


    enum { TEST_LENGTH = 1024 };


    array_alloc(a, 0, destructed_element_count_destructor);
    for (int i = 0; i < TEST_LENGTH; ++i) {
        array_append(a, i);
        test(a[i] == i);
    }
    test(array_size(a) == TEST_LENGTH);
    test(array_capacity(a) >= TEST_LENGTH);
    for (int i = 0; i < TEST_LENGTH; ++i) {
        test(a[i] == i);
    }
    {
        int i = 0;
        const int* const end = array_end(a);
        for (int* itr = array_begin(a); itr < end; ++itr) {
            test(*itr == i++);
        }
    }
    {
        int i = 0;
        while (array_size(a)) {
            test(a[0] == i++);
            array_remove(a,0);
        }
        test(array_size(a) == 0);
        test(array_capacity(a) >= TEST_LENGTH);
        test(destructed_element_count == TEST_LENGTH);
        destructed_element_count = 0;
    }
    array_free(a);
    test(a == NULL);
    test(array_size(a) == 0);
    test(array_capacity(a) == 0);


    array_alloc(a, 0, destructed_element_count_destructor);
    for (int i = 0; i < TEST_LENGTH; ++i) {
        array_insert(a, 0, i);
    }
    test(array_size(a) == TEST_LENGTH);
    test(array_capacity(a) >= TEST_LENGTH);
    for (int i = 0; i < TEST_LENGTH; ++i) {
        test(a[i] == (TEST_LENGTH - 1) - i);
    }
    array_free(a);
    test(a == NULL);
    test(array_size(a) == 0);
    test(array_capacity(a) == 0);


    puts("array tests passed");
}