Fix memory leaks

This commit is contained in:
schmidt9
2017-07-17 17:14:43 +03:00
committed by Howard Hinnant
parent a828109809
commit 496497d16e

111
ios.mm
View File

@@ -36,7 +36,8 @@
# define TAR_DEBUG 0
#endif
#define INTERNAL_DIR "Library/tzdata"
#define INTERNAL_DIR "Library"
#define TZDATA_DIR "tzdata"
#define TARGZ_EXTENSION "tar.gz"
#define TAR_BLOCK_SIZE 512
@@ -60,27 +61,51 @@ struct TarInfo
bool success;
};
char* convertCFStringRefPathToCStringPath(CFStringRef ref);
std::string convertCFStringRefPathToCStringPath(CFStringRef ref);
bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath);
TarInfo getTarObjectInfo(CFReadStreamRef readStream, int64_t location);
std::string getTarObject(CFReadStreamRef readStream, int64_t size);
bool writeFile(CFURLRef tzdataUrl, std::string fileName, std::string data,
int64_t realContentSize);
std::string
get_current_timezone()
{
CFTimeZoneRef tzRef = CFTimeZoneCopySystem();
CFStringRef tzNameRef = CFTimeZoneGetName(tzRef);
CFIndex bufferSize = CFStringGetLength(tzNameRef) + 1;
char buffer[bufferSize];
if (CFStringGetCString(tzNameRef, buffer, bufferSize, kCFStringEncodingUTF8))
{
CFRelease(tzRef);
return std::string(buffer);
}
CFRelease(tzRef);
return "";
}
std::string
date::iOSUtils::get_tzdata_path()
get_tzdata_path()
{
CFURLRef ref = CFCopyHomeDirectoryURL();
CFStringRef homePath = CFURLCopyPath(CFCopyHomeDirectoryURL());
std::string tzdata_path(std::string(convertCFStringRefPathToCStringPath(homePath)) +
INTERNAL_DIR);
if (access(tzdata_path.c_str(), F_OK) == 0)
CFURLRef homeUrlRef = CFCopyHomeDirectoryURL();
CFStringRef homePath = CFURLCopyPath(homeUrlRef);
std::string path(std::string(convertCFStringRefPathToCStringPath(homePath)) +
INTERNAL_DIR + "/" + TZDATA_DIR);
std::string result_path(std::string(convertCFStringRefPathToCStringPath(homePath)) +
INTERNAL_DIR);
if (access(path.c_str(), F_OK) == 0)
{
#if TAR_DEBUG
printf("tzdata exists\n");
printf("tzdata dir exists\n");
#endif
return tzdata_path;
CFRelease(homeUrlRef);
CFRelease(homePath);
return result_path;
}
CFBundleRef mainBundle = CFBundleGetMainBundle();
@@ -91,22 +116,31 @@ date::iOSUtils::get_tzdata_path()
{
// get archive path, assume there is no other tar.gz in bundle
CFURLRef archiveUrl = static_cast<CFURLRef>(CFArrayGetValueAtIndex(paths, 0));
CFStringRef archiveName= CFURLCopyPath(archiveUrl);
CFStringRef archiveName = CFURLCopyPath(archiveUrl);
archiveUrl = CFBundleCopyResourceURL(mainBundle, archiveName, NULL, NULL);
extractTzdata(CFCopyHomeDirectoryURL(), archiveUrl, tzdata_path);
extractTzdata(homeUrlRef, archiveUrl, path);
CFRelease(archiveUrl);
CFRelease(archiveName);
}
CFRelease(homeUrlRef);
CFRelease(homePath);
CFRelease(paths);
return tzdata_path;
return result_path;
}
char*
std::string
convertCFStringRefPathToCStringPath(CFStringRef ref)
{
CFIndex bufferSize = CFStringGetMaximumSizeOfFileSystemRepresentation(ref);
char *buffer = new char[bufferSize];
CFStringGetFileSystemRepresentation(ref, buffer, bufferSize);
return buffer;
auto result = std::string(buffer);
delete[] buffer;
return result;
}
bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
@@ -114,35 +148,43 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
const char *TAR_TMP_PATH = "/tmp.tar";
// create Library path
CFStringRef libraryStr = CFStringCreateWithCString(NULL, "Library",
CFStringRef libraryStr = CFStringCreateWithCString(NULL, INTERNAL_DIR,
CFStringGetSystemEncoding());
CFURLRef libraryUrl = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault,
homeUrl, libraryStr,
false);
// create tzdata path
CFStringRef tzdataPathRef = CFStringCreateWithCString(NULL, INTERNAL_DIR,
CFStringRef tzdataPathRef = CFStringCreateWithCString(NULL, std::string(std::string(INTERNAL_DIR) + "/" + TZDATA_DIR).c_str(),
CFStringGetSystemEncoding());
CFURLRef tzdataPathUrl = CFURLCreateCopyAppendingPathComponent(NULL, homeUrl,
tzdataPathRef, false);
// create src archive path
CFStringRef archivePath = CFURLCopyPath(archiveUrl);
gzFile tarFile = gzopen(convertCFStringRefPathToCStringPath(archivePath), "rb");
gzFile tarFile = gzopen(convertCFStringRefPathToCStringPath(archivePath).c_str(), "rb");
// create tar unpacking path
CFStringRef tarName = CFStringCreateWithCString(NULL, TAR_TMP_PATH,
CFStringGetSystemEncoding());
CFURLRef tarUrl = CFURLCreateCopyAppendingPathComponent(NULL, libraryUrl, tarName,
false);
const char *tarPath = convertCFStringRefPathToCStringPath(CFURLCopyPath(tarUrl));
CFStringRef tarPathRef = CFURLCopyPath(tarUrl);
auto tarPath = convertCFStringRefPathToCStringPath(tarPathRef);
// create tzdata directory
mkdir(destPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
// create stream
CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(NULL, tarUrl);
bool success = true;
CFRelease(libraryStr);
CFRelease(libraryUrl);
CFRelease(tzdataPathRef);
CFRelease(archivePath);
CFRelease(tarName);
CFRelease(tarPathRef);
if (!CFWriteStreamOpen(writeStream))
{
@@ -162,7 +204,8 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
if (!success)
{
remove(tarPath);
CFRelease(tzdataPathUrl);
CFRelease(writeStream);
return false;
}
@@ -213,7 +256,7 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
if (!success)
{
remove(tarPath);
CFRelease(tzdataPathUrl);
return false;
}
@@ -223,17 +266,18 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
// get file size
struct stat stat_buf;
int res = stat(tarPath, &stat_buf);
int res = stat(tarPath.c_str(), &stat_buf);
if (res != 0)
{
printf("error file size\n");
remove(tarPath);
CFRelease(tzdataPathUrl);
return false;
}
int64_t tarSize = stat_buf.st_size;
// create read stream
CFReadStreamRef readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault, tarUrl);
CFRelease(tarUrl);
if (!CFReadStreamOpen(readStream))
{
@@ -253,14 +297,11 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
if (!success)
{
CFRelease(tzdataPathUrl);
CFRelease(readStream);
remove(tarPath);
return false;
}
int count = 0;
long size = 0;
// process files
while (location < tarSize)
{
@@ -289,12 +330,11 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
}
}
}
CFRelease(tzdataPathUrl);
CFReadStreamClose(readStream);
CFRelease(readStream);
remove(tarPath);
return true;
}
@@ -309,8 +349,6 @@ getTarObjectInfo(CFReadStreamRef readStream, int64_t location)
char sizeBuf[TAR_SIZE_SIZE + 1];
CFIndex bytesRead;
bool avail = CFReadStreamHasBytesAvailable(readStream);
bytesRead = CFReadStreamRead(readStream, buffer, length);
if (bytesRead < 0)
@@ -359,6 +397,9 @@ writeFile(CFURLRef tzdataUrl, std::string fileName, std::string data,
CFURLRef url = CFURLCreateCopyAppendingPathComponent(NULL, tzdataUrl, fileNameRef,
false);
CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(NULL, url);
CFRelease(fileNameRef);
CFRelease(url);
// open stream
if (!CFWriteStreamOpen(writeStream))