From 2c1f84406e0680fb80f7f2aa72e01d2fa12e94de Mon Sep 17 00:00:00 2001 From: Pirater12 Date: Tue, 17 Jul 2018 22:19:18 +0530 Subject: [PATCH] UTF16-to UTF8 Translation --- libctru/include/3ds/services/frd.h | 10 +++--- libctru/source/services/frd.c | 52 ++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/libctru/include/3ds/services/frd.h b/libctru/include/3ds/services/frd.h index f92ef1e..65d4674 100644 --- a/libctru/include/3ds/services/frd.h +++ b/libctru/include/3ds/services/frd.h @@ -93,9 +93,10 @@ Result FRD_GetMyProfile(Profile *profile); /** * @brief Gets the current user's screen name. - * @param name Pointer to write the current user's screen name to. 11-byte UTF-16 screen name (with null terminator) + * @param name Pointer to write the current user's screen name to. + * @param max_size Max size of the screen name. */ -Result FRD_GetMyScreenName(u16 *name); +Result FRD_GetMyScreenName(char *name, size_t max_size); /** * @brief Gets the current user's Mii data. @@ -118,8 +119,9 @@ Result FRD_GetMyFavoriteGame(u64 *titleId); /** * @brief Gets the current user's comment on their friend profile. * @param comment Pointer to write the current user's comment to. + * @param max_size Max size of the comment. */ -Result FRD_GetMyComment(u16 *comment); +Result FRD_GetMyComment(char *comment, size_t max_size); /** * @brief Gets the current user's firend key list @@ -141,7 +143,7 @@ Result FRD_IsFromFriendList(FriendKey *friendKeyList, bool *isFromList); * @brief Updates the game mode description string. * @param desc Pointer to write the game mode description to. */ -Result FRD_UpdateGameModeDescription(u16 *desc); +Result FRD_UpdateGameModeDescription(const char *desc); /** * @brief Returns the friend code using the given principal ID. diff --git a/libctru/source/services/frd.c b/libctru/source/services/frd.c index 1cb7954..71dab45 100644 --- a/libctru/source/services/frd.c +++ b/libctru/source/services/frd.c @@ -4,6 +4,42 @@ static Handle frdHandle; static int frdRefCount; +static void frdConvertToUTF8(char* out, const u16* in, size_t max) +{ + if (!in || !*in) + { + out[0] = 0; + return; + } + + ssize_t units = utf16_to_utf8((uint8_t*)out, in, max); + if (units < 0) + { + out[0] = 0; + return; + } + + out[units] = 0; +} + +static void frdConvertToUTF16(u16* out, const char* in, size_t max) +{ + if (!in || !*in) + { + out[0] = 0; + return; + } + + ssize_t units = utf8_to_utf16(out, (const uint8_t*)in, max-1); + if (units < 0) + { + out[0] = 0; + return; + } + + out[units] = 0; +} + Result frdInit(void) { Result ret = 0; @@ -108,7 +144,7 @@ Result FRD_GetMyProfile(Profile *profile) return (Result)cmdbuf[1]; } -Result FRD_GetMyScreenName(u16 *name) +Result FRD_GetMyScreenName(char *name, size_t max_size) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); @@ -117,7 +153,7 @@ Result FRD_GetMyScreenName(u16 *name) if (R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret; - memcpy(name, &cmdbuf[2], FRIENDS_SCREEN_NAME_SIZE); // 11-byte UTF-16 screen name (with null terminator) + frdConvertToUTF8(name, (u16*)&cmdbuf[2], max_size); return (Result)cmdbuf[1]; } @@ -164,7 +200,7 @@ Result FRD_GetMyFavoriteGame(u64 *titleId) return (Result)cmdbuf[1]; } -Result FRD_GetMyComment(u16 *comment) +Result FRD_GetMyComment(char *comment, size_t max_size) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); @@ -173,7 +209,7 @@ Result FRD_GetMyComment(u16 *comment) if (R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret; - memcpy(comment, &cmdbuf[2], FRIENDS_COMMENT_SIZE); // 16-byte UTF-16 comment + frdConvertToUTF8(comment, (u16*)&cmdbuf[2], max_size); return (Result)cmdbuf[1]; } @@ -212,14 +248,18 @@ Result FRD_IsFromFriendList(FriendKey *friendKeyList, bool *isFromList) return (Result)cmdbuf[1]; } -Result FRD_UpdateGameModeDescription(u16 *desc) +Result FRD_UpdateGameModeDescription(const char *desc) { + u16 u16_desc[strlen(desc) + 1]; + + frdConvertToUTF16(u16_desc, desc, strlen(desc) + 1); + Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); cmdbuf[0] = IPC_MakeHeader(0x1D,0,2); // 0x1D0002 cmdbuf[1] = 0x400802; - cmdbuf[2] = (uintptr_t)desc; + cmdbuf[2] = (uintptr_t)u16_desc; if (R_FAILED(ret = svcSendSyncRequest(frdHandle))) return ret;