#ifndef __COMPRESS_STATE_AH__ #define __COMPRESS_STATE_AH__ #include "config/VariantConfig.hpp" #include "config/FailConfig.hpp" #if defined(BUILD_BOCHS) && defined(CONFIG_BOCHS_COMPRESS_STATE) #include #include aspect CompressState { advice call ("% fwrite(...)") && within ("% bx_real_sim_c::save_sr_param(...)") && args(ptr, size, nmemb, stream) : around (const void *ptr, size_t size, size_t nmemb, FILE *stream) { *tjp->result() = fwrite_compressed(ptr, size, nmemb, stream); } advice call ("% fread(...)") && within ("% bx_real_sim_c::restore_bochs_param(...)") && args(ptr, size, nmemb, stream) : around (void *ptr, size_t size, size_t nmemb, FILE *stream) { *tjp->result() = fread_compressed(ptr, size, nmemb, stream); } // FIXME move implementation to a separate compilation unit size_t fread_compressed(void *ptr, size_t size, size_t nmemb, FILE *stream) { size_t remaining = size * nmemb; ssize_t ret; char *cbuf = (char *) ptr; // FIXME check return values gzFile f = gzdopen(dup(fileno(stream)), "rb"); #if ZLIB_VERNUM >= 0x1240 gzbuffer(f, 1024*1024); #endif do { ret = gzread(f, cbuf, remaining); // EOF or error? if (ret == 0 || ret == -1) { break; } remaining -= ret; cbuf += ret; } while (remaining); gzclose(f); return (cbuf - (char *)ptr) / size; } size_t fwrite_compressed(const void *ptr, size_t size, size_t nmemb, FILE *stream) { size_t remaining = size * nmemb; ssize_t ret; const char *cbuf = (const char *) ptr; // FIXME check return values gzFile f = gzdopen(dup(fileno(stream)), "wb9"); #if ZLIB_VERNUM >= 0x1240 gzbuffer(f, 1024*1024); #endif do { ret = gzwrite(f, cbuf, remaining); // error? if (ret == 0) { break; } remaining -= ret; cbuf += ret; } while (remaining); gzclose(f); return (cbuf - (const char *)ptr) / size; } }; #endif // BUILD_BOCHS && CONFIG_BOCHS_COMPRESS_STATE #endif // __COMPRESS_STATE_AH__