#include "TBundle.h"
#include "TSystemUtils.h"
#define DEBUG 0
#ifndef DEBUG_ASSERT_COMPONENT_NAME_STRING
#define DEBUG_ASSERT_COMPONENT_NAME_STRING "TBundle"
#endif
#include <AssertMacros.h>
#define kLocalizableString "Localizable"
#define kStringsTypeString "strings"
#define kEmptyString ""
TBundle::TBundle ( CFBundleRef bundle ) :
fLocalizationDictionaryForTable ( NULL )
{
check ( bundle );
fCFBundleRef = ( CFBundleRef ) ::CFRetain ( bundle );
}
TBundle::~TBundle ( void )
{
check ( fCFBundleRef );
::CFRelease ( fCFBundleRef );
fCFBundleRef = NULL;
if ( fLocalizationDictionaryForTable != NULL )
{
::CFRelease ( fLocalizationDictionaryForTable );
fLocalizationDictionaryForTable = NULL;
}
}
CFStringRef
TBundle::CopyLocalizedStringForKey ( CFStringRef key,
CFStringRef defaultValue,
CFStringRef tableName )
{
CFStringRef result = NULL;
if ( tableName == NULL )
{
tableName = CFSTR ( kLocalizableString );
}
if ( fLocalizationDictionaryForTable == NULL )
{
fLocalizationDictionaryForTable = CopyLocalizationDictionaryForTable ( tableName );
}
if ( fLocalizationDictionaryForTable != NULL )
{
result = ( CFStringRef ) ::CFDictionaryGetValue ( fLocalizationDictionaryForTable, key );
::CFRetain ( result );
}
if ( ( result == NULL ) && ( defaultValue != NULL ) )
{
result = ( CFStringRef ) ::CFRetain ( defaultValue );
}
return result;
}
CFDictionaryRef
TBundle::CopyLocalizationDictionaryForTable ( CFStringRef table )
{
CFDictionaryRef stringTable = NULL;
CFURLRef localizedStringsURL = NULL;
CFDataRef tableData = NULL;
CFStringRef errStr = NULL;
SInt32 errCode = 0;
Boolean result = false;
localizedStringsURL = CopyURLForResourceOfTypeInBundle (
table,
CFSTR ( kStringsTypeString ),
fCFBundleRef );
require ( ( localizedStringsURL != NULL ), ErrorExit );
result = ::CFURLCreateDataAndPropertiesFromResource ( kCFAllocatorDefault,
localizedStringsURL,
&tableData,
NULL,
NULL,
&errCode );
require ( result, ReleaseURL );
require ( ( tableData != NULL ), ReleaseURL );
stringTable = ( CFDictionaryRef ) ::CFPropertyListCreateFromXMLData (
kCFAllocatorDefault,
tableData,
kCFPropertyListImmutable,
&errStr );
if ( errStr != NULL )
{
CFShow ( errStr );
::CFRelease ( errStr );
errStr = NULL;
}
::CFRelease ( tableData );
tableData = NULL;
check ( stringTable != NULL );
ReleaseURL:
::CFRelease ( localizedStringsURL );
localizedStringsURL = NULL;
ErrorExit:
return stringTable;
}
CFArrayRef
TBundle::CopyLocalizations ( void )
{
return ::CFBundleCopyBundleLocalizations ( fCFBundleRef );
}
CFArrayRef
TBundle::CopyLocalizationsForPrefs ( CFArrayRef bundleLocalizations,
CFArrayRef preferredLanguages )
{
return ::CFBundleCopyLocalizationsForPreferences ( bundleLocalizations, preferredLanguages );
}
CFURLRef
TBundle::CopyURLForResourceOfTypeInBundle ( CFStringRef resource,
CFStringRef type,
CFBundleRef bundle )
{
CFURLRef result = NULL;
CFArrayRef preferredLanguages = NULL;
CFArrayRef bundleLocalizations = NULL;
CFArrayRef preferredLocalizations = NULL;
UInt32 index = 0;
UInt32 count = 0;
if ( bundle == NULL )
{
bundle = ::CFBundleGetMainBundle ( );
}
require ( ( bundle != NULL ), ErrorExit );
preferredLanguages = TSystemUtils::GetPreferredLanguages ( );
require ( ( preferredLanguages != NULL ), ErrorExit );
bundleLocalizations = CopyLocalizations ( );
preferredLocalizations = CopyLocalizationsForPrefs ( bundleLocalizations, preferredLanguages );
count = ::CFArrayGetCount ( preferredLocalizations );
for ( index = 0; ( result == NULL ) && ( index < count ); index++)
{
CFStringRef item = ( CFStringRef ) ::CFArrayGetValueAtIndex ( preferredLocalizations, index );
result = CopyURLForResource ( resource,
type,
NULL,
item );
}
if ( result == NULL )
{
CFStringRef developmentLocalization = ::CFBundleGetDevelopmentRegion ( fCFBundleRef );
if ( developmentLocalization != NULL )
{
result = CopyURLForResource ( resource, type, NULL, developmentLocalization );
}
}
if ( preferredLanguages != NULL )
::CFRelease ( preferredLanguages );
if ( bundleLocalizations != NULL )
::CFRelease ( bundleLocalizations );
ErrorExit:
return result;
}
CFURLRef
TBundle::CopyURLForResource ( CFStringRef resource,
CFStringRef type,
CFStringRef dir,
CFStringRef localization )
{
CFURLRef resultURL = NULL;
resultURL = ::CFBundleCopyResourceURLForLocalization ( fCFBundleRef,
resource,
type,
dir,
localization );
return resultURL;
}