Skip to content

Commit 7bb4100

Browse files
iCharlesHukperryua
andauthored
OpenStep plist decoding via PropertyListDecoder is not available on Windows and Linux (#1002)
resolves: rdar://136243566 Co-authored-by: Kevin Perry <kperry@apple.com>
1 parent 03004e9 commit 7bb4100

File tree

7 files changed

+47
-20
lines changed

7 files changed

+47
-20
lines changed

Sources/FoundationEssentials/PropertyList/OpenStepPlist.swift

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -302,12 +302,7 @@ private func parseOctal(startingWith ch: UInt16, _ pInfo: inout _ParseInfo) -> U
302302
}
303303
}
304304

305-
// A probably more expensive replacement for CFStringEncodingBytesToUnicode(kCFStringEncodingNextStepLatin, …)
306-
guard let str = String(bytes: [num], encoding: .nextstep) else {
307-
pInfo.err = OpenStepPlistError("Unable to convert octet-stream while parsing plist")
308-
return 0
309-
}
310-
return str.utf16.first ?? 0
305+
return .init(nextStep: num)
311306
}
312307

313308
private func parseU16Scalar(_ pInfo: inout _ParseInfo) -> UInt16 {

Sources/FoundationEssentials/PropertyList/PlistDecoder.swift

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@ open class PropertyListDecoder {
158158
format = .xml
159159
return result
160160
}, openstep: { utf16View in
161-
#if FOUNDATION_FRAMEWORK
162161
let value: Any
163162
do {
164163
value = try __ParseOldStylePropertyList(utf16: utf16View)
@@ -168,10 +167,6 @@ open class PropertyListDecoder {
168167
let decoder = __PlistDictionaryDecoder(referencing: value, at: [], options: options)
169168
format = .openStep
170169
return try doDecode(decoder)
171-
#else
172-
// Unsupported until __PlistDictionaryDecoder is available
173-
throw DecodingError.dataCorrupted(.init(codingPath: [], debugDescription: "The openStep format is unsupported on this platform."))
174-
#endif
175170
})
176171
}
177172

Sources/FoundationEssentials/PropertyList/PlistDictionaryDecoder.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
// Relies on NSNumber
14-
#if FOUNDATION_FRAMEWORK
15-
1613
// MARK: - __PlistDictionaryDecoder
1714

1815
internal class __PlistDictionaryDecoder : Decoder, _PlistDecoderEntryPointProtocol {
@@ -899,10 +896,14 @@ extension __PlistDictionaryDecoder {
899896
}
900897
return converted
901898
}
899+
900+
// Relies on NSNumber
901+
#if FOUNDATION_FRAMEWORK
902902
if let ns = value as? NSNumber {
903903
// This was some other NSNumber value that couldn't fit in T.
904904
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed property list number <\(ns)> does not fit in \(type)."))
905905
}
906+
#endif
906907

907908
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
908909
}
@@ -966,10 +967,14 @@ extension __PlistDictionaryDecoder {
966967
}
967968
return converted
968969
}
970+
971+
// Relies on NSNumber
972+
#if FOUNDATION_FRAMEWORK
969973
if let ns = value as? NSNumber {
970974
// This was some other NSNumber value that couldn't fit in T.
971975
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed property list number <\(ns)> does not fit in \(type)."))
972976
}
977+
#endif
973978

974979
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
975980
}
@@ -1028,5 +1033,3 @@ extension __PlistDictionaryDecoder {
10281033
return try type.init(from: self, configuration: configuration)
10291034
}
10301035
}
1031-
1032-
#endif // FOUNDATION_FRAMEWORK

Sources/FoundationEssentials/String/StringProtocol+Essentials.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,21 @@ extension UInt8 {
7474
}
7575
}
7676

77+
extension UInt16 {
78+
init(nextStep codepoint: UInt8) {
79+
if codepoint < 128 {
80+
self = Self(codepoint)
81+
} else {
82+
let tableOffset = Int(codepoint - 128)
83+
self = withUnsafePointer(to: _stringshims_nextstep_mapping) {
84+
$0.withMemoryRebound(to: Self.self, capacity: Int(_STRINGSHIMS_NEXTSTEP_MAP_SIZE)) {
85+
$0.advanced(by: tableOffset).pointee
86+
}
87+
}
88+
}
89+
}
90+
}
91+
7792
// These provides concrete implementations for String and Substring, enhancing performance over generic StringProtocol.
7893

