[GB.COMPRESS.ZLIB]

* NEW: Uncompress.String(): Detect gzip format.



git-svn-id: svn://localhost/gambas/trunk@7393 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Tobias Boege 2015-10-07 01:02:31 +00:00
parent f073b22eae
commit 4a8947f64b

View File

@ -180,47 +180,71 @@ or NULL and zero if it fails by any reason
*********************************************************************************/ *********************************************************************************/
static void u_String(char **target,unsigned int *lent,char *source,unsigned int len) static void u_String(char **target,unsigned int *lent,char *source,unsigned int len)
{ {
int myok=Z_BUF_ERROR; int res, try_gzip = 0;
unsigned long l; z_stream stream = {
.zalloc = Z_NULL,
.zfree = Z_NULL,
.opaque = Z_NULL,
.avail_in = len,
.next_in = (Bytef *) source,
};
unsigned long pos = 0;
/* we assume src len * 1.8 as target len */ *lent = 2 * len;
*lent=1.8*len; GB.Alloc((void **) target, *lent);
GB.Alloc ((void**)target,(*lent)*sizeof(char));
while (myok==Z_BUF_ERROR) stream.avail_out = *lent;
{ stream.next_out = (Bytef *) *target;
l = *lent;
myok=uncompress ((Bytef*)(*target),&l,(Bytef *)source,len); inflateInit(&stream);
*lent = (uint)l; while (1) {
switch (myok) res = inflate(&stream, Z_NO_FLUSH);
{ switch (res) {
case Z_OK: break; case Z_OK:
case Z_DATA_ERROR: break;
*lent=0; case Z_BUF_ERROR:
if (*target) GB.Free((void**)target); pos = (unsigned long) (stream.next_out - (unsigned long) *target);
GB.Error ("Invalid compressed string"); *lent += *lent / 2;
return; GB.Realloc((void **) target, *lent);
case Z_BUF_ERROR: /* test and error method ! */ stream.avail_out = *lent - pos;
if ((*lent)<=10) stream.next_out = (Bytef *) (*target + pos);
*lent+=(*lent); break;
else case Z_STREAM_END:
*lent+=((*lent)*0.5); pos = (unsigned long) (stream.next_out - (unsigned long) *target);
GB.Realloc ((void**)target,(*lent)*sizeof(char)); goto out;
break; case Z_DATA_ERROR:
case Z_MEM_ERROR: /* Maybe we have gzip format? */
*lent=0; if (try_gzip) {
if (*target) GB.Free((void**)target); GB.Error("Invalid compressed string");
GB.Error ("Not enough memory: String too long"); goto error;
return; }
default: inflateEnd(&stream);
*lent=0; stream.avail_in = len;
GB.Free((void**)target); stream.next_in = (Bytef *) source;
GB.Error ("Unable to inflate string"); stream.avail_out = *lent;
return; stream.next_out = (Bytef *) *target;
inflateInit2(&stream, 16 + MAX_WBITS);
try_gzip = 1;
continue;
case Z_MEM_ERROR:
GB.Error("Not enough memory: String too long");
goto error;
default:
GB.Error("Unable to inflate string");
goto error;
} }
} }
out:
inflateEnd(&stream);
*lent = pos;
GB.Realloc((void **) target, *lent);
return;
error:
*lent = 0;
GB.Free((void **) target);
} }
/********************************************************************************* /*********************************************************************************
The Driver must provide this function: The Driver must provide this function: