Skip to content

Commit 65f8428

Browse files
committed
Localization: Add plist support
1 parent 4ccb364 commit 65f8428

3 files changed

Lines changed: 93 additions & 6 deletions

File tree

Source/NSBundle.m

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#import "GNUstepBase/NSTask+GNUstepBase.h"
5555

5656
#import "GSPrivate.h"
57+
#import "NSPropertyListPrivate.h"
5758

5859
/* Store the working directory at startup */
5960
static NSString *_launchDirectory = nil;
@@ -2872,21 +2873,58 @@ - (NSString *) localizedStringForKey: (NSString *)key
28722873
tablePath = [self pathForResource: tableName ofType: @"strings"];
28732874
if (tablePath != nil)
28742875
{
2876+
NSPropertyListFormat format;
28752877
NSStringEncoding encoding;
28762878
NSString *tableContent;
28772879
NSData *tableData;
28782880
const unsigned char *bytes;
28792881
unsigned length;
28802882

2881-
tableData = [[NSData alloc] initWithContentsOfFile: tablePath];
2882-
bytes = [tableData bytes];
2883-
length = [tableData length];
28842883
/*
28852884
* A localisation file can be:
2886-
* - UTF-16 with a leading BOM,
2887-
* - UTF-8,
2888-
* - or ASCII with \U escapes.
2885+
* 1. A reduced "old-style" plist containing only one top-level dictionary
2886+
* 2. An xml-based or binary plist.
2887+
*/
2888+
tableData = [[NSData alloc] initWithContentsOfFile: tablePath];
2889+
if (tableData == nil)
2890+
{
2891+
NSWarnMLog(@"Failed read contents of file at path %@", tablePath);
2892+
goto end;
2893+
}
2894+
2895+
/*
2896+
* Check if tableData is a proper plist
2897+
*/
2898+
format = [NSPropertyListSerialization formatFromData: tableData];
2899+
if (format != 0)
2900+
{
2901+
NSString *errorDescription = nil;
2902+
table = [NSPropertyListSerialization propertyListFromData: tableData
2903+
mutabilityOption: NSPropertyListImmutable
2904+
format: &format
2905+
errorDescription: &errorDescription];
2906+
if (table == nil)
2907+
{
2908+
NSWarnMLog(@"Expected localization file at path %@ to be a property list"
2909+
@" of type %lu, but parsing failed - %@", tableData, format, errorDescription);
2910+
}
2911+
else
2912+
{
2913+
[_localizations setObject: table forKey: tableName];
2914+
}
2915+
2916+
goto end;
2917+
}
2918+
2919+
2920+
/*
2921+
* The following encodings are supported for the reduced "old-style" plist:
2922+
* - UTF-16 with a leading BOM,
2923+
* - UTF-8,
2924+
* - or ASCII with \U escapes.
28892925
*/
2926+
bytes = [tableData bytes];
2927+
length = [tableData length];
28902928
if (length > 2
28912929
&& ((bytes[0] == 0xFF && bytes[1] == 0xFE)
28922930
|| (bytes[0] == 0xFE && bytes[1] == 0xFF)))
@@ -2949,6 +2987,7 @@ - (NSString *) localizedStringForKey: (NSString *)key
29492987
[_localizations setObject: table forKey: tableName];
29502988
}
29512989

2990+
end:
29522991
if (key == nil || (newString = [table objectForKey: key]) == nil)
29532992
{
29542993
NSString *show = [[NSUserDefaults standardUserDefaults]

Source/NSPropertyList.m

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424

2525
#import "common.h"
26+
#include <stdint.h>
2627
#import "GNUstepBase/GSMime.h"
2728

2829
#import "Foundation/NSArray.h"
@@ -2460,6 +2461,40 @@ + (void) initialize
24602461
classInitialized = YES;
24612462
}
24622463

2464+
// Private class method for retrieving the format from an encoding plist
2465+
+ (NSPropertyListFormat) formatFromData: (NSData *) data
2466+
{
2467+
const uint8_t *bytes = [data bytes];
2468+
NSUInteger length = [data length];
2469+
if (length >= 8 && memcmp(bytes, "bplist00", 8) == 0)
2470+
{
2471+
return NSPropertyListBinaryFormat_v1_0;
2472+
}
2473+
else if (bytes[0] == 0 || bytes[0] == 1)
2474+
{
2475+
return NSPropertyListGNUstepBinaryFormat;
2476+
}
2477+
else
2478+
{
2479+
unsigned int index = 0;
2480+
2481+
// Skip any leading white space.
2482+
while (index < length && GS_IS_WHITESPACE(bytes[index]) == YES)
2483+
{
2484+
index++;
2485+
}
2486+
2487+
if (length - index > 2
2488+
&& bytes[index] == '<' && bytes[index+1] == '?')
2489+
{
2490+
// It begins with '<?' so it is xml
2491+
return NSPropertyListXMLFormat_v1_0;
2492+
}
2493+
}
2494+
2495+
return 0;
2496+
}
2497+
24632498
+ (NSData*) dataFromPropertyList: (id)aPropertyList
24642499
format: (NSPropertyListFormat)aFormat
24652500
errorDescription: (NSString**)anErrorString

Source/NSPropertyListPrivate.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#ifndef _INCLUDED_NSPROPERTYLISTPRIVATE_H
2+
#define _INCLUDED_NSPROPERTYLISTPRIVATE_H
3+
4+
#import <Foundation/NSPropertyList.h>
5+
6+
@interface NSPropertyListSerialization (CheckFormat)
7+
// Checks if the content of data is a property list.
8+
// Returns 0 if not a binary plist (NSPropertyListBinaryFormat_v1_0),
9+
// GNUstep binary plist, or XML plist.
10+
+ (NSPropertyListFormat) formatFromData: (NSData *) data;
11+
@end
12+
13+
#endif // _INCLUDED_NSPROPERTYLISTPRIVATE_H

0 commit comments

Comments
 (0)