Skip to content

Commit

Permalink
Add hsDarwin with helpers for string conversion
Browse files Browse the repository at this point in the history
The NSString category in the macOS plClient folder is useful, but there
are several other spots where we're wanting to convert between
CFString/NSString and ST::string, so it make sense to have helpers
available throughout the engine. These helper functions are written so
that they can be used from C++ code without needing to bring in
Objective-C.
  • Loading branch information
dpogue committed Sep 7, 2023
1 parent 085186d commit 19978b8
Show file tree
Hide file tree
Showing 17 changed files with 310 additions and 60 deletions.
4 changes: 2 additions & 2 deletions Sources/Plasma/Apps/plClient/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,22 +92,22 @@ if(WIN32)
elseif(APPLE)
set(plClient_SOURCES ${plClient_SOURCES}
Mac-Cocoa/main.mm
Mac-Cocoa/NSString+StringTheory.mm
Mac-Cocoa/PLSKeyboardEventMonitor.mm
Mac-Cocoa/PLSView.mm
Mac-Cocoa/PLSLoginWindowController.mm
Mac-Cocoa/PLSPatcherWindowController.mm
Mac-Cocoa/PLSPatcher.mm
Mac-Cocoa/PLSServerStatus.mm
Mac-Cocoa/StringTheory_NSString.mm
)
set(plClient_HEADERS ${plClient_HEADERS}
Mac-Cocoa/NSString+StringTheory.h
Mac-Cocoa/PLSKeyboardEventMonitor.h
Mac-Cocoa/PLSView.h
Mac-Cocoa/PLSLoginWindowController.h
Mac-Cocoa/PLSPatcherWindowController.h
Mac-Cocoa/PLSPatcher.h
Mac-Cocoa/PLSServerStatus.h
Mac-Cocoa/StringTheory_NSString.h
)
set(RESOURCES
Mac-Cocoa/MainMenu.xib
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ NS_ASSUME_NONNULL_BEGIN

@interface NSString (StringTheory)

- (id)initWithSTString:(const ST::string&)string;
+ (id)stringWithSTString:(const ST::string&)string;

- (const ST::string)STString;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,19 @@
*==LICENSE==*/

#include "StringTheory_NSString.h"
#include "NSString+StringTheory.h"
#include "hsDarwin.h"

@implementation NSString (StringTheory)

- (id)initWithSTString:(const ST::string&)string
{
self = [self initWithUTF8String:string.c_str()];
return self;
}

+ (id)stringWithSTString:(const ST::string&)string
{
return [[NSString alloc] initWithSTString:string];
return NSStringCreateWithSTString(string);
}

- (const ST::string)STString
{
return ST::string([self UTF8String]);
return STStringFromNSString(self);
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
#import "PLSLoginWindowController.h"
#include <regex>
#import "PLSServerStatus.h"
#include "StringTheory_NSString.h"
#import "NSString+StringTheory.h"
#include "pfPasswordStore/pfPasswordStore.h"
#include "plNetGameLib/plNetGameLib.h"
#include "plProduct.h"
Expand Down Expand Up @@ -128,8 +128,8 @@ - (void)save
[[NSUserDefaults standardUserDefaults] synchronize];

if (self.password && ![self.password isEqualToString:FAKE_PASS_STRING]) {
ST::string username = ST::string([self.username cStringUsingEncoding:NSUTF8StringEncoding]);
ST::string password = ST::string([self.password cStringUsingEncoding:NSUTF8StringEncoding]);
ST::string username = [self.username STString];
ST::string password = [self.password STString];

pfPasswordStore* store = pfPasswordStore::Instance();
if (self.rememberPassword)
Expand Down Expand Up @@ -160,8 +160,8 @@ - (void)storeHash:(ShaDigest&)namePassHash
// Hash username and password before sending over the 'net.
// -- Legacy compatibility: @gametap (and other usernames with domains in them) need
// to be hashed differently.
ST::string username = ST::string([self.username cStringUsingEncoding:NSUTF8StringEncoding]);
ST::string password = ST::string([self.password cStringUsingEncoding:NSUTF8StringEncoding]);
ST::string username = [self.username STString];
ST::string password = [self.password STString];
static const std::regex re_domain("[^@]+@([^.]+\\.)*([^.]+)\\.[^.]+");
std::cmatch match;
std::regex_search(username.c_str(), match, re_domain);
Expand All @@ -185,7 +185,7 @@ - (void)makeCurrent
ShaDigest hash;
[self storeHash:hash];

ST::string username = ST::string([self.username cStringUsingEncoding:NSUTF8StringEncoding]);
ST::string username = [self.username STString];
NetCommSetAccountUsernamePassword(username, hash);
NetCommSetAuthTokenAndOS(nullptr, u"mac");
}
Expand Down Expand Up @@ -214,7 +214,7 @@ - (void)windowDidLoad

[self.window center];
[self.productTextField
setStringValue:[NSString stringWithSTString:plProduct::ProductString().c_str()]];
setStringValue:[NSString stringWithSTString:plProduct::ProductString()]];
}

