Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -928,10 +928,11 @@ ENCODINGS_SRCS="$ENCODINGS_SRCS $1.m" ]) ]) ENCODING_FLAG(codepage-437, codepage_437, [Codepage 437], HAVE_CODEPAGE_437) ENCODING_FLAG(codepage-850, codepage_850, [Codepage 850], HAVE_CODEPAGE_850) +ENCODING_FLAG(codepage-852, codepage_852, [Codepage 852], HAVE_CODEPAGE_852) ENCODING_FLAG(codepage-858, codepage_858, [Codepage 858], HAVE_CODEPAGE_858) ENCODING_FLAG(iso-8859-2, iso_8859_2, [ISO 8859-2], HAVE_ISO_8859_2) ENCODING_FLAG(iso-8859-3, iso_8859_3, [ISO 8859-3], HAVE_ISO_8859_3) ENCODING_FLAG(iso-8859-15, iso_8859_15, [ISO 8859-15], HAVE_ISO_8859_15) ENCODING_FLAG(koi8-r, koi8_r, [KOI8-R], HAVE_KOI8_R) Index: src/OFString.h ================================================================== --- src/OFString.h +++ src/OFString.h @@ -95,10 +95,12 @@ OFStringEncodingKOI8R, /** KOI8-U */ OFStringEncodingKOI8U, /** Windows-1250 */ OFStringEncodingWindows1250, + /** Code page 852 */ + OFStringEncodingCodepage852, /** Try to automatically detect the encoding */ OFStringEncodingAutodetect = -1 } OFStringEncoding; /** Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -118,10 +118,12 @@ size_t, bool); extern bool _OFUnicodeToCodepage437(const OFUnichar *, unsigned char *, size_t, bool); extern bool _OFUnicodeToCodepage850(const OFUnichar *, unsigned char *, size_t, bool); +extern bool _OFUnicodeToCodepage852(const OFUnichar *, unsigned char *, + size_t, bool); extern bool _OFUnicodeToCodepage858(const OFUnichar *, unsigned char *, size_t, bool); extern bool _OFUnicodeToMacRoman(const OFUnichar *, unsigned char *, size_t, bool); extern bool _OFUnicodeToKOI8R(const OFUnichar *, unsigned char *, @@ -190,10 +192,13 @@ [string isEqual: @"ibm437"] || [string isEqual: @"437"]) encoding = OFStringEncodingCodepage437; else if ([string isEqual: @"cp850"] || [string isEqual: @"cp-850"] || [string isEqual: @"ibm850"] || [string isEqual: @"850"]) encoding = OFStringEncodingCodepage850; + else if ([string isEqual: @"cp852"] || [string isEqual: @"cp-852"] || + [string isEqual: @"ibm852"] || [string isEqual: @"852"]) + encoding = OFStringEncodingCodepage852; else if ([string isEqual: @"cp858"] || [string isEqual: @"cp-858"] || [string isEqual: @"ibm858"] || [string isEqual: @"858"]) encoding = OFStringEncodingCodepage858; else if ([string isEqual: @"macintosh"] || [string isEqual: @"mac"]) encoding = OFStringEncodingMacRoman; @@ -233,10 +238,12 @@ return @"Windows-1252"; case OFStringEncodingCodepage437: return @"Codepage 437"; case OFStringEncodingCodepage850: return @"Codepage 850"; + case OFStringEncodingCodepage852: + return @"Codepage 852"; case OFStringEncodingCodepage858: return @"Codepage 858"; case OFStringEncodingMacRoman: return @"Mac Roman"; case OFStringEncodingKOI8R: @@ -1237,10 +1244,23 @@ (unsigned char *)cString, length, lossy)) @throw [OFInvalidEncodingException exception]; cString[length] = '\0'; + return length; +#endif +#ifdef HAVE_CODEPAGE_852 + case OFStringEncodingCodepage852: + if (length + 1 > maxLength) + @throw [OFOutOfRangeException exception]; + + if (!_OFUnicodeToCodepage852(characters, + (unsigned char *)cString, length, lossy)) + @throw [OFInvalidEncodingException exception]; + + cString[length] = '\0'; + return length; #endif #ifdef HAVE_CODEPAGE_858 case OFStringEncodingCodepage858: if (length + 1 > maxLength) @@ -1356,10 +1376,11 @@ case OFStringEncodingWindows1250: case OFStringEncodingWindows1251: case OFStringEncodingWindows1252: case OFStringEncodingCodepage437: case OFStringEncodingCodepage850: + case OFStringEncodingCodepage852: case OFStringEncodingCodepage858: case OFStringEncodingMacRoman: case OFStringEncodingKOI8R: case OFStringEncodingKOI8U: cString = OFAllocMemory(length + 1, 1); @@ -1440,10 +1461,11 @@ case OFStringEncodingWindows1250: case OFStringEncodingWindows1251: case OFStringEncodingWindows1252: case OFStringEncodingCodepage437: case OFStringEncodingCodepage850: + case OFStringEncodingCodepage852: case OFStringEncodingCodepage858: case OFStringEncodingMacRoman: case OFStringEncodingKOI8R: case OFStringEncodingKOI8U: return self.length; Index: src/OFUTF8String.m ================================================================== --- src/OFUTF8String.m +++ src/OFUTF8String.m @@ -57,10 +57,12 @@ extern const size_t _OFWindows1252TableOffset; extern const OFChar16 _OFCodepage437Table[]; extern const size_t _OFCodepage437TableOffset; extern const OFChar16 _OFCodepage850Table[]; extern const size_t _OFCodepage850TableOffset; +extern const OFChar16 _OFCodepage852Table[]; +extern const size_t _OFCodepage852TableOffset; extern const OFChar16 _OFCodepage858Table[]; extern const size_t _OFCodepage858TableOffset; extern const OFChar16 _OFMacRomanTable[]; extern const size_t _OFMacRomanTableOffset; extern const OFChar16 _OFKOI8RTable[]; @@ -339,10 +341,13 @@ CASE(OFStringEncodingCodepage437, _OFCodepage437Table) #endif #ifdef HAVE_CODEPAGE_850 CASE(OFStringEncodingCodepage850, _OFCodepage850Table) #endif +#ifdef HAVE_CODEPAGE_852 + CASE(OFStringEncodingCodepage852, _OFCodepage852Table) +#endif #ifdef HAVE_CODEPAGE_858 CASE(OFStringEncodingCodepage858, _OFCodepage858Table) #endif #ifdef HAVE_MAC_ROMAN CASE(OFStringEncodingMacRoman, _OFMacRomanTable) ADDED src/encodings/codepage-852.m Index: src/encodings/codepage-852.m ================================================================== --- /dev/null +++ src/encodings/codepage-852.m @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2008-2024 Jonathan Schleifer + * + * All rights reserved. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License version 3.0 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * version 3.0 for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * version 3.0 along with this program. If not, see + * . + */ + +#include "config.h" + +#import "OFString.h" + +#import "common.h" + +const OFChar16 _OFCodepage852Table[] OF_VISIBILITY_HIDDEN = { + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, + 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106, + 0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, + 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, + 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, + 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, + 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, + 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4, + 0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, + 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0 +}; +const size_t _OFCodepage852TableOffset OF_VISIBILITY_HIDDEN = + 256 - (sizeof(_OFCodepage852Table) / sizeof(*_OFCodepage852Table)); + +static const unsigned char page0[] = { + 0xFF, 0x00, 0x00, 0x00, 0xCF, 0x00, 0x00, 0xF5, + 0xF9, 0x00, 0x00, 0xAE, 0xAA, 0xF0, 0x00, 0x00, + 0xF8, 0x00, 0x00, 0x00, 0xEF, 0x00, 0x00, 0x00, + 0xF7, 0x00, 0x00, 0xAF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xB5, 0xB6, 0x00, 0x8E, 0x00, 0x00, 0x80, + 0x00, 0x90, 0x00, 0xD3, 0x00, 0xD6, 0xD7, 0x00, + 0x00, 0x00, 0x00, 0xE0, 0xE2, 0x00, 0x99, 0x9E, + 0x00, 0x00, 0xE9, 0x00, 0x9A, 0xED, 0x00, 0xE1, + 0x00, 0xA0, 0x83, 0x00, 0x84, 0x00, 0x00, 0x87, + 0x00, 0x82, 0x00, 0x89, 0x00, 0xA1, 0x8C, 0x00, + 0x00, 0x00, 0x00, 0xA2, 0x93, 0x00, 0x94, 0xF6, + 0x00, 0x00, 0xA3, 0x00, 0x81, 0xEC +}; +static const uint8_t page0Start = 0xA0; + +static const unsigned char page1[] = { + 0xC6, 0xC7, 0xA4, 0xA5, 0x8F, 0x86, 0x00, 0x00, + 0x00, 0x00, 0xAC, 0x9F, 0xD2, 0xD4, 0xD1, 0xD0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xA9, + 0xB7, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, + 0x92, 0x00, 0x00, 0x95, 0x96, 0x00, 0x00, 0x9D, + 0x88, 0xE3, 0xE4, 0x00, 0x00, 0xD5, 0xE5, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x8B, + 0x00, 0x00, 0xE8, 0xEA, 0x00, 0x00, 0xFC, 0xFD, + 0x97, 0x98, 0x00, 0x00, 0xB8, 0xAD, 0xE6, 0xE7, + 0xDD, 0xEE, 0x9B, 0x9C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xDE, 0x85, 0xEB, 0xFB, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8D, + 0xAB, 0xBD, 0xBE, 0xA6, 0xA7 +}; +static const uint8_t page1Start = 0x02; + +static const unsigned char page2[] = { + 0xF3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xF4, 0xFA, 0x00, 0xF2, 0x00, 0xF1 +}; +static const uint8_t page2Start = 0xC7; + +static const unsigned char page25[] = { + 0xC4, 0x00, 0xB3, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xDA, 0x00, 0x00, 0x00, + 0xBF, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, + 0xD9, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC2, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC5, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xCD, 0xBA, 0x00, 0x00, 0xC9, 0x00, 0x00, 0xBB, + 0x00, 0x00, 0xC8, 0x00, 0x00, 0xBC, 0x00, 0x00, + 0xCC, 0x00, 0x00, 0xB9, 0x00, 0x00, 0xCB, 0x00, + 0x00, 0xCA, 0x00, 0x00, 0xCE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xDF, 0x00, 0x00, 0x00, 0xDC, 0x00, 0x00, 0x00, + 0xDB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xB0, 0xB1, 0xB2, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFE +}; +static const uint8_t page25Start = 0x00; + +bool OF_VISIBILITY_HIDDEN +_OFUnicodeToCodepage852(const OFUnichar *input, unsigned char *output, + size_t length, bool lossy) +{ + for (size_t i = 0; i < length; i++) { + OFUnichar c = input[i]; + + if OF_UNLIKELY (c > 0x7F) { + uint8_t idx; + + if OF_UNLIKELY (c > 0xFFFF) { + if (lossy) { + output[i] = '?'; + continue; + } else + return false; + } + + switch (c >> 8) { + CASE_MISSING_IS_ERROR(0) + CASE_MISSING_IS_ERROR(1) + CASE_MISSING_IS_ERROR(2) + CASE_MISSING_IS_ERROR(25) + default: + if (lossy) { + output[i] = '?'; + continue; + } else + return false; + } + } else + output[i] = (unsigned char)c; + } + + return true; +} Index: tests/OFStringTests.m ================================================================== --- tests/OFStringTests.m +++ tests/OFStringTests.m @@ -41,10 +41,19 @@ }; static const OFChar16 swappedChar16String[] = { 0xFFFE, 0x6600, 0xF600, 0xF600, 0x6200, 0xE400, 0x7200, 0x3CD8, 0x3ADC, 0 }; +static const char *range80ToFF = + "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91" + "\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3" + "\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5" + "\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7" + "\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9" + "\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB" + "\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD" + "\xFE\xFF"; @interface CustomString: OFString { OFMutableString *_string; } @@ -301,12 +310,51 @@ #ifdef HAVE_CODEPAGE_437 - (void)testStringWithCStringEncodingCodepage437 { OTAssertEqualObjects([self.stringClass - stringWithCString: "\xB0\xB1\xB2\xDB" - encoding: OFStringEncodingCodepage437], @"░▒▓█"); + stringWithCString: range80ToFF + encoding: OFStringEncodingCodepage437], + @"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛" + @"┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²" + @"■ "); +} +#endif + +#ifdef HAVE_CODEPAGE_850 +- (void)testStringWithCStringEncodingCodepage850 +{ + OTAssertEqualObjects([self.stringClass + stringWithCString: range80ToFF + encoding: OFStringEncodingCodepage850], + @"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥" + @"┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²" + @"■ "); +} +#endif + +#ifdef HAVE_CODEPAGE_852 +- (void)testStringWithCStringEncodingCodepage852 +{ + OTAssertEqualObjects([self.stringClass + stringWithCString: range80ToFF + encoding: OFStringEncodingCodepage852], + @"ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż" + @"┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´­˝˛ˇ˘§÷¸°¨˙űŘř" + @"■ "); +} +#endif + +#ifdef HAVE_CODEPAGE_858 +- (void)testStringWithCStringEncodingCodepage858 +{ + OTAssertEqualObjects([self.stringClass + stringWithCString: range80ToFF + encoding: OFStringEncodingCodepage858], + @"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥" + @"┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²" + @"■ "); } #endif #ifdef OF_HAVE_FILES - (void)testStringWithContentsOfFileEncoding @@ -401,20 +449,58 @@ #ifdef HAVE_CODEPAGE_437 - (void)testCStringWithEncodingCodepage437 { OTAssertEqual( - strcmp([[self.stringClass stringWithString: @"Tést strîng ░▒▓"] - cStringWithEncoding: OFStringEncodingCodepage437], - "T\x82st str\x8Cng \xB0\xB1\xB2"), 0); + strcmp([[self.stringClass stringWithString: + @"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛" + @"┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²" + @"■ "] cStringWithEncoding: OFStringEncodingCodepage437], + range80ToFF), 0); OTAssertThrowsSpecific( [[self.stringClass stringWithString: @"T€st strîng ░▒▓"] cStringWithEncoding: OFStringEncodingCodepage437], OFInvalidEncodingException); } #endif + +#ifdef HAVE_CODEPAGE_850 +- (void)testCStringWithEncodingCodepage850 +{ + OTAssertEqual( + strcmp([[self.stringClass stringWithString: + @"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥" + @"┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²" + @"■ "] cStringWithEncoding: OFStringEncodingCodepage850], + range80ToFF), 0); +} +#endif + +#ifdef HAVE_CODEPAGE_852 +- (void)testCStringWithEncodingCodepage852 +{ + OTAssertEqual( + strcmp([[self.stringClass stringWithString: + @"ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż" + @"┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´­˝˛ˇ˘§÷¸°¨˙űŘř" + @"■ "] cStringWithEncoding: OFStringEncodingCodepage852], + range80ToFF), 0); +} +#endif + +#ifdef HAVE_CODEPAGE_858 +- (void)testCStringWithEncodingCodepage858 +{ + OTAssertEqual( + strcmp([[self.stringClass stringWithString: + @"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥" + @"┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²" + @"■ "] cStringWithEncoding: OFStringEncodingCodepage858], + range80ToFF), 0); +} +#endif - (void)testLossyCStringWithEncodingASCII { OTAssertEqual(strcmp([[self.stringClass stringWithString: @"This is a tést"] lossyCStringWithEncoding: OFStringEncodingASCII],