Esempio n. 1
0
chunk_reader::pointer chunk_reader::get(slice_reader & base, const chunk & chunk) {
	
	if(!base.seek(chunk.first_slice, chunk.offset)) {
		throw chunk_error("error seeking");
	}
	
	char magic[ARRAY_SIZE(chunk_id)];
	if(base.read(magic, 4) != 4 || memcmp(magic, chunk_id, ARRAY_SIZE(chunk_id))) {
		throw chunk_error("bad chunk magic");
	}
	
	pointer result = boost::make_shared<type>();
	
	switch(chunk.compression) {
		case Stored: break;
		case Zlib:   result->push(io::zlib_decompressor(), 8192); break;
		case BZip2:  result->push(io::bzip2_decompressor(), 8192); break;
	#ifdef HAVE_LZMA
		case LZMA1:  result->push(inno_lzma1_decompressor(), 8192); break;
		case LZMA2:  result->push(inno_lzma2_decompressor(), 8192); break;
	#else
		case LZMA1: case LZMA2:
			throw chunk_error("LZMA decompression not supported by this Inno Extract build");
	#endif
		default: throw chunk_error("unknown compression");
	}
	
	result->push(io::restrict(boost::ref(base), 0, int64_t(chunk.size)));
	
	return result;
}
Esempio n. 2
0
/* Insert word into chunk */
void chunk_insert_word(chunk_ptr cp, word_t wd, size_t offset) {
    if (cp == NULL && chunk_check_level >= 2) {
	chunk_error("Null Pointer", cp);
	return;
    }
    if (chunk_check_level >= 2 && offset >= cp->length) {
	chunk_error("Out of bounds insertion", cp);
	return;
    }
    cp->words[offset] = wd;
}
Esempio n. 3
0
static int check_err(int code, char *source) {
    char ebuf[100];
    if (code != 0) {
	sprintf(ebuf, "Error in %s.  Number %d\n", source, code);
	chunk_error(ebuf, NULL);
    }
    return code;
}
Esempio n. 4
0
/* Create a new chunk */
chunk_ptr chunk_new(size_t len) {
    size_t more_bytes = len == 0  ? 0 : WORD_BYTES * (len - 1);
    chunk_ptr cp = (chunk_ptr) malloc_or_fail(sizeof(chunk_t) + more_bytes,
					      "chunk_new");
    if (cp == NULL && chunk_check_level >= 1) {
	chunk_error("Could not allocate chunk", cp);
    }
    cp->length = len;
    return cp;
}
Esempio n. 5
0
/* Read chunk from file.  Return null pointer if fail. */
chunk_ptr chunk_read_legacy(int fd, bool *eofp) {
    unsigned char buf[CHUNK_MAX_SIZE];
    /* Must get enough bytes to read chunk length */
    size_t cnt = 0;
    size_t need_cnt = sizeof(chunk_t);
    while (cnt < need_cnt) {
	ssize_t n = read(fd, &buf[cnt], need_cnt-cnt);
	if (n < 0) {
	    chunk_error("Failed read", NULL);
	    if (eofp)
		*eofp = false;
	    return NULL;
	}
	if (n == 0) {
	    if (eofp)
		*eofp = true;
	    else
		chunk_error("Unexpected EOF", NULL);
	    return NULL;
	}
	cnt += n;
    }
    chunk_ptr creadp = (chunk_ptr) buf;
    size_t len = creadp->length;
    if (len > 1) {
	need_cnt += WORD_BYTES * (len - 1);
	while (cnt < need_cnt) {
	    ssize_t n = read(fd, &buf[cnt], need_cnt-cnt);
	    if (n < 0) {
		chunk_error("Failed read", NULL);
		if (eofp)
		    *eofp = false;
		return NULL;
	    }
	    cnt += n;
	}
    }
    if (eofp)
	*eofp = false;


    return chunk_clone(creadp);
}
Esempio n. 6
0
/* Get word from chunk */
word_t chunk_get_word(chunk_ptr cp, size_t offset) {
    if (cp == NULL && chunk_check_level >= 2) {
	chunk_error("Null Pointer", cp);
    }
    if (chunk_check_level >= 2 && offset >= cp->length) {
	err(false, "Out of bounds retrieval.  Length %lu, offset %lu",
	    cp->length, offset);
    }
    return cp->words[offset];
}
Esempio n. 7
0
/* Insert words from source chunk into destination chunk with designated offset */
void chunk_insert_chunk(chunk_ptr cdestp, chunk_ptr csrcp, size_t offset) {
    if (csrcp == NULL && chunk_check_level >= 2) {
	chunk_error("Null Source Pointer", csrcp);
	return;
    }
    size_t i;
    size_t len = (size_t) csrcp->length;
    for(i = 0; i < len; i++) {
	chunk_insert_word(cdestp, csrcp->words[i], i + offset);
    }
}
Esempio n. 8
0
/* Get double word from chunk.  Offset indicates position of first word */
dword_t chunk_get_dword(chunk_ptr cp, size_t offset) {
    if (cp == NULL && chunk_check_level >= 2) {
	chunk_error("Null Pointer", cp);
    }
    if (chunk_check_level >= 2 && offset+1 >= cp->length) {
	err(false, "Out of bounds retrieval.  Length %lu, offset %lu",
	    cp->length, offset+1);
    }
    dword_t result;
    result.w0 = cp->words[offset];
    result.w1 = cp->words[offset+1];
    return result;
}
Esempio n. 9
0
/* Replicate a chunk */
chunk_ptr chunk_clone(chunk_ptr cp) {
    if (cp == NULL && chunk_check_level >= 2) {
	chunk_error("Null Pointer", cp);
	return NULL;
    }
    chunk_ptr ncp = chunk_new(cp->length);
    ncp->length = cp->length;
    size_t i;
    for (i = 0; i < cp->length; i++) {
	    ncp->words[i] = cp->words[i];
    }
    return ncp;
}
Esempio n. 10
0
void chunk_deinit()
{
    buf_node* temp_node = buf_list_head;
    //create new head
    while (temp_node != NULL) {
        buf_list_head = temp_node;
        temp_node = temp_node->next;
        if (buf_list_head->buf != NULL)
            free_block(buf_list_head->buf, 2*CHUNK_MAX_SIZE*sizeof(char));
        else
            chunk_error("Chunk buffer was null in a buffer list node", NULL);

        free_block(buf_list_head, sizeof(buf_node));
    }

}
Esempio n. 11
0
/* Return 1 if successful, 0 if failed */
bool chunk_write(int fd, chunk_ptr cp) {
    unsigned char *bytes = (unsigned char *) cp;
    size_t len = cp->length;
    size_t more_bytes = len == 0  ? 0 : WORD_BYTES * (len - 1);
    size_t cnt = sizeof(chunk_t) + more_bytes;
    size_t save_cnt = cnt;
    while (cnt > 0) {
	ssize_t n = write(fd, bytes, cnt);
	if (n < 0) {
	    chunk_error("Failed write", cp);
	    return false;
	}
	bytes += n;
	cnt -= n;
    }
    chunks_sent ++;
    chunk_bytes_sent += save_cnt;
    return true;
}
Esempio n. 12
0
chunk_ptr chunk_read(int fd, bool* eofp)
{
    if (fd > maxfd)
    {
        // on first call, we zero the buffer set
        if (maxfd == 0)
        {
            FD_ZERO(&buf_set);
            FD_ZERO(&in_set);
        }
        maxfd = fd;
    }

    buf_node* curr_node = NULL;
    buf_node* temp_node = NULL;
    //create new head
    if (buf_list_head == NULL) {
        buf_list_head = calloc_or_fail(sizeof(buf_node), 1,
				       "chunk_read create head");
        buf_list_head->fd = fd;
#if RPT >= 5
        report(5, "created a node for fd %d as head\n", fd);
#endif
        buf_list_head->length = 0;
        buf_list_head->location = 0;
        buf_list_head->buf = calloc_or_fail(CHUNK_MAX_SIZE, 2,
					    "chunk_read create head buf");
        curr_node = buf_list_head;
    }
    // search for the fd in the buffer list, if it exists
    else {
        temp_node = buf_list_head;
        while (temp_node != NULL && curr_node == NULL) {
            if (fd == temp_node->fd) {
                curr_node = temp_node;
#if RPT >= 5
                report(5, "found node for fd %d\n", fd);
#endif
            }
            temp_node = temp_node->next;
        }
    }
    // if it doesn't exist, create the new fd buffer at the head of the list
    if (curr_node == NULL) {
        curr_node = calloc_or_fail(sizeof(buf_node), 1, "chunk_read create node");
        curr_node->fd = fd;
        curr_node->length = 0;
        curr_node->location = 0;
        curr_node->next = buf_list_head;
        curr_node->buf = calloc_or_fail(CHUNK_MAX_SIZE, 2,
					"chunk_read create head buf");
#if RPT >= 5
        report(5, "created a node for fd %d at head\n", fd);
#endif
        buf_list_head = curr_node;
    }

    // if we can copy to the beginning, then we copy to the beginning
    // (if the read point is past the beginning, and if the end of
    // the buffered data is past the midway point of the buffer)
    if (curr_node->length + curr_node->location >= CHUNK_MAX_SIZE
	&& curr_node->location > 0)
    {
        memmove(curr_node->buf, (char *)(curr_node->buf + curr_node->location),
		curr_node->length);
        curr_node->location = 0;
    }

    // read if possible - if there is space, if the inset contains it, and if we
    // want to use buffering (otherwise we don't want random buffer refills)
    if (((curr_node->length + curr_node->location) < CHUNK_MAX_SIZE)
	&& bufferReadBool && !(!(FD_ISSET(fd, &in_set))) )
    {
#if RPT >= 5
        report(5, "reading for %d\n", curr_node->fd);
#endif
        ssize_t n = read(curr_node->fd,
			 curr_node->buf + curr_node->location + curr_node->length,
			 CHUNK_MAX_SIZE);
        curr_node->length += n;
    }

#if RPT >= 5
    report(5, "about to get header for %d\n", fd);
#endif
    // get header of chunk
    size_t need_cnt = sizeof(chunk_t);
    unsigned char buf[CHUNK_MAX_SIZE];
    unsigned char* buf_ptr = (unsigned char*)buf;
    ssize_t n = buf_read(curr_node, eofp, buf_ptr, need_cnt);
    //ssize_t n = read(curr_node->fd, buf, need_cnt);
    if (n <= 0)
    {
	return NULL;
    }
#if RPT >= 5
    report(5, "about to get rest of chunk for fd %d\n", fd);
#endif
    // get rest of chunk
    chunk_ptr creadp = (chunk_ptr) buf_ptr;
    size_t len = creadp->length;
#if RPT >= 5
    report(5, "len needed: %d", len);
#endif
    if (len > 1) {
	need_cnt = WORD_BYTES * (len - 1);
#if RPT >= 5
        report(5, "head buf pointer at %p", buf_ptr);
#endif
        buf_ptr = (unsigned char *)(buf_ptr + n);
#if RPT >= 5
        report(5, "moved pointer to %p for rest", buf_ptr);
#endif
        ssize_t n = buf_read(curr_node, eofp, buf_ptr, need_cnt);
        //ssize_t n = read(curr_node->fd, buf_ptr, need_cnt);

        if (n < 0) {
            chunk_error("Failed read", NULL);
	    if (eofp)
		*eofp = false;
            return NULL;
        }
    }

#if RPT >= 5
    report(5, "exiting chunk_read_buffered_builtin!\n");
#endif
    if (eofp)
	*eofp = false;
    return chunk_clone(creadp);
}
Esempio n. 13
0
static ssize_t buf_read(buf_node* curr_node, bool* eofp,
			unsigned char* buf, int len)
{
    int cnt = 0;
    int copyLen = 0;
    while (cnt < len)
    {
#if RPT >= 5
        report(5, "waiting for %d bytes", (len - cnt));
#endif
        //if there's stuff in the buffer, copy it over
        if (curr_node->length > 0)
        {
            copyLen = ((len - cnt) < curr_node->length ?
		       (len - cnt) : curr_node->length);
#if RPT >= 5
            report(5,
"copying a buffer of length %d from total length %d, to the return buffer",
		   copyLen, curr_node->length);
            report(5, "old length = %d, new length = %d",
		   curr_node->length, curr_node->length - copyLen);
#endif
            memcpy(buf + cnt,
		   curr_node->buf + curr_node->location, copyLen);
            cnt = cnt + copyLen;
            curr_node->length = curr_node->length - copyLen;
            if (curr_node->length == 0)
            {
                curr_node->location = 0;
            }
            else
            {
                curr_node->location = curr_node->location + copyLen;
            }
#if RPT >= 5
            report(5, "new location: %d\n", curr_node->location);
#endif
        }
        //otherwise, we refill the buffer
        else
        {
#if RPT >= 5
            report(5, "fill the saved buffer!");
#endif
            ssize_t n = read(curr_node->fd,
			     curr_node->buf + curr_node->location +
			     curr_node->length, CHUNK_MAX_SIZE);
            if (n < 0) {
                chunk_error("Failed read", NULL);
                if (eofp)
                    *eofp = false;
                toggle_buffered_in_set(curr_node);
                return n;
            }
            if (n == 0) {
                if (eofp)
                    *eofp = true;
                else
                    chunk_error("Unexpected EOF", NULL);
                toggle_buffered_in_set(curr_node);
                return n;
            }
            curr_node->length = curr_node->length + n;
#if RPT >= 5
            report(5,
"added %d bytes to the saved buffer; length is now %d at location %d\n",
		   n, curr_node->length, curr_node->location);
#endif
        }
    }


    toggle_buffered_in_set(curr_node);
    return (ssize_t)cnt;
}