<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent changes to Unicode</title><link>https://sourceforge.net/p/sxmlc/wiki/Unicode/</link><description>Recent changes to Unicode</description><atom:link href="https://sourceforge.net/p/sxmlc/wiki/Unicode/feed" rel="self"/><language>en</language><lastBuildDate>Fri, 01 Sep 2017 18:11:55 -0000</lastBuildDate><atom:link href="https://sourceforge.net/p/sxmlc/wiki/Unicode/feed" rel="self" type="application/rss+xml"/><item><title>Unicode modified by Matthieu Labas</title><link>https://sourceforge.net/p/sxmlc/wiki/Unicode/</link><description>&lt;div class="markdown_content"&gt;&lt;p&gt;Unicode is available since version 4.0.0.&lt;/p&gt;
&lt;p&gt;It required quite a lot of work to mutualize code between Unicode and non-Unicode functions, as char became wchar_t and all functions related to character handling had to be changed to their wide version.&lt;br/&gt;
Hence, the code has complexified somehow due to the &lt;code&gt;#ifdef&lt;/code&gt;/&lt;code&gt;#else&lt;/code&gt;/&lt;code&gt;#endif&lt;/code&gt; that has to cope with Unicode being used or not.&lt;/p&gt;
&lt;h3 id="using-unicode"&gt;Using Unicode&lt;/h3&gt;
&lt;p&gt;Unicode is handled through the definition of &lt;code&gt;SXMLC_UNICODE&lt;/code&gt; in preprocessor. To activate it, give &lt;code&gt;-DSXMLC_UNICODE&lt;/code&gt; to the compiler (to most of them anyway).&lt;br/&gt;
Defining it changes the definition of &lt;code&gt;SXML_CHAR&lt;/code&gt; type to &lt;code&gt;wchar_t&lt;/code&gt; instead of &lt;code&gt;char&lt;/code&gt;.&lt;br/&gt;
It also adds three more members to the &lt;code&gt;XMLDoc&lt;/code&gt; struct to deal with Byte Order Mark (BOM):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bom_type&lt;/code&gt; represents the BOM that has been read in the file. It is &lt;code&gt;BOM_NONE&lt;/code&gt; when no BOM has been detected, or one of the &lt;code&gt;BOM_*&lt;/code&gt; enum.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bom&lt;/code&gt; is the BOM byte content.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sz_bom&lt;/code&gt; is the size of the BOM (i.e. how many bytes is the BOM, usefull when writing the file).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The function &lt;code&gt;freadBOM()&lt;/code&gt; has been added to determine the BOM and skip it, so that the file can be read straight.&lt;br/&gt;
It can recognize several BOMs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No BOM&lt;/li&gt;
&lt;li&gt;UTF-8 (file starts with sequence &lt;code&gt;0xef 0xbb 0xbf&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;UTF-16LE (Little Endian, file starts with sequence &lt;code&gt;0xff 0xfe&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;UTF-16BE (Big Endian, file starts with sequence &lt;code&gt;0xfe 0xff&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;UTF-32LE (Little Endian, file starts with sequence &lt;code&gt;0xff 0xfe 0x00 0x00&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;UTF-32BE (Big Endian, file starts with sequence &lt;code&gt;0x00 0x00 0xfe 0xff&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;/!\ Warning!&lt;/strong&gt;&lt;br/&gt;
Though it can recognize (and skip) UTF-32 BOM, SXMLC can handle it only to the extent of &lt;code&gt;wchar_t&lt;/code&gt;. &lt;em&gt;That means that under Microsoft OS, Unicode handling stops at UTF-16!&lt;/em&gt;&lt;br/&gt;
Also, UTF-8 is handled only on a one-byte-per-character basis as, internally, SXMLC opens the file in text mode when detecting UTF-8 BOM. If you know fancier portable &lt;code&gt;fopen&lt;/code&gt;/&lt;code&gt;fgetc&lt;/code&gt;/&lt;code&gt;fprintf&lt;/code&gt; functions to process UTF-8, please tell me! :-)&lt;/p&gt;
&lt;h3 id="coding-unicode"&gt;Coding Unicode&lt;/h3&gt;
&lt;p&gt;To ease creating Unicode-portable code, several macros are defined when opening/reading/writing streams. All of them start with &lt;code&gt;sx_&lt;/code&gt; and should be used instead of the "regular" ones. E.g use &lt;code&gt;sx_fopen&lt;/code&gt; instead of &lt;code&gt;fopen&lt;/code&gt; or &lt;code&gt;sx_strcpy&lt;/code&gt; instead of &lt;code&gt;strcpy&lt;/code&gt;.&lt;br/&gt;
A special macro &lt;code&gt;C2SX()&lt;/code&gt; adds the &lt;code&gt;L&lt;/code&gt; in front of constant strings and characters when &lt;code&gt;SXMLC_UNICODE&lt;/code&gt; is defined. This allows to use string constants with or without Unicode.&lt;br/&gt;
Of course, when writing your application, if you know for sure whether you will be using Unicode, you don't have to use these macros and can use the direct function calls instead. The following three examples are equivalent:&lt;/p&gt;
&lt;p&gt;No Unicode, &lt;code&gt;SXMLC_UNICODE&lt;/code&gt; is undefined:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;char tag[128];
XMLNode node;

XMLNode_init(&amp;amp;node);
strcpy(tag, "element");
XMLNode_set_tag(&amp;amp;node, tag);
XMLNode_add_attribute(&amp;amp;node, "name", "toto");
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Pure Unicode, &lt;code&gt;SXMLC_UNICODE&lt;/code&gt; is defined:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;wchar_t tag[128];
XMLNode node;

XMLNode_init(&amp;amp;node);
wcscpy(tag, L"element");
XMLNode_set_tag(&amp;amp;node, tag);
XMLNode_add_attribute(&amp;amp;node, L"name", L"toto");
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Portable code, works whether &lt;code&gt;SXMLC_UNICODE&lt;/code&gt; is defined:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;SXML_CHAR tag[128];
XMLNode node;

XMLNode_init(&amp;amp;node);
sx_strcpy(tag, C2SX("element"));
XMLNode_set_tag(&amp;amp;node, tag);
XMLNode_add_attribute(&amp;amp;node, C2SX("name"), C2SX("toto"));
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The full list of &lt;code&gt;sx_*&lt;/code&gt; function is available in &lt;code&gt;utils.h&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="writing-unicode-xml"&gt;Writing Unicode XML&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;/!\ Be careful when writing files with XMLDoc_print!&lt;/strong&gt; The &lt;code&gt;FILE*&lt;/code&gt; object has to be opened in binary mode when dealing with UTF-16 encoding! (either Little or Big Endian).&lt;br/&gt;
Other encodings such as ASCII or "regular" UTF-8 have to be opened in text mode as they are one-byte characters.&lt;br/&gt;
Note that you &lt;strong&gt;HAVE TO&lt;/strong&gt; define &lt;code&gt;SXMLC_UNICODE&lt;/code&gt; if you plan to write or read Unicode files.&lt;/p&gt;
&lt;p&gt;Usually, you can open the &lt;code&gt;FILE*&lt;/code&gt; in binary mode when there is a BOM to write in the document (&lt;code&gt;doc.sz_bom &amp;gt; 0&lt;/code&gt;).&lt;br/&gt;
The following code would write a document to a file according to whether the XML document is Unicode:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;int write_doc(XMLDoc* doc, SXML_CHAR* filename)
{
    SXML_CHAR* mode;
    FILE* f;

    if (doc-&amp;gt;sz_bom &amp;gt; 0 &amp;amp;&amp;amp; doc-&amp;gt;bom_type != BOM_UTF_8) /* Use text mode for UTF-8 */
        mode = C2SX("w+b");
    else
        mode = C2SX("w+t");

    f = sx_fopen(filename, mode);

    return XMLDoc_print(doc, f, NULL, NULL, false, 0, 0);
}
&lt;/pre&gt;&lt;/div&gt;

&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matthieu Labas</dc:creator><pubDate>Fri, 01 Sep 2017 18:11:55 -0000</pubDate><guid>https://sourceforge.net72a393fbad471322cab9a1601d3a7cf882eb5aa2</guid></item></channel></rss>