summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Walleij <triad@df.lth.se>2006-08-21 10:04:02 +0000
committerLinus Walleij <triad@df.lth.se>2006-08-21 10:04:02 +0000
commit96c6243edb6a4e435562779b87543d652fb40e6d (patch)
tree30882e42735583c914415f67cc9ba58d3b325454
parent924236a8c9755b3704239d1f85344d49615b86c3 (diff)
downloadlibmtp-96c6243edb6a4e435562779b87543d652fb40e6d.tar.gz
Getting files immediately to file descriptor.
-rw-r--r--ChangeLog6
-rw-r--r--src/libmtp.c15
-rw-r--r--src/ptp.c150
-rw-r--r--src/ptp.h10
4 files changed, 142 insertions, 39 deletions
diff --git a/ChangeLog b/ChangeLog
index fb4679a..c6c5325 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,11 @@
2006-08-21 Linus Walleij <triad@df.lth.se>
* src/libmtp.c: fixup mmap() usage and add madvise()
- as result of experiments by Gavin McCullagh.
+ as result of experiments by Gavin McCullagh. Upstream
+ accept patch to get files directly to file descriptor.
+ * src/ptp.c: sync to upstream which merges patch to get
+ file directly to file descriptor.
+ * src/ptp.h: dito.
2006-08-20 Linus Walleij <triad@df.lth.se>
diff --git a/src/libmtp.c b/src/libmtp.c
index 714fd54..56dd79f 100644
--- a/src/libmtp.c
+++ b/src/libmtp.c
@@ -1999,10 +1999,8 @@ int LIBMTP_Get_File_To_File_Descriptor(LIBMTP_mtpdevice_t *device,
void const * const data)
{
PTPObjectInfo oi;
- unsigned char *image = NULL;
uint16_t ret;
PTPParams *params = (PTPParams *) device->params;
- ssize_t written;
if (ptp_getobjectinfo(params, id, &oi) != PTP_RC_OK) {
printf("LIBMTP_Get_File_To_File_Descriptor(): Could not get object info\n");
@@ -2013,23 +2011,14 @@ int LIBMTP_Get_File_To_File_Descriptor(LIBMTP_mtpdevice_t *device,
return -1;
}
- // Copy object to memory
- // We could use ptp_getpartialobject to make for progress bars etc.
- ret = ptp_getobject(params, id, &image);
-
- // If we get this into upstream, use this.
- // ret = ptp_getobject_tofd(params, id, fd);
+ // This now exist in upstream
+ ret = ptp_getobject_tofd(params, id, fd);
if (ret != PTP_RC_OK) {
printf("LIBMTP_Get_File_To_File_Descriptor(): Could not get file from device (%d)\n", ret);
return -1;
}
- written = write(fd, image, oi.ObjectCompressedSize);
- if (written != oi.ObjectCompressedSize) {
- printf("LIBMTP_Get_File_To_File_Descriptor(): Could not write object properly\n");
- }
-
return 0;
}
diff --git a/src/ptp.c b/src/ptp.c
index 61b4f8b..b663ffd 100644
--- a/src/ptp.c
+++ b/src/ptp.c
@@ -26,6 +26,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#include <unistd.h>
#ifdef ENABLE_NLS
# include <libintl.h>
@@ -167,13 +168,17 @@ ptp_usb_senddata (PTPParams* params, PTPContainer* ptp,
uint16_t
ptp_usb_getdata (PTPParams* params, PTPContainer* ptp,
- unsigned char **data, unsigned int *readlen)
+ unsigned char **data, unsigned int *readlen,
+ int to_fd)
{
uint16_t ret;
PTPUSBBulkContainer usbdata;
PTP_CNT_INIT(usbdata);
- if (*data!=NULL) return PTP_ERROR_BADPARAM;
+
+ if (to_fd == -1 && *data != NULL)
+ return PTP_ERROR_BADPARAM;
+
do {
unsigned int len, rlen;
/* read the header and potentially the first data */
@@ -209,25 +214,85 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp,
if (dtoh32(usbdata.length) > 12 && (rlen==12))
params->split_header_data = 1;
- /* Allocate memory for data. */
- *data=calloc(len,1);
- if (readlen)
- *readlen = len;
+ if (to_fd == -1) {
+ /* Allocate memory for data. */
+ *data=calloc(len,1);
+ if (readlen)
+ *readlen = len;
+
+ /* Copy first part of data to 'data' */
+ memcpy(*data,usbdata.payload.data,rlen - PTP_USB_BULK_HDR_LEN);
+
+ /* Is that all of data? */
+ if (len+PTP_USB_BULK_HDR_LEN<=rlen) break;
+
+ /* If not read the rest of it. */
+ ret=params->read_func(((unsigned char *)(*data))+
+ rlen - PTP_USB_BULK_HDR_LEN,
+ len-(rlen - PTP_USB_BULK_HDR_LEN),
+ params->data, &rlen);
+ if (ret!=PTP_RC_OK) {
+ ret = PTP_ERROR_IO;
+ break;
+ }
+ } else {
+ uint32_t bytes_to_write, written;
+ uint32_t bytes_left_to_transfer;
+ uint32_t temp_buf_size = 0x100000;
+ void *temp_buf;
+
+ if (readlen)
+ *readlen = len;
+
+ bytes_to_write = rlen - PTP_USB_BULK_HDR_LEN;
+
+ ret = write(to_fd, usbdata.payload.data, bytes_to_write);
+ if (ret != bytes_to_write) {
+ ret = PTP_ERROR_IO;
+ break;
+ }
+
+ if (len + PTP_USB_BULK_HDR_LEN <= rlen)
+ break;
+
+ temp_buf = malloc(temp_buf_size);
+ if (temp_buf == NULL) {
+ ret = PTP_ERROR_IO;
+ break;
+ }
+
+ ret = PTP_RC_OK;
+ bytes_left_to_transfer = len - (rlen - PTP_USB_BULK_HDR_LEN);
+
+ while (bytes_left_to_transfer > 0) {
+ bytes_to_write = ((bytes_left_to_transfer > temp_buf_size) ?
+ temp_buf_size : bytes_left_to_transfer);
+
+ ret = params->read_func(temp_buf,
+ bytes_to_write,
+ params->data, &rlen);
+
+ if (ret != PTP_RC_OK) {
+ ret = PTP_ERROR_IO;
+ break;
+ }
+
+ written = write(to_fd, temp_buf, bytes_to_write);
+ if (written != bytes_to_write) {
+ ret = PTP_ERROR_IO;
+ break;
+ } else {
+ ret = PTP_RC_OK;
+ }
+
+ bytes_left_to_transfer -= bytes_to_write;
+ }
- /* Copy first part of data to 'data' */
- memcpy(*data,usbdata.payload.data,rlen - PTP_USB_BULK_HDR_LEN);
+ free(temp_buf);
- /* Is that all of data? */
- if (len+PTP_USB_BULK_HDR_LEN<=rlen) break;
+ if (ret != PTP_RC_OK)
+ break;
- /* If not read the rest of it. */
- ret=params->read_func(((unsigned char *)(*data))+
- rlen - PTP_USB_BULK_HDR_LEN,
- len-(rlen - PTP_USB_BULK_HDR_LEN),
- params->data, &rlen);
- if (ret!=PTP_RC_OK) {
- ret = PTP_ERROR_IO;
- break;
}
} while (0);
/*
@@ -315,9 +380,9 @@ ptp_usb_getresp (PTPParams* params, PTPContainer* resp)
* all fields filled in.
**/
static uint16_t
-ptp_transaction (PTPParams* params, PTPContainer* ptp,
- uint16_t flags, unsigned int sendlen, unsigned char** data,
- unsigned int *recvlen)
+_ptp_transaction (PTPParams* params, PTPContainer* ptp,
+ uint16_t flags, unsigned int sendlen, unsigned char** data,
+ int to_fd, unsigned int *recvlen)
{
if ((params==NULL) || (ptp==NULL))
return PTP_ERROR_BADPARAM;
@@ -334,7 +399,7 @@ ptp_transaction (PTPParams* params, PTPContainer* ptp,
break;
case PTP_DP_GETDATA:
CHECK_PTP_RC(params->getdata_func(params, ptp,
- (unsigned char**)data, recvlen));
+ (unsigned char**)data, recvlen, to_fd));
break;
case PTP_DP_NODATA:
break;
@@ -347,6 +412,22 @@ ptp_transaction (PTPParams* params, PTPContainer* ptp,
return ptp->Code;
}
+static uint16_t
+ptp_transaction (PTPParams* params, PTPContainer* ptp,
+ uint16_t flags, unsigned int sendlen, unsigned char** data,
+ unsigned int *recvlen)
+{
+ return _ptp_transaction(params, ptp, flags, sendlen, data, -1, recvlen);
+}
+
+static uint16_t
+ptp_transaction_tofd (PTPParams* params, PTPContainer* ptp,
+ uint16_t flags, unsigned int sendlen,
+ int to_fd, unsigned int *recvlen)
+{
+ return _ptp_transaction(params, ptp, flags, sendlen, NULL, to_fd, recvlen);
+}
+
/* Enets handling functions */
/* PTP Events wait for or check mode */
@@ -684,6 +765,31 @@ ptp_getobject (PTPParams* params, uint32_t handle, unsigned char** object)
}
/**
+ * ptp_getobject_tofd:
+ * params: PTPParams*
+ * handle - Object handle
+ * fd - File descriptor to write() to
+ *
+ * Get object 'handle' from device and write the data to the
+ * given file descriptor.
+ *
+ * Return values: Some PTP_RC_* code.
+ **/
+uint16_t
+ptp_getobject_tofd (PTPParams* params, uint32_t handle, int fd)
+{
+ PTPContainer ptp;
+ unsigned int len;
+
+ PTP_CNT_INIT(ptp);
+ ptp.Code=PTP_OC_GetObject;
+ ptp.Param1=handle;
+ ptp.Nparam=1;
+ len=0;
+ return ptp_transaction_tofd(params, &ptp, PTP_DP_GETDATA, 0, fd, &len);
+}
+
+/**
* ptp_getpartialobject:
* params: PTPParams*
* handle - Object handle
diff --git a/src/ptp.h b/src/ptp.h
index 5031a85..002ec2b 100644
--- a/src/ptp.h
+++ b/src/ptp.h
@@ -1045,7 +1045,8 @@ typedef uint16_t (* PTPIOSendData) (PTPParams* params, PTPContainer* ptp,
unsigned char *data, unsigned int size);
typedef uint16_t (* PTPIOGetResp) (PTPParams* params, PTPContainer* resp);
typedef uint16_t (* PTPIOGetData) (PTPParams* params, PTPContainer* ptp,
- unsigned char **data, unsigned int *recvlen);
+ unsigned char **data, unsigned int *recvlen,
+ int to_fd);
/* debug functions */
typedef void (* PTPErrorFunc) (void *data, const char *format, va_list args)
#if (__GNUC__ >= 3)
@@ -1114,7 +1115,8 @@ uint16_t ptp_usb_senddata (PTPParams* params, PTPContainer* ptp,
unsigned char *data, unsigned int size);
uint16_t ptp_usb_getresp (PTPParams* params, PTPContainer* resp);
uint16_t ptp_usb_getdata (PTPParams* params, PTPContainer* ptp,
- unsigned char **data, unsigned int *readlen);
+ unsigned char **data, unsigned int *readlen,
+ int to_fd);
uint16_t ptp_usb_event_check (PTPParams* params, PTPContainer* event);
uint16_t ptp_usb_event_wait (PTPParams* params, PTPContainer* event);
@@ -1124,7 +1126,8 @@ uint16_t ptp_ptpip_senddata (PTPParams* params, PTPContainer* ptp,
unsigned char *data, unsigned int size);
uint16_t ptp_ptpip_getresp (PTPParams* params, PTPContainer* resp);
uint16_t ptp_ptpip_getdata (PTPParams* params, PTPContainer* ptp,
- unsigned char **data, unsigned int *readlen);
+ unsigned char **data, unsigned int *readlen,
+ int to_fd);
uint16_t ptp_ptpip_event_wait (PTPParams* params, PTPContainer* event);
uint16_t ptp_ptpip_event_check (PTPParams* params, PTPContainer* event);
@@ -1152,6 +1155,7 @@ uint16_t ptp_getobjectinfo (PTPParams *params, uint32_t handle,
uint16_t ptp_getobject (PTPParams *params, uint32_t handle,
unsigned char** object);
+uint16_t ptp_getobject_tofd (PTPParams* params, uint32_t handle, int fd);
uint16_t ptp_getpartialobject (PTPParams* params, uint32_t handle, uint32_t offset,
uint32_t maxbytes, unsigned char** object);
uint16_t ptp_getthumb (PTPParams *params, uint32_t handle,