Changeset 48797 in vbox for trunk/src/VBox/Runtime/common/zip
- Timestamp:
- Oct 1, 2013 2:43:17 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/zip/xarvfs.cpp
r48780 r48797 73 73 /** The TOC XML document. */ 74 74 xml::Document *pDoc; 75 /** The current file ID. */ 76 uint32_t idCurFile; 75 76 /** The current file. */ 77 xml::ElementNode const *pCurFile; 78 /** The depth of the current file, with 0 being the root level. */ 79 uint32_t cCurDepth; 80 /** Set if it's the first file. */ 81 bool fFirstFile; 77 82 } RTZIPXARREADER; 78 83 /** Pointer to the XAR reader instance data. */ … … 84 89 typedef struct RTZIPXARBASEOBJ 85 90 { 86 /** The stream offset of the (first) header. */87 RTFOFF offHdr;88 91 /** Pointer to the reader instance data (resides in the filesystem 89 92 * stream). 90 93 * @todo Fix this so it won't go stale... Back ref from this obj to fss? */ 91 94 PRTZIPXARREADER pXarReader; 92 /** The object info with unix attributes. */93 RTFSOBJINFO ObjInfo;95 /** The file TOC element. */ 96 xml::ElementNode const *pFileElem; 94 97 } RTZIPXARBASEOBJ; 95 98 /** Pointer to a XAR filesystem stream base object. */ … … 98 101 99 102 /** 103 * XAR data encoding. 104 */ 105 typedef enum RTZIPXARENCODING 106 { 107 RTZIPXARENCODING_INVALID = 0, 108 RTZIPXARENCODING_STORE, 109 RTZIPXARENCODING_GZIP, 110 RTZIPXARENCODING_UNSUPPORTED, 111 RTZIPXARENCODING_END 112 } RTZIPXARENCODING; 113 114 115 /** 116 * Data stream attributes. 117 */ 118 typedef struct RTZIPXARDATASTREAM 119 { 120 /** Offset of the data in the stream, relative to XARREADER::offZero. */ 121 RTFOFF offData; 122 /** The size of the archived data. */ 123 RTFOFF cbDataArchived; 124 /** The size of the extracted data. */ 125 RTFOFF cbDataExtracted; 126 /** The encoding of the archived ata. */ 127 RTZIPXARENCODING enmEncoding; 128 /** The hash function used for the archived data. */ 129 uint8_t uHashFunArchived; 130 /** The hash function used for the extracted data. */ 131 uint8_t uHashFunExtracted; 132 /** The digest of the archived data. */ 133 RTZIPXARHASHDIGEST DigestArchived; 134 /** The digest of the extracted data. */ 135 RTZIPXARHASHDIGEST DigestExtracted; 136 } RTZIPXARDATASTREAM; 137 /** Pointer to XAR data stream attributes. */ 138 typedef RTZIPXARDATASTREAM *PRTZIPXARDATASTREAM; 139 140 141 /** 100 142 * Xar file represented as a VFS I/O stream. 101 143 */ … … 104 146 /** The basic XAR object data. */ 105 147 RTZIPXARBASEOBJ BaseObj; 106 /** The number of bytes in the file. */107 RT FOFF cbFile;148 /** The attributes of the primary data stream. */ 149 RTZIPXARDATASTREAM Data; 108 150 /** The current file position. */ 109 151 RTFOFF offFile; 110 /** The number of padding bytes following the file. */111 uint32_t cbPadding;152 /** The input I/O stream. */ 153 RTVFSIOSTREAM hVfsIos; 112 154 /** Set if we've reached the end of the file. */ 113 155 bool fEndOfStream; 114 /** The input I/O stream. */ 115 RTVFSIOSTREAM hVfsIos; 156 /** The size of the file that we've currently hashed. 157 * We use this to check whether the user skips part of the file while reading 158 * and when to compare the digests. */ 159 RTFOFF cbDigested; 160 /** The digest of the archived data. */ 161 RTZIPXARHASHDIGEST DigestArchived; 162 /** The digest of the extracted data. */ 163 RTZIPXARHASHDIGEST DigestExtracted; 116 164 } RTZIPXARIOSTREAM; 117 165 /** Pointer to a the private data of a XAR file I/O stream. */ 118 166 typedef RTZIPXARIOSTREAM *PRTZIPXARIOSTREAM; 167 168 169 /** 170 * Xar file represented as a VFS file. 171 */ 172 typedef struct RTZIPXARFILE 173 { 174 /** The XAR I/O stream object. */ 175 RTZIPXARIOSTREAM IosObj; 176 /** The input file. */ 177 RTVFSFILE hVfsFile; 178 } RTZIPXARFILE; 179 /** Pointer to a the private data of a XAR file. */ 180 typedef RTZIPXARFILE *PRTZIPXARFILE; 119 181 120 182 … … 184 246 static int rtZipXarGetOffsetSizeFromElem(xml::ElementNode const *pElement, PRTFOFF poff, uint64_t *pcb) 185 247 { 248 if (pElement) 249 return VERR_XAR_DATA_NODE_NOT_FOUND; 250 186 251 /* 187 252 * The offset. … … 415 480 416 481 /* Currently there is nothing we really have to do here. */ 417 pThis->offHdr = -1;482 NOREF(pThis); 418 483 419 484 return VINF_SUCCESS; … … 530 595 return pcbRead ? VINF_EOF : VERR_EOF; 531 596 532 Assert(pThis-> cbFile>= pThis->offFile);533 uint64_t cbLeft = (uint64_t)(pThis-> cbFile- pThis->offFile);597 Assert(pThis->Data.cbDataExtracted >= pThis->offFile); 598 uint64_t cbLeft = (uint64_t)(pThis->Data.cbDataExtracted - pThis->offFile); 534 599 if (cbToRead > cbLeft) 535 600 { … … 547 612 int rc = RTVfsIoStrmRead(pThis->hVfsIos, pvBuf, cbToRead, fBlocking, pcbRead); 548 613 pThis->offFile += *pcbRead; 549 if (pThis->offFile >= pThis-> cbFile)550 { 551 Assert(pThis->offFile == pThis-> cbFile);614 if (pThis->offFile >= pThis->Data.cbDataExtracted) 615 { 616 Assert(pThis->offFile == pThis->Data.cbDataExtracted); 552 617 pThis->fEndOfStream = true; 553 RTVfsIoStrmSkip(pThis->hVfsIos, pThis->cbPadding);618 /// @todo RTVfsIoStrmSkip(pThis->hVfsIos, pThis->cbPadding); 554 619 } 555 620 … … 785 850 pThis->hVfsIos = NIL_RTVFSIOSTREAM; 786 851 852 RTVfsFileRelease(pThis->hVfsFile); 853 pThis->hVfsFile = NIL_RTVFSFILE; 854 787 855 return VINF_SUCCESS; 788 856 } … … 801 869 802 870 871 static xml::ElementNode const *rtZipXarGetNextFileElement(xml::ElementNode const *pCurFile, uint32_t *pcCurDepth) 872 { 873 /* 874 * Consider children first. 875 */ 876 xml::ElementNode const *pChild = pCurFile->findChildElement("file"); 877 if (pChild) 878 { 879 *pcCurDepth += 1; 880 return pChild; 881 } 882 883 /* 884 * Then siblings. 885 */ 886 xml::ElementNode const *pSibling = pCurFile->findNextSibilingElement("file"); 887 if (pSibling != NULL) 888 return pSibling; 889 890 /* 891 * Ascend and see if some parent has more siblings. 892 */ 893 while (*pcCurDepth > 0) 894 { 895 pCurFile = static_cast<const xml::ElementNode *>(pCurFile->getParent()); 896 AssertBreak(pCurFile); 897 Assert(pCurFile->nameEquals("file")); 898 *pcCurDepth -= 1; 899 900 pSibling = pCurFile->findNextSibilingElement("file"); 901 if (pSibling != NULL) 902 return pSibling; 903 } 904 905 return NULL; 906 } 907 908 803 909 /** 804 910 * @interface_method_impl{RTVFSFSSTREAMOPS,pfnNext} … … 816 922 { 817 923 pThis->pCurIosData->fEndOfStream = true; 818 pThis->pCurIosData->offFile = pThis->pCurIosData->cbFile;924 /// @todo pThis->pCurIosData->offFile = pThis->pCurIosData->cbFile; 819 925 pThis->pCurIosData = NULL; 820 926 } … … 832 938 return pThis->rcFatal; 833 939 940 /* 941 * Get the next file element. 942 */ 943 if (pThis->XarReader.fFirstFile) 944 { 945 pThis->XarReader.pCurFile = pThis->XarReader.pToc->findChildElement("file"); 946 pThis->XarReader.cCurDepth = 0; 947 } 948 else if (pThis->XarReader.pCurFile) 949 pThis->XarReader.pCurFile = rtZipXarGetNextFileElement(pThis->XarReader.pCurFile, &pThis->XarReader.cCurDepth); 950 if (!pThis->XarReader.pCurFile) 951 { 952 pThis->fEndOfStream = true; 953 return VERR_EOF; 954 } 955 956 /* 957 * Retrive the fundamental attributes (elements actually). 958 */ 959 const char *pszName = pThis->XarReader.pCurFile->findChildElementValueP("name"); 960 const char *pszType = pThis->XarReader.pCurFile->findChildElementValueP("type"); 961 if (RT_UNLIKELY(!pszName || !pszType)) 962 return pThis->rcFatal = VERR_XAR_BAD_FILE_ELEMENT; 963 964 /* 965 * Gather any additional attributes that are essential to the file type, 966 * then create the VFS object we're going to return. 967 */ 968 int rc; 969 RTVFSOBJ hVfsObj; 970 RTVFSOBJTYPE enmType; 971 if (!strcmp(pszType, "file")) 972 { 973 #if 0 /// @todo continue hacking here 974 rc = rtZipXarGetDataStreamAttributes(pThis->XarReader.pCurFile, &offData, &cbData); 975 if (RT_FAILURE(rc)) 976 return pThis->rcFatal = rc; 977 978 979 if (pThis->hVfsFile != NIL_RTVFSFILE) 980 { 981 982 } 983 else 984 { 985 RTVFSIOSTREAM hVfsIos; 986 PRTZIPXARIOSTREAM pIosData; 987 rc = RTVfsNewIoStream(&g_rtZipXarFssIosOps, 988 sizeof(*pIosData), 989 RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, 990 NIL_RTVFS, 991 NIL_RTVFSLOCK, 992 &hVfsIos, 993 (void **)&pIosData); 994 if (RT_FAILURE(rc)) 995 return pThis->rcFatal = rc; 996 997 pIosData->BaseObj.pXarReader = &pThis->XarReader; 998 pIosData->BaseObj.pFileElem = pThis->XarReader.pCurFile; 999 pIosData->cbFile = cbData; 1000 pIosData->offFile = 0; 1001 pIosData->cbPadding = (uint32_t)(Info.cbAllocated - Info.cbObject); 1002 pIosData->fEndOfStream = false; 1003 pIosData->hVfsIos = pThis->hVfsIos; 1004 RTVfsIoStrmRetain(pThis->hVfsIos); 1005 1006 pThis->pCurIosData = pIosData; 1007 pThis->offNextHdr += pIosData->cbFile + pIosData->cbPadding; 1008 1009 enmType = RTVFSOBJTYPE_IO_STREAM; 1010 hVfsObj = RTVfsObjFromIoStream(hVfsIos); 1011 RTVfsIoStrmRelease(hVfsIos); 1012 } 1013 #endif 1014 } 1015 else if (!strcmp(pszType, "directory")) 1016 { 1017 PRTZIPXARBASEOBJ pBaseObjData; 1018 rc = RTVfsNewBaseObj(&g_rtZipXarFssBaseObjOps, 1019 sizeof(*pBaseObjData), 1020 NIL_RTVFS, 1021 NIL_RTVFSLOCK, 1022 &hVfsObj, 1023 (void **)&pBaseObjData); 1024 if (RT_FAILURE(rc)) 1025 return pThis->rcFatal = rc; 1026 1027 pBaseObjData->pXarReader = &pThis->XarReader; 1028 pBaseObjData->pFileElem = pThis->XarReader.pCurFile; 1029 1030 enmType = RTVFSOBJTYPE_BASE; 1031 } 1032 else 1033 return pThis->rcFatal = VERR_XAR_BAD_UNKNOWN_FILE_TYPE; 1034 834 1035 #if 0 835 /*836 * Make sure the input stream is in the right place.837 */838 RTFOFF offHdr = RTVfsIoStrmTell(pThis->hVfsIos);839 while ( offHdr >= 0840 && offHdr < pThis->offNextHdr)841 {842 int rc = RTVfsIoStrmSkip(pThis->hVfsIos, pThis->offNextHdr - offHdr);843 if (RT_FAILURE(rc))844 {845 /** @todo Ignore if we're at the end of the stream? */846 return pThis->rcFatal = rc;847 }848 849 offHdr = RTVfsIoStrmTell(pThis->hVfsIos);850 }851 852 if (offHdr < 0)853 return pThis->rcFatal = (int)offHdr;854 if (offHdr > pThis->offNextHdr)855 return pThis->rcFatal = VERR_INTERNAL_ERROR_3;856 857 1036 /* 858 1037 * Consume XAR headers. … … 913 1092 case RTFS_TYPE_FILE: 914 1093 { 915 RTVFSIOSTREAM hVfsIos;916 PRTZIPXARIOSTREAM pIosData;917 rc = RTVfsNewIoStream(&g_rtZipXarFssIosOps,918 sizeof(*pIosData),919 RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN,920 NIL_RTVFS,921 NIL_RTVFSLOCK,922 &hVfsIos,923 (void **)&pIosData);924 if (RT_FAILURE(rc))925 return pThis->rcFatal = rc;926 927 pIosData->BaseObj.offHdr = offHdr;928 pIosData->BaseObj.pXarReader= &pThis->XarReader;929 pIosData->BaseObj.ObjInfo = Info;930 pIosData->cbFile = Info.cbObject;931 pIosData->offFile = 0;932 pIosData->cbPadding = (uint32_t)(Info.cbAllocated - Info.cbObject);933 pIosData->fEndOfStream = false;934 pIosData->hVfsIos = pThis->hVfsIos;935 RTVfsIoStrmRetain(pThis->hVfsIos);936 937 pThis->pCurIosData = pIosData;938 pThis->offNextHdr += pIosData->cbFile + pIosData->cbPadding;939 940 enmType = RTVFSOBJTYPE_IO_STREAM;941 hVfsObj = RTVfsObjFromIoStream(hVfsIos);942 RTVfsIoStrmRelease(hVfsIos);943 1094 break; 944 1095 } … … 1005 1156 } 1006 1157 pThis->hVfsCurObj = hVfsObj; 1158 #endif 1007 1159 1008 1160 /* … … 1011 1163 if (ppszName) 1012 1164 { 1013 rc = RTStrDupEx(ppszName, p This->XarReader.szName);1165 rc = RTStrDupEx(ppszName, pszName); /** @todo fixme */ 1014 1166 if (RT_FAILURE(rc)) 1015 1167 return rc; … … 1024 1176 if (penmType) 1025 1177 *penmType = enmType; 1026 #endif1027 1178 1028 1179 return VINF_SUCCESS; … … 1354 1505 pThis->XarReader.pDoc = pDoc; 1355 1506 pThis->XarReader.pToc = pTocElem; 1356 pThis->XarReader.idCurFile = 0; /* Assuming the ID numbering is from 1. */ 1507 pThis->XarReader.pCurFile = 0; 1508 pThis->XarReader.cCurDepth = 0; 1509 pThis->XarReader.fFirstFile = true; 1357 1510 1358 1511 /*
Note:
See TracChangeset
for help on using the changeset viewer.