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 + -
显示快捷键?