[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:
parent
f073b22eae
commit
4a8947f64b
@ -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:
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user