Exemplo n.º 1
0
/*
 * Read the entire contents of a file into a buffer.  This is a slight
 * optimization over buffer_read_all because it can stat the file descriptor
 * first and size the buffer appropriately.  buffer_read_all will still handle
 * the case where the file size changes while it's being read.  Returns true
 * on success, false on failure (in which case errno will be set).
 */
bool
buffer_read_file(struct buffer *buffer, int fd)
{
    struct stat st;
    size_t used = buffer->used + buffer->left;

    if (fstat(fd, &st) < 0)
        return false;
    buffer_resize(buffer, st.st_size + used);
    return buffer_read_all(buffer, fd);
}
Exemplo n.º 2
0
static int buffer_move_and_read_all (rtsp_client_t *client)
{
	if (buffer_len(client) == RECV_BUFF_DEFAULT_LEN)
	{
		dTRACE("buffer is full when read, len=%d\n", RECV_BUFF_DEFAULT_LEN);
		return RECV_BUFF_DEFAULT_LEN;
	}
	buffer_move_head(client);
	buffer_read_all(client);

	return buffer_len(client);
}
Exemplo n.º 3
0
int rtsp_recv_response (rtsp_client_t *client, rtsp_resp_t *response)
{
	const char *line;
	const char *p;
	rtsp_resp_t *decode;
	int done;
	int len;

	decode = response;
	
	if (buffer_move_and_read_all(client) == 0)
	{
		dTRACE("#######string buffer is null and no data recv\n");
		return -1;
	}

	do 
	{
		line = get_next_line(client);
		if (line == 0)
		{
			dTRACE("couldn't get response first line\n");
			return -1;
		}
	}
	while (*line == '\0');

	if (strncasecmp(line, "RTSP/1.0", strlen("RTSP/1.0")) != 0)
	{
		char str[20];
		
		p = line;
		while ( *p != ' ')
		{
			p++;
		}
		memcpy(str, line, p - line);
		str[p-line] = '\0';
		decode->caption = rtsp_strdup(str);
	}
	else
	{
		p = line + strlen("RTSP/1.0");
		SKIP_SPACE(p);
		memcpy(decode->retcode, p, 3);
		decode->retcode[3] = '\0';
		p += 3;
		SKIP_SPACE(p);
		decode->retresp = rtsp_strdup((char*)p);
		decode->caption = rtsp_strdup("RTSP/1.0");
	}

	done = 0;
	do
	{
		line = get_next_line(client);
		if (line == 0)
		{
			dTRACE("couldn't get line from response content\n");
			return -1;
		}

		if (*line != '\0')
		{
			rtsp_decode_header(line, response, client);
		}
		else
		{
            dTRACE("done ======= 1\n");
			done = 1;
		}
	}
	while (done == 0);
	if (decode->content_length != 0)
	{
		decode->body = (char*)malloc(decode->content_length + 1);
		decode->body[decode->content_length] = '\0';
		len = buffer_len(client);
		dTRACE("response body length=%d, current buffer size=%d, offset=%d\n", decode->content_length, len, client->m_offset_on);

		if (len < decode->content_length)
		{
			memcpy(decode->body, client->m_recv_buffer + client->m_offset_on, len);
			while (len < decode->content_length)
			{
				int left;
				int ret;

				client->m_offset_on = 0;
				client->m_buffer_len = 0;
				ret = buffer_read_all(client);
                if (ret <= 0)
				{
					dTRACE("recv fail at get rtsp body\n");
					return -1;
				}
                
				left = decode->content_length - len;
				if (left < client->m_buffer_len)
				{
					memcpy(decode->body + len, client->m_recv_buffer, left);
					len += left;
					client->m_offset_on = left;
				}
				else
				{
					memcpy(decode->body + len, client->m_recv_buffer, client->m_buffer_len);
					len += client->m_buffer_len;
					client->m_offset_on = client->m_buffer_len;
				}
			}
		}
		else
		{
			memcpy(decode->body, client->m_recv_buffer + client->m_offset_on, decode->content_length);
			client->m_offset_on += decode->content_length;
		}
	}

	if (decode->body != 0)
	{
        dTRACE("%s", decode->body);
	}

	dTRACE("complete recv response, buffer state: offset=%d len=%d\n", client->m_offset_on, buffer_len(client));

	return 0;
}
Exemplo n.º 4
0
int
main(void)
{
    struct buffer one = { 0, 0, 0, NULL };
    struct buffer two = { 0, 0, 0, NULL };
    struct buffer *three;
    int fd;
    char *data;
    ssize_t count;
    size_t offset;

    plan(89);

    /* buffer_set, buffer_append, buffer_swap */
    buffer_set(&one, test_string1, sizeof(test_string1));
    is_int(1024, one.size, "minimum size is 1024");
    is_int(0, one.used, "used starts at 0");
    is_int(sizeof(test_string1), one.left, "left is correct");
    is_string(test_string1, one.data, "data is corect");
    buffer_append(&one, test_string2, sizeof(test_string2));
    is_int(1024, one.size, "appended data doesn't change size");
    is_int(0, one.used, "or used");
    is_int(sizeof(test_string3), one.left, "but left is the right size");
    ok(memcmp(one.data, test_string3, sizeof(test_string3)) == 0,
       "and the resulting data is correct");
    one.left -= sizeof(test_string1);
    one.used += sizeof(test_string1);
    buffer_append(&one, test_string1, sizeof(test_string1));
    is_int(1024, one.size, "size still isn't larger after adding data");
    is_int(sizeof(test_string1), one.used, "and used is preserved on append");
    is_int(sizeof(test_string3), one.left, "and left is updated properly");
    ok(memcmp(one.data + one.used, test_string2, sizeof(test_string2)) == 0,
       "and the middle data is unchanged");
    ok(memcmp(one.data + one.used + sizeof(test_string2), test_string1,
              sizeof(test_string1)) == 0, "and the final data is correct");
    buffer_set(&one, test_string1, sizeof(test_string1));
    buffer_set(&two, test_string2, sizeof(test_string2));
    buffer_swap(&one, &two);
    is_int(1024, one.size, "swap #1 size is correct");
    is_int(0, one.used, "swap #1 used is correct");
    is_int(sizeof(test_string2), one.left, "swap #1 left is correct");
    is_string(test_string2, one.data, "swap #1 data is correct");
    is_int(1024, two.size, "swap #2 size is correct");
    is_int(0, two.used, "swap #2 used is correct");
    is_int(sizeof(test_string1), two.left, "swap #2 left is correct");
    is_string(test_string1, two.data, "swap #2 data is correct");
    free(one.data);
    free(two.data);
    one.data = NULL;
    two.data = NULL;
    one.size = 0;
    two.size = 0;

    /* buffer_resize */
    three = buffer_new();
    ok(three != NULL, "buffer_new works");
    if (three == NULL)
        bail("buffer_new returned NULL");
    is_int(0, three->size, "initial size is 0");
    buffer_set(three, test_string1, sizeof(test_string1));
    is_int(1024, three->size, "size becomes 1024 when adding data");
    buffer_resize(three, 512);
    is_int(1024, three->size, "resizing to something smaller doesn't change");
    buffer_resize(three, 1025);
    is_int(2048, three->size, "resizing to something larger goes to 2048");
    buffer_free(three);

    /* buffer_read, buffer_find_string, buffer_compact */
    fd = open("buffer-test", O_RDWR | O_CREAT | O_TRUNC, 0666);
    if (fd < 0)
        sysbail("cannot create buffer-test");
    data = bmalloc(2048);
    memset(data, 'a', 1023);
    data[1023] = '\r';
    data[1024] = '\n';
    memset(data + 1025, 'b', 1023);
    if (xwrite(fd, data, 2048) < 2048)
        sysbail("cannot write to buffer-test");
    if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
        sysbail("cannot rewind buffer-test");
    three = buffer_new();
    ok(three != NULL, "buffer_new works");
    if (three == NULL)
        bail("buffer_new returned NULL");
    is_int(0, three->size, "and initial size is 0");
    buffer_resize(three, 1024);
    is_int(1024, three->size, "resize to 1024 works");
    count = buffer_read(three, fd);
    is_int(1024, count, "reading into a buffer of size 1024 reads 1024");
    offset = 0;
    ok(!buffer_find_string(three, "\r\n", 0, &offset),
       "buffer_find_string with truncated string fails");
    is_int(0, offset, "and offset is unchanged");
    ok(memcmp(three->data, data, three->size) == 0, "buffer data is correct");
    buffer_resize(three, 2048);
    is_int(2048, three->size, "resizing the buffer to 2048 works");
    count = buffer_read(three, fd);
    is_int(1024, count, "and now we can read the rest of the data");
    ok(memcmp(three->data, data, 2048) == 0, "and it's all there");
    ok(!buffer_find_string(three, "\r\n", 1024, &offset),
       "buffer_find_string with a string starting before offset fails");
    is_int(0, offset, "and offset is unchanged");
    ok(buffer_find_string(three, "\r\n", 0, &offset),
       "finding the string on the whole buffer works");
    is_int(1023, offset, "and returns the correct location");
    three->used += 400;
    three->left -= 400;
    buffer_compact(three);
    is_int(2048, three->size, "compacting buffer doesn't change the size");
    is_int(0, three->used, "but used is now zero");
    is_int(1648, three->left, "and left is decreased appropriately");
    ok(memcmp(three->data, data + 400, 1648) == 0, "and the data is correct");
    count = buffer_read(three, fd);
    is_int(0, count, "reading at EOF returns 0");
    close(fd);
    unlink("buffer-test");
    free(data);
    buffer_free(three);

    /* buffer_sprintf and buffer_append_sprintf */
    three = buffer_new();
    buffer_append_sprintf(three, "testing %d testing", 6);
    is_int(0, three->used, "buffer_append_sprintf doesn't change used");
    is_int(17, three->left, "but sets left correctly");
    buffer_append(three, "", 1);
    is_int(18, three->left, "appending a nul works");
    is_string("testing 6 testing", three->data, "and the data is correct");
    three->left--;
    three->used += 5;
    three->left -= 5;
    buffer_append_sprintf(three, " %d", 7);
    is_int(14, three->left, "appending a digit works");
    buffer_append(three, "", 1);
    is_string("testing 6 testing 7", three->data, "and the data is correct");
    buffer_sprintf(three, "%d testing", 8);
    is_int(9, three->left, "replacing the buffer works");
    is_string("8 testing", three->data, "and the results are correct");
    data = bmalloc(1050);
    memset(data, 'a', 1049);
    data[1049] = '\0';
    is_int(1024, three->size, "size before large sprintf is 1024");
    buffer_sprintf(three, "%s", data);
    is_int(2048, three->size, "size after large sprintf is 2048");
    is_int(1049, three->left, "and left is correct");
    buffer_append(three, "", 1);
    is_string(data, three->data, "and data is correct");
    free(data);
    buffer_free(three);

    /* buffer_read_all */
    fd = open("buffer-test", O_RDWR | O_CREAT | O_TRUNC, 0666);
    if (fd < 0)
        sysbail("cannot create buffer-test");
    data = bmalloc(2049);
    memset(data, 'a', 2049);
    if (xwrite(fd, data, 2049) < 2049)
        sysbail("cannot write to buffer-test");
    if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
        sysbail("cannot rewind buffer-test");
    three = buffer_new();
    ok(buffer_read_all(three, fd), "buffer_read_all succeeds");
    is_int(0, three->used, "and unused is zero");
    is_int(2049, three->left, "and left is correct");
    is_int(4096, three->size, "and size is correct");
    ok(memcmp(data, three->data, 2049) == 0, "and data is correct");
    if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
        sysbail("cannot rewind buffer-test");
    ok(buffer_read_all(three, fd), "reading again succeeds");
    is_int(0, three->used, "and used is correct");
    is_int(4098, three->left, "and left is now larger");
    is_int(8192, three->size, "and size doubled");
    ok(memcmp(data, three->data + 2049, 2049) == 0, "and data is correct");

    /* buffer_read_file */
    if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
        sysbail("cannot rewind buffer-test");
    buffer_free(three);
    three = buffer_new();
    ok(buffer_read_file(three, fd), "buffer_read_file succeeds");
    is_int(0, three->used, "and leaves unused at 0");
    is_int(2049, three->left, "and left is correct");
    is_int(3072, three->size, "and size is a multiple of 1024");
    ok(memcmp(data, three->data, 2049) == 0, "and the data is correct");

    /* buffer_read_all and buffer_read_file errors */
    close(fd);
    ok(!buffer_read_all(three, fd), "buffer_read_all on closed fd fails");
    is_int(3072, three->size, "and size is unchanged");
    ok(!buffer_read_file(three, fd), "buffer_read_file on closed fd fails");
    is_int(3072, three->size, "and size is unchanged");
    is_int(2049, three->left, "and left is unchanged");
    unlink("buffer-test");
    free(data);
    buffer_free(three);

    /* buffer_vsprintf and buffer_append_vsprintf */
    three = buffer_new();
    test_append_vsprintf(three, "testing %d testing", 6);
    is_int(0, three->used, "buffer_append_vsprintf leaves used as 0");
    is_int(17, three->left, "and left is correct");
    buffer_append(three, "", 1);
    is_int(18, three->left, "and left is correct after appending a nul");
    is_string("testing 6 testing", three->data, "and data is correct");
    three->left--;
    three->used += 5;
    three->left -= 5;
    test_append_vsprintf(three, " %d", 7);
    is_int(14, three->left, "and appending results in the correct left");
    buffer_append(three, "", 1);
    is_string("testing 6 testing 7", three->data, "and the right data");
    test_vsprintf(three, "%d testing", 8);
    is_int(9, three->left, "replacing the buffer results in the correct size");
    is_string("8 testing", three->data, "and the correct data");
    data = bmalloc(1050);
    memset(data, 'a', 1049);
    data[1049] = '\0';
    is_int(1024, three->size, "size is 1024 before large vsprintf");
    test_vsprintf(three, "%s", data);
    is_int(2048, three->size, "and 2048 afterwards");
    is_int(1049, three->left, "and left is correct");
    buffer_append(three, "", 1);
    is_string(data, three->data, "and data is correct");
    free(data);
    buffer_free(three);

    /* Test buffer_free with NULL and ensure it doesn't explode. */
    buffer_free(NULL);

    return 0;
}
Exemplo n.º 5
0
void decode(const char* old_file, const char* diff_file, const char* target_file) {
  char *old_file_data;

  int old_file_size = mapfile(old_file, 0, (void*) &old_file_data);
  if (old_file_size < 0)
    exit(EXIT_FAILURE);

  struct delta_stream* stream = malloc(sizeof(struct delta_stream));
  stream->fd = open(diff_file, O_RDONLY);
  lseek(stream->fd, 7, SEEK_CUR); //Skip MMDELTA

  int new_file_size;
  char *new_file_data;
  read(stream->fd, &new_file_size, sizeof(int));
  if (mapfile(target_file, new_file_size, (void*) &new_file_data) < 0)
    exit(EXIT_FAILURE);

  lzma_stream_decoder(&stream->lzma, UINT64_MAX, LZMA_TELL_NO_CHECK);

  char* buffer;
  u_int32_t buffer_length = 0, buffer_offset, written = 0;
  u_int32_t last_length = 0;
  while (buffer_read_all(stream)) {
    for (int i=0;i<buffer_operations(stream).length;i++) {
      u_int32_t length;
      u_int8_t index;
      switch (buffer_operations(stream).data[i]) {
      case 'A':
      case 'C':
          if (buffer_length > 0) {
              memcpy(new_file_data + written, buffer + buffer_offset, buffer_length);
              written += buffer_length;
              buffer_length = 0;
          }
      }

      switch (buffer_operations(stream).data[i]) {
      case 'A':
        buffer_read(&buffer_lengths(stream), length);

        memcpy(new_file_data + written, buffer_data(stream).data + buffer_data(stream).offset, length);
        buffer_data(stream).offset += length;
        written += length;
        break;
      case 'C':
        buffer_read(&buffer_lengths(stream), buffer_length);
        buffer_read(&buffer_addresses(stream), buffer_offset);

        if (buffer_offset >= old_file_size / BLOCKSIZE) {
          buffer_offset -= old_file_size / BLOCKSIZE;
          buffer = new_file_data;
        } else
          buffer = old_file_data;

        buffer_offset *= BLOCKSIZE;
        last_length = 0;
        break;
      case 'E':
        buffer_read(&buffer_diff_index(stream), index);
        length = index+1;

        int position = buffer_read_uleb128(&buffer_offsets(stream)) - last_length;

        memcpy(new_file_data + written, buffer + buffer_offset, position);
        buffer_length -= position;
        buffer_offset += position;
        written += position;

        struct mismatch_diff *diff = mismatch_add_dec(buffer + buffer_offset, buffer_data(stream).data + buffer_data(stream).offset, length, written);
        buffer_data(stream).offset += length;

        memcpy(new_file_data + written, diff->new_data, length);
        buffer_length -= length;
        buffer_offset += length;
        written += length;
        last_length = length;
        break;
      case 'F':
        buffer_read(&buffer_diff_index(stream), index);
        length = (index & 0x3) + 1;
        index >>= 2;

        position = buffer_read_uleb128(&buffer_offsets(stream)) - last_length;

        memcpy(new_file_data + written, buffer + buffer_offset, position);
        written += position;
        buffer_length -= position;
        buffer_offset += position;

        if (index > 0) {
          diffs[length-1][index-1].last_usage = written;
          char mismatch_buffer[MAX_MISMATCHES];
          for (int i=0;i<length;i++) {
            mismatch_buffer[i] = patch(buffer[buffer_offset+i], diffs[length-1][index-1].diff_data[i]);
          }
          memcpy(new_file_data + written, mismatch_buffer, length);
        } else {
          struct mismatch_diff* diff = mismatch_find_data(buffer + buffer_offset, length);
          if (diff == NULL) {
            printf("Mismatch diff can't be found\n");
            exit(EXIT_FAILURE);
          }
          diff->last_usage = written;
          memcpy(new_file_data + written, diff->new_data, length);
        }

        buffer_length -= length;
        buffer_offset += length;
        last_length = length;
        written += length;
        break;
      default:
        fprintf(stderr, "Unsupported action '%c'\n", buffer_operations(stream).data[i]);
        exit(EXIT_FAILURE);
      }
    }
  }
  if (buffer_length > 0) {
    memcpy(new_file_data + written, buffer + buffer_offset, buffer_length);
  }
}