| 849 | } |
| 850 | |
| 851 | bool ZipArchive::extractFile(const char *pathInZip, const char *filename, bool *crcFail /* = NULL */) |
| 852 | { |
| 853 | if(crcFail) |
| 854 | *crcFail = false; |
| 855 | |
| 856 | const CentralDir *realCD = findFileInfo(pathInZip); |
| 857 | if(realCD == NULL) |
| 858 | return false; |
| 859 | |
| 860 | FileStream dest; |
| 861 | if(! dest.open(filename, Torque::FS::File::Write)) |
| 862 | return false; |
| 863 | |
| 864 | Stream *source = openFile(pathInZip, Read); |
| 865 | if(source == NULL) |
| 866 | { |
| 867 | dest.close(); |
| 868 | return false; |
| 869 | } |
| 870 | |
| 871 | // [tom, 2/7/2007] CRC checking the lazy man's way |
| 872 | // ZipStatFilter only fails if it doesn't have a central directory, so this is safe |
| 873 | CentralDir fakeCD; |
| 874 | ZipStatFilter zsf(&fakeCD); |
| 875 | zsf.attachStream(source); |
| 876 | |
| 877 | bool ret = dest.copyFrom(&zsf); |
| 878 | |
| 879 | zsf.detachStream(); |
| 880 | |
| 881 | if(ret && fakeCD.mCRC32 != realCD->mCRC32) |
| 882 | { |
| 883 | if(crcFail) |
| 884 | *crcFail = true; |
| 885 | |
| 886 | if(isVerbose()) |
| 887 | Con::errorf("ZipArchive::extractFile - CRC failure extracting file %s", pathInZip); |
| 888 | ret = false; |
| 889 | } |
| 890 | |
| 891 | closeFile(source); |
| 892 | dest.close(); |
| 893 | |
| 894 | return ret; |
| 895 | } |
| 896 | |
| 897 | bool ZipArchive::deleteFile(const char *filename) |
| 898 | { |
nothing calls this directly
no test coverage detected