Strings and UTF-8
StringType and StringViewType
Every string in the API is UTF-8.
RealtimeCore::Common::StringType is an alias for std::u8string, StringViewType for std::u8string_view and CharType for char8_t, plain std::string never appears in a signature.
The aliases are defined in RealtimeCore/Common/StringType.h in the RealtimeCore::Common namespace and are used consistently across the whole API surface.
Every string parameter, return value and data-type field, room names, player names, property keys, error messages, is a StringType or a StringViewType.
Building on char8_t makes the encoding part of the type system: a StringType is UTF-8 by construction, on every platform and on the wire.
This removes the classic ambiguity of std::string, whose encoding depends on platform and locale, and turns accidental mixing of encodings into a compile error instead of corrupted text.
Writing String Literals
Use the PHOTON_STR("...") macro for string literals.
It expands to a u8"..." literal, so it produces char8_t text that converts directly to StringType and StringViewType.
Writing u8"..." yourself is equivalent, but discuraged as your code won't break if you use the PHOTON_STR("...") macro if there are internal changes on our string data types.
Literals are used wherever the API takes a string.
C++
using namespace RealtimeCore::Matchmaking;
ClientConstructOptions options;
options.AppId = PHOTON_STR("your-app-id");
RealtimeClient client(options);
client.SetPlayerName(PHOTON_STR("Alice"));
C
/* Every string on the ABI is a plain, null-terminated UTF-8 const char*. */
RealtimeHandle client = realtime_create("your-app-id", "1.0", queue);
realtime_set_player_name(client, "Alice");
/* There is no StringType, no PHOTON_STR and no char8_t over the C API: an
ordinary string literal is already the right type, as long as the source
file is saved as UTF-8. The encoding guarantee moves from the type
system to a convention, so validate text that comes from a file, a
socket or a platform SDK before passing it in. */
Converting To and From Other String Types
RealtimeCore::Common::ToStringType(...) builds a StringType from the common sources: any integral value, a bool (formatted as True or False) and a raw CharType* pointer.
It is handy when composing property values or log messages from numeric game state.
C++20 makes char8_t a distinct character type, so a UTF-8 std::string and a StringType do not convert into each other implicitly even when their bytes are identical.
Interfacing with code that stores UTF-8 in std::string therefore needs an explicit conversion at the boundary.
The conversion is a plain byte copy and is lossless in both directions, because both sides hold the same UTF-8 data.
It is important to make sure that any std::string you convert is encoded as UTF-8 (or ASCII which is a subset of UTF-8).
Both directions are a byte-wise copy.
C++
// std::string (holding UTF-8) to StringType:
std::string utf8Name = "Alice";
RealtimeCore::Common::StringType photonName(utf8Name.begin(), utf8Name.end());
// StringType back to std::string, e.g. for display or serialization:
std::string display(reinterpret_cast<const char*>(photonName.data()), photonName.size());
C
/* Nothing to convert on the way in: a UTF-8 char* is the ABI's string type. */
const char* utf8Name = "Alice";
realtime_set_player_name(client, utf8Name);
/* On the way out, strings from a blob are length-prefixed and NOT terminated,
so copy them into a buffer to get a C string. */
int32_t nameLen = 0;
const char* name = rt_get_str(&reader, &nameLen);
char display[64];
if (nameLen > (int32_t)sizeof(display) - 1)
{
nameLen = (int32_t)sizeof(display) - 1;
}
memcpy(display, name, (size_t)nameLen);
display[nameLen] = '\0';
/* Or print in place, without the copy: */
printf("%.*s\n", (int)nameLen, name);
/* Text that a realtime_* function writes into a caller buffer, such as
realtime_room_name or realtime_user_id, arrives null-terminated and
needs neither the copy nor the precision. Blob strings are the ones that
do not, because their length prefix is the only terminator they have. */