Example #1
0
/**
 * Writes the browse host data of the context ``ctx'' to the buffer
 * ``dest''. This must be called multiple times to retrieve the complete
 * data until zero is returned i.e., the end of file is reached.
 *
 * This routine deals with query hit data generation.
 *
 * @param ctx an initialized browse host context.
 * @param dest the destination buffer.
 * @param size the amount of bytes ``dest'' can hold.
 *
 * @return -1 on failure, zero at the end-of-file condition or if size
 *         was zero. On success, the amount of bytes copied to ``dest''
 *         is returned.
 */
static ssize_t
browse_host_read_qhits(struct special_upload *ctx,
	void *const dest, size_t size)
{
	struct browse_host_upload *bh = cast_to_browse_host_upload(ctx);
	size_t remain = size;
	char *p = dest;

	/*
	 * If we have no hit pending that we can send, build some more.
	 */

	if (NULL == bh->hits) {
		pslist_t *files = NULL, *sl;
		int i;

		for (i = 0; i < BH_SCAN_AHEAD; i++) {
			shared_file_t *sf;

			do {
				/* Skip holes in indices */
				bh->file_index++;
				sf = shared_file_sorted(bh->file_index);
			} while (NULL == sf && bh->file_index <= shared_files_scanned());

			if (SHARE_REBUILDING == sf || NULL == sf)
				break;

			files = pslist_prepend(files, sf);
		}

		if (NULL == files)		/* Did not find any more file to include */
			return 0;			/* We're done */

		/*
		 * Now build the query hits containing the files we selected.
		 */

		files = pslist_reverse(files);			/* Preserve order */

		if (bh->flags & BH_F_G2) {
			g2_build_qh2_results(files, i, BH_MAX_QH2_SIZE,
				browse_host_record_qh2, bh, &blank_guid, 0);
		} else {
			qhit_build_results(files, i, BH_MAX_QHIT_SIZE,
				browse_host_record_hit, bh, &blank_guid, 0, &zero_array);
		}

		g_assert(bh->hits != NULL);		/* At least 1 hit enqueued */

		bh->hits = pslist_reverse(bh->hits);	/* Preserve order */
		PSLIST_FOREACH(files, sl) {
			shared_file_t *sf = sl->data;
			shared_file_unref(&sf);
		}
Example #2
0
/**
 * Writes the browse host data of the context ``ctx'' to the buffer
 * ``dest''. This must be called multiple times to retrieve the complete
 * data until zero is returned i.e., the end of file is reached.
 *
 * This routine deals with query hit data generation.
 *
 * @param ctx an initialized browse host context.
 * @param dest the destination buffer.
 * @param size the amount of bytes ``dest'' can hold.
 *
 * @return -1 on failure, zero at the end-of-file condition or if size
 *         was zero. On success, the amount of bytes copied to ``dest''
 *         is returned.
 */
static ssize_t
browse_host_read_qhits(struct special_upload *ctx,
	void *const dest, size_t size)
{
	struct browse_host_upload *bh = cast_to_browse_host_upload(ctx);
	size_t remain = size;
	char *p = dest;

	/*
	 * If we have no hit pending that we can send, build some more.
	 */

	if (NULL == bh->hits) {
		GSList *files = NULL;
		int i;

		for (i = 0; i < BH_SCAN_AHEAD; i++) {
			const shared_file_t *sf;

			do {
				/* Skip holes in indices */
				bh->file_index++;
				sf = shared_file_sorted(bh->file_index);
			} while (NULL == sf && bh->file_index <= shared_files_scanned());

			if (SHARE_REBUILDING == sf || NULL == sf)
				break;
			
			files = g_slist_prepend(files, deconstify_pointer(sf));
		}

		if (NULL == files)		/* Did not find any more file to include */
			return 0;			/* We're done */

		/*
		 * Now build the query hits containing the files we selected.
		 */

		files = g_slist_reverse(files);			/* Preserve order */

		qhit_build_results(files, i, BH_MAX_QHIT_SIZE,
			browse_host_record_hit, bh, &blank_guid, FALSE, &zero_array);

		g_assert(bh->hits != NULL);		/* At least 1 hit enqueued */

		bh->hits = g_slist_reverse(bh->hits);	/* Preserve order */
 		gm_slist_free_null(&files);
	}

	/*
	 * Read each query hit in turn.
	 */

	while (remain > 0 && NULL != bh->hits) {
		pmsg_t *mb = bh->hits->data;
		int r;

		r = pmsg_read(mb, p, remain);
		p += r;
		remain -= r;

		if (r == 0 || 0 == pmsg_size(mb)) {
			bh->hits = g_slist_remove(bh->hits, mb);
			pmsg_free(mb);
		}
	}

	return size - remain;
}