// (0, 0, 0) is at the left-back-bottom corner of chunck, same coord-system as OpenGL. void mapchunk_set_unit(MapChunk* mc, int x, int y, int z, int w) { assert(0 <= x && x < CHUNK_SIZE); assert(0 <= y && y < CHUNK_SIZE); assert(0 <= z && z < CHUNK_SIZE); assert(0 <= w && w < CHUNK_SIZE); // TODO(later): check if already exists at (x, y, z) // unsigned int u = (w << 24) | (z << 16) | (y << 8) | x; // see if chunk has enough space to set if (mc->pos >= mc->size) { chunk_grow(mc); } // mc->data[mc->pos++].value = u; MapUnit* mu = &(mc->data[mc->pos++]); mu->u.x = (unsigned char)x; mu->u.y = (unsigned char)y; mu->u.z = (unsigned char)z; mu->u.w = (unsigned char)w; }
/** Collapse data from the first N chunks from <b>buf</b> into buf->head, * growing it as necessary, until buf->head has the first <b>bytes</b> bytes * of data from the buffer, or until buf->head has all the data in <b>buf</b>. * * Set *<b>head_out</b> to point to the first byte of available data, and * *<b>len_out</b> to the number of bytes of data available at * *<b>head_out</b>. Note that *<b>len_out</b> may be more or less than * <b>bytes</b>, depending on the number of bytes available. */ void buf_pullup(buf_t *buf, size_t bytes, const char **head_out, size_t *len_out) { chunk_t *dest, *src; size_t capacity; if (!buf->head) { *head_out = NULL; *len_out = 0; return; } check(); if (buf->datalen < bytes) bytes = buf->datalen; capacity = bytes; if (buf->head->datalen >= bytes) { *head_out = buf->head->data; *len_out = buf->head->datalen; return; } if (buf->head->memlen >= capacity) { /* We don't need to grow the first chunk, but we might need to repack it.*/ size_t needed = capacity - buf->head->datalen; if (CHUNK_REMAINING_CAPACITY(buf->head) < needed) chunk_repack(buf->head); tor_assert(CHUNK_REMAINING_CAPACITY(buf->head) >= needed); } else { chunk_t *newhead; size_t newsize; /* We need to grow the chunk. */ chunk_repack(buf->head); newsize = CHUNK_SIZE_WITH_ALLOC(buf_preferred_chunk_size(capacity)); newhead = chunk_grow(buf->head, newsize); tor_assert(newhead->memlen >= capacity); if (newhead != buf->head) { if (buf->tail == buf->head) buf->tail = newhead; buf->head = newhead; } } dest = buf->head; while (dest->datalen < bytes) { size_t n = bytes - dest->datalen; src = dest->next; tor_assert(src); if (n >= src->datalen) { memcpy(CHUNK_WRITE_PTR(dest), src->data, src->datalen); dest->datalen += src->datalen; dest->next = src->next; if (buf->tail == src) buf->tail = dest; buf_chunk_free_unchecked(src); } else { memcpy(CHUNK_WRITE_PTR(dest), src->data, n); dest->datalen += n; src->data += n; src->datalen -= n; tor_assert(dest->datalen == bytes); } } check(); *head_out = buf->head->data; *len_out = buf->head->datalen; }