2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @File : FBaseUtil_FileZipperImpl.cpp
20 * @brief : Implementation for _FileZipperImpl Class
27 #include <FBaseResult.h>
28 #include <FBaseSysLog.h>
29 #include <FBaseUtilStringUtil.h>
30 #include <FBaseUtilFileZipper.h>
32 #include "FBase_NativeError.h"
33 #include "FBaseUtil_FileUnzipperImpl.h"
34 #include "FBaseUtil_FileZipperImpl.h"
37 using namespace Tizen::Io;
39 namespace Tizen { namespace Base { namespace Utility
44 void operator ()(void* p)
53 #define UNZ_COMP_CASE_SENSITIVE 1
54 #define UNZ_COMP_NO_CASE_SENSITIVE 2
56 #define ZIP_WRITE_BUF_LEN 4096
58 _FileZipperImpl::_FileZipperImpl(void)
59 : __pArchiveName(null)
64 _FileZipperImpl::~_FileZipperImpl(void)
69 _FileZipperImpl::Construct(const String& filePath)
71 SysAssertf(__pArchiveName == null, "Already constructed! "
72 "Calling Construct() twice or more on a same instance is not allowed for this class");
74 std::unique_ptr< ByteBuffer > pFilePathBuff(StringUtil::StringToUtf8N(filePath));
75 SysTryReturnResult(NID_BASE_UTIL, pFilePathBuff != null, E_INVALID_ARG, "Invalid file path.");
77 const char* pFilePath = reinterpret_cast<const char*> (pFilePathBuff->GetPointer());
79 result r = IsFileExists(pFilePath);
80 SysTryReturnResult(NID_BASE_UTIL, (r == E_SUCCESS) || (r == E_FILE_NOT_FOUND), r, "Invalid file path [%s].", pFilePath);
82 int createOption = (r == E_FILE_NOT_FOUND)? APPEND_STATUS_CREATE : APPEND_STATUS_ADDINZIP;
83 std::unique_ptr< void, ZipFileDeleter > pZfile(zipOpen(pFilePath, createOption));
84 SysTryReturnResult(NID_BASE_UTIL, pZfile != null, E_IO, "Invalid file path [%s].", pFilePath);
86 int len = strlen(pFilePath);
87 std::unique_ptr< char[] > pArchiveName(new (std::nothrow) char[len + 1]);
88 SysTryReturnResult(NID_BASE_UTIL, pArchiveName != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
90 strncpy(pArchiveName.get(), pFilePath, len);
91 pArchiveName[len] = 0;
93 __pArchiveName = std::move(pArchiveName);
100 _FileZipperImpl::AddToZip(const String& filePath, bool excludePath, CompressionLevel level)
102 SysAssertf(__pArchiveName != null, "Not yet constructed! Construct() should be called before use");
104 std::unique_ptr< ByteBuffer > pFilePathBuff(StringUtil::StringToUtf8N(filePath));
105 SysTryReturnResult(NID_BASE_UTIL, pFilePathBuff != null, E_INVALID_ARG, "Invalid file path argument.");
107 const char* pFilePath = reinterpret_cast<const char*> (pFilePathBuff->GetPointer());
109 result r = IsFileExists(pFilePath);
110 SysTryReturnResult(NID_BASE_UTIL, r == E_SUCCESS, E_FILE_NOT_FOUND, "The file is not found.");
112 const char* pFilePathForZip = pFilePath;
113 if (excludePath == true)
115 const char* pPos = strrchr(pFilePathForZip, '/');
118 pFilePathForZip = pPos;
121 if (pFilePathForZip[0] == '/')
127 // while (pFilePathForZip[0] == '/' || pFilePathForZip[0] == '\\')
129 // pFilePathForZip++;
132 int compLevel = DEFAULT_COMPRESSION;
133 if (level == BEST_SPEED)
135 compLevel = Z_BEST_SPEED;
137 else if (level == BEST_COMPRESSION)
139 compLevel = Z_BEST_COMPRESSION;
142 if (_FileUnzipperImpl::IsFileExistsInZip(__pArchiveName.get(), pFilePathForZip))
144 SysTryReturnResult(NID_BASE_UTIL, __overwrite == true, E_FILE_ALREADY_EXIST, "File already exist but overwrite flag is not set");
145 return OverwriteInZip(pFilePath, pFilePathForZip, compLevel);
148 return AddToZip(pFilePath, pFilePathForZip, compLevel);
153 _FileZipperImpl::GetOverwriteFlag(void) const
160 _FileZipperImpl::SetOverwriteFlag(bool flag)
166 _FileZipperImpl::AddToZip(const char* pFilePath, const char* pFilePathForZip, int level)
169 result r = E_SUCCESS;
171 std::unique_ptr< void, ZipFileDeleter > pZfile(zipOpen(__pArchiveName.get(), APPEND_STATUS_ADDINZIP));
172 SysTryReturnResult(NID_BASE_UTIL, pZfile != null, E_IO, "Invalid file path [%s].", __pArchiveName.get());
174 zip_fileinfo zipInfo = {{0}};
175 err = zipOpenNewFileInZip(pZfile.get(), pFilePathForZip, &zipInfo, null, 0, null, 0, null, Z_DEFLATED, level);
176 SysTryReturnResult(NID_BASE_UTIL, err == ZIP_OK, E_IO, "Failed to open new file in zip.");
178 FILE* pFile = fopen(pFilePath, "r");
181 zipCloseFileInZip(pZfile.get());
182 SysTryReturnResult(NID_BASE_UTIL, pFile != null, __ConvertNativeErrorToResult(errno), "[%s] Failed to open the file.");
186 char buffer[ZIP_WRITE_BUF_LEN] = {0};
187 while (readCnt > 0 && !feof(pFile))
189 readCnt = fread(buffer, 1, ZIP_WRITE_BUF_LEN, pFile);
192 err = zipWriteInFileInZip(pZfile.get(), buffer, readCnt);
193 SysTryCatch(NID_BASE_UTIL, err == ZIP_OK, r = E_IO, E_IO, "[%s] Failed to write in zip file.", GetErrorMessage(E_IO));
199 zipCloseFileInZip(pZfile.get());
210 _FileZipperImpl::OverwriteInZip(const char* pFilePath, const char* pFilePathForZip, int level)
212 // TODO: Add Support for overwriting
213 return AddToZip(pFilePath, pFilePathForZip, level);
217 _FileZipperImpl::IsFileExists(const char* pFilePath)
219 if (access(pFilePath, F_OK) != 0)
221 return __ConvertNativeErrorToResult(errno);
228 } } } // Tizen::Base::Utility