uncompressing data in memory

S

Slaanesh

Hi,

I have to uncompress a buffer extracted from a file (not the entire file is
compressed, it begins after the 8th byte). The data has been compressed
using zlib library. My problem is that it doesn't work ;(
I wrote this code the map the content of the file in memory:
    /* gets file size */
    file = fopen(src, "r");
    if (!file) {
        return (0);
    }
    fseek(file, 0, SEEK_END);
    fileSize = ftell(file);
    rewind(file);

    /* maps file content into memory */
    data = (char *) mmap(0, fileSize, PROT_READ, MAP_SHARED, fileno(file),
0);

    fclose(file);


Then I call uncompress function this way:

    uncomprLen = fileSize * 2;
    dest = (unsigned char *) calloc(uncomprLen, sizeof (char));
    if (!dest) {
        return (0);
    }

    err = uncompress(dest, &uncomprLen, data + 8, fileSize - 8);
    if (err != Z_OK) {
        /* error */
        switch (err) {
        case Z_DATA_ERROR:
            fprintf(stderr, "cannot uncompress file (data corrupted)\n");
            break;
        case Z_MEM_ERROR:
            fprintf(stderr, "cannot uncompress file (not enough memory)\n");
            break;
        case Z_BUF_ERROR:
            fprintf(stderr, "cannot uncompress file (not enough room in the
output buffer)\n");
            break;
        default:
            fprintf(stderr, "cannot uncompress file, unknown error code:
%d\n", err);
        }
        return (0);
    }
    return (1);

My problem is I always get the Z_DATA_ERROR return code whatever data I gave
to uncompress....
So if someone could help me, it would by very nice ;)
 
J

Jack Klein

Hi,

I have to uncompress a buffer extracted from a file (not the entire file is
compressed, it begins after the 8th byte). The data has been compressed
using zlib library. My problem is that it doesn't work ;(

Note that we do not discuss the workings of third party libraries
here, and that is what you are asking about.
I wrote this code the map the content of the file in memory:
    /* gets file size */
    file = fopen(src, "r");
    if (!file) {
        return (0);
    }
    fseek(file, 0, SEEK_END);

If your file contains compressed data, it is almost certainly binary
and not text. Yet you have opened it in text mode. Also, SEEK_END
has undefined behavior for binary files, although it might not work
all that well for text files either.
    fileSize = ftell(file);
    rewind(file);

    /* maps file content into memory */
    data = (char *) mmap(0, fileSize, PROT_READ, MAP_SHARED, fileno(file),
0);

There is no mmap() function in standard C. It is some sort of
non-standard extension. Any problems you have with memory accessed
through this pointer are off-topic here, because C doesn't define it.
    fclose(file);


Then I call uncompress function this way:

    uncomprLen = fileSize * 2;
    dest = (unsigned char *) calloc(uncomprLen, sizeof (char));

Casting the return value of calloc() or malloc() is almost always a
mistake. If you have included <stdilb.h> you do not need the cast.
If you get compiler diagnostics without the cast then you haven't
included the proper header and the behavior is undefined with the
cast.
    if (!dest) {
        return (0);
    }

    err = uncompress(dest, &uncomprLen, data + 8, fileSize - 8);
    if (err != Z_OK) {
        /* error */
        switch (err) {
        case Z_DATA_ERROR:
            fprintf(stderr, "cannot uncompress file (data corrupted)\n");
            break;
        case Z_MEM_ERROR:
            fprintf(stderr, "cannot uncompress file (not enough memory)\n");
            break;
        case Z_BUF_ERROR:
            fprintf(stderr, "cannot uncompress file (not enough room in the
output buffer)\n");
            break;
        default:
            fprintf(stderr, "cannot uncompress file, unknown error code:
%d\n", err);
        }
        return (0);
    }
    return (1);

My problem is I always get the Z_DATA_ERROR return code whatever data I gave
to uncompress....
So if someone could help me, it would by very nice ;)

You need to ask about this in a group that supports your compiler/OS
combination and/or the zlib library. None of these things are defined
by the C language.
 
D

Dan Pop

In said:
If your file contains compressed data, it is almost certainly binary
and not text. Yet you have opened it in text mode. Also, SEEK_END
has undefined behavior for binary files,

Chapter and verse, please. AFAICT, "need not meaningfully support" is
FAR from invoking undefined behaviour.
although it might not work all that well for text files either.

It is *guaranteed* to work for text streams, when offset is 0. Otherwise,
using SEEK_END is genuine undefined behaviour (violation of a "shall"):

4 For a text stream, either offset shall be zero, or offset shall
be a value returned by an earlier successful call to the ftell
function on a stream associated with the same file and whence
shall be SEEK_SET.

Dan
 
R

Richard Bos

Jack Klein said:
Ahem.

has undefined behavior for wide-oriented binary files,

Not quite, though it's muddled.

# — Binary wide-oriented streams have the file-positioning restrictions
# ascribed to both text and binary streams.

However,

# A binary stream need not meaningfully support fseek calls with a
# whence value of SEEK_END.

Undefined behaviour is surely too strong, since the footnote to 7.19.3#9
is not normative and "need not meaningfully support" IYAM gives
allowance to fail or to seek to an unexpected position, but _not_ to
crash - but it isn't properly defined, either. Neither is it explicitly
unspecified or implementation-defined; it would fit unspecified best.

What this means for wide-oriented binary streams is that:
- fseek(wide_stream, non_zero_value, SEEK_END) _is_ undefined
behaviour, since it is so for normal text streams;
- fseek(wide_stream, 0, SEEK_END) is whatever it is for binary streams,
probably unspecified, since it is well-defined for text streams.

Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top