<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: How to convert wstring to Unistring in macOS in Archicad C++ API</title>
    <link>https://community.graphisoft.com/t5/Archicad-C-API/How-to-convert-wstring-to-Unistring-in-macOS/m-p/276592#M4040</link>
    <description>This is an issue of text encoding. wchar_t is a data type rather than an encoding, and the result may be implementation-specific (depending on the compiler and platform). Try one of the following:&lt;BR /&gt;
&lt;BR /&gt;
1) If this is text that is meant to be user-readable, it would be better to store it in a string resource rather than hard-coding it. Then the encoding can be dealt with by ARCHICAD and your add-on will be far easier to localise.&lt;BR /&gt;
&lt;BR /&gt;
2) Use a prefix to specify the encoding, e.g. for utf-8:&lt;PRE&gt;GS::UniString a(u8"xxx", CC_UTF8);&lt;/PRE&gt;</description>
    <pubDate>Fri, 16 Mar 2018 11:21:09 GMT</pubDate>
    <dc:creator>Ralph Wessel</dc:creator>
    <dc:date>2018-03-16T11:21:09Z</dc:date>
    <item>
      <title>How to convert wstring to Unistring in macOS</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/How-to-convert-wstring-to-Unistring-in-macOS/m-p/276591#M4039</link>
      <description>&lt;DIV class="actalk-migrated-content"&gt;I need to put unicode words in my addon but I am facing some problems:&lt;BR /&gt;For example, when I have the following code :
&lt;PRE&gt;const GS::UniString a = L"xxx";&lt;/PRE&gt;
or
&lt;PRE&gt;DGTreeViewSetItemText(dialogID, itemID, CS,L"xxx");&lt;/PRE&gt;
It is no problem if I develop in windows&lt;BR /&gt;but in macOS it will show error: have no viable conversion for const wchar_t[4] to GS::UniString&lt;BR /&gt;Thanks for helping!!!!&lt;/DIV&gt;</description>
      <pubDate>Tue, 06 Dec 2022 12:44:07 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/How-to-convert-wstring-to-Unistring-in-macOS/m-p/276591#M4039</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2022-12-06T12:44:07Z</dc:date>
    </item>
    <item>
      <title>Re: How to convert wstring to Unistring in macOS</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/How-to-convert-wstring-to-Unistring-in-macOS/m-p/276592#M4040</link>
      <description>This is an issue of text encoding. wchar_t is a data type rather than an encoding, and the result may be implementation-specific (depending on the compiler and platform). Try one of the following:&lt;BR /&gt;
&lt;BR /&gt;
1) If this is text that is meant to be user-readable, it would be better to store it in a string resource rather than hard-coding it. Then the encoding can be dealt with by ARCHICAD and your add-on will be far easier to localise.&lt;BR /&gt;
&lt;BR /&gt;
2) Use a prefix to specify the encoding, e.g. for utf-8:&lt;PRE&gt;GS::UniString a(u8"xxx", CC_UTF8);&lt;/PRE&gt;</description>
      <pubDate>Fri, 16 Mar 2018 11:21:09 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/How-to-convert-wstring-to-Unistring-in-macOS/m-p/276592#M4040</guid>
      <dc:creator>Ralph Wessel</dc:creator>
      <dc:date>2018-03-16T11:21:09Z</dc:date>
    </item>
    <item>
      <title>Re: How to convert wstring to Unistring in macOS</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/How-to-convert-wstring-to-Unistring-in-macOS/m-p/276593#M4041</link>
      <description>Ralph is generally correct. UniString is implemented differently on Mac: it stores characters in UTF-8 encoding on Mac(e.g. 1-byte per character). On Windows it uses wchar_t which is 2-bytes per character. Thus  &lt;B&gt;const GS::UniString a = L"xxx";&lt;/B&gt; will compile on Windows, but will fail on Mac. Graphisoft changed implementation of &lt;B&gt;UniString &lt;/B&gt;somewhere between AC15 and AC21. In older versions it used wchart_t.&lt;BR /&gt;
&lt;BR /&gt;
You may use &lt;B&gt;u8"my string"&lt;/B&gt; literals on both platforms, or you may convert your &lt;B&gt;L"my string"&lt;/B&gt; constants into appropriate format for every platform.&lt;BR /&gt;
&lt;BR /&gt;
I'd implement it like that:
&lt;PRE&gt;&lt;I&gt;
&lt;/I&gt;#ifndef SL