- (NSNibName)windowNibName
Expand Down
2 changes: 1 addition & 1 deletion Sources/Plasma/Apps/plClient/Mac-Cocoa/PLSPatcher.mm
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@
*==LICENSE==*/

#import "PLSPatcher.h"
#import "NSString+StringTheory.h"

#include <unordered_set>
#include <string_theory/format>
#include "StringTheory_NSString.h"

#include "HeadSpin.h"
#include "hsTimer.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
*==LICENSE==*/

#import "PLSPatcherWindowController.h"
#include <string_theory/string>
#import "NSString+StringTheory.h"
#include "PLSServerStatus.h"
#include "plProduct.h"

Expand Down Expand Up @@ -111,8 +111,7 @@ - (void)windowDidLoad
[super windowDidLoad];

[self.progressBar startAnimation:self];
self.productLabel.stringValue =
[NSString stringWithUTF8String:plProduct::ProductString().c_str()];
self.productLabel.stringValue = [NSString stringWithSTString:plProduct::ProductString()];
// register for an async notification of when status loads
[[PLSServerStatus sharedStatus]
addObserver:self
Expand Down
3 changes: 1 addition & 2 deletions Sources/Plasma/Apps/plClient/Mac-Cocoa/PLSServerStatus.mm
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@
*==LICENSE==*/

#import "PLSServerStatus.h"
#include <string_theory/string>
#include "StringTheory_NSString.h"
#import "NSString+StringTheory.h"
#include "plNetGameLib/plNetGameLib.h"

@interface PLSServerStatus () <NSURLSessionDelegate>
Expand Down
2 changes: 1 addition & 1 deletion Sources/Plasma/Apps/plClient/Mac-Cocoa/main.mm
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@
#import <QuartzCore/QuartzCore.h>

// Cocoa client
#import "NSString+StringTheory.h"
#import "PLSKeyboardEventMonitor.h"
#import "PLSLoginWindowController.h"
#import "PLSPatcherWindowController.h"
#import "PLSServerStatus.h"
#import "PLSView.h"
#import "StringTheory_NSString.h"

// stdlib
#include <algorithm>
Expand Down
2 changes: 1 addition & 1 deletion Sources/Plasma/CoreLib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ set(CoreLib_HEADERS
hsBounds.h
hsColorRGBA.h
hsCpuID.h
hsDarwin.h
hsExceptions.h
hsExceptionStack.h
hsFastMath.h
Expand Down Expand Up @@ -81,7 +82,6 @@ target_link_libraries(
Threads::Threads
$<$<AND:$<CONFIG:Debug>,$<BOOL:${USE_VLD}>>:VLD::VLD>
"$<$<PLATFORM_ID:Darwin>:-framework Accelerate>"
PRIVATE
"$<$<PLATFORM_ID:Darwin>:-framework CoreFoundation>"
)
target_include_directories(
Expand Down
1 change: 1 addition & 0 deletions Sources/Plasma/CoreLib/_CoreLibPch.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ You can contact Cyan Worlds, Inc. by email [email protected]

#include "HeadSpin.h"
#include "hsWindows.h"
#include "hsDarwin.h"

#include <string_theory/formatter>
#include <string_theory/string>
Expand Down
114 changes: 114 additions & 0 deletions Sources/Plasma/CoreLib/hsDarwin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email [email protected]
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/

#ifndef _hsDarwin_inc_
#define _hsDarwin_inc_

#include <string_theory/string>
#include <string_theory/format>

#ifdef HS_BUILD_FOR_APPLE
#include <CoreFoundation/CoreFoundation.h>

[[nodiscard]]
#if __has_feature(attribute_cf_returns_retained)
__attribute__((cf_returns_retained))
#endif
inline CFStringRef CFStringCreateWithSTString(const ST::string& str)
{
return CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8*)str.data(), str.size(), kCFStringEncodingUTF8, false);
}

inline ST::string STStringFromCFString(CFStringRef str, ST::utf_validation_t validation = ST_DEFAULT_VALIDATION)
{
CFRange range = CFRangeMake(0, CFStringGetLength(str));
CFIndex strBufSz = 0;
CFStringGetBytes(str, range, kCFStringEncodingUTF8, 0, false, nullptr, 0, &strBufSz);
ST::char_buffer buffer;
buffer.allocate(strBufSz);
CFStringGetBytes(str, range, kCFStringEncodingUTF8, 0, false, (UInt8*)buffer.data(), strBufSz, nullptr);

return ST::string(buffer, validation);
}

inline void format_type(const ST::format_spec &format, ST::format_writer &output, CFStringRef str)
{
ST::char_buffer utf8 = STStringFromCFString(str).to_utf8();
ST::format_string(format, output, utf8.data(), utf8.size());
}


#ifdef __OBJC__
@class NSString;

[[nodiscard]]
#if __has_feature(attribute_ns_returns_retained)
__attribute__((ns_returns_retained))
#endif
inline NSString* NSStringCreateWithSTString(const ST::string& str)
{
#if __has_feature(objc_arc)
return (NSString*)CFBridgingRelease(CFStringCreateWithSTString(str));
#else
return (NSString*)CFStringCreateWithSTString(str);
#endif
}

inline ST::string STStringFromNSString(NSString* str, ST::utf_validation_t validation = ST_DEFAULT_VALIDATION)
{
#if __has_feature(objc_arc)
return STStringFromCFString((__bridge CFStringRef)str, validation);
#else
return STStringFromCFString((CFStringRef)str, validation);
#endif
}

inline void format_type(const ST::format_spec &format, ST::format_writer &output, NSString* str)
{
ST::char_buffer utf8 = STStringFromNSString(str).to_utf8();
ST::format_string(format, output, utf8.data(), utf8.size());
}
#endif // __OBJC__

#endif // HS_BUILD_FOR_APPLE

#endif // _hsDarwin_inc_
9 changes: 2 additions & 7 deletions Sources/Plasma/CoreLib/hsSystemInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ You can contact Cyan Worlds, Inc. by email [email protected]
#include "plFileSystem.h"
#include "hsStream.h"
#include "hsWindows.h"
#include "hsDarwin.h"

#include <cstring>
#include <iterator>
Expand Down Expand Up @@ -191,13 +192,7 @@ static inline bool IGetAppleVersion(ST::string& system)
CFRelease(name);
CFRelease(dict);

CFIndex infoLen = CFStringGetLength(info);
CFIndex infoBufSz = 0;
CFStringGetBytes(info, CFRangeMake(0, infoLen), kCFStringEncodingUTF8, 0, false, nullptr, 0, &infoBufSz);
ST::char_buffer systemBuf;
systemBuf.allocate(infoBufSz);
CFStringGetBytes(info, CFRangeMake(0, infoLen), kCFStringEncodingUTF8, 0, false, (UInt8*)systemBuf.data(), infoLen, nullptr);
system = ST::string(systemBuf);
system = STStringFromCFString(info);

CFRelease(info);

Expand Down
Loading

0 comments on commit 19978b8

Please sign in to comment.