user46523: I'm using a library that takes a String as it's parameter (https://github.com/gmag11/painlessMesh)
I want to pass char arrays that is binary (UTF-8) data that also contains null-bytes (0x00). Right now, the resulting String is cut off at the first null-byte as expected. I know the full length of the char array, is it possible to construct an Arduino String while passing the arbitrary length, so that the full String also contains the null-bytes including the data that follows after, up until the pre-set length?
I had this problem before and then I solved it by converting the UTF-8 data to hex and then add a null-byte. I was hoping there is a more elegant way, since this forces me to double the data-size.
Thanks!

user30175: Assuming you are talking about the function
bool painlessMesh::sendBroadcast( String &msg, bool includeSelf = false)

Then you'll see that ultimately, the library passes msg into the function buildMeshPackage where it constructs a JSON message (see here)
String ICACHE_FLASH_ATTR painlessMesh::buildMeshPackage(uint32_t destId, uint32_t fromId, meshPackageType type, String &msg) {
    debugMsg(GENERAL, "In buildMeshPackage(): msg=%s\n", msg.c_str());

    DynamicJsonBuffer jsonBuffer;
    JsonObject& root = jsonBuffer.createObject();
    root["dest"] = destId;
    //root["from"] = _nodeId;
    root["from"] = fromId;
    root["type"] = (uint8_t)type;

    switch (type) {
    case NODE_SYNC_REQUEST:
    case NODE_SYNC_REPLY:
    {
        JsonArray& subs = jsonBuffer.parseArray(msg);
        if (!subs.success()) {
            debugMsg(GENERAL, "buildMeshPackage(): subs = jsonBuffer.parseArray( msg ) failed!");
        }
        root["subs"] = subs;
        break;
    }
    case TIME_SYNC:
        root["msg"] = jsonBuffer.parseObject(msg);
        break;
    default:
        root["msg"] = msg;
    }

    String ret;
    root.printTo(ret);
    return ret;
}

Even if you did construct a String with null terminators in it, the moment it gets put into the JSON string it destroys everything. JSON by default doesn't support binary data strings (reference).
So, the library is a problem because it happily passes data as JSON messages, and that's bad if you want binary data transported. You could use Base64 or the more efficient http://base91.sourceforge.net/ encoding though to mitigate this a little bit, or search for a different lib.

46523: <p>I'm using a library that takes a <code>String</code> as it's parameter (<a href="https://github.com/gmag11/painlessMesh" rel="nofollow noreferrer">https://github.com/gmag11/painlessMesh</a>)</p>

<p>I want to pass char arrays that is binary (UTF-8) data that also contains null-bytes (<code>0x00</code>). Right now, the resulting String is cut off at the first null-byte as expected. I know the full length of the char array, is it possible to construct an Arduino String while passing the arbitrary length, so that the full String also contains the null-bytes including the data that follows after, up until the pre-set length?</p>

<p>I had this problem before and then I solved it by converting the UTF-8 data to hex and then add a null-byte. I was hoping there is a more elegant way, since this forces me to double the data-size.</p>

<p>Thanks!</p>
 30175: <p>Assuming you are talking about the function</p>

<pre><code>bool painlessMesh::sendBroadcast( String &amp;msg, bool includeSelf = false)
</code></pre>

<p>Then you'll see that ultimately, the library passes <code>msg</code> into the function <code>buildMeshPackage</code> where it constructs a JSON message (<a href="https://github.com/gmag11/painlessMesh/blob/master/src/painlessMeshComm.cpp" rel="nofollow noreferrer">see here</a>)</p>

<pre class="lang-cpp prettyprint-override"><code>String ICACHE_FLASH_ATTR painlessMesh::buildMeshPackage(uint32_t destId, uint32_t fromId, meshPackageType type, String &amp;msg) {
    debugMsg(GENERAL, "In buildMeshPackage(): msg=%s\n", msg.c_str());

    DynamicJsonBuffer jsonBuffer;
    JsonObject&amp; root = jsonBuffer.createObject();
    root["dest"] = destId;
    //root["from"] = _nodeId;
    root["from"] = fromId;
    root["type"] = (uint8_t)type;

    switch (type) {
    case NODE_SYNC_REQUEST:
    case NODE_SYNC_REPLY:
    {
        JsonArray&amp; subs = jsonBuffer.parseArray(msg);
        if (!subs.success()) {
            debugMsg(GENERAL, "buildMeshPackage(): subs = jsonBuffer.parseArray( msg ) failed!");
        }
        root["subs"] = subs;
        break;
    }
    case TIME_SYNC:
        root["msg"] = jsonBuffer.parseObject(msg);
        break;
    default:
        root["msg"] = msg;
    }

    String ret;
    root.printTo(ret);
    return ret;
}
</code></pre>

<p>Even if you did construct a <code>String</code> with null terminators in it, the moment it gets put into the JSON string it destroys everything. JSON by default doesn't support binary data strings (<a href="https://stackoverflow.com/questions/1443158/binary-data-in-json-string-something-better-than-base64">reference</a>).</p>

<p>So, the library is a problem because it happily passes data as JSON messages, and that's bad if you want binary data transported. You could use Base64 or the more efficient <a href="http://base91.sourceforge.net/" rel="nofollow noreferrer">http://base91.sourceforge.net/</a> encoding though to mitigate this a little bit, or search for a different lib.</p>