7994
@available(FoundationPreview 0.4, *)

Sources/_FoundationCShims/include/string_shims.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ INTERNAL float _stringshims_strtof_l(const char * _Nullable __restrict nptr, cha
4646
#define _STRINGSHIMS_MACROMAN_MAP_SIZE 129
4747
INTERNAL const uint8_t _stringshims_macroman_mapping[_STRINGSHIMS_MACROMAN_MAP_SIZE][3];
4848

49+
#define _STRINGSHIMS_NEXTSTEP_MAP_SIZE 128
50+
INTERNAL const uint16_t _stringshims_nextstep_mapping[_STRINGSHIMS_NEXTSTEP_MAP_SIZE];
51+
4952
#ifdef __cplusplus
5053
}
5154
#endif

Sources/_FoundationCShims/string_shims.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,23 @@ const uint8_t _stringshims_macroman_mapping[_STRINGSHIMS_MACROMAN_MAP_SIZE][3] =
234234
{ 0xEF, 0xAC, 0x81 }, /* LATIN SMALL LIGATURE FI */
235235
{ 0xEF, 0xAC, 0x82 }, /* LATIN SMALL LIGATURE FL */
236236
};
237+
238+
// NEXTSTEP string encoding character mapping, offset by 128.
239+
const uint16_t _stringshims_nextstep_mapping[_STRINGSHIMS_NEXTSTEP_MAP_SIZE] = {
240+
0x00A0, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C7,
241+
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
242+
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D9,
243+
0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00B5, 0x00D7, 0x00F7,
244+
0x00A9, 0x00A1, 0x00A2, 0x00A3, 0x2044, 0x00A5, 0x0192, 0x00A7,
245+
0x00A4, 0x2019, 0x201C, 0x00AB, 0x2039, 0x203A, 0xFB01, 0xFB02,
246+
0x00AE, 0x2013, 0x2020, 0x2021, 0x00B7, 0x00A6, 0x00B6, 0x2022,
247+
0x201A, 0x201E, 0x201D, 0x00BB, 0x2026, 0x2030, 0x00AC, 0x00BF,
248+
0x00B9, 0x02CB, 0x00B4, 0x02C6, 0x02DC, 0x00AF, 0x02D8, 0x02D9,
249+
0x00A8, 0x00B2, 0x02DA, 0x00B8, 0x00B3, 0x02DD, 0x02DB, 0x02C7,
250+
0x2014, 0x00B1, 0x00BC, 0x00BD, 0x00BE, 0x00E0, 0x00E1, 0x00E2,
251+
0x00E3, 0x00E4, 0x00E5, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB,
252+
0x00EC, 0x00C6, 0x00ED, 0x00AA, 0x00EE, 0x00EF, 0x00F0, 0x00F1,
253+
0x0141, 0x00D8, 0x0152, 0x00BA, 0x00F2, 0x00F3, 0x00F4, 0x00F5,
254+
0x00F6, 0x00E6, 0x00F9, 0x00FA, 0x00FB, 0x0131, 0x00FC, 0x00FD,
255+
0x0142, 0x00F8, 0x0153, 0x00DF, 0x00FE, 0x00FF, 0xFFFD, 0xFFFD
256+
};

Tests/FoundationEssentialsTests/PropertyListEncoderTests.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -858,9 +858,6 @@ class TestPropertyListEncoder : XCTestCase {
858858
}
859859
}
860860

861-
#if FOUNDATION_FRAMEWORK
862-
// Requires old style plist support
863-
// Requires "NEXTStep" decoding in String(bytes:encoding:) for decoding the octal characters
864861

865862
func test_oldStylePlist_invalid() {
866863
let data = "goodbye cruel world".data(using: String._Encoding.utf16)!
@@ -968,7 +965,6 @@ string3 = "Good evening"; // Test
968965
XCTFail("Unexpected error: \(error)")
969966
}
970967
}
971-
#endif
972968

973969
#if FOUNDATION_FRAMEWORK
974970
// Requires __PlistDictionaryDecoder

0 commit comments

Comments
 (0)