brasero r712 - trunk/src



Author: philippr
Date: Sun Apr 13 18:59:04 2008
New Revision: 712
URL: http://svn.gnome.org/viewvc/brasero?rev=712&view=rev

Log:
Another forgotten file

Added:
   trunk/src/burn-volume-read.c

Added: trunk/src/burn-volume-read.c
==============================================================================
--- (empty file)
+++ trunk/src/burn-volume-read.c	Sun Apr 13 18:59:04 2008
@@ -0,0 +1,305 @@
+/***************************************************************************
+ *            brasero-medium-handle.c
+ *
+ *  Sat Mar 15 17:27:29 2008
+ *  Copyright  2008  Philippe Rouquier
+ *  <bonfire-app wanadoo fr>
+ ****************************************************************************/
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
+ */
+
+#include "scsi-device.h"
+#include "scsi-mmc1.h"
+#include "burn-volume.h"
+#include "burn-iso9660.h"
+#include "burn-volume-read.h"
+
+struct _BraseroVolFileHandle {
+	guchar buffer [2048];
+	guint buffer_max;
+
+	/* position in buffer */
+	guint offset;
+
+	/* address (in blocks) for current extent */
+	guint extent_last;
+
+	/* size in bytes for the current extent */
+	guint extent_size;
+
+	BraseroDeviceHandle *device;
+	GSList *extents_backward;
+	GSList *extents_forward;
+	guint position;
+};
+
+void
+brasero_volume_file_close (BraseroVolFileHandle *handle)
+{
+	brasero_device_handle_close (handle->device);
+	g_slist_free (handle->extents_forward);
+	g_slist_free (handle->extents_backward);
+	g_free (handle);
+}
+
+BraseroVolFileHandle *
+brasero_volume_file_open (const gchar *path,
+			  BraseroVolFile *file)
+{
+	BraseroVolFileHandle *handle;
+	BraseroVolFileExtent *extent;
+	BraseroScsiErrCode error;
+	BraseroScsiResult result;
+	GSList *node;
+
+	if (file->isdir)
+		return NULL;
+
+	handle = g_new0 (BraseroVolFileHandle, 1);
+	handle->device = brasero_device_handle_open (path, &error);
+	if (!handle->device) {
+		g_free (handle);
+		return NULL;
+	}
+
+	handle->extents_forward = g_slist_copy (file->specific.file.extents);
+
+	node = handle->extents_forward;
+	extent = node->data;
+
+	handle->extents_forward = g_slist_remove_link (handle->extents_forward, node);
+	node->next = handle->extents_backward;
+	handle->extents_backward = node;
+
+	handle->position = extent->block;
+	handle->extent_size = extent->size;
+	handle->extent_last = BRASERO_SIZE_TO_SECTORS (extent->size, 2048) + extent->block;
+
+	/* start loading first block */
+	result = brasero_mmc1_read_block (handle->device,
+					  TRUE,
+					  BRASERO_SCSI_BLOCK_TYPE_ANY,
+					  BRASERO_SCSI_BLOCK_HEADER_NONE,
+					  BRASERO_SCSI_BLOCK_NO_SUBCHANNEL,
+					  handle->position,
+					  1,
+					  handle->buffer,
+					  sizeof (handle->buffer),
+					  &error);
+
+	if (result != BRASERO_SCSI_OK) {
+		brasero_volume_file_close (handle);
+		return NULL;
+	}
+
+	handle->offset = 0;
+	handle->position ++;
+
+	if (handle->position == handle->extent_last)
+		handle->buffer_max = handle->extent_size % 2048;
+	else
+		handle->buffer_max = sizeof (handle->buffer);
+
+	return handle;
+}
+
+BraseroBurnResult
+brasero_volume_file_check_state (BraseroVolFileHandle *handle)
+{
+	BraseroBurnResult result;
+
+	/* check if we need to load a new block */
+	if (handle->offset < handle->buffer_max)
+		return BRASERO_BURN_RETRY;
+
+	/* check if we need to change our extent */
+	if (handle->position >= handle->extent_last) {
+		BraseroVolFileExtent *extent;
+		GSList *node;
+
+		/* we are at the end of current extent try to find another */
+		if (!handle->extents_forward) {
+			/* we reached the end of our file */
+			return BRASERO_BURN_OK;
+		}
+
+		node = handle->extents_forward;
+		extent = node->data;
+
+		handle->extents_forward = g_slist_remove_link (handle->extents_forward, node);
+		node->next = handle->extents_backward;
+		handle->extents_backward = node;
+
+		handle->position = extent->block;
+		handle->extent_size = extent->size;
+		handle->extent_last = BRASERO_SIZE_TO_SECTORS (extent->size, 2048) + extent->block;
+	}
+
+	result = brasero_mmc1_read_block (handle->device,
+					  TRUE,
+					  BRASERO_SCSI_BLOCK_TYPE_ANY,
+					  BRASERO_SCSI_BLOCK_HEADER_NONE,
+					  BRASERO_SCSI_BLOCK_NO_SUBCHANNEL,
+					  handle->position,
+					  1,
+					  handle->buffer,
+					  sizeof (handle->buffer),
+					  NULL);
+
+	if (result != BRASERO_SCSI_OK)
+		return BRASERO_BURN_ERR;
+
+	handle->offset = 0;
+	handle->position ++;
+
+	if (handle->position == handle->extent_last)
+		handle->buffer_max = handle->extent_size % 2048;
+	else
+		handle->buffer_max = sizeof (handle->buffer);
+
+	return BRASERO_BURN_RETRY;
+}
+
+gint
+brasero_volume_file_read (BraseroVolFileHandle *handle,
+			  gchar *buffer,
+			  guint len)
+{
+	guint buffer_offset = 0;
+	BraseroBurnResult result;
+
+	while ((len - buffer_offset) > (handle->buffer_max - handle->offset)) {
+		/* copy what we already have */
+		memcpy (buffer + buffer_offset,
+			handle->buffer + handle->offset,
+			handle->buffer_max - handle->offset);
+
+		buffer_offset += handle->buffer_max - handle->offset;
+
+		result = brasero_volume_file_check_state (handle);
+		if (result == BRASERO_BURN_OK)
+			return buffer_offset;
+
+		if (result == BRASERO_BURN_ERR)
+			return -1;
+	}
+
+	/* we filled the buffer */
+	memcpy (buffer + buffer_offset,
+		handle->buffer + handle->offset,
+		len - buffer_offset);
+
+	handle->offset += len - buffer_offset;
+
+	result = brasero_volume_file_check_state (handle);
+	if (result == BRASERO_BURN_ERR)
+		return -1;
+
+	return len;
+}
+
+static gint
+brasero_volume_file_find_line_break (BraseroVolFileHandle *handle,
+				     guint buffer_offset,
+				     gchar *buffer,
+				     guint len)
+{
+	guchar *break_line;
+
+	/* search the next end of line characher in the buffer */
+	break_line = memchr (handle->buffer + handle->offset,
+			     '\n',
+			     handle->buffer_max - handle->offset);
+
+	if (break_line) {
+		guint line_len;
+
+		line_len = break_line - (handle->buffer + handle->offset);
+		if (line_len >= len) {
+			/* - 1 is to be able to set last character to '\0' */
+			memcpy (buffer + buffer_offset,
+				handle->buffer + handle->offset,
+				len - buffer_offset - 1);
+
+			buffer [len - 1] = '\0';
+			handle->offset += len - buffer_offset - 1;
+			return TRUE;
+		}
+
+		memcpy (buffer, handle->buffer + handle->offset, line_len);
+		buffer [line_len] = '\0';
+
+		/* add 1 to skip the line break */
+		handle->offset += line_len + 1;
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+BraseroBurnResult
+brasero_volume_file_read_line (BraseroVolFileHandle *handle,
+			       gchar *buffer,
+			       guint len)
+{
+	guint buffer_offset = 0;
+	gboolean found;
+
+	found = brasero_volume_file_find_line_break (handle,
+						     buffer_offset,
+						     buffer,
+						     len);
+	if (found)
+		return brasero_volume_file_check_state (handle);
+
+	/* continue while remaining data is too small to fit buffer */
+	while ((len - buffer_offset) > (handle->buffer_max - handle->offset)) {
+		BraseroScsiResult result;
+
+		/* copy what we already have in the buffer. */
+		memcpy (buffer + buffer_offset,
+			handle->offset + handle->buffer,
+			handle->buffer_max - handle->offset);
+
+		buffer_offset += handle->buffer_max - handle->offset;
+		handle->offset = handle->buffer_max;
+
+		/* refill buffer */
+		result = brasero_volume_file_check_state (handle);
+		if (result == BRASERO_BURN_OK) {
+			buffer [len - 1] = '\0';
+			return result;
+		}
+
+		found = brasero_volume_file_find_line_break (handle,
+							     buffer_offset,
+							     buffer,
+							     len);
+		if (found)
+			return brasero_volume_file_check_state (handle);
+	}
+
+	memcpy (buffer + buffer_offset,
+		handle->buffer + handle->offset,
+		len - buffer_offset - 1);
+
+	/* we filled the buffer */
+	buffer [len - 1] = '\0';
+	handle->offset += len - buffer_offset - 1;
+
+	return brasero_volume_file_check_state (handle);
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]