Commit 09cecd82 authored by Mikhail Karpenko's avatar Mikhail Karpenko
Browse files

Build file index directory instead of copying files

parent 3e396b5e
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -800,6 +800,9 @@ void camogm_set_prefix(camogm_state *state, const char * p, path_type type)
		} else {
			D0(fprintf(debug_file, "WARNING: raw device write initiated\n"));
			state->rawdev_op = 1;
			/* debug code follows */
			state->rawdev.end_pos = 10485760; // 10 Mib
			/* end of debug code */
		}
	}
}
@@ -1300,7 +1303,8 @@ int parse_cmd(camogm_state *state, FILE* npipe)
		return 28;
	} else if (strcmp(cmd, "rawdev_read") == 0) {
		if (state->rawdev_op)
			camogm_read(state);
//			camogm_read(state);
			build_index(state);
		return 29;
	}

+286 −123
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@

/** @brief This define is needed to use lseek64 and should be set before includes */
#define _LARGEFILE64_SOURCE
#define _XOPEN_SOURCE

#include <stdio.h>
#include <stdlib.h>
@@ -39,6 +40,7 @@
#define TIFF_HDR_OFFSET           12
/** @brief Separator character between seconds and microseconds in JPEG file name */
#define SUBSEC_SEPARATOR          '.'
#define EXIF_DATE_TIME_FORMAT     "%Y:%m:%d %H:%M:%S"
/** @brief The size of read buffer in bytes. The data will be read from disk in blocks of this size */
#define PHY_BLK_SZ                4096
/** @brief Include or exclude file start and stop markers from resulting file. This must be set to 1 for JPEG files */
@@ -115,6 +117,11 @@ enum file_ops {
	WRITE_STOP
};

enum search_state {
	SEARCH_SKIP,
	SEARCH_FILE_START,
	SEARCH_FILE_DATA
};
/**
 * @brief Exif data format table.
 *
@@ -207,6 +214,117 @@ struct crb_ptrs {
	struct iovec        second_buff;
};

void dump_index_dir(const struct disk_idir *idir)
{
	struct disk_index *ind = idir->head;

	while (ind != NULL) {
		fprintf(debug_file, "port number = %d; unix time = %ld; usec time = %06u; offset = 0x%010llx; file size = %u\n",
				ind->port, ind->rawtime, ind->usec, ind->f_offset, ind->f_size);
		ind = ind->next;
	}
}

int create_node(struct disk_index **index)
{
	fprintf(debug_file, "Creating new disk node\n");
	if (*index != NULL)
		return -1;

	*index = malloc(sizeof(struct disk_index));
	if (*index != NULL) {
		memset(*index, 0, sizeof(struct disk_index));
		fprintf(debug_file, "New disk node created\n");
		return 0;
	} else {
		fprintf(debug_file, "New disk node NOT created\n");
		return -1;
	}
}

int add_node(struct disk_idir *idir, struct disk_index *index)
{
	fprintf(debug_file, "Adding new disk node\n");
	if (idir->head == NULL && idir->tail == NULL) {
		idir->head = index;
		idir->tail = index;
		idir->size = 1;
	} else {
		index->prev = idir->tail;
		idir->tail->next = index;
		idir->tail = index;
		idir->size++;
	}

	fprintf(debug_file, "New disk node added\n");
	return idir->size;
}

struct disk_index *find_by_offset(const struct disk_idir *idir, uint64_t offset)
{
	struct disk_index *index = idir->head;

	while (index != NULL) {
		if (index->f_offset == offset)
			break;
		index = index->next;
	}

	return index;
}

int remove_node(struct disk_idir *idir, struct disk_index *node)
{
	if (node == NULL)
		return -1;

	if (node == idir->head) {
		idir->head = node->next;
		idir->head->prev = NULL;
	} else if (node == idir->tail) {
		idir->tail = node->prev;
		idir->tail->next = NULL;
	} else {
		struct disk_index *ind = idir->head;
		while (ind != NULL) {
			if (ind == node) {
				ind->prev->next = ind->next;
				ind->next->prev = ind->prev;
				break;
			}
			ind = ind->next;
		}
	}
	free(node);
	node = NULL;
	idir->size--;

	return idir->size;
}

int delete_idir(struct disk_idir *idir)
{
	fprintf(debug_file, "Deleting disk index directory\n");
	struct disk_index *curr_ind;
	struct disk_index *next_ind;

	if (idir == NULL || idir->head == NULL)
		return -1;

	curr_ind = idir->head;
	next_ind = curr_ind->next;
	while (curr_ind != NULL) {
		free(curr_ind);
		curr_ind = next_ind;
		if (curr_ind != NULL)
			next_ind = curr_ind->next;
	}
	idir->head = idir->tail = NULL;
	idir->size = 0;

	return 0;
}

/**
 * @brief Find pattern in a data buffer
 *
@@ -218,7 +336,8 @@ struct crb_ptrs {
 * @param[in]   pt_sz     size of the pattern array
 * @return      the index in data buffer where pattern matches or error code from #match_result if it was not found
 */
