[vlmc-devel] [PATCH 1/4] Settings: Use Base64 to save QByteArray

Hugo Beauzée-Luyssen hugo at beauzee.fr
Mon May 2 13:11:04 CEST 2016


On 05/01/2016 05:56 AM, yikei lu wrote:
> FYI, saveGeometry() will create a byte array like
> "\001ÙÐË\000\002\000\000ÿÿþu\000\000\000L\000\000\003R\000\000\002¾ÿÿþv\000\000\000f\000\000\003Q\000\000\002½\000\000\000\000\000\000\000\000\007\200"
>
> saveState():
> "\000\000\000ÿ\000\000\000\000ý\000\000\000\001\000\000\000\002\000\000\004Ü\000\000\001\004ü\001\000\000\000\005û\000\000\000\030\000M\000e\000d\000i\000a\000L\000i\000b\000r\000a\000r\000y\001\000\000\000\000\000\000\001\030\000\000\001\030\000ÿÿÿû\000\000\000\030\000E\000f\000f\000e\000c\000t\000s\000
> \000L"... (327)
>
> A LOT OF \0 !!!
>
> 2016-05-01 12:48 GMT+09:00 yikei lu <luyikei.qmltu at gmail.com>:
>> "QByteArray QMainWindow::saveState(int version = 0) const" is. It will
>> always start with \0 in my case, which makes QJsonValue mistakenly
>> recognizes it as null.
>> Also, saveGeometry() doesn't work since there must be \0 anywhere in
>> the QByteArray.
>> So you can see that unless the patch be applied, you can't save and
>> restore the mainwindow's state/geometry.
>>
>> You can confirm this with vlmc.conf
>>
>> 2016-05-01 2:03 GMT+09:00 Hugo Beauzée-Luyssen <hugo at beauzee.fr>:
>>> On 04/29/2016 10:05 AM, Yikai Lu wrote:
>>>> "Note: A QByteArray can store any byte values including '\0's, but most functions that take char * arguments assume that the data ends at the first '\0' they encounter."
>>>>
>>>> Because of the above, we can't save QByteArray directly.
>>>> ---
>>>>   src/Settings/Settings.cpp | 13 +++++++++++--
>>>>   1 file changed, 11 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/src/Settings/Settings.cpp b/src/Settings/Settings.cpp
>>>> index b8cef75..2092d59 100644
>>>> --- a/src/Settings/Settings.cpp
>>>> +++ b/src/Settings/Settings.cpp
>>>> @@ -159,8 +159,14 @@ Settings::loadJsonFrom( const QJsonObject &object )
>>>>           if ( isChildSettings == true )
>>>>               continue;
>>>>
>>>> -        if ( setValue( it.key(), (*it).toVariant() ) == false )
>>>> +        SettingValue* val = value( it.key() );
>>>> +        if ( val == nullptr )
>>>>               vlmcWarning() << "Loaded invalid project setting:" << it.key();
>>>> +
>>>> +        if ( val->type() == SettingValue::ByteArray )
>>>> +            val->set( QByteArray::fromBase64( (*it).toVariant().toByteArray() ) );
>>>> +        else
>>>> +            val->set( (*it).toVariant() );
>>>>       }
>>>>       emit postLoad();
>>>>   }
>>>> @@ -173,7 +179,10 @@ Settings::saveJsonTo( QJsonObject &object )
>>>>       {
>>>>           if ( ( val->flags() & SettingValue::Runtime ) != 0 )
>>>>               continue ;
>>>> -        object.insert( val->key(), QJsonValue::fromVariant( val->get() ) );
>>>> +        if ( val->type() == SettingValue::ByteArray )
>>>> +            object.insert( val->key(), QJsonValue( QString( val->get().toByteArray().toBase64() ) ) );
>>>> +        else
>>>> +            object.insert( val->key(), QJsonValue::fromVariant( val->get() ) );
>>>>       }
>>>>   }
>>>>
>>>>
>>> Is there a specific case where this would be an issue?
>>>
>>> --
>>> Hugo Beauzée-Luyssen
>>> www.beauzee.fr
>>> _______________________________________________
>>> Vlmc-devel mailing list
>>> Vlmc-devel at videolan.org
>>> https://mailman.videolan.org/listinfo/vlmc-devel
> _______________________________________________
> Vlmc-devel mailing list
> Vlmc-devel at videolan.org
> https://mailman.videolan.org/listinfo/vlmc-devel
>

Oh ok I got it now, though the way I understand it, the problem isn't 
linked with conversions to char* per-se, but rather that QJsonValue 
doesn't know QByteArray, so it will use the QString conversion, which 
indeed fails.
This seems like a lack of feature in Qt, but your patch seems to be a 
proper workaround, thanks!


More information about the Vlmc-devel mailing list