diff options
author | Linus Walleij <triad@df.lth.se> | 2006-08-21 10:04:02 +0000 |
---|---|---|
committer | Linus Walleij <triad@df.lth.se> | 2006-08-21 10:04:02 +0000 |
commit | 96c6243edb6a4e435562779b87543d652fb40e6d (patch) | |
tree | 30882e42735583c914415f67cc9ba58d3b325454 | |
parent | 924236a8c9755b3704239d1f85344d49615b86c3 (diff) | |
download | libmtp-96c6243edb6a4e435562779b87543d652fb40e6d.tar.gz |
Getting files immediately to file descriptor.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | src/libmtp.c | 15 | ||||
-rw-r--r-- | src/ptp.c | 150 | ||||
-rw-r--r-- | src/ptp.h | 10 |
4 files changed, 142 insertions, 39 deletions
@@ -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; } @@ -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 @@ -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, |