Example #1
0
static int fill_buffer(stream_t *s, char *buffer, int max_len)
{
    struct priv *p = s->priv;
    if (s->pos < 0)
        return -1;
    if (s->pos >= p->max_size) {
        if (stream_seek(p->original, s->pos) < 1)
            return -1;
        return stream_read(p->original, buffer, max_len);
    }
    // Size of file changes -> invalidate last block
    if (s->pos >= p->size - BLOCK_SIZE) {
        int64_t new_size = -1;
        stream_control(s, STREAM_CTRL_GET_SIZE, &new_size);
        if (new_size != p->size)
            set_bit(p, BLOCK_ALIGN(p->size), 0);
        p->size = MPMIN(p->max_size, new_size);
    }
    int64_t aligned = BLOCK_ALIGN(s->pos);
    if (!test_bit(p, aligned)) {
        char tmp[BLOCK_SIZE];
        stream_seek(p->original, aligned);
        int r = stream_read(p->original, tmp, BLOCK_SIZE);
        if (r < BLOCK_SIZE) {
            if (p->size < 0) {
                MP_WARN(s, "suspected EOF\n");
            } else if (aligned + r < p->size) {
                MP_ERR(s, "unexpected EOF\n");
                return -1;
            }
        }
        if (fseeko(p->cache_file, aligned, SEEK_SET))
            return -1;
        if (fwrite(tmp, r, 1, p->cache_file) != 1)
            return -1;
        set_bit(p, aligned, 1);
    }
    if (fseeko(p->cache_file, s->pos, SEEK_SET))
        return -1;
    // align/limit to blocks
    max_len = MPMIN(max_len, BLOCK_SIZE - (s->pos % BLOCK_SIZE));
    // Limit to max. known file size
    max_len = MPMIN(max_len, p->size - s->pos);
    return fread(buffer, 1, max_len, p->cache_file);
}
Example #2
0
void* malloc(size_t nbytes)
{
	if (nbytes == 0)
		return NULL;
	
	/* round number of units up to block size */
    size_t nunits = BLOCK_ALIGN(nbytes);

    Header *prevp;
    if ((prevp = freep) == NULL) {
		/* initialize free segment */
		Header *e = (Header *) MEMLOC;
		e->next = freep = prevp = &base; e->size = ALLOCSIZ;
		base.next = e; base.size = 0;
    }
    
    Header *p;
    for (p = prevp->next; ; prevp = p, p = p->next) {
		/* check block size */
		if (p->size >= nunits) {
			if (p->size == nunits) {
				/* exact */
				prevp->next = p->next;
			} else {
				/* allocate tail end */
				p->size -= nunits;
				p += p->size;		
				p->size = nunits;
			}
			
			/* move free pointer */
			freep = prevp;
			return BLOCK_PTR(p);
		}
		
		if (p == freep) {
			/* wrapped around free list; no blocks left */
			return NULL;
		}
    }
}
Example #3
0
static int
copy_blocks(int ifd, int ofd, unsigned long *offset, unsigned long *size)
{
	off_t cur;
	int amt;
	unsigned long len = 0;
	char buffer[SIZE];

	cur = lseek(ofd, 0, SEEK_CUR);

	if (cur % SIZE) {
		cur = BLOCK_ALIGN(cur);
		cur = lseek(ofd, cur, SEEK_SET);
	}

	*offset = (unsigned long) cur;
	while((amt = read(ifd, buffer, SIZE)) > 0) {
		write(ofd, buffer, amt);
		len += amt;
	}
	*size = len;
	return 0;
}