forked from HowardHinnant/date
Fix memory leaks
This commit is contained in:
99
ios.mm
99
ios.mm
@@ -36,7 +36,8 @@
|
|||||||
# define TAR_DEBUG 0
|
# define TAR_DEBUG 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define INTERNAL_DIR "Library/tzdata"
|
#define INTERNAL_DIR "Library"
|
||||||
|
#define TZDATA_DIR "tzdata"
|
||||||
#define TARGZ_EXTENSION "tar.gz"
|
#define TARGZ_EXTENSION "tar.gz"
|
||||||
|
|
||||||
#define TAR_BLOCK_SIZE 512
|
#define TAR_BLOCK_SIZE 512
|
||||||
@@ -60,7 +61,7 @@ struct TarInfo
|
|||||||
bool success;
|
bool success;
|
||||||
};
|
};
|
||||||
|
|
||||||
char* convertCFStringRefPathToCStringPath(CFStringRef ref);
|
std::string convertCFStringRefPathToCStringPath(CFStringRef ref);
|
||||||
bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath);
|
bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath);
|
||||||
TarInfo getTarObjectInfo(CFReadStreamRef readStream, int64_t location);
|
TarInfo getTarObjectInfo(CFReadStreamRef readStream, int64_t location);
|
||||||
std::string getTarObject(CFReadStreamRef readStream, int64_t size);
|
std::string getTarObject(CFReadStreamRef readStream, int64_t size);
|
||||||
@@ -68,19 +69,43 @@ bool writeFile(CFURLRef tzdataUrl, std::string fileName, std::string data,
|
|||||||
int64_t realContentSize);
|
int64_t realContentSize);
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
date::iOSUtils::get_tzdata_path()
|
get_current_timezone()
|
||||||
{
|
{
|
||||||
CFURLRef ref = CFCopyHomeDirectoryURL();
|
CFTimeZoneRef tzRef = CFTimeZoneCopySystem();
|
||||||
CFStringRef homePath = CFURLCopyPath(CFCopyHomeDirectoryURL());
|
CFStringRef tzNameRef = CFTimeZoneGetName(tzRef);
|
||||||
std::string tzdata_path(std::string(convertCFStringRefPathToCStringPath(homePath)) +
|
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
|
||||||
|
get_tzdata_path()
|
||||||
|
{
|
||||||
|
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);
|
INTERNAL_DIR);
|
||||||
|
|
||||||
if (access(tzdata_path.c_str(), F_OK) == 0)
|
if (access(path.c_str(), F_OK) == 0)
|
||||||
{
|
{
|
||||||
#if TAR_DEBUG
|
#if TAR_DEBUG
|
||||||
printf("tzdata exists\n");
|
printf("tzdata dir exists\n");
|
||||||
#endif
|
#endif
|
||||||
return tzdata_path;
|
CFRelease(homeUrlRef);
|
||||||
|
CFRelease(homePath);
|
||||||
|
|
||||||
|
return result_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
CFBundleRef mainBundle = CFBundleGetMainBundle();
|
CFBundleRef mainBundle = CFBundleGetMainBundle();
|
||||||
@@ -94,19 +119,28 @@ date::iOSUtils::get_tzdata_path()
|
|||||||
CFStringRef archiveName = CFURLCopyPath(archiveUrl);
|
CFStringRef archiveName = CFURLCopyPath(archiveUrl);
|
||||||
archiveUrl = CFBundleCopyResourceURL(mainBundle, archiveName, NULL, NULL);
|
archiveUrl = CFBundleCopyResourceURL(mainBundle, archiveName, NULL, NULL);
|
||||||
|
|
||||||
extractTzdata(CFCopyHomeDirectoryURL(), archiveUrl, tzdata_path);
|
extractTzdata(homeUrlRef, archiveUrl, path);
|
||||||
|
|
||||||
|
CFRelease(archiveUrl);
|
||||||
|
CFRelease(archiveName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tzdata_path;
|
CFRelease(homeUrlRef);
|
||||||
|
CFRelease(homePath);
|
||||||
|
CFRelease(paths);
|
||||||
|
|
||||||
|
return result_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
char*
|
std::string
|
||||||
convertCFStringRefPathToCStringPath(CFStringRef ref)
|
convertCFStringRefPathToCStringPath(CFStringRef ref)
|
||||||
{
|
{
|
||||||
CFIndex bufferSize = CFStringGetMaximumSizeOfFileSystemRepresentation(ref);
|
CFIndex bufferSize = CFStringGetMaximumSizeOfFileSystemRepresentation(ref);
|
||||||
char *buffer = new char[bufferSize];
|
char *buffer = new char[bufferSize];
|
||||||
CFStringGetFileSystemRepresentation(ref, buffer, 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)
|
bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
|
||||||
@@ -114,28 +148,29 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
|
|||||||
const char *TAR_TMP_PATH = "/tmp.tar";
|
const char *TAR_TMP_PATH = "/tmp.tar";
|
||||||
|
|
||||||
// create Library path
|
// create Library path
|
||||||
CFStringRef libraryStr = CFStringCreateWithCString(NULL, "Library",
|
CFStringRef libraryStr = CFStringCreateWithCString(NULL, INTERNAL_DIR,
|
||||||
CFStringGetSystemEncoding());
|
CFStringGetSystemEncoding());
|
||||||
CFURLRef libraryUrl = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault,
|
CFURLRef libraryUrl = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault,
|
||||||
homeUrl, libraryStr,
|
homeUrl, libraryStr,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
// create tzdata path
|
// create tzdata path
|
||||||
CFStringRef tzdataPathRef = CFStringCreateWithCString(NULL, INTERNAL_DIR,
|
CFStringRef tzdataPathRef = CFStringCreateWithCString(NULL, std::string(std::string(INTERNAL_DIR) + "/" + TZDATA_DIR).c_str(),
|
||||||
CFStringGetSystemEncoding());
|
CFStringGetSystemEncoding());
|
||||||
CFURLRef tzdataPathUrl = CFURLCreateCopyAppendingPathComponent(NULL, homeUrl,
|
CFURLRef tzdataPathUrl = CFURLCreateCopyAppendingPathComponent(NULL, homeUrl,
|
||||||
tzdataPathRef, false);
|
tzdataPathRef, false);
|
||||||
|
|
||||||
// create src archive path
|
// create src archive path
|
||||||
CFStringRef archivePath = CFURLCopyPath(archiveUrl);
|
CFStringRef archivePath = CFURLCopyPath(archiveUrl);
|
||||||
gzFile tarFile = gzopen(convertCFStringRefPathToCStringPath(archivePath), "rb");
|
gzFile tarFile = gzopen(convertCFStringRefPathToCStringPath(archivePath).c_str(), "rb");
|
||||||
|
|
||||||
// create tar unpacking path
|
// create tar unpacking path
|
||||||
CFStringRef tarName = CFStringCreateWithCString(NULL, TAR_TMP_PATH,
|
CFStringRef tarName = CFStringCreateWithCString(NULL, TAR_TMP_PATH,
|
||||||
CFStringGetSystemEncoding());
|
CFStringGetSystemEncoding());
|
||||||
CFURLRef tarUrl = CFURLCreateCopyAppendingPathComponent(NULL, libraryUrl, tarName,
|
CFURLRef tarUrl = CFURLCreateCopyAppendingPathComponent(NULL, libraryUrl, tarName,
|
||||||
false);
|
false);
|
||||||
const char *tarPath = convertCFStringRefPathToCStringPath(CFURLCopyPath(tarUrl));
|
CFStringRef tarPathRef = CFURLCopyPath(tarUrl);
|
||||||
|
auto tarPath = convertCFStringRefPathToCStringPath(tarPathRef);
|
||||||
|
|
||||||
// create tzdata directory
|
// create tzdata directory
|
||||||
mkdir(destPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
mkdir(destPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||||
@@ -144,6 +179,13 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
|
|||||||
CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(NULL, tarUrl);
|
CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(NULL, tarUrl);
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
|
CFRelease(libraryStr);
|
||||||
|
CFRelease(libraryUrl);
|
||||||
|
CFRelease(tzdataPathRef);
|
||||||
|
CFRelease(archivePath);
|
||||||
|
CFRelease(tarName);
|
||||||
|
CFRelease(tarPathRef);
|
||||||
|
|
||||||
if (!CFWriteStreamOpen(writeStream))
|
if (!CFWriteStreamOpen(writeStream))
|
||||||
{
|
{
|
||||||
CFStreamError err = CFWriteStreamGetError(writeStream);
|
CFStreamError err = CFWriteStreamGetError(writeStream);
|
||||||
@@ -162,7 +204,8 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
|
|||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
remove(tarPath);
|
CFRelease(tzdataPathUrl);
|
||||||
|
CFRelease(writeStream);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +256,7 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
|
|||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
remove(tarPath);
|
CFRelease(tzdataPathUrl);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,17 +266,18 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
|
|||||||
|
|
||||||
// get file size
|
// get file size
|
||||||
struct stat stat_buf;
|
struct stat stat_buf;
|
||||||
int res = stat(tarPath, &stat_buf);
|
int res = stat(tarPath.c_str(), &stat_buf);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
{
|
{
|
||||||
printf("error file size\n");
|
printf("error file size\n");
|
||||||
remove(tarPath);
|
CFRelease(tzdataPathUrl);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int64_t tarSize = stat_buf.st_size;
|
int64_t tarSize = stat_buf.st_size;
|
||||||
|
|
||||||
// create read stream
|
// create read stream
|
||||||
CFReadStreamRef readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault, tarUrl);
|
CFReadStreamRef readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault, tarUrl);
|
||||||
|
CFRelease(tarUrl);
|
||||||
|
|
||||||
if (!CFReadStreamOpen(readStream))
|
if (!CFReadStreamOpen(readStream))
|
||||||
{
|
{
|
||||||
@@ -253,14 +297,11 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
|
|||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
|
CFRelease(tzdataPathUrl);
|
||||||
CFRelease(readStream);
|
CFRelease(readStream);
|
||||||
remove(tarPath);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
long size = 0;
|
|
||||||
|
|
||||||
// process files
|
// process files
|
||||||
while (location < tarSize)
|
while (location < tarSize)
|
||||||
{
|
{
|
||||||
@@ -290,11 +331,10 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CFRelease(tzdataPathUrl);
|
||||||
CFReadStreamClose(readStream);
|
CFReadStreamClose(readStream);
|
||||||
CFRelease(readStream);
|
CFRelease(readStream);
|
||||||
|
|
||||||
remove(tarPath);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,8 +349,6 @@ getTarObjectInfo(CFReadStreamRef readStream, int64_t location)
|
|||||||
char sizeBuf[TAR_SIZE_SIZE + 1];
|
char sizeBuf[TAR_SIZE_SIZE + 1];
|
||||||
CFIndex bytesRead;
|
CFIndex bytesRead;
|
||||||
|
|
||||||
bool avail = CFReadStreamHasBytesAvailable(readStream);
|
|
||||||
|
|
||||||
bytesRead = CFReadStreamRead(readStream, buffer, length);
|
bytesRead = CFReadStreamRead(readStream, buffer, length);
|
||||||
|
|
||||||
if (bytesRead < 0)
|
if (bytesRead < 0)
|
||||||
@@ -360,6 +398,9 @@ writeFile(CFURLRef tzdataUrl, std::string fileName, std::string data,
|
|||||||
false);
|
false);
|
||||||
CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(NULL, url);
|
CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(NULL, url);
|
||||||
|
|
||||||
|
CFRelease(fileNameRef);
|
||||||
|
CFRelease(url);
|
||||||
|
|
||||||
// open stream
|
// open stream
|
||||||
if (!CFWriteStreamOpen(writeStream))
|
if (!CFWriteStreamOpen(writeStream))
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user