Qt/C++ program has a function which writes an objects data (_token
) to a file as follows:
QFile f( _tokenFile);
if (!f.open( QIODevice::WriteOnly)) {
qDebug() << "Unable to open token file for writing" << f.errorString();
return false;
}
QByteArray tokenBa;
QDataStream ds( &tokenBa, QIODevice::WriteOnly);
ds << _token;
tokenBa = qCompress( tokenBa);
f.write( tokenBa);
f.close();
The _token is an instance of the following struct
:
struct Token {
QString accessToken;
QString refreshToken;
QString clientSecret;
QString authCode;
QTime expiryTime;
enum AuthState {
A_Invalid,
A_RequestAuth,
A_Authenticated,
};
AuthState state;
Token() : state( A_Invalid) {}
bool isValid() const {
if (accessToken.isEmpty() ||
refreshToken.isEmpty()) {
return false;
}
return true;
}
void inValidate() {
accessToken.clear();
refreshToken.clear();
clientSecret.clear();
authCode.clear();
expiryTime = QTime();
}
void cleanUp() {
accessToken.clear();
refreshToken.clear();
clientSecret.clear();
authCode.clear();
expiryTime = QTime();
}
};
When the file is saved it has 4 extra bytes at the start which render the file as a invalid zlib file.
0000000 0000 5e01 9c78 904d 4f5d 5082 871c fa9f
0000020 353e 25cd 6975 2c2f d563 4c2c 62b8 cad1
We can see above bytes 5-6 are 9C 78
which is the zlib signature, but the 4 bytes before these are the issue.
To check the compressed data is correct I do the following:
dd if=file.token bs=1 skip=4 | openssl zlib -d
And this produces the expected result (for testing).
The problem is in the application reading this data back into the data object:
QFile f( _tokenFile);
if (!f.exists()) {
qDebug() << "Token file doesn't exist" << f.fileName();
return false;
}
if (!f.open( QIODevice::ReadOnly)) {
qDebug() << "Unable to open token file for reading" << f.errorString();
return false;
}
QByteArray tokenBa = f.readAll();
f.close();
if (tokenBa.isEmpty()) {
qDebug() << "Token file is empty.";
return false;
}
tokenBa = qUncompress( tokenBa);
QDataStream ds( &tokenBa, QIODevice::ReadOnly);
ds >> _token;
This returns null - because of the leading 4 extraneous bytes. I could put some code in to skip these 4 leading bytes, but how do I know it will always be 4 bytes? I'd like to instead have certainly that the files data is all zlib compressed.
My question is how to avoid those bytes being saved in the first place so that on re-read the format is known to be zlib type?