2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 * @File : FBaseUtil_FileZipperImpl.cpp
19 * @brief : Implementation for _FileZipperImpl Class
26 #include <FBaseResult.h>
27 #include <FBaseSysLog.h>
28 #include <FBaseUtilStringUtil.h>
29 #include <FBaseUtilFileZipper.h>
31 #include "FBase_NativeError.h"
32 #include "FBaseUtil_FileUnzipperImpl.h"
33 #include "FBaseUtil_FileZipperImpl.h"
36 using namespace Tizen::Io;
38 namespace Tizen { namespace Base { namespace Utility
43 void operator ()(void* p)
52 #define UNZ_COMP_CASE_SENSITIVE 1
53 #define UNZ_COMP_NO_CASE_SENSITIVE 2
55 #define ZIP_WRITE_BUF_LEN 4096
57 _FileZipperImpl::_FileZipperImpl(void)
58 : __pArchiveName(null)
63 _FileZipperImpl::~_FileZipperImpl(void)
68 _FileZipperImpl::Construct(const String& filePath)
70 SysAssertf(__pArchiveName == null, "Already constructed! "
71 "Calling Construct() twice or more on a same instance is not allowed for this class");
73 std::unique_ptr< ByteBuffer > pFilePathBuff(StringUtil::StringToUtf8N(filePath));
74 SysTryReturnResult(NID_BASE_UTIL, pFilePathBuff != null, E_INVALID_ARG, "Invalid file path.");
76 const char* pFilePath = reinterpret_cast<const char*> (pFilePathBuff->GetPointer());
78 result r = IsFileExists(pFilePath);
79 SysSecureTryReturnResult(NID_BASE_UTIL, (r == E_SUCCESS) || (r == E_FILE_NOT_FOUND), r, "Invalid file path [%s].", pFilePath);
81 int createOption = (r == E_FILE_NOT_FOUND)? APPEND_STATUS_CREATE : APPEND_STATUS_ADDINZIP;
82 std::unique_ptr< void, ZipFileDeleter > pZfile(zipOpen(pFilePath, createOption));
83 SysSecureTryReturnResult(NID_BASE_UTIL, pZfile != null, E_IO, "Invalid file path [%s].", pFilePath);
85 int len = strlen(pFilePath);
86 std::unique_ptr< char[] > pArchiveName(new (std::nothrow) char[len + 1]);
87 SysTryReturnResult(NID_BASE_UTIL, pArchiveName != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
89 strncpy(pArchiveName.get(), pFilePath, len);
90 pArchiveName[len] = 0;
92 __pArchiveName = std::move(pArchiveName);
99 _FileZipperImpl::AddToZip(const String& filePath, bool excludePath, CompressionLevel level)
101 SysAssertf(__pArchiveName != null, "Not yet constructed! Construct() should be called before use");
103 std::unique_ptr< ByteBuffer > pFilePathBuff(StringUtil::StringToUtf8N(filePath));
104 SysTryReturnResult(NID_BASE_UTIL, pFilePathBuff != null, E_INVALID_ARG, "Invalid file path argument.");
106 const char* pFilePath = reinterpret_cast<const char*> (pFilePathBuff->GetPointer());
108 result r = IsFileExists(pFilePath);
109 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_FILE_NOT_FOUND, "The file is not found.");
111 const char* pFilePathForZip = pFilePath;
112 if (excludePath == true)
114 const char* pPos = strrchr(pFilePathForZip, '/');
117 pFilePathForZip = pPos;
120 if (pFilePathForZip[0] == '/')
126 // while (pFilePathForZip[0] == '/' || pFilePathForZip[0] == '\\')
128 // pFilePathForZip++;
131 int compLevel = DEFAULT_COMPRESSION;
132 if (level == BEST_SPEED)
134 compLevel = Z_BEST_SPEED;
136 else if (level == BEST_COMPRESSION)
138 compLevel = Z_BEST_COMPRESSION;
141 if (_FileUnzipperImpl::IsFileExistsInZip(__pArchiveName.get(), pFilePathForZip))
143 SysTryReturnResult(NID_BASE_UTIL, __overwrite == true, E_FILE_ALREADY_EXIST, "File already exist but overwrite flag is not set");
144 return OverwriteInZip(pFilePath, pFilePathForZip, compLevel);
147 return AddToZip(pFilePath, pFilePathForZip, compLevel);
152 _FileZipperImpl::GetOverwriteFlag(void) const
159 _FileZipperImpl::SetOverwriteFlag(bool flag)
165 _FileZipperImpl::AddToZip(const char* pFilePath, const char* pFilePathForZip, int level)
168 result r = E_SUCCESS;
170 std::unique_ptr< void, ZipFileDeleter > pZfile(zipOpen(__pArchiveName.get(), APPEND_STATUS_ADDINZIP));
171 SysSecureTryReturnResult(NID_BASE_UTIL, pZfile != null, E_IO, "Invalid file path [%s].", __pArchiveName.get());
173 zip_fileinfo zipInfo = {{0}};
174 err = zipOpenNewFileInZip(pZfile.get(), pFilePathForZip, &zipInfo, null, 0, null, 0, null, Z_DEFLATED, level);
175 SysTryReturnResult(NID_BASE_UTIL, err == ZIP_OK, E_IO, "Failed to open new file in zip.");
177 FILE* pFile = fopen(pFilePath, "r");
180 zipCloseFileInZip(pZfile.get());
181 SysTryReturnResult(NID_BASE_UTIL, pFile != null, __ConvertNativeErrorToResult(errno), "Failed to open the file.");
185 char buffer[ZIP_WRITE_BUF_LEN] = {0};
186 while (readCnt > 0 && !feof(pFile))
188 readCnt = fread(buffer, 1, ZIP_WRITE_BUF_LEN, pFile);
191 err = zipWriteInFileInZip(pZfile.get(), buffer, readCnt);
192 SysTryCatch(NID_BASE_UTIL, err == ZIP_OK, r = E_IO, E_IO, "[%s] Failed to write in zip file.", GetErrorMessage(E_IO));
198 zipCloseFileInZip(pZfile.get());
209 _FileZipperImpl::OverwriteInZip(const char* pFilePath, const char* pFilePathForZip, int level)
211 // TODO: Add Support for overwriting
212 return AddToZip(pFilePath, pFilePathForZip, level);
216 _FileZipperImpl::IsFileExists(const char* pFilePath)
218 if (access(pFilePath, F_OK) != 0)
220 return __ConvertNativeErrorToResult(errno);
227 } } } // Tizen::Base::Utility