std::string ToUtf8(const std::wstring&amp;amp; widestring)
{
	size_t widesize = widestring.length();

	if (sizeof(wchar_t) == 2)
	{
		size_t utf8size = 3 * widesize + 1;
		char* utf8stringnative = new char[utf8size];
		const UTF16* sourcestart = 
	reinterpret_cast&amp;lt;const UTF16*&amp;gt;(widestring.c_str());
		const UTF16* sourceend = sourcestart + widesize;
		UTF8* targetstart = reinterpret_cast&amp;lt;UTF8*&amp;gt;(utf8stringnative);
		UTF8* targetend = targetstart + utf8size;
		ConversionResult res = ConvertUTF16toUTF8
	(&amp;amp;sourcestart, sourceend, &amp;amp;targetstart, targetend, strictConversion);
		if (res != conversionOK)
		{
			delete [] utf8stringnative;
			throw std::exception("La falla!");
		}
		*targetstart = 0;
		std::string resultstring(utf8stringnative);
		delete [] utf8stringnative;
		return resultstring;
	}
	else if (sizeof(wchar_t) == 4)
	{
		size_t utf8size = 4 * widesize + 1;
		char* utf8stringnative = new char[utf8size];
		const UTF32* sourcestart = 
	reinterpret_cast&amp;lt;const UTF32*&amp;gt;(widestring.c_str());
		const UTF32* sourceend = sourcestart + widesize;
		UTF8* targetstart = reinterpret_cast&amp;lt;UTF8*&amp;gt;(utf8stringnative);
		UTF8* targetend = targetstart + utf8size;
		ConversionResult res = ConvertUTF32toUTF8
	(&amp;amp;sourcestart, sourceend, &amp;amp;targetstart, targetend, strictConversion);
		if (res != conversionOK)
		{
			delete [] utf8stringnative;
			throw std::exception("La falla!");
		}
		*targetstart = 0;
		std::string resultstring(utf8stringnative);
		delete [] utf8stringnative;
		return resultstring;
	}
	else
	{
		throw std::exception("La falla!");
	}
	return "";
}

#ifdef _WIN32
#define SL(str) str
#else
#define SL(str) ToUtf8(str).c_str()
#endif
#endif

const GS::UniString a = SL(L"xxx");  // This will compile well now.
&lt;/PRE&gt;

You may move the code into a separate header file and include it everywhere you want to initialize UniString with a string literal. Just remove the last line with a comment.&lt;BR /&gt;
&lt;BR /&gt;
Like that:
&lt;PRE&gt;&lt;I&gt;
&lt;/I&gt;#include "sl.h"

const GS::UniString a = SL(L"xxx");  // This will compile well now.
&lt;/PRE&gt;</description>
      <pubDate>Mon, 26 Mar 2018 12:29:54 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/How-to-convert-wstring-to-Unistring-in-macOS/m-p/276593#M4041</guid>
      <dc:creator>Anonymous</dc:creator>
      <dc:date>2018-03-26T12:29:54Z</dc:date>
    </item>
    <item>
      <title>Re: How to convert wstring to Unistring in macOS</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/How-to-convert-wstring-to-Unistring-in-macOS/m-p/276594#M4042</link>
      <description>&lt;BLOCKQUOTE&gt;chebum wrote:&lt;BR /&gt;UniString is implemented differently on Mac: it stores characters in UTF-8 encoding on Mac(e.g. 1-byte per character). On Windows it uses wchar_t which is 2-bytes per character. Thus  &lt;B&gt;const GS::UniString a = L"xxx";&lt;/B&gt; will compile on Windows, but will fail on Mac. Graphisoft changed implementation of &lt;B&gt;UniString &lt;/B&gt;somewhere between AC15 and AC21. In older versions it used wchart_t.&lt;/BLOCKQUOTE&gt;
A few observations:&lt;UL&gt;
&lt;LI&gt;1) All text encoding is UTF-8 from AC21 –&amp;nbsp;from the documentation: &lt;BLOCKQUOTE&gt;All C strings (char *, char []) are now UTF-8 encoded.&lt;/BLOCKQUOTE&gt;
2) Text encoding is not the same as the number of bytes consumed by a character. Many different encodings will use the same number of bytes, but are not equivalent. Constructing a UniString from wchar_t only works on Windows because it's commonly assumed to be UTF-16. It's a bad idea if you intend to write cross-platform code.&lt;BR /&gt;
&lt;BR /&gt;
3) UTF-8 doesn't have a fixed number of bytes per character. The only thing that can be said in relation to 8-bit encodings is that old string methods assuming fixed 8-bit characters with null termination won't crash on UTF-8 text.&lt;/LI&gt;
&lt;/UL&gt;
&lt;BLOCKQUOTE&gt;chebum wrote:&lt;BR /&gt;&lt;PRE&gt;&lt;I&gt;
&lt;/I&gt;#include "sl.h"

const GS::UniString a = SL(L"xxx");  // This will compile well now.
&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
I'd strongly recommend using the mechanisms provided by GS. Writing your own methods for solved problems just wastes time and opens you up to more bugs and future migration problems.</description>
      <pubDate>Mon, 26 Mar 2018 17:25:59 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/How-to-convert-wstring-to-Unistring-in-macOS/m-p/276594#M4042</guid>
      <dc:creator>Ralph Wessel</dc:creator>
      <dc:date>2018-03-26T17:25:59Z</dc:date>
    </item>
    <item>
      <title>Re: How to convert wstring to Unistring in macOS</title>
      <link>https://community.graphisoft.com/t5/Archicad-C-API/How-to-convert-wstring-to-Unistring-in-macOS/m-p/367305#M4043</link>
      <description>&lt;P&gt;Ralph, your expression throws me in an "Excess elements in scalar initializer" error.&lt;/P&gt;&lt;P&gt;Knowing that I am not familiar with the ACAPI expressions, can you tell me what am I doing wrong?&lt;BR /&gt;Thank you&lt;/P&gt;&lt;P&gt;Nic&lt;/P&gt;</description>
      <pubDate>Thu, 12 Jan 2023 20:03:42 GMT</pubDate>
      <guid>https://community.graphisoft.com/t5/Archicad-C-API/How-to-convert-wstring-to-Unistring-in-macOS/m-p/367305#M4043</guid>
      <dc:creator>Nic Tulban</dc:creator>
      <dc:date>2023-01-12T20:03:42Z</dc:date>
    </item>
  </channel>
</rss>

