static int snappy_in_java_compress(FILE *infp, FILE *outfp, size_t block_size) { work_buffer_t wb; size_t uncompressed_length; int err = 1; wb.c = NULL; wb.uc = NULL; if (block_size == 0) { block_size = DEFAULT_BLOCK_SIZE; } if (block_size > MAX_BLOCK_SIZE) { print_error("Too large block size: %lu. (default: %d, max: %d)\n", (unsigned long)block_size, DEFAULT_BLOCK_SIZE, MAX_BLOCK_SIZE); goto cleanup; } if (fwrite_unlocked(&snappy_in_java_header, sizeof(snappy_in_java_header), 1, outfp) != 1) { print_error("Failed to write a file: %s\n", strerror(errno)); goto cleanup; } /* write file body */ work_buffer_init(&wb, block_size); while ((uncompressed_length = fread_unlocked(wb.uc, 1, wb.uclen, infp)) > 0) { size_t compressed_length = wb.clen; unsigned int crc32c = masked_crc32c(wb.uc, uncompressed_length); trace("read %lu bytes.\n", (unsigned long)uncompressed_length); /* compress the block. */ snappy_compress(wb.uc, uncompressed_length, wb.c, &compressed_length); trace("compressed_legnth is %lu.\n", (unsigned long)compressed_length); if (compressed_length >= (uncompressed_length - (uncompressed_length / 8))) { trace("write uncompressed data\n"); if (write_block(outfp, wb.uc, uncompressed_length, FALSE, crc32c) != 0) { goto cleanup; } } else { trace("write compressed data\n"); if (write_block(outfp, wb.c, compressed_length, TRUE, crc32c) != 0) { goto cleanup; } } } if (!feof_unlocked(infp)) { /* fread_unlocked() failed. */ print_error("Failed to read a file: %s\n", strerror(errno)); goto cleanup; } err = 0; cleanup: work_buffer_free(&wb); return err; }
/* * Callers must ensure that the checksum pointer is aligned to a 4 byte boundary * if the CPU disallows unaligned accesss. */ static int check_crc32c(const char *data, size_t datalen, const char *checksum) { unsigned int actual_crc32c = masked_crc32c(data, datalen); unsigned int expected_crc32c = SNZ_FROM_LE32(*(unsigned int*)checksum); if (actual_crc32c != expected_crc32c) { print_error("CRC32C error! (expected 0x%08x but 0x%08x)\n", expected_crc32c, actual_crc32c); return -1; } return 0; }
static int check_and_write_block(int outfd, const char *buffer, size_t length, int verify_checksum, unsigned int crc32c) { if (verify_checksum) { unsigned int actual_crc32c = masked_crc32c(buffer, length); if (actual_crc32c != crc32c) { print_error("Invalid crc code (expected 0x%08x but 0x%08x)\n", crc32c, actual_crc32c); return 1; } } if (write_full(outfd, buffer, length) != length) { print_error("Failed to write a file: %s\n", strerror(errno)); return 1; } trace("write %ld bytes\n", (long)length); return 0; }
/* * Callers must ensure that the checksum pointer is aligned to a 4 byte boundary * on little endian environment. */ static int check_crc32c(const char *data, size_t datalen, const char *checksum) { unsigned int actual_crc32c = masked_crc32c(data, datalen); #ifdef WORDS_BIGENDIAN unsigned int expected_crc32c = ((unsigned int)checksum[0] & 0xff) | (((unsigned int)checksum[1] & 0xff) << 8) | (((unsigned int)checksum[2] & 0xff) << 16) | (((unsigned int)checksum[3] & 0xff) << 24); #else unsigned int expected_crc32c = *(unsigned int*)checksum; #endif if (actual_crc32c != expected_crc32c) { print_error("CRC32C error! (expected 0x%08x but 0x%08x)\n", expected_crc32c, actual_crc32c); return -1; } return 0; }
primitiveMaskedCrc32c(void) { const char*buf; sqInt inputObj; size_t len; unsigned int maskedCrc; sqInt num; char* ptr; if (!((interpreterProxy->methodArgumentCount()) == 2)) { interpreterProxy->primitiveFail(); return; } inputObj = interpreterProxy->stackValue(1); /* begin charPointerFor: */ if (!(interpreterProxy->isBytes(inputObj))) { buf = ((char*) null); goto l1; } ptr = ((char*) (interpreterProxy->firstIndexableField(inputObj))); buf = ((char*) ptr); l1: /* end charPointerFor: */; if (!(buf)) { interpreterProxy->primitiveFail(); return; } /* begin stackPositiveIntegerValue: */ num = interpreterProxy->stackValue(0); if ((interpreterProxy->isIntegerValue(num)) && (num < 0)) { len = ((sqInt) null); goto l2; } len = ((sqInt) (interpreterProxy->positive32BitValueOf(num))); l2: /* end stackPositiveIntegerValue: */; if (!(len)) { interpreterProxy->primitiveFail(); return; } maskedCrc = masked_crc32c(buf, len); /* begin returnIntegerFor: */ interpreterProxy->pop((interpreterProxy->methodArgumentCount()) + 1); if (maskedCrc <= 1073741823) { interpreterProxy->pushInteger(maskedCrc); } else { interpreterProxy->push(interpreterProxy->positive32BitIntegerFor(maskedCrc)); } }
static int comment_43_compress(FILE *infp, FILE *outfp, size_t block_size) { const size_t max_raw_data_len = 32 * 1024; /* maximum data length */ const size_t max_compressed_data_len = snappy_max_compressed_length(max_raw_data_len); /* maximum compressed length */ size_t raw_data_len; size_t compressed_data_len; char *raw_data = malloc(max_raw_data_len); char *compressed_data = malloc(max_compressed_data_len); int err = 1; if (raw_data == NULL || compressed_data == NULL) { print_error("out of memory\n"); goto cleanup; } putc_unlocked(HEADER_TYPE_CODE, outfp); putc_unlocked(MAGIC_LEN, outfp); putc_unlocked(MAGIC_LEN >> 8, outfp); fwrite_unlocked(MAGIC, MAGIC_LEN, 1, outfp); /* write file body */ while ((raw_data_len = fread_unlocked(raw_data, 1, max_raw_data_len, infp)) > 0) { unsigned int crc32c = masked_crc32c(raw_data, raw_data_len); char type_code; size_t write_len; const char *write_data; /* compress the block. */ compressed_data_len = max_compressed_data_len; snappy_compress(raw_data, raw_data_len, compressed_data, &compressed_data_len); if (compressed_data_len >= (raw_data_len - (raw_data_len / 8))) { /* write uncompressed data */ type_code = UNCOMPRESSED_TYPE_CODE; write_len = raw_data_len; write_data = raw_data; } else { /* write compressed data */ type_code = COMPRESSED_TYPE_CODE; write_len = compressed_data_len; write_data = compressed_data; } /* block type */ putc_unlocked(type_code, outfp); /* data length */ putc_unlocked(((write_len + 4) >> 0), outfp); putc_unlocked(((write_len + 4) >> 8), outfp); /* data */ putc_unlocked((crc32c >> 0), outfp); putc_unlocked((crc32c >> 8), outfp); putc_unlocked((crc32c >> 16), outfp); putc_unlocked((crc32c >> 24), outfp); if (fwrite_unlocked(write_data, write_len, 1, outfp) != 1) { print_error("Failed to write a file: %s\n", strerror(errno)); goto cleanup; } } if (!feof_unlocked(infp)) { /* fread_unlocked() failed. */ print_error("Failed to read a file: %s\n", strerror(errno)); goto cleanup; } putc_unlocked(END_OF_STREAM_TYPE_CODE, outfp); putc_unlocked(0, outfp); putc_unlocked(0, outfp); if (ferror_unlocked(outfp)) { print_error("Failed to write a file: %s\n", strerror(errno)); goto cleanup; } err = 0; cleanup: free(raw_data); free(compressed_data); return err; }
static stream_state_t process_block(FILE *fp, stream_state_t state, block_data_t *bd, char *work, size_t work_len) { unsigned int crc32c; size_t outlen; switch (state) { case INITIAL_STATE: case END_OF_STREAM_STATE: /* the next block must be a header block. */ if (bd->type != HEADER_TYPE_CODE) { print_error("Invaid file format\n"); return ERROR_STATE; } if (bd->data_len != 6) { print_error("invalid data length %d for header block\n", bd->data_len); return ERROR_STATE; } if (memcmp(bd->data, "snappy", 6) != 0) { print_error("invalid file header\n"); return ERROR_STATE; } return PROCESSING_STATE; case PROCESSING_STATE: switch (bd->type) { case COMPRESSED_TYPE_CODE: if (bd->data_len <= 4) { print_error("too short data length for compressed data block\n"); return ERROR_STATE; } crc32c = ((unsigned char)bd->data[0] << 0); crc32c |= ((unsigned char)bd->data[1] << 8); crc32c |= ((unsigned char)bd->data[2] << 16); crc32c |= ((unsigned char)bd->data[3] << 24); /* uncompress and write */ outlen = work_len; if (snappy_uncompress(bd->data + 4, bd->data_len - 4, work, &outlen)) { print_error("Invalid data: RawUncompress failed\n"); return ERROR_STATE; } if (crc32c != masked_crc32c(work, outlen)) { print_error("Invalid data: CRC32c error\n"); return ERROR_STATE; } if (fwrite_unlocked(work, outlen, 1, fp) != 1) { print_error("Failed to write: %s\n", strerror(errno)); return ERROR_STATE; } break; case UNCOMPRESSED_TYPE_CODE: if (bd->data_len <= 4) { print_error("too short data length for uncompressed data block\n"); return ERROR_STATE; } crc32c = ((unsigned char)bd->data[0] << 0); crc32c |= ((unsigned char)bd->data[1] << 8); crc32c |= ((unsigned char)bd->data[2] << 16); crc32c |= ((unsigned char)bd->data[3] << 24); if (crc32c != masked_crc32c(bd->data + 4, bd->data_len - 4)) { print_error("Invalid data: CRC32c error\n"); return ERROR_STATE; } if (fwrite_unlocked(bd->data + 4, bd->data_len - 4, 1, fp) != 1) { print_error("Failed to write: %s\n", strerror(errno)); return ERROR_STATE; } break; case END_OF_STREAM_TYPE_CODE: if (bd->data_len != 0) { print_error("invalid data length for end-of-stream block\n"); return ERROR_STATE; } return END_OF_STREAM_STATE; case HEADER_TYPE_CODE: print_error("Invalid data: unexpected header\n"); return ERROR_STATE; default: if (bd->type < 0x80) { print_error("Invalid data: unknown block type %d\n", bd->type); return ERROR_STATE; } } return PROCESSING_STATE; case ERROR_STATE: ; } /* never reach here. This is added to suppress a warning */ return ERROR_STATE; }
static int framing_format_compress(FILE *infp, FILE *outfp, size_t block_size) { const size_t max_uncompressed_data_len = MAX_UNCOMPRESSED_DATA_LEN; const size_t max_compressed_data_len = snappy_max_compressed_length(max_uncompressed_data_len); size_t uncompressed_data_len; size_t compressed_data_len; char *uncompressed_data = malloc(max_uncompressed_data_len); char *compressed_data = malloc(max_compressed_data_len); int err = 1; if (uncompressed_data == NULL || compressed_data == NULL) { print_error("out of memory\n"); goto cleanup; } /* write the steam header */ fwrite_unlocked(stream_header, sizeof(stream_header), 1, outfp); /* write file body */ while ((uncompressed_data_len = fread_unlocked(uncompressed_data, 1, max_uncompressed_data_len, infp)) > 0) { unsigned int crc32c = masked_crc32c(uncompressed_data, uncompressed_data_len); char type_code; size_t write_len; const char *write_data; /* compress the block. */ compressed_data_len = max_compressed_data_len; snappy_compress(uncompressed_data, uncompressed_data_len, compressed_data, &compressed_data_len); if (compressed_data_len >= (uncompressed_data_len - (uncompressed_data_len / 8))) { /* uncompressed data */ type_code = UNCOMPRESSED_DATA_IDENTIFIER; write_len = uncompressed_data_len; write_data = uncompressed_data; } else { /* compressed data */ type_code = COMPRESSED_DATA_IDENTIFIER; write_len = compressed_data_len; write_data = compressed_data; } /* write block type */ putc_unlocked(type_code, outfp); /* write data length */ putc_unlocked(((write_len + 4) >> 0), outfp); putc_unlocked(((write_len + 4) >> 8), outfp); /* write checksum */ putc_unlocked((crc32c >> 0), outfp); putc_unlocked((crc32c >> 8), outfp); putc_unlocked((crc32c >> 16), outfp); putc_unlocked((crc32c >> 24), outfp); /* write data */ if (fwrite_unlocked(write_data, write_len, 1, outfp) != 1) { print_error("Failed to write a file: %s\n", strerror(errno)); goto cleanup; } } /* check stream errors */ if (ferror_unlocked(infp)) { print_error("Failed to read a file: %s\n", strerror(errno)); goto cleanup; } if (ferror_unlocked(outfp)) { print_error("Failed to write a file: %s\n", strerror(errno)); goto cleanup; } err = 0; cleanup: free(uncompressed_data); free(compressed_data); return err; }