static intptr_t ReadHeader(intptr_t base, size_t *length, header_t* header) { if((!length) || (!header)) throw Exception(E_POINTER); // Get the LZO API version from the minilzo library uint16_t version = static_cast<uint16_t>(lzo_version()); memset(header, 0, sizeof(header_t)); header->version_needed_to_extract = 0x0900; // version base = ReadBE16(base, length, &header->version); if(header->version < 0x0900) throw Exception(E_DECOMPRESS_BADHEADER, COMPRESSION_METHOD); // lib_version base = ReadBE16(base, length, &header->lib_version); // version_needed_to_extract if(header->version >= 0x0940) { base = ReadBE16(base, length, &header->version_needed_to_extract); if(header->version_needed_to_extract > version) throw Exception(E_DECOMPRESS_BADHEADER, COMPRESSION_METHOD); if(header->version_needed_to_extract < 0x0900) throw Exception(E_DECOMPRESS_BADHEADER, COMPRESSION_METHOD); } // method base = ReadBE8(base, length, &header->method); // level if(header->version >= 0x0940) base = ReadBE8(base, length, &header->level); // flags base = ReadBE32(base, length, &header->flags); // filter if(header->flags & F_H_FILTER) base = ReadBE32(base, length, &header->filter); // mode base = ReadBE32(base, length, &header->mode); if(header->flags & F_STDIN) header->mode = 0; // mtime_low base = ReadBE32(base, length, &header->mtime_low); // mtime_high if(header->version >= 0x0940) base = ReadBE32(base, length, &header->mtime_high); // filename (skipped) uint8_t fnlen; base = ReadBE8(base, length, &fnlen); if(fnlen) { base += fnlen; *length -= fnlen; } // checksum base = ReadBE32(base, length, &header->header_checksum); // TODO: check this?? // skip extra fields if(header->flags & F_H_EXTRA_FIELD) { // length of extra data uint32_t extralen; base = ReadBE32(base, length, &extralen); base += extralen; *length -= extralen; // extra fields checksum uint32_t extrachecksum; base = ReadBE32(base, length, &extrachecksum); } return base; // Return adjusted base pointer }
iow_t *lzo_wopen(iow_t *child, int compress_level) { const int opt_filter = 0; int flags; iow_t *iow; struct buffer_t buffer; buffer.offset=0; int i; if (!child) return NULL; if (lzo_init() != LZO_E_OK) { /* Fail */ return NULL; } /* Compress level is useless for LZO, but getting UNUSED into here * is more trouble than it is worth so this check will at least * stop us from getting warnings about it. */ if (compress_level < 0) return NULL; iow = malloc(sizeof(iow_t)); iow->source = &lzo_wsource; iow->data = malloc(sizeof(struct lzow_t)); DATA(iow)->child = child; DATA(iow)->err = ERR_OK; flags = 0; flags |= F_OS_UNIX & F_OS_MASK; /* Operating System */ flags |= F_CS_NATIVE & F_CS_MASK; /* Character Set */ flags |= F_ADLER32_D; /* We adler32 the uncompressed data */ /* flags |= F_STDIN; */ /* flags |= F_STDOUT */ /* flags |= F_MULTIPART; */ /* flags |= F_H_CRC32; */ write_buf(&buffer, lzop_magic, sizeof(lzop_magic)); write16(&buffer, 0x1010 &0xFFFF); /* version: pretend to be LZOP version 0x1010 from lzop's version.h */ write16(&buffer, lzo_version() & 0xFFFF); /* libversion */ write16(&buffer, opt_filter ? 0x0950 : 0x0940); /* version needed to extract */ write8(&buffer, M_LZO1X_1); /* method */ write8(&buffer, 5); /* level */ write32(&buffer, flags); /* flags */ /* if (flags & F_H_FILTER) write32(iow, opt_filter); */ write32(&buffer, 0x600); /* mode: We assume traces may be sensitive */ write32(&buffer, time(NULL)); /* mtime */ write32(&buffer, 0); /* GMTdiff */ /* Length, filename */ write8(&buffer, strlen("compresseddata")); write_buf(&buffer, "compresseddata",strlen("compresseddata")); if (flags & F_H_CRC32) { write32(&buffer, lzo_crc32(CRC32_INIT_VALUE, (const void*)buffer.buffer+sizeof(lzop_magic), buffer.offset-sizeof(lzop_magic))); } else { uint32_t chksum=lzo_adler32( ADLER32_INIT_VALUE, (const void *)buffer.buffer+sizeof(lzop_magic), buffer.offset-sizeof(lzop_magic)); write32(&buffer, chksum); } wandio_wwrite(DATA(iow)->child, buffer.buffer, buffer.offset); /* Set up the thread pool -- one thread per core */ DATA(iow)->threads = min((uint32_t)sysconf(_SC_NPROCESSORS_ONLN), use_threads); DATA(iow)->thread = malloc( sizeof(struct lzothread_t) * DATA(iow)->threads); DATA(iow)->next_thread = 0; for(i=0; i<DATA(iow)->threads; ++i) { pthread_cond_init(&DATA(iow)->thread[i].in_ready, NULL); pthread_cond_init(&DATA(iow)->thread[i].out_ready, NULL); pthread_mutex_init(&DATA(iow)->thread[i].mutex, NULL); DATA(iow)->thread[i].closing = false; DATA(iow)->thread[i].num = i; DATA(iow)->thread[i].state = EMPTY; DATA(iow)->thread[i].inbuf.offset = 0; pthread_create(&DATA(iow)->thread[i].thread, NULL, lzo_compress_thread, (void*)&DATA(iow)->thread[i]); } return iow; }
void* lzowrite_init(const char* filename) { //Prepare the buffers struct lzowrite_buffer* buffer = malloc(sizeof(struct lzowrite_buffer)); buffer->output = fopen(filename, "w"); buffer->length = 0; //Allocate workmemory HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS); buffer->workmemory = wrkmem; //Write LZO fileformat unsigned char magic[LZOWRITE_LZO_MAGIC_LEN] = LZOWRITE_LZO_MAGIC; fwrite(magic, sizeof(unsigned char), LZOWRITE_LZO_MAGIC_LEN, buffer->output); //Init header struct lzowrite_file_header* fheader = malloc(sizeof(struct lzowrite_file_header)); fheader->version = LZOWRITE_LZO_VERSION; fheader->library_version = lzo_version(); fheader->needed_version = LZOWRITE_LZO_VERSION_NEEDED_TO_EXTRACT; fheader->compression_method = LZOWRITE_LZO_METHOD; fheader->compression_level = LZOWRITE_LZO_COMPRESSION_LEVEL; fheader->compression_flags = LZOWRITE_LZO_FLAGS; fheader->mode = LZOWRITE_LZO_MODE; fheader->file_name_length = 0; fheader->file_header_checksum = 1; fheader->file_mtime_high = 0; fheader->file_mtime_low = 0; fwrite(&fheader->version, sizeof(uint16_t), 1, buffer->output); fwrite(&fheader->library_version, sizeof(uint16_t), 1, buffer->output); fwrite(&fheader->needed_version, sizeof(uint16_t), 1, buffer->output); fwrite(&fheader->compression_method, sizeof(uint8_t), 1, buffer->output); fwrite(&fheader->compression_level, sizeof(uint8_t), 1, buffer->output); fwrite(&fheader->compression_flags, sizeof(uint32_t), 1, buffer->output); fwrite(&fheader->mode, sizeof(uint32_t), 1, buffer->output); fwrite(&fheader->file_mtime_low, sizeof(uint32_t), 1, buffer->output); fwrite(&fheader->file_mtime_high, sizeof(uint32_t), 1, buffer->output); fwrite(&fheader->file_name_length, sizeof(uint8_t), 1, buffer->output); //Calculate checksum fheader->file_header_checksum = lzo_adler32(fheader->file_header_checksum, (lzo_bytep)&fheader->version, 2); fheader->file_header_checksum = lzo_adler32(fheader->file_header_checksum, (lzo_bytep)&fheader->library_version, 2); fheader->file_header_checksum = lzo_adler32(fheader->file_header_checksum, (lzo_bytep)&fheader->needed_version, 2); fheader->file_header_checksum = lzo_adler32(fheader->file_header_checksum, (lzo_bytep)&fheader->compression_method, 1); fheader->file_header_checksum = lzo_adler32(fheader->file_header_checksum, (lzo_bytep)&fheader->compression_level, 1); fheader->file_header_checksum = lzo_adler32(fheader->file_header_checksum, (lzo_bytep)&fheader->compression_flags, 4); fheader->file_header_checksum = lzo_adler32(fheader->file_header_checksum, (lzo_bytep)&fheader->mode, 4); fheader->file_header_checksum = lzo_adler32(fheader->file_header_checksum, (lzo_bytep)&fheader->file_mtime_low, 4); fheader->file_header_checksum = lzo_adler32(fheader->file_header_checksum, (lzo_bytep)&fheader->file_mtime_high, 4); fheader->file_header_checksum = lzo_adler32(fheader->file_header_checksum, (lzo_bytep)&fheader->file_name_length, 1); fwrite(&((uint8_t*)(&fheader->file_header_checksum))[3], sizeof(uint8_t), 1, buffer->output); fwrite(&((uint8_t*)(&fheader->file_header_checksum))[2], sizeof(uint8_t), 1, buffer->output); fwrite(&((uint8_t*)(&fheader->file_header_checksum))[1], sizeof(uint8_t), 1, buffer->output); fwrite(&((uint8_t*)(&fheader->file_header_checksum))[0], sizeof(uint8_t), 1, buffer->output); free(fheader); return buffer; }