Esempio n. 1
0
char *BufferProtocol::gather(size_t size)
{
    if(!input || size > bufsize)
        return NULL;

    if(size + bufpos > insize) {
        if(end)
            return NULL;

        size_t adjust = outsize - bufpos;
        memmove(input, input + bufpos, adjust);
        insize = adjust +  _pull(input, bufsize - adjust);
        bufpos = 0;

        if(insize < bufsize)
            end = true;
    }

    if(size + bufpos <= insize) {
        char *bp = input + bufpos;
        bufpos += size;
        return bp;
    }

    return NULL;
}
Esempio n. 2
0
int BufferProtocol::_getch(void)
{
    if(!input)
        return EOF;

    if(back) {
        back = 0;
        return back;
    }

    if(bufpos == insize) {
        if(end)
            return EOF;

        insize = _pull(input, bufsize);
        bufpos = 0;
        if(insize == 0)
            end = true;
        else if(insize < bufsize && !_blocking())
            end = true;

        if(!insize)
            return EOF;
    }

    return input[bufpos++];
}
Esempio n. 3
0
size_t BufferProtocol::get(void *address, size_t size)
{
    size_t count = 0;

    if(!input || !address || !size)
        return 0;

    char *cp = (char *)address;

    while(count < size) {
        if(bufpos == insize) {
            if(end)
                return count;

            insize = _pull(input, bufsize);
            bufpos = 0;
            if(insize == 0)
                end = true;
            else if(insize < bufsize && !_blocking())
                end = true;

            if(!insize)
                return count;
        }
        cp[count++] = input[bufpos++];
    }
    return count;
}
Esempio n. 4
0
size_t rbs_read(void *ptr, size_t size, size_t nmemb, rbstream_p rbsp)
{
	medvdbg("[%s] ptr %p nmemb %lu\n", __FUNCTION__, ptr, nmemb);
	RETURN_VAL_IF_FAIL(ptr != NULL, SIZE_ZERO);
	RETURN_VAL_IF_FAIL(rbsp != NULL, SIZE_ZERO);

	// only size:1 supported
	assert(size == 1);

	size_t len = size * nmemb;
	size_t read = SIZE_ZERO;

	while (read < len) {
		void *_ptr = (void *) ((uint8_t *) ptr + read);
		size_t need = len - read;
		size_t offset = rbsp->cur_pos - rbsp->rd_size;
		// read data desired
		size_t rlen = rb_read_ext(rbsp->rbp, _ptr, need, offset);
		read += rlen;
		rbsp->cur_pos += rlen; // increase cur_pos

		if (read < len) {
			// need to read more data
			size_t least = len - read;
			size_t avail = rb_avail(rbsp->rbp);
			if (least > avail) {
				// need to dequeue data
				if (RBS_OPTION_TEST(rbsp, OPTION_ALLOW_TO_DEQUEUE)) {
					offset = rbsp->cur_pos - rbsp->rd_size;
					size_t _len = MINIMUM(offset, (least - avail));
					size_t _rlen = rb_read(rbsp->rbp, NULL, _len);
					assert(_rlen == _len);
					rbsp->rd_size += _rlen;
				}
			}

			// pull stream data, then it's available to read more.
			if (_pull(rb_avail(rbsp->rbp), least, rbsp) == SIZE_ZERO) {
				// pull data failed
				break;
			}
		}
	}

	medvdbg("[%s] done, read %lu\n", __FUNCTION__, read);
	return read;
}
Esempio n. 5
0
int rbs_seek(rbstream_p rbsp, ssize_t offset, int whence)
{
	medvdbg("[%s] offset %ld, whence %d\n", __FUNCTION__, offset, whence);
	RETURN_VAL_IF_FAIL(rbsp != NULL, ERROR);

	switch (whence) {
	case SEEK_SET:
		// checking underflow
		RETURN_VAL_IF_FAIL(((size_t) offset >= rbsp->rd_size), ERROR);

		while ((size_t) offset > rbsp->wr_size) {
			size_t least = (size_t) offset - rbsp->wr_size;
			size_t wlen;

			// pull stream data, then wr_size will be increased
			wlen = _pull(rb_avail(rbsp->rbp), least, rbsp);

			if ((size_t) offset > rbsp->wr_size) {
				// not enough
				if (rb_avail(rbsp->rbp) == SIZE_ZERO) {
					// ring-buffer is full
					RETURN_VAL_IF_FAIL((RBS_OPTION_TEST(rbsp, OPTION_ALLOW_TO_DEQUEUE)), ERROR); // overflow

					// dequeue minimal data from ring-buffer
					size_t len = rbsp->wr_size - rbsp->rd_size;
					least = (size_t) offset - rbsp->wr_size;
					len = MINIMUM(len, least);
					size_t rlen = rb_read(rbsp->rbp, NULL, len);
					assert(rlen == len);
					rbsp->rd_size += rlen;
				} else {
					RETURN_VAL_IF_FAIL((wlen != SIZE_ZERO), ERROR);    // EOS
				}

				// request more data
				continue;
			}
			// got enough data
			break;
		}

		rbsp->cur_pos = (size_t) offset;
		break;
	}

	return OK;
}