Writing ValueTree to to stream and then to base64encoding twice doesn't give same result

ValueTree lm(“myStuff”);
MemoryBlock b;
MemoryOutputStream memStream(b, false);
String base64Txt = b.toBase64Encoding();

Doing this directly afterwards for the same valuetree again doesn’t give the same base64Txt. It works on Win but not Mac. This is a problem since I compare that text along with other textstuff to see if anything changed. I can’t really go JUCE all the way and save everything in valuetrees because of old saveformats.

I can’t see the reason why doing the same action gives a different result been done by purpose on MAC only, so I guess it’s a bug?

You’re not just doing something silly like appending the second version to the end of the first stream rather than a new one?

No, new memoryblock, new stream…just same valuetree

I’m struggling to believe that… Can you post a complete sample that shows the whole thing, including the comparison?

juce::ValueTree lm(“myStuff”);
MemoryBlock b4;
MemoryOutputStream m4(b4, false);
String base64Txt4 = b4.toBase64Encoding(); ->

MemoryBlock b5;
MemoryOutputStream m5(b5, false);
String base64Txt5 = b5.toBase64Encoding(); ->


This is just bad scope hygiene - you’re using the contents of those streams before you’ve deleted/flushed them. If you actually structure your code properly, e.g.

static String toBase64 (const ValueTree& v)
    MemoryBlock b;

        MemoryOutputStream m (b, false);
        v.writeToStream (m);

    return b.toBase64Encoding();

juce::ValueTree lm("myStuff");
DBG (toBase64 (lm));
DBG (toBase64 (lm));

then problems like that magically go away!

This is why it’s such a bad habit to clutter a single block-scope with a bunch of copy-pasted code. When you have complex objects like streams whose destructors have side-effects, you need to clearly think about when they get deleted.

1 Like

Yes it makes sense and works, thanks!