ptp-pack.c

来自「Media transfer protocol implementation o」· C语言 代码 · 共 1,202 行 · 第 1/3 页

C
1,202
字号
/* currently this file is included into ptp.c */#include <iconv.h>static inline uint16_thtod16p (PTPParams *params, uint16_t var){	return ((params->byteorder==PTP_DL_LE)?htole16(var):htobe16(var));}static inline uint32_thtod32p (PTPParams *params, uint32_t var){	return ((params->byteorder==PTP_DL_LE)?htole32(var):htobe32(var));}static inline voidhtod16ap (PTPParams *params, unsigned char *a, uint16_t val){	if (params->byteorder==PTP_DL_LE)		htole16a(a,val);	else 		htobe16a(a,val);}static inline voidhtod32ap (PTPParams *params, unsigned char *a, uint32_t val){	if (params->byteorder==PTP_DL_LE)		htole32a(a,val);	else 		htobe32a(a,val);}static inline uint16_tdtoh16p (PTPParams *params, uint16_t var){	return ((params->byteorder==PTP_DL_LE)?le16toh(var):be16toh(var));}static inline uint32_tdtoh32p (PTPParams *params, uint32_t var){	return ((params->byteorder==PTP_DL_LE)?le32toh(var):be32toh(var));}static inline uint16_tdtoh16ap (PTPParams *params, unsigned char *a){	return ((params->byteorder==PTP_DL_LE)?le16atoh(a):be16atoh(a));}static inline uint32_tdtoh32ap (PTPParams *params, unsigned char *a){	return ((params->byteorder==PTP_DL_LE)?le32atoh(a):be32atoh(a));}static inline uint64_tdtoh64ap (PTPParams *params, unsigned char *a){	uint64_t tmp = 0;	int i;	if (params->byteorder==PTP_DL_LE) {		for (i=0;i<8;i++)			tmp |= (((uint64_t)a[i]) << (8*i));	} else {		for (i=0;i<8;i++)			tmp |= (((uint64_t)a[i]) << (8*(7-i)));	}	return tmp;}#define htod8a(a,x)	*(uint8_t*)(a) = x#define htod16a(a,x)	htod16ap(params,a,x)#define htod32a(a,x)	htod32ap(params,a,x)#define htod16(x)	htod16p(params,x)#define htod32(x)	htod32p(params,x)#define dtoh8a(x)	(*(uint8_t*)(x))#define dtoh16a(a)	dtoh16ap(params,a)#define dtoh32a(a)	dtoh32ap(params,a)#define dtoh64a(a)	dtoh64ap(params,a)#define dtoh16(x)	dtoh16p(params,x)#define dtoh32(x)	dtoh32p(params,x)static inline char*ptp_unpack_string(PTPParams *params, unsigned char* data, uint16_t offset, uint8_t *len){	int i;	uint8_t loclen;	/* Cannot exceed 255 (PTP_MAXSTRLEN) since it is a single byte, duh ... */	loclen = dtoh8a(&data[offset]);	/* This len is used to advance the buffer pointer */	*len = loclen;	if (loclen) {		uint16_t string[PTP_MAXSTRLEN+1];		char *stringp = (char *) string;		char loclstr[PTP_MAXSTRLEN*3+1]; /* UTF-8 encoding is max 3 bytes per UCS2 char. */		char *locp = loclstr;		size_t nconv;		size_t convlen = loclen * 2; /* UCS-2 is 16 bit wide */		size_t convmax = PTP_MAXSTRLEN*3;				for (i=0;i<loclen;i++) {			string[i]=dtoh16a(&data[offset+i*2+1]);		}		/* be paranoid! Add a terminator. :( */		string[loclen]=0x0000U;		loclstr[0]='\0';		/* loclstr=ucs2_to_utf8(string); */		/* Do the conversion.  */		nconv = iconv (params->cd_ucs2_to_locale, &stringp, &convlen, &locp, &convmax);		/* FIXME: handle size errors */		loclstr[PTP_MAXSTRLEN*3] = '\0';		if (nconv == (size_t) -1)			return NULL;		return strdup(loclstr);	}	return NULL;}static inline intucs2strlen(uint16_t const * const unicstr){	int length;		/* Unicode strings are terminated with 2 * 0x00 */	for(length = 0; unicstr[length] != 0x0000U; length ++);	return length;}static inline voidptp_pack_string(PTPParams *params, char *string, unsigned char* data, uint16_t offset, uint8_t *len){	int i;	int packedlen;	uint16_t ucs2str[PTP_MAXSTRLEN+1];	char *ucs2strp = (char *) ucs2str;	char *stringp = string;	size_t nconv;	size_t convlen = strlen(string);	size_t convmax = PTP_MAXSTRLEN * 2; /* Includes the terminator */	/* Cannot exceed 255 (PTP_MAXSTRLEN) since it is a single byte, duh ... */	ucs2str[0] = 0x0000U;	memset(ucs2strp, 0, PTP_MAXSTRLEN*2+2);	nconv = iconv (params->cd_locale_to_ucs2, &stringp, &convlen, &ucs2strp, &convmax);	if (nconv == (size_t) -1)		ucs2str[0] = 0x0000U;	packedlen = ucs2strlen(ucs2str);	if (packedlen > PTP_MAXSTRLEN-1) {		*len=0;		return;	}		/* number of characters + leading 0 */	htod8a(&data[offset],packedlen+1);	for (i=0;i<packedlen && i< PTP_MAXSTRLEN; i++) {		htod16a(&data[offset+i*2+1],ucs2str[i]);	}	htod16a(&data[offset+i*2+1],0x0000);	/* The returned length is in number of characters */	*len = (uint8_t) packedlen+1;}static inline unsigned char *ptp_get_packed_stringcopy(PTPParams *params, char *string, uint32_t *packed_size){	uint8_t packed[PTP_MAXSTRLEN*2+3], len;	size_t plen;	unsigned char *retcopy = NULL;	ptp_pack_string(params, string, (unsigned char*) packed, 0, &len);	/* returned length is in characters, then one byte for string length */	plen = len*2 + 1;		retcopy = malloc(plen);	if (!retcopy) {		*packed_size = 0;		return NULL;	}	memcpy(retcopy, packed, plen);	*packed_size = plen;	return (retcopy);}static inline uint32_tptp_unpack_uint32_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint32_t **array){	uint32_t n, i=0;	n=dtoh32a(&data[offset]);	*array = malloc (n*sizeof(uint32_t));	while (n>i) {		(*array)[i]=dtoh32a(&data[offset+(sizeof(uint32_t)*(i+1))]);		i++;	}	return n;}static inline uint32_tptp_pack_uint32_t_array(PTPParams *params, uint32_t *array, uint32_t arraylen, unsigned char **data ){	uint32_t i=0;	*data = malloc ((arraylen+1)*sizeof(uint32_t));	htod32a(&(*data)[0],arraylen);	for (i=0;i<arraylen;i++)		htod32a(&(*data)[sizeof(uint32_t)*(i+1)], array[i]);	return (arraylen+1)*sizeof(uint32_t);}static inline uint32_tptp_unpack_uint16_t_array(PTPParams *params, unsigned char* data, uint16_t offset, uint16_t **array){	uint32_t n, i=0;	n=dtoh32a(&data[offset]);	*array = malloc (n*sizeof(uint16_t));	while (n>i) {		(*array)[i]=dtoh16a(&data[offset+(sizeof(uint16_t)*(i+2))]);		i++;	}	return n;}/* DeviceInfo pack/unpack */#define PTP_di_StandardVersion		 0#define PTP_di_VendorExtensionID	 2#define PTP_di_VendorExtensionVersion	 6#define PTP_di_VendorExtensionDesc	 8#define PTP_di_FunctionalMode		 8#define PTP_di_OperationsSupported	10static inline voidptp_unpack_DI (PTPParams *params, unsigned char* data, PTPDeviceInfo *di, unsigned int datalen){	uint8_t len;	unsigned int totallen;		di->StandardVersion = dtoh16a(&data[PTP_di_StandardVersion]);	di->VendorExtensionID =		dtoh32a(&data[PTP_di_VendorExtensionID]);	di->VendorExtensionVersion =		dtoh16a(&data[PTP_di_VendorExtensionVersion]);	di->VendorExtensionDesc = 		ptp_unpack_string(params, data,		PTP_di_VendorExtensionDesc, &len); 	totallen=len*2+1;	di->FunctionalMode = 		dtoh16a(&data[PTP_di_FunctionalMode+totallen]);	di->OperationsSupported_len = ptp_unpack_uint16_t_array(params, data,		PTP_di_OperationsSupported+totallen,		&di->OperationsSupported);	totallen=totallen+di->OperationsSupported_len*sizeof(uint16_t)+sizeof(uint32_t);	di->EventsSupported_len = ptp_unpack_uint16_t_array(params, data,		PTP_di_OperationsSupported+totallen,		&di->EventsSupported);	totallen=totallen+di->EventsSupported_len*sizeof(uint16_t)+sizeof(uint32_t);	di->DevicePropertiesSupported_len =		ptp_unpack_uint16_t_array(params, data,		PTP_di_OperationsSupported+totallen,		&di->DevicePropertiesSupported);	totallen=totallen+di->DevicePropertiesSupported_len*sizeof(uint16_t)+sizeof(uint32_t);	di->CaptureFormats_len = ptp_unpack_uint16_t_array(params, data,		PTP_di_OperationsSupported+totallen,		&di->CaptureFormats);	totallen=totallen+di->CaptureFormats_len*sizeof(uint16_t)+sizeof(uint32_t);	di->ImageFormats_len = ptp_unpack_uint16_t_array(params, data,		PTP_di_OperationsSupported+totallen,		&di->ImageFormats);	totallen=totallen+di->ImageFormats_len*sizeof(uint16_t)+sizeof(uint32_t);	di->Manufacturer = ptp_unpack_string(params, data,		PTP_di_OperationsSupported+totallen,		&len);	totallen+=len*2+1;	di->Model = ptp_unpack_string(params, data,		PTP_di_OperationsSupported+totallen,		&len);	totallen+=len*2+1;	di->DeviceVersion = ptp_unpack_string(params, data,		PTP_di_OperationsSupported+totallen,		&len);	totallen+=len*2+1;	di->SerialNumber = ptp_unpack_string(params, data,		PTP_di_OperationsSupported+totallen,		&len);}	/* ObjectHandles array pack/unpack */#define PTP_oh				 0static inline voidptp_unpack_OH (PTPParams *params, unsigned char* data, PTPObjectHandles *oh, unsigned int len){	oh->n = ptp_unpack_uint32_t_array(params, data, PTP_oh, &oh->Handler);}/* StoreIDs array pack/unpack */#define PTP_sids			 0static inline voidptp_unpack_SIDs (PTPParams *params, unsigned char* data, PTPStorageIDs *sids, unsigned int len){	sids->n = ptp_unpack_uint32_t_array(params, data, PTP_sids,	&sids->Storage);}/* StorageInfo pack/unpack */#define PTP_si_StorageType		 0#define PTP_si_FilesystemType		 2#define PTP_si_AccessCapability		 4#define PTP_si_MaxCapability		 6#define PTP_si_FreeSpaceInBytes		14#define PTP_si_FreeSpaceInImages	22#define PTP_si_StorageDescription	26static inline voidptp_unpack_SI (PTPParams *params, unsigned char* data, PTPStorageInfo *si, unsigned int len){	uint8_t storagedescriptionlen;	si->StorageType=dtoh16a(&data[PTP_si_StorageType]);	si->FilesystemType=dtoh16a(&data[PTP_si_FilesystemType]);	si->AccessCapability=dtoh16a(&data[PTP_si_AccessCapability]);	si->MaxCapability=dtoh64a(&data[PTP_si_MaxCapability]);	si->FreeSpaceInBytes=dtoh64a(&data[PTP_si_FreeSpaceInBytes]);	si->FreeSpaceInImages=dtoh32a(&data[PTP_si_FreeSpaceInImages]);	si->StorageDescription=ptp_unpack_string(params, data,		PTP_si_StorageDescription, &storagedescriptionlen);	si->VolumeLabel=ptp_unpack_string(params, data,		PTP_si_StorageDescription+storagedescriptionlen*2+1,		&storagedescriptionlen);}/* ObjectInfo pack/unpack */#define PTP_oi_StorageID		 0#define PTP_oi_ObjectFormat		 4#define PTP_oi_ProtectionStatus		 6#define PTP_oi_ObjectCompressedSize	 8#define PTP_oi_ThumbFormat		12#define PTP_oi_ThumbCompressedSize	14#define PTP_oi_ThumbPixWidth		18#define PTP_oi_ThumbPixHeight		22#define PTP_oi_ImagePixWidth		26#define PTP_oi_ImagePixHeight		30#define PTP_oi_ImageBitDepth		34#define PTP_oi_ParentObject		38#define PTP_oi_AssociationType		42#define PTP_oi_AssociationDesc		44#define PTP_oi_SequenceNumber		48#define PTP_oi_filenamelen		52#define PTP_oi_Filename			53static inline uint32_tptp_pack_OI (PTPParams *params, PTPObjectInfo *oi, unsigned char** oidataptr){	unsigned char* oidata;	uint8_t filenamelen;	uint8_t capturedatelen=0;	/* let's allocate some memory first; XXX i'm sure it's wrong */	oidata=malloc(PTP_oi_Filename+(strlen(oi->Filename)+1)*2+4);	/* the caller should free it after use! */#if 0	char *capture_date="20020101T010101"; /* XXX Fake date */#endif	memset (oidata, 0, (PTP_oi_Filename+(strlen(oi->Filename)+1)*2+4));	htod32a(&oidata[PTP_oi_StorageID],oi->StorageID);	htod16a(&oidata[PTP_oi_ObjectFormat],oi->ObjectFormat);	htod16a(&oidata[PTP_oi_ProtectionStatus],oi->ProtectionStatus);	htod32a(&oidata[PTP_oi_ObjectCompressedSize],oi->ObjectCompressedSize);	htod16a(&oidata[PTP_oi_ThumbFormat],oi->ThumbFormat);	htod32a(&oidata[PTP_oi_ThumbCompressedSize],oi->ThumbCompressedSize);	htod32a(&oidata[PTP_oi_ThumbPixWidth],oi->ThumbPixWidth);	htod32a(&oidata[PTP_oi_ThumbPixHeight],oi->ThumbPixHeight);	htod32a(&oidata[PTP_oi_ImagePixWidth],oi->ImagePixWidth);	htod32a(&oidata[PTP_oi_ImagePixHeight],oi->ImagePixHeight);	htod32a(&oidata[PTP_oi_ImageBitDepth],oi->ImageBitDepth);	htod32a(&oidata[PTP_oi_ParentObject],oi->ParentObject);	htod16a(&oidata[PTP_oi_AssociationType],oi->AssociationType);	htod32a(&oidata[PTP_oi_AssociationDesc],oi->AssociationDesc);	htod32a(&oidata[PTP_oi_SequenceNumber],oi->SequenceNumber);		ptp_pack_string(params, oi->Filename, oidata, PTP_oi_filenamelen, &filenamelen);/*	filenamelen=(uint8_t)strlen(oi->Filename);	htod8a(&req->data[PTP_oi_filenamelen],filenamelen+1);	for (i=0;i<filenamelen && i< PTP_MAXSTRLEN; i++) {		req->data[PTP_oi_Filename+i*2]=oi->Filename[i];

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?