static int find_marker(const unsigned char * restrict buff_ptr, ssize_t buff_sz, const unsigned char * restrict pattern, ssize_t pt_sz)
static int find_marker(const unsigned char * restrict buff_ptr, ssize_t buff_sz, const unsigned char * restrict pattern, ssize_t pt_sz,
		int add_pattern)
{
	int ret = MATCH_NOT_FOUND;
	int j = 0;
@@ -233,6 +352,9 @@ static int find_marker(const unsigned char * restrict buff_ptr, ssize_t buff_sz,
			j++;
		} else if (buff_ptr[i] == pattern[j] && j == pt_sz - 1) {
			// last pattern symbol match
			if (add_pattern)
				ret = i;
			else
				ret = i - j;
			j = 0;
			break;
@@ -281,24 +403,18 @@ static void hdr_byte_order(struct tiff_hdr *hdr)
 * @param[in]   ifd     Exif image file directory record containing string offset
 * @param[out]  buff    buffer for the string
 * @return      The number of bytes placed to the read buffer
 * @todo update description
 */
static size_t exif_get_text(camogm_state *state, struct ifd_entry *ifd, char *buff)
static size_t exif_get_text(camogm_state *state, struct ifd_entry *tag, char *buff)
{
	size_t j = 0;
	size_t sz = ifd->len * exif_data_fmt[ifd->format];
	uint64_t curr_pos = state->rawdev.file_start + TIFF_HDR_OFFSET + ifd->offset;
	char read_buff[MAX_EXIF_SIZE] = {0};
	size_t bytes = 0;
	size_t str_len = tag->len * exif_data_fmt[tag->format];
	uint64_t curr_pos = state->rawdev.file_start + TIFF_HDR_OFFSET + tag->offset;

	lseek64(state->rawdev.rawdev_fd, curr_pos, SEEK_SET);
	read(state->rawdev.rawdev_fd, read_buff, sz);
	for (int i = 0; i < sz; i++) {
		if (isdigit(read_buff[i]))
			buff[j++] = read_buff[i];
		else if (isblank(read_buff[i]))
			buff[j++] = '_';
	}
	bytes = read(state->rawdev.rawdev_fd, buff, str_len);

	return j;
	return bytes;
}

/**
@@ -316,26 +432,34 @@ static size_t exif_get_text(camogm_state *state, struct ifd_entry *ifd, char *bu
 * @param[in]   state   a pointer to a structure containing current state
 * @param[out]  name    resulting file name
 * @return      0 if file name was successfully created and negative value otherwise
 * @todo update description
 */
static int make_fname(camogm_state *state, char *name)
static int save_index(camogm_state *state, struct disk_idir *idir)
{
	int ret = 0;
	int process = 2;
	size_t sz = 0;
	uint32_t data32;
	uint16_t num_entries = 0;
	uint64_t curr_pos;
	uint64_t subifd_offset = 0;
	struct tiff_hdr hdr;
	struct ifd_entry ifd;
	struct ifd_entry ifd_page_num;
	struct ifd_entry ifd_date_time;
	struct ifd_entry ifd_subsec;
	struct ifd_entry ifd_page_num = {0};
	struct ifd_entry ifd_date_time = {0};
	struct ifd_entry ifd_subsec = {0};
	struct disk_index *node = NULL;
	unsigned char read_buff[TIFF_HDR_OFFSET] = {0};
	char str_buff[32] = {0};
	uint64_t save_pos = lseek64(state->rawdev.rawdev_fd, 0, SEEK_CUR);

	if (name == NULL)
	fprintf(debug_file, "Adding new disk index to index directory\n");
	if (idir == NULL)
		return -1;

	if (create_node(&node) != 0)
		return -1;

	fprintf(debug_file, "%s: file start position 0x%llx\n", __func__, state->rawdev.file_start);
	curr_pos = state->rawdev.file_start;
	lseek64(state->rawdev.rawdev_fd, curr_pos, SEEK_SET);
	if (read(state->rawdev.rawdev_fd, read_buff, sizeof(read_buff)) <= 0) {
@@ -350,6 +474,7 @@ static int make_fname(camogm_state *state, char *name)
		lseek64(state->rawdev.rawdev_fd, curr_pos, SEEK_SET);
		// process IFD0 and SubIFD fields
		do {
			fprintf(debug_file, "%s: processing IFD\n", __func__);
			read(state->rawdev.rawdev_fd, &num_entries, sizeof(num_entries));
			num_entries = __be16_to_cpu(num_entries);
			for (int i = 0; i < num_entries; i++) {
@@ -378,29 +503,46 @@ static int make_fname(camogm_state *state, char *name)
			lseek64(state->rawdev.rawdev_fd, curr_pos, SEEK_SET);
		} while (process > 0);

		// assemble file name from collected Exif fields
		// fill disk index node with Exif data and add it to disk index directory
		fprintf(debug_file, "%s: filling node data\n", __func__);
		node->f_offset = state->rawdev.file_start;
		if (ifd_page_num.len != 0) {
			sz = sprintf(name, "%02lu_", ifd_page_num.offset);
			fprintf(debug_file, "%s: filling node data, page_num\n", __func__);
			node->port = (uint32_t)ifd_page_num.offset;
		}
		if (ifd_date_time.len != 0) {
			sz += exif_get_text(state, &ifd_date_time, name + sz);
			fprintf(debug_file, "%s: filling node data, date_time\n", __func__);
			struct tm tm;
			exif_get_text(state, &ifd_date_time, str_buff);
			strptime(str_buff, EXIF_DATE_TIME_FORMAT, &tm);
			node->rawtime = mktime(&tm);
		}
		if (ifd_subsec.len != 0) {
			name[sz++] = SUBSEC_SEPARATOR;
			sz += exif_get_text(state, &ifd_subsec, name + sz);
			fprintf(debug_file, "%s: filling node data, subsec\n", __func__);
			exif_get_text(state, &ifd_subsec, str_buff);
			node->usec = strtoul(str_buff, NULL, 10);
		}
		sprintf(name + sz, ".jpeg");
	} else {
		// a fallback option in case exif is not found - randomly generate file name
		int num;
		srand(time(NULL));
		num = rand();
		sprintf(name, "%010d.jpeg", num);
		D3(fprintf(debug_file, "Exif marker is not found not found, using randomly generated file name: %s\n", name));
		fprintf(debug_file, "%s: node data filled\n", __func__);
		if (node->rawtime != -1)
			add_node(idir, node);
		else
			ret = -1;
	}

	lseek64(state->rawdev.rawdev_fd, save_pos, SEEK_SET);
	return 0;
	return ret;
}

int stop_index(struct disk_idir *idir, uint64_t pos_stop)
{
	fprintf(debug_file, "Stop index at position 0x%llx\n", pos_stop);
	int ret = 0;
	if (idir->tail != NULL) {
		idir->tail->f_size = pos_stop - idir->tail->f_offset;
	} else {
		ret = -1;
	}
	return ret;
}

/**
@@ -429,7 +571,7 @@ static int start_new_file(struct file_opts *f_op)
		return -CAMOGM_NO_SPACE;
	}

	make_fname(f_op->state, file_name);
//	make_fname(f_op->state, file_name);
	sprintf(f_op->state->path, "%s%s", f_op->state->path_prefix, file_name);

	if ((f_op->fh = fopen(f_op->state->path, "w")) == NULL) {
@@ -560,30 +702,34 @@ static int write_buffer(struct file_opts *f_op, unsigned char *from, unsigned ch
 * analyzed for JPEG markers and then the data from buffer is written to a file.
 * @param[in]   state   a pointer to a structure containing current state
 * @return      0 if files were extracted successfully and negative error code otherwise
 * @todo update description, reorder decision tree
 */
int camogm_read(camogm_state *state)
int build_index(camogm_state *state)
{
	const int include_markers = INCLUDE_MARKERS;
	int process;
	int zero_cross;
	int file_op;
	int err;
	int pos_start, pos_stop;
	int buff_processed;
	int file_pos_saved;
	int search_state;
	int idir_result;
	ssize_t rd;
	unsigned char buff[PHY_BLK_SZ];
	unsigned char next_buff[PHY_BLK_SZ];
	unsigned char *active_buff = buff;
	unsigned char *save_from = NULL;
	unsigned char *save_to = NULL;
	struct file_opts f_opts;
//	struct file_opts f_opts;
	uint64_t dev_curr_pos = 0;
	uint64_t include_st_marker, include_en_marker;
	struct disk_idir index_dir = {0};
	size_t add_stm_len, add_enm_len;

	memset(&f_opts, 0, sizeof(struct file_opts));
	f_opts.file_state = WRITE_STOP;
	f_opts.state = state;

//	memset(&f_opts, 0, sizeof(struct file_opts));
//	f_opts.file_state = WRITE_STOP;
//	f_opts.state = state;
//
	state->rawdev.rawdev_fd = open(state->rawdev.rawdev_path, O_RDONLY);
	if (state->rawdev.rawdev_fd < 0) {
		D0(perror(__func__));
@@ -592,16 +738,21 @@ int camogm_read(camogm_state *state)
	}

	if (include_markers) {
		include_st_marker = elphel_st.iov_len;
		include_en_marker = elphel_en.iov_len;
		include_st_marker = 0;
		add_stm_len = elphel_st.iov_len;
		include_en_marker = 1;
		add_enm_len = 0;
	} else {
		include_st_marker = 0;
		include_en_marker = 0;
		add_stm_len = 0;
		include_en_marker = 1;
		add_enm_len = elphel_en.iov_len;
	}

	process = 1;
	zero_cross = 0;
	file_op = FILE_OK;
	search_state = SEARCH_SKIP;
	idir_result = 0;
	while (process) {
		rd = read(state->rawdev.rawdev_fd, buff, sizeof(buff));
		err = errno;
@@ -629,60 +780,70 @@ int camogm_read(camogm_state *state)
		if (process) {
			save_from = buff;
			save_to = buff + rd;
			active_buff = buff;
			buff_processed = 0;
			file_pos_saved = 0;
			do {
				// process data in read buffer
				pos_start = find_marker(save_from, save_to - save_from, elphel_st.iov_base, elphel_st.iov_len);
				pos_stop = find_marker(save_from, save_to - save_from, elphel_en.iov_base, elphel_en.iov_len);

				if (pos_start == MATCH_NOT_FOUND && pos_stop == MATCH_NOT_FOUND &&
						(f_opts.file_state == WRITE_RUNNING || f_opts.file_state == WRITE_START)) {
					// writing in progress, got full buffer of new data
					f_opts.file_state = WRITE_RUNNING;
					file_op = write_buffer(&f_opts, save_from, save_to);
				pos_start = find_marker(save_from, save_to - save_from, elphel_st.iov_base, elphel_st.iov_len, include_st_marker);
				pos_stop = find_marker(save_from, save_to - save_from, elphel_en.iov_base, elphel_en.iov_len, include_en_marker);
				fprintf(debug_file, "pos_start = %d, pos_stop = %d\n", pos_start, pos_stop);

				if (pos_start == MATCH_NOT_FOUND && pos_stop == MATCH_NOT_FOUND) {
					// normal condition, search in progress
					buff_processed = 1;
					D6(fprintf(debug_file, "State 'skip data'\n"));
				} else if (pos_start >= 0 && pos_stop == MATCH_NOT_FOUND && search_state == SEARCH_SKIP) {
					// normal condition, new file found
					search_state = SEARCH_FILE_DATA;
					state->rawdev.file_start = dev_curr_pos + pos_start + (save_from - active_buff);
					idir_result = save_index(state, &index_dir);
					buff_processed = 1;
					D6(fprintf(debug_file, "State 'writing'\n"));
				} else if (pos_start >= 0 /*&& pos_stop == MATCH_NOT_FOUND */ &&
						f_opts.file_state == WRITE_STOP) {
					// not writing, start marker found - start writing
					f_opts.file_state = WRITE_START;
					if (file_pos_saved == 0)
						state->rawdev.file_start = dev_curr_pos + pos_start;
					D6(fprintf(debug_file, "New file found. File start position: %llu\n", state->rawdev.file_start));
					save_from = save_from + pos_start + elphel_st.iov_len;
					file_op = write_buffer(&f_opts, save_from - include_st_marker, save_to);
					D6(fprintf(debug_file, "State 'starting file'\n"));
				} else if (pos_start >= 0 && pos_stop == MATCH_NOT_FOUND && search_state == SEARCH_FILE_DATA) {
					// error condition (normally should not happen), discard current index and start a new one
					buff_processed = 1;
					f_opts.file_state = WRITE_RUNNING;
					D6(fprintf(debug_file, "State 'starting file', file_op = %d\n", file_op));
					remove_node(&index_dir, index_dir.tail);
					if (zero_cross == 0) {
						state->rawdev.file_start = dev_curr_pos + pos_start + (save_from - active_buff);
						idir_result = save_index(state, &index_dir);
					} else {
						process = 0;
					}
					D6(fprintf(debug_file, "State 'abnormal start marker, remove current disk index from directory and skip data'\n"));
				} else if (pos_start == MATCH_NOT_FOUND && pos_stop >= 0 &&
						(f_opts.file_state == WRITE_RUNNING || f_opts.file_state == WRITE_START)) {
					// writing in progress, end marker found - stop writing
					f_opts.file_state = WRITE_STOP;
					save_to = save_from + pos_stop;
					file_op = write_buffer(&f_opts, save_from, save_to + include_en_marker);
						search_state == SEARCH_FILE_DATA) {
					// normal condition, save current file size to index directory
					uint64_t disk_pos = dev_curr_pos + pos_stop + (save_from - active_buff);
					search_state = SEARCH_SKIP;
					idir_result = stop_index(&index_dir, disk_pos);
					buff_processed = 1;
					if (zero_cross)
						process = 0;
					D6(fprintf(debug_file, "State 'finishing file'\n"));
				} else if (pos_start >= 0 && pos_stop >= 0 && pos_start > pos_stop &&
						f_opts.file_state == WRITE_RUNNING) {
					// writing in progress, start marker following stop marker found - this indicates a new file
					f_opts.file_state = WRITE_STOP;
					state->rawdev.file_start = dev_curr_pos + pos_start;
					file_pos_saved = 1;
					save_to = save_from + pos_stop;
					file_op = write_buffer(&f_opts, save_from, save_to + include_en_marker);
					save_from = save_from + pos_start;
				} else if (pos_start == MATCH_NOT_FOUND && pos_stop >= 0 && search_state == SEARCH_SKIP) {
					// error condition (normally should not happen), drop current read buffer and do nothing
					buff_processed = 1;
					D6(fprintf(debug_file, "State 'abnormal stop marker, skip data'\n"));
				} else if (pos_start >= 0 && pos_stop >= 0 && pos_start > pos_stop && search_state == SEARCH_FILE_DATA) {
					// normal condition, start marker following stop marker found - this indicates a new file
					uint64_t disk_pos = dev_curr_pos + pos_stop + (save_from - active_buff);
					fprintf(debug_file, "dev_curr_pos = 0x%llx, save_from = 0x%p, active_buff = 0x%p\n", dev_curr_pos, save_from, active_buff);
					idir_result = stop_index(&index_dir, disk_pos);
					dump_index_dir(&index_dir);
					if (zero_cross == 0) {
						state->rawdev.file_start = dev_curr_pos + pos_start + (save_from - active_buff);
						idir_result = save_index(state, &index_dir);
						save_from = save_from + pos_start + add_stm_len;
						// @todo: replace with pointer to current buffer
						save_to = buff + rd;
					if (zero_cross) {
					} else {
						buff_processed = 1;
						process = 0;
					}
					D6(fprintf(debug_file, "State 'starting new file'\n"));
				} else if (pos_start == MATCH_PARTIAL &&
						f_opts.file_state == WRITE_STOP) {
					// partial start marker found in the end of read buffer - get next chunk of data and try to find marker there
					D6(fprintf(debug_file, "State 'stop current file and start new file'\n"));
				} else if (pos_start == MATCH_PARTIAL && search_state == SEARCH_SKIP) {
					// partial start marker found in the end of read buffer, get next chunk of data and try to find marker there
					enum match_result result;
					struct crb_ptrs field_markers;
					struct iovec next_chunk = {
@@ -694,29 +855,30 @@ int camogm_read(camogm_state *state)
					};
					ssize_t next_rd = read(state->rawdev.rawdev_fd, next_buff, sizeof(next_buff));
					next_chunk.iov_len = next_rd;
					dev_curr_pos += next_rd;
					result = check_edge_case(&curr_chunk, &next_chunk, &elphel_st, &field_markers);
					if (result == MATCH_FOUND  && f_opts.file_state == WRITE_STOP) {
						f_opts.file_state = WRITE_START;
						state->rawdev.file_start = dev_curr_pos + pos_start;
					if (result == MATCH_FOUND) {
						search_state = SEARCH_FILE_DATA;
						state->rawdev.file_start = dev_curr_pos + pos_start + (save_from - active_buff);
						idir_result = save_index(state, &index_dir);
						D6(fprintf(debug_file, "File start position: %llu\n", state->rawdev.file_start));
						if (include_markers) {
							unsigned char *from = field_markers.first_buff.iov_base;
							unsigned char *to = from + field_markers.first_buff.iov_len;
							file_op = write_buffer(&f_opts, from, to);
							from = field_markers.second_buff.iov_base;
							to = from + field_markers.second_buff.iov_len;
							file_op = write_buffer(&f_opts, from, to);
						}
//						if (include_markers) {
//							unsigned char *from = field_markers.first_buff.iov_base;
//							unsigned char *to = from + field_markers.first_buff.iov_len;
//							file_op = write_buffer(&f_opts, from, to);
//							from = field_markers.second_buff.iov_base;
//							to = from + field_markers.second_buff.iov_len;
//							file_op = write_buffer(&f_opts, from, to);
//						}
						save_from = next_chunk.iov_base + field_markers.second_buff.iov_len;
						save_to = next_chunk.iov_base + next_chunk.iov_len;
					} else {
						save_from = next_chunk.iov_base;
						save_to = next_chunk.iov_base + next_chunk.iov_len;
					}
					dev_curr_pos += next_rd;
					active_buff = next_buff;
					D6(fprintf(debug_file, "State 'check elphel_st cross boundary'; result = %d\n", result));
				} else if (pos_stop == MATCH_PARTIAL &&
						f_opts.file_state != WRITE_STOP) {
				} else if (pos_stop == MATCH_PARTIAL && search_state == SEARCH_FILE_DATA) {
					// partial end marker found in the end of read buffer - get next chunk of data and try to find marker there
					enum match_result result;
					struct crb_ptrs field_markers;
@@ -729,53 +891,54 @@ int camogm_read(camogm_state *state)
					};
					ssize_t next_rd = read(state->rawdev.rawdev_fd, next_buff, sizeof(next_buff));
					next_chunk.iov_len = next_rd;
					dev_curr_pos += next_rd;
					result = check_edge_case(&curr_chunk, &next_chunk, &elphel_en, &field_markers);
					if (result == MATCH_FOUND) {
						f_opts.file_state = WRITE_STOP;
						file_op = write_buffer(&f_opts, save_from, save_to);
						if (include_markers) {
							unsigned char *from = field_markers.first_buff.iov_base;
							unsigned char *to = from + field_markers.first_buff.iov_len;
							file_op = write_buffer(&f_opts, from, to);
							from = field_markers.second_buff.iov_base;
							to = from + field_markers.second_buff.iov_len;
							file_op = write_buffer(&f_opts, from, to);
						}
						search_state = SEARCH_SKIP;
						uint64_t disk_pos = dev_curr_pos + pos_stop + (save_from - active_buff);
						idir_result = stop_index(&index_dir, disk_pos);
//						if (include_markers) {
//							unsigned char *from = field_markers.first_buff.iov_base;
//							unsigned char *to = from + field_markers.first_buff.iov_len;
//							file_op = write_buffer(&f_opts, from, to);
//							from = field_markers.second_buff.iov_base;
//							to = from + field_markers.second_buff.iov_len;
//							file_op = write_buffer(&f_opts, from, to);
//						}
						save_from = next_chunk.iov_base + field_markers.second_buff.iov_len;
						save_to = next_chunk.iov_base + next_chunk.iov_len;
					} else {
						file_op = write_buffer(&f_opts, save_from, save_to);
//						file_op = write_buffer(&f_opts, save_from, save_to);
						save_from = next_chunk.iov_base;
						save_to = next_chunk.iov_base + next_chunk.iov_len;
					}
					dev_curr_pos += next_rd;
					active_buff = next_buff;
					D6(fprintf(debug_file, "State 'check elphel_en' cross boundary:; result = %d\n", result));
				} else {
					// no markers found and new file has not bee started yet - skip data
					D6(fprintf(debug_file, "Undefined state: pos_start = %d, pos_stop = %d, file_state = %d\n",
							pos_start, pos_stop, f_opts.file_state));
					D6(fprintf(debug_file, "Undefined state: pos_start = %d, pos_stop = %d, search_state = %d\n",
							pos_start, pos_stop, search_state));
					buff_processed = 1;
					if (zero_cross)
						process = 0;
				}
			} while (buff_processed == 0 && file_op == FILE_OK);
			if (file_op != FILE_OK) {
			} while (buff_processed == 0 && idir_result == 0);
			if (idir_result != 0) {
				process = 0;
			}
			dev_curr_pos += rd;
		}
	}

	D0(fprintf(debug_file, "\n%d files read from %s\n", f_opts.file_cntr, state->rawdev.rawdev_path));
	D0(fprintf(debug_file, "\n%d files read from %s\n", index_dir.size, state->rawdev.rawdev_path));

	if (close(state->rawdev.rawdev_fd) != 0) {
		perror("Unable to close raw device: ");
		return -CAMOGM_FRAME_FILE_ERR;
	}
	if (f_opts.fh != NULL && fclose(f_opts.fh) != 0) {
		perror("Unable to close data file: ");
		return -CAMOGM_FRAME_FILE_ERR;
	}

	dump_index_dir(&index_dir);
	delete_idir(&index_dir);

	return 0;
}
+18 −1
Original line number Diff line number Diff line
@@ -19,6 +19,23 @@

#include "camogm.h"

int camogm_read(camogm_state *state);
struct disk_index {
	struct disk_index *next;
	struct disk_index *prev;
	time_t rawtime;
	useconds_t usec;
	uint32_t port;
	size_t f_size;
	uint64_t f_offset;
};

struct disk_idir {
	struct disk_index *head;
	struct disk_index *tail;
	size_t size;
};

//int camogm_read(camogm_state *state);
int build_index(camogm_state *state);

#endif /* _CAMOGM_READ_H */