Esempio n. 1
0
int zlib_test(int argc, char **argv)
{
  int zlib_test(int argc, char **argv)
    int ret;

  /* avoid end-of-line conversions */
  SET_BINARY_MODE(stdin);
  SET_BINARY_MODE(stdout);

  /* do compression if no arguments */
  if (argc == 1) {
    ret = zlib_compress(stdin, stdout, Z_DEFAULT_COMPRESSION);
    if (ret != Z_OK)
      zerr(ret);
    return ret;
  }

  /* do decompression if -d specified */
  else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
    ret = zlib_decompress(stdin, stdout);
    if (ret != Z_OK)
      zerr(ret);
    return ret;
  }

  /* otherwise, report usage */
  else {
    fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
    return 1;
  }
}
Esempio n. 2
0
int32 send_parse(int8 *buff, size_t* buffsize, sockaddr_in* from, map_session_data_t* map_session_data)
{
	// Модификация заголовка исходящего пакета
	// Суть преобразований:
	//  - отправить клиенту номер последнего полученного от него пакета
	//  - присвоить исходящему пакету номер последнего отправленного клиенту пакета +1
	//  - записать текущее время отправки пакета

	WBUFW(buff,0) = map_session_data->server_packet_id;
	WBUFW(buff,2) = map_session_data->client_packet_id;

	// сохранение текущего времени (32 BIT!)
	WBUFL(buff,8) = (uint32)time(NULL);

	//Сжимаем данные без учета заголовка
	//Возвращаемый размер в 8 раз больше реальных данных
	uint32 PacketSize = zlib_compress(buff+FFXI_HEADER_SIZE, *buffsize-FFXI_HEADER_SIZE, PTempBuff, *buffsize, zlib_compress_table);

	//Запись размера данных без учета заголовка
	WBUFL(PTempBuff,(PacketSize+7)/8) = PacketSize;

	//Расчет hash'a также без учета заголовка, но с учетом записанного выше размера данных
	PacketSize = (PacketSize+7)/8+4;
	uint8 hash[16];
	md5((uint8*)PTempBuff, hash, PacketSize);
	memcpy(PTempBuff+PacketSize, hash, 16);
	PacketSize += 16;

    if (PacketSize > map_config.buffer_size + 20)
    {
        ShowFatalError(CL_RED"%Memory manager: PTempBuff is overflowed (%u)\n" CL_RESET, PacketSize);
    }

	//making total packet
	memcpy(buff+FFXI_HEADER_SIZE, PTempBuff, PacketSize);

	uint32 CypherSize = (PacketSize/4)&-2;

	blowfish_t* pbfkey = &map_session_data->blowfish;

	for(uint32 j = 0; j < CypherSize; j += 2)
	{
		blowfish_encipher((uint32*)(buff)+j+7, (uint32*)(buff)+j+8, pbfkey->P, pbfkey->S[0]);
	}

	// контролируем размер отправляемого пакета. в случае,
	// если его размер превышает 1400 байт (размер данных + 42 байта IP заголовок),
	// то клиент игнорирует пакет и возвращает сообщение о его потере

	// в случае возникновения подобной ситуации выводим предупреждующее сообщение и
	// уменьшаем размер BuffMaxSize с шагом в 4 байта до ее устранения (вручную)

	*buffsize = PacketSize+FFXI_HEADER_SIZE;

	if (*buffsize > 1350)
	{
		ShowWarning(CL_YELLOW"send_parse: packet is very big <%u>\n" CL_RESET,*buffsize);
	}
	return 0;
}
Esempio n. 3
0
static int compress_inner(grpc_compression_algorithm algorithm,
                          grpc_slice_buffer* input, grpc_slice_buffer* output) {
  switch (algorithm) {
    case GRPC_COMPRESS_NONE:
      /* the fallback path always needs to be send uncompressed: we simply
         rely on that here */
      return 0;
    case GRPC_COMPRESS_DEFLATE:
      return zlib_compress(input, output, 0);
    case GRPC_COMPRESS_GZIP:
      return zlib_compress(input, output, 1);
    case GRPC_COMPRESS_ALGORITHMS_COUNT:
      break;
  }
  gpr_log(GPR_ERROR, "invalid compression algorithm %d", algorithm);
  return 0;
}
Esempio n. 4
0
// 对数据包进行加密和压缩
char *pkg_compress_encrypt(const packet_parser_t *pkg, const char *source, int source_len, int *cipher_body_len)
{
	char *encrypt_string;
	char *compress_string = NULL;
	uLongf compress_dest_len;

	if (source_len < 0)
	{
		source_len = strlen(source);
	}
	
	// 先对数据源进行压缩
	if (pkg->compress_hook == NULL)
	{
		zlib_compress((unsigned char **)(&compress_string), &compress_dest_len, (unsigned char *)source, source_len, 0, COMPRESS_TYPE);
	}
	else
	{
		pkg->compress_hook((unsigned char **)(&compress_string), &compress_dest_len, (unsigned char *)source, source_len, 0, COMPRESS_TYPE);
	}

	printf("source len:%d\tcompress len:%ld\n", source_len, compress_dest_len);
	// 再对数据进行加密
	if (strcmp(pkg->curr_ert.transfer_ert_type, ENCRYPT_AES_128) == 0)
	{
		if (pkg->sym_encrypt_hook == NULL)
		{
			encrypt_string = (char *)aes_encrypt((unsigned char *)compress_string, compress_dest_len, cipher_body_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_ENCRYPT);
		}
		else
		{
			encrypt_string = (char *)aes_encrypt((unsigned char *)compress_string, compress_dest_len, cipher_body_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_ENCRYPT);
		}
	}
	else if (strcmp(pkg->curr_ert.transfer_ert_type, ENCRYPT_DES3_128) == 0)
	{
		if (pkg->sym_encrypt_hook == NULL)
		{
			encrypt_string = (char *)des3_encrypt((unsigned char *)compress_string, compress_dest_len, cipher_body_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_ENCRYPT);
		}
		else
		{
			encrypt_string = (char *)pkg->sym_encrypt_hook((unsigned char *)compress_string, compress_dest_len, cipher_body_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_ENCRYPT);
		}
	}

	if (compress_string)
	{
		free(compress_string);
	}

	return encrypt_string;
}
Esempio n. 5
0
static void _bta_write_cell(FILE *fp, bta_cell_t *btac)
{
	fp_write16le(fp, btac->x);
	fp_write16le(fp, btac->y);
	fp_write16le(fp, btac->width);
	fp_write16le(fp, btac->height);
	fp_write16le(fp, btac->delay);

	btac->gfx = zlib_compress(btac->gfx);

	/* Write the compressed size */
	fp_write32le(fp, btac->gfx->size);
	xfwrite(btac->gfx->buf, sizeof(uint8_t), btac->gfx->size, fp);
}
Esempio n. 6
0
char *pkg_uncompress_decrypt(const packet_parser_t *pkg, const char *source, int source_len, int plain_body_len)
{
	char *encrypt_string;
	char *compress_string = NULL;
	int decrypt_dest_len;
	uLongf uncompress_dest_len;

	// 先对数据源进行解密
		if (strcmp(pkg->curr_ert.transfer_ert_type, ENCRYPT_AES_128) == 0)
		{
			if (pkg->sym_encrypt_hook == NULL)
			{
				encrypt_string = (char *)aes_encrypt((unsigned char *)source, source_len, &decrypt_dest_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_DECRYPT);
			}
			else
			{
				encrypt_string = (char *)pkg->sym_encrypt_hook((unsigned char *)source, source_len, &decrypt_dest_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_DECRYPT);
			}
		}
		else if (strcmp(pkg->curr_ert.transfer_ert_type, ENCRYPT_DES3_128) == 0)
		{
			if (pkg->sym_encrypt_hook == NULL)
			{
				encrypt_string = (char *)des3_encrypt((unsigned char *)source, source_len, &decrypt_dest_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_DECRYPT);
			}
			else
			{
				encrypt_string = (char *)pkg->sym_encrypt_hook((unsigned char *)source, source_len, &decrypt_dest_len, (char *)pkg->curr_ert.ert_keys[2], CRYPT_TYPE_DECRYPT);
			}
		}
	// 再对数据进行解压缩
	if (pkg->compress_hook == NULL)
	{
		zlib_compress((unsigned char **)(&compress_string), &uncompress_dest_len, (unsigned char *)encrypt_string, decrypt_dest_len, plain_body_len, UNCOMPRESS_TYPE);
	}
	else
	{
		pkg->compress_hook((unsigned char **)(&compress_string), &uncompress_dest_len, (unsigned char *)encrypt_string, decrypt_dest_len, plain_body_len, UNCOMPRESS_TYPE);
	}

	if (encrypt_string)
	{
		free(encrypt_string);
	}

	return compress_string;
}
Esempio n. 7
0
int main(int argc, char **argv)
{
	FILE **infiles;
	FILE *outfile;
	
	if (argc == 1 || argc == 2) {
		usage();
		return(EXIT_FAILURE);
	}
	
	if (!strcmp(argv[1], "-d")) { // Decompress
		infiles = calloc(1, sizeof(FILE*));
		if (argc != 4) {
			usage();
			return(EXIT_FAILURE);
		} 
		infiles[0] = fopen(argv[2], "rb");
		if (infiles[0] == NULL) {
			fprintf(stderr, "Error. Cannot open input file %s", argv[2]);
			return(EXIT_FAILURE);
		}
		outfile = fopen(argv[3], "wb");
		if (outfile == NULL) {
			fprintf(stderr, "Error. Cannot open output file %s", argv[3]);
			return(EXIT_FAILURE);
		}
		return zlib_decompress(infiles[0], outfile);

	} else { // Compress

		infiles = calloc(argc-2, sizeof(FILE*));
		for (uint16_t i = 0; i < argc-2; i++) { 
			infiles[i] = fopen(argv[i+1], "rb");
			if (infiles[i] == NULL) {
				fprintf(stderr, "Error. Cannot open input file %s", argv[i+1]);
				return(EXIT_FAILURE);
			}
		}
		outfile = fopen(argv[argc-1], "wb");
		if (outfile == NULL) {
			fprintf(stderr, "Error. Cannot open output file %s", argv[argc-1]);
			return(EXIT_FAILURE);
		}
		return zlib_compress(infiles, argc-2, outfile);
	}
}
Esempio n. 8
0
CGOGN_IO_API void write_binary_xml_data(std::ostream& output, const char* data_str, std::size_t size, bool compress)
{
	std::vector<char> data;
	std::vector<uint32> header;
	if (!compress)
	{
		header.push_back(static_cast<uint32>(size));
		data.resize(sizeof(uint32) + size);

		std::memcpy(&data[0], reinterpret_cast<const char*>(&header[0]), sizeof(uint32)* header.size());
		std::memcpy(&data[sizeof(uint32)], data_str, size);
	} else {
		const std::size_t uncompressed_chunk_size = std::min(size, std::size_t(1048576));
		const std::vector<std::vector<unsigned char>>& compressed_blocks = zlib_compress(reinterpret_cast<const unsigned char*>(data_str), size, uncompressed_chunk_size);
		std::size_t compressed_size{0ul};
		const std::size_t last_block_size = (compressed_blocks.size() == 1ul) ? uncompressed_chunk_size : size % uncompressed_chunk_size;

		header.push_back(static_cast<uint32>(compressed_blocks.size()));
		header.push_back(static_cast<uint32>(uncompressed_chunk_size));
		header.push_back(static_cast<uint32>(last_block_size));
		for (const auto& block : compressed_blocks)
		{
			header.push_back(static_cast<uint32>(block.size()));
			compressed_size += block.size();
		}

		const auto& encoded_header = base64_encode(reinterpret_cast<char*>(&header[0]), header.size() * sizeof(uint32));
		output.write(&encoded_header[0], encoded_header.size());

		data.resize(compressed_size);
		char* data_ptr = &data[0];
		for (const auto& block : compressed_blocks)
		{
			const char* src = reinterpret_cast<const char*>(&block[0]);
			std::memcpy(data_ptr, src, block.size());
			data_ptr += block.size();
		}
	}

	const auto& encoded_data = base64_encode(&data[0], data.size());
	output.write(&encoded_data[0], encoded_data.size());
}
Esempio n. 9
0
File: compr.c Progetto: nhanh0/hah
/* jffs2_compress:
 * @data: Pointer to uncompressed data
 * @cdata: Pointer to buffer for compressed data
 * @datalen: On entry, holds the amount of data available for compression.
 *	On exit, expected to hold the amount of data actually compressed.
 * @cdatalen: On entry, holds the amount of space available for compressed
 *	data. On exit, expected to hold the actual size of the compressed
 *	data.
 *
 * Returns: Byte to be stored with data indicating compression type used.
 * Zero is used to show that the data could not be compressed - the 
 * compressed version was actually larger than the original.
 *
 * If the cdata buffer isn't large enough to hold all the uncompressed data,
 * jffs2_compress should compress as much as will fit, and should set 
 * *datalen accordingly to show the amount of data which were compressed.
 */
unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out, 
		    __u32 *datalen, __u32 *cdatalen)
{
	int ret;

	ret = zlib_compress(data_in, cpage_out, datalen, cdatalen);
	if (!ret) {
		return JFFS2_COMPR_ZLIB;
	}
#if 0 /* Disabled 23/9/1. With zlib it hardly ever gets a look in */
	ret = dynrubin_compress(data_in, cpage_out, datalen, cdatalen);
	if (!ret) {
		return JFFS2_COMPR_DYNRUBIN;
	}
#endif
#if 0 /* Disabled 26/2/1. Obsoleted by dynrubin */
	ret = rubinmips_compress(data_in, cpage_out, datalen, cdatalen);
	if (!ret) {
		return JFFS2_COMPR_RUBINMIPS;
	}
#endif
	/* rtime does manage to recompress already-compressed data */
	ret = rtime_compress(data_in, cpage_out, datalen, cdatalen);
	if (!ret) {
		return JFFS2_COMPR_RTIME;
	}
#if 0
	/* We don't need to copy. Let the caller special-case the COMPR_NONE case. */
	/* If we get here, no compression is going to work */
	/* But we might want to use the fragmentation part -- Arjan */
	memcpy(cpage_out,data_in,min(*datalen,*cdatalen));
	if (*datalen > *cdatalen)
		*datalen = *cdatalen;
#endif		
	return JFFS2_COMPR_NONE; /* We failed to compress */

}
Esempio n. 10
0
static void on_msg_recv_cb(wslay_event_context_ptr ev,
                           const struct wslay_event_on_msg_recv_arg *arg,
                           void *user_data)
{
    struct transaction_t *txn = (struct transaction_t *) user_data;
    struct ws_context *ctx = (struct ws_context *) txn->ws_ctx;
    struct buf inbuf = BUF_INITIALIZER, outbuf = BUF_INITIALIZER;
    struct wslay_event_msg msgarg = { arg->opcode, NULL, 0 };
    uint8_t rsv = WSLAY_RSV_NONE;
    double cmdtime, nettime;
    const char *err_msg;
    int r, err_code = 0;

    /* Place client request into a buf */
    buf_init_ro(&inbuf, (const char *) arg->msg, arg->msg_length);

    /* Decompress request, if necessary */
    if (wslay_get_rsv1(arg->rsv)) {
        /* Add trailing 4 bytes */
        buf_appendmap(&inbuf, "\x00\x00\xff\xff", 4);

        r = zlib_decompress(txn, buf_base(&inbuf), buf_len(&inbuf));
        if (r) {
            syslog(LOG_ERR, "on_msg_recv_cb(): zlib_decompress() failed");

            err_code = WSLAY_CODE_PROTOCOL_ERROR;
            err_msg = DECOMP_FAILED_ERR;
            goto err;
        }

        buf_move(&inbuf, &txn->zbuf);
    }

    /* Log the uncompressed client request */
    buf_truncate(&ctx->log, ctx->log_tail);
    buf_appendcstr(&ctx->log, " (");
    if (txn->strm_ctx) {
        buf_printf(&ctx->log, "stream-id=%d; ",
                   http2_get_streamid(txn->strm_ctx));
    }
    buf_printf(&ctx->log, "opcode=%s; rsv=0x%x; length=%ld",
               wslay_str_opcode(arg->opcode), arg->rsv, arg->msg_length);

    switch (arg->opcode) {
    case WSLAY_CONNECTION_CLOSE:
        buf_printf(&ctx->log, "; status=%d; msg='%s'", arg->status_code,
                   buf_len(&inbuf) ? buf_cstring(&inbuf)+2 : "");
        txn->flags.conn = CONN_CLOSE;
        break;

    case WSLAY_TEXT_FRAME:
    case WSLAY_BINARY_FRAME:
        if (txn->conn->logfd != -1) {
            /* Telemetry logging */
            struct iovec iov[2];
            int niov = 0;

            assert(!buf_len(&txn->buf));
            buf_printf(&txn->buf, "<%ld<", time(NULL));  /* timestamp */
            WRITEV_ADD_TO_IOVEC(iov, niov,
                                buf_base(&txn->buf), buf_len(&txn->buf));
            WRITEV_ADD_TO_IOVEC(iov, niov, buf_base(&inbuf), buf_len(&inbuf));
            writev(txn->conn->logfd, iov, niov);
            buf_reset(&txn->buf);
        }

        /* Process the request */
        r = ctx->data_cb(&inbuf, &outbuf, &ctx->log, &ctx->cb_rock);
        if (r) {

            err_code = (r == HTTP_SERVER_ERROR ?
                        WSLAY_CODE_INTERNAL_SERVER_ERROR :
                        WSLAY_CODE_INVALID_FRAME_PAYLOAD_DATA);
            err_msg = error_message(r);
            goto err;
        }

        if (txn->conn->logfd != -1) {
            /* Telemetry logging */
            struct iovec iov[2];
            int niov = 0;

            assert(!buf_len(&txn->buf));
            buf_printf(&txn->buf, ">%ld>", time(NULL));  /* timestamp */
            WRITEV_ADD_TO_IOVEC(iov, niov,
                                buf_base(&txn->buf), buf_len(&txn->buf));
            WRITEV_ADD_TO_IOVEC(iov, niov, buf_base(&outbuf), buf_len(&outbuf));
            writev(txn->conn->logfd, iov, niov);
            buf_reset(&txn->buf);
        }

        /* Compress the server response, if supported by the client */
        if (ctx->ext & EXT_PMCE_DEFLATE) {
            r = zlib_compress(txn,
                              ctx->pmce.deflate.no_context ? COMPRESS_START : 0,
                              buf_base(&outbuf), buf_len(&outbuf));
            if (r) {
                syslog(LOG_ERR, "on_msg_recv_cb(): zlib_compress() failed");

                err_code = WSLAY_CODE_INTERNAL_SERVER_ERROR;
                err_msg = COMP_FAILED_ERR;
                goto err;
            }

            /* Trim the trailing 4 bytes */
            buf_truncate(&txn->zbuf, buf_len(&txn->zbuf) - 4);
            buf_move(&outbuf, &txn->zbuf);

            rsv |= WSLAY_RSV1_BIT;
        }

        /* Queue the server response */
        msgarg.msg = (const uint8_t *) buf_base(&outbuf);
        msgarg.msg_length = buf_len(&outbuf);
        wslay_event_queue_msg_ex(ev, &msgarg, rsv);

        /* Log the server response */
        buf_printf(&ctx->log,
                   ") => \"Success\" (opcode=%s; rsv=0x%x; length=%ld",
                   wslay_str_opcode(msgarg.opcode), rsv, msgarg.msg_length);
        break;
    }

  err:
    if (err_code) {
        size_t err_msg_len = strlen(err_msg);

        syslog(LOG_DEBUG, "wslay_event_queue_close()");
        wslay_event_queue_close(ev, err_code, (uint8_t *) err_msg, err_msg_len);

        /* Log the server response */
        buf_printf(&ctx->log,
                   ") => \"Fail\" (opcode=%s; rsv=0x%x; length=%ld"
                   "; status=%d; msg='%s'",
                   wslay_str_opcode(WSLAY_CONNECTION_CLOSE), rsv, err_msg_len,
                   err_code, err_msg);
    }

    /* Add timing stats */
    cmdtime_endtimer(&cmdtime, &nettime);
    buf_printf(&ctx->log, ") [timing: cmd=%f net=%f total=%f]",
               cmdtime, nettime, cmdtime + nettime);

    syslog(LOG_INFO, "%s", buf_cstring(&ctx->log));

    buf_free(&inbuf);
    buf_free(&outbuf);
}
Esempio n. 11
0
int main(int argc, char **argv)
{
	FILE **infiles;
	char **infile_names;
	FILE *outfile;
	
	if (argc == 1 || argc == 2) {
		usage();
		return(EXIT_FAILURE);
	}
	
	if (!strcmp(argv[1], "-d")) { // Decompress

		infiles = calloc(1, sizeof(FILE*));
		if (argc != 4) {
			usage();
			return(EXIT_FAILURE);
		} 
		infiles[0] = fopen(argv[2], "rb");
		if (infiles[0] == NULL) {
			fprintf(stderr, "Error. Cannot open input file %s\n\n", argv[2]);
			return(EXIT_FAILURE);
		}
		outfile = fopen(argv[3], "wb");
		if (outfile == NULL) {
			fprintf(stderr, "Error. Cannot open output file %s\n\n", argv[3]);
			return(EXIT_FAILURE);
		}
		return zlib_decompress(infiles[0], outfile);

	} else { // Compress or gemerate version info

		bool hardnested_mode = false;
		bool generate_version_file = false;
		int num_input_files = 0;
		if (!strcmp(argv[1], "-t")) { 			// compress one hardnested table
			if (argc != 4) {
				usage();
				return(EXIT_FAILURE);
			}
			hardnested_mode = true;
			num_input_files = 1;
		} else if (!strcmp(argv[1], "-v")) { 	// generate version info
			generate_version_file = true;
			num_input_files = argc-3;
		} else { 								// compress 1..n fpga files
			num_input_files = argc-2;
		}
			
		infiles = calloc(num_input_files, sizeof(FILE*));
		infile_names = calloc(num_input_files, sizeof(char*));
		for (uint16_t i = 0; i < num_input_files; i++) {
			infile_names[i] = argv[i+((hardnested_mode || generate_version_file)?2:1)];
			infiles[i] = fopen(infile_names[i], "rb");
			if (infiles[i] == NULL) {
				fprintf(stderr, "Error. Cannot open input file %s\n\n", infile_names[i]);
				return(EXIT_FAILURE);
			}
		}
		outfile = fopen(argv[argc-1], "wb");
		if (outfile == NULL) {
			fprintf(stderr, "Error. Cannot open output file %s\n\n", argv[argc-1]);
			return(EXIT_FAILURE);
		}
		if (generate_version_file) {
			if (generate_fpga_version_info(infiles, infile_names, num_input_files, outfile)) {
				return(EXIT_FAILURE);
			}
		} else {
			return zlib_compress(infiles, num_input_files, outfile, hardnested_mode);
		}
	}
}
Esempio n. 12
0
int32 send_parse(int8 *buff, size_t* buffsize, sockaddr_in* from, map_session_data_t* map_session_data)
{
    // Модификация заголовка исходящего пакета
    // Суть преобразований:
    //  - отправить клиенту номер последнего полученного от него пакета
    //  - присвоить исходящему пакету номер последнего отправленного клиенту пакета +1
    //  - записать текущее время отправки пакета

    WBUFW(buff, 0) = map_session_data->server_packet_id;
    WBUFW(buff, 2) = map_session_data->client_packet_id;

    // сохранение текущего времени (32 BIT!)
    WBUFL(buff, 8) = (uint32)time(nullptr);

    // собираем большой пакет, состоящий из нескольких маленьких
    CCharEntity *PChar = map_session_data->PChar;
    CBasicPacket* PSmallPacket;
    uint32 PacketSize = UINT32_MAX;
    uint32 PacketCount = PChar->getPacketCount();
    uint8 packets = 0;

    while (PacketSize > 1300 - FFXI_HEADER_SIZE - 16) //max size for client to accept
    {
        *buffsize = FFXI_HEADER_SIZE;
        PacketList_t packetList = PChar->getPacketList();
        packets = 0;

        while (!packetList.empty() && *buffsize + packetList.front()->length() < map_config.buffer_size &&
            packets < PacketCount)
        {
            PSmallPacket = packetList.front();

            PSmallPacket->sequence(map_session_data->server_packet_id);
            memcpy(buff + *buffsize, *PSmallPacket, PSmallPacket->length());

            *buffsize += PSmallPacket->length();
            packetList.pop_front();
            packets++;
        }
        //Сжимаем данные без учета заголовка
        //Возвращаемый размер в 8 раз больше реальных данных
        PacketSize = zlib_compress(buff + FFXI_HEADER_SIZE, *buffsize - FFXI_HEADER_SIZE, PTempBuff, *buffsize, zlib_compress_table);
        WBUFL(PTempBuff, (PacketSize + 7) / 8) = PacketSize;

        PacketSize = (PacketSize + 7) / 8 + 4;

        PacketCount /= 2;
    }
    PChar->erasePackets(packets);

    //Запись размера данных без учета заголовка
    uint8 hash[16];
    md5((uint8*)PTempBuff, hash, PacketSize);
    memcpy(PTempBuff + PacketSize, hash, 16);
    PacketSize += 16;

    if (PacketSize > map_config.buffer_size + 20)
    {
        ShowFatalError(CL_RED"%Memory manager: PTempBuff is overflowed (%u)\n" CL_RESET, PacketSize);
    }

    //making total packet
    memcpy(buff + FFXI_HEADER_SIZE, PTempBuff, PacketSize);

    uint32 CypherSize = (PacketSize / 4)&-2;

    blowfish_t* pbfkey = &map_session_data->blowfish;

    for (uint32 j = 0; j < CypherSize; j += 2)
    {
        blowfish_encipher((uint32*)(buff)+j + 7, (uint32*)(buff)+j + 8, pbfkey->P, pbfkey->S[0]);
    }

    // контролируем размер отправляемого пакета. в случае,
    // если его размер превышает 1400 байт (размер данных + 42 байта IP заголовок),
    // то клиент игнорирует пакет и возвращает сообщение о его потере

    // в случае возникновения подобной ситуации выводим предупреждующее сообщение и
    // уменьшаем размер BuffMaxSize с шагом в 4 байта до ее устранения (вручную)

    *buffsize = PacketSize + FFXI_HEADER_SIZE;

    return 0;
}
Esempio n. 13
0
// returns the length of the packed data
// TBH, I really can't be stuffed writing a buffered copy/compress/decompressor
//
// (and anyway, it may not work with future compression routines, so meh)
uint32_t
rco_write_resource (FILE * dest, rRCOEntry * entry, uint32_t destCompression,
    writerco_options * opts, rRCOFile * rco)
{

  uint32_t len = 0;
  uint8_t *bufferMid = (uint8_t *) read_resource (entry, &len);

  if (!bufferMid) {
    if (entry->labelOffset)
      warning ("Failed to read resource '%s'.",
	  rco->labels + entry->labelOffset);
    return 0;
  }

  if (len != entry->srcLenUnpacked) {
    free (bufferMid);
    return 0;
  }

  uint8_t *bufferOut;
  uint32_t packedSize = 0;

  if (destCompression == RCO_DATA_COMPRESSION_ZLIB) {
    uint32_t compSize = compressBound (entry->srcLenUnpacked);

    bufferOut = (uint8_t *) malloc (compSize);
    packedSize =
	zlib_compress (bufferMid, entry->srcLenUnpacked, bufferOut, compSize,
	opts->zlibLevel, opts->zlibMethod);
    if (!packedSize) {
      if (entry->labelOffset)
	warning ("Failed to compress resource '%s'.",
	    rco->labels + entry->labelOffset);
      return 0;
    }

    free (bufferMid);
  } else if (destCompression == RCO_DATA_COMPRESSION_RLZ) {
#ifdef DISABLE_RLZ
    error ("RLZ compression not supported.");
    exit (1);
#endif
    bufferOut = (uint8_t *) malloc (entry->srcLenUnpacked);
    packedSize =
	rlz_compress (bufferMid, entry->srcLenUnpacked, bufferOut,
	entry->srcLenUnpacked, opts->rlzMode);
    if (!packedSize) {
      if (entry->labelOffset)
	warning ("Failed to compress resource '%s'.",
	    rco->labels + entry->labelOffset);
      return 0;
    }

    free (bufferMid);
  } else {
    bufferOut = bufferMid;
    packedSize = entry->srcLenUnpacked;
  }

  filewrite (dest, bufferOut, packedSize);
  free (bufferOut);

  /*
   * char buffer[65536], outBuffer[65536]; uint32_t len=entry->srcLen; z_stream
   * out; if(destStream == RCO_DATA_COMPRESSION_ZLIB) { ZLIB_INIT_DEFLATE(out,
   * 9, Z_DEFAULT_STRATEGY); out.next_in = buffer; out.avail_in = 65536;
   * out.next_out = outBuffer; out.avail_out = 65536; }
   *
   * // copy with buffer while(len) { uint32_t readAmt = (len < 65536 ? len :
   * 65536); if(!fileread(src, &buffer, readAmt)) { fclose(src); return FALSE;
   * }
   *
   * if(destCompression == RCO_DATA_COMPRESSION_NONE) filewrite(dest, &buffer,
   * readAmt); else if(destCompression == RCO_DATA_COMPRESSION_ZLIB) {
   *
   * }
   *
   * len -= readAmt; }
   *
   * // TOxDO: also don't forget to check lenUnpacked
   *
   * fclose(src);
   *
   * if(destStream == RCO_DATA_COMPRESSION_ZLIB) deflateEnd(&out); */

  // 4byte alignment
  if (packedSize % 4) {
    uint32_t zero = 0;

    filewrite (dest, &zero, 4 - (packedSize % 4));
  }

  return packedSize;
}
Esempio n. 14
0
lzo_bool x_compress(file_t *fip, file_t *fop, header_t *h)
{
    lzo_bool ok = 0;

    init_compress_header(h,fip,fop);
    switch (h->method)
    {
#if defined(WITH_LZO)
    case M_LZO1X_1:
    case M_LZO1X_1_15:
    case M_LZO1X_999:
        lzo_init_compress_header(h);
        break;
#endif
#if defined(WITH_NRV)
    case M_NRV1A:
    case M_NRV1B:
    case M_NRV2A:
    case M_NRV2B:
        nrv_init_compress_header(h);
        break;
#endif
#if defined(WITH_ZLIB)
    case M_ZLIB:
        zlib_init_compress_header(h);
        break;
#endif
    default:
        fatal(fip,"Internal error");
        break;
    }

    if (!x_enter(h))
        e_memory();

    if (opt_verbose > 1)
    {
        if (opt_unlink)
            fprintf(con_term,"replacing %s with %s", fip->name, fop->name);
        else
            fprintf(con_term,"compressing %s into %s", fip->name, fop->name);
        fflush(con_term);
        set_err_nl(1);
    }

    write_header(fop,h);

    fip->bytes_processed = fop->bytes_processed = 0;

    switch (h->method)
    {
#if defined(WITH_LZO)
    case M_LZO1X_1:
    case M_LZO1X_1_15:
    case M_LZO1X_999:
        ok = lzo_compress(fip,fop,h);
        break;
#endif
#if defined(WITH_NRV)
    case M_NRV1A:
    case M_NRV1B:
    case M_NRV2A:
    case M_NRV2B:
        ok = nrv_compress(fip,fop,h);
        break;
#endif
#if defined(WITH_ZLIB)
    case M_ZLIB:
        ok = zlib_compress(fip,fop,h);
        break;
#endif
    default:
        fatal(fip,"Internal error");
        ok = 0;
        break;
    }

    if (opt_cmd == CMD_COMPRESS && opt_verbose > 1)
    {
        fprintf(con_term, ok ? "\n" : " FAILED\n");
        fflush(con_term);
    }
    set_err_nl(0);

    x_leave(h);
    return ok;
}
Esempio n. 15
0
// packing: use RCO_DATA_COMPRESSION_* constants
uint8_t
write_rco (rRCOFile * rco, char *fn, writerco_options opts)
{
  uint32_t i;
  rRCOFile_writehelper rcoH;

  // delete file if exists
  if (file_exists (fn)) {
    if (remove (fn)) {
      error ("Unable to write to file %s", fn);
      return FALSE;
    }
  }

  rcoH.rco = rco;
  rcoH.fp = fopen (fn, "wb");
  if (!rcoH.fp) {
    error ("Unable to open file %s", fn);
    return FALSE;
  }

  PRFHeader header;

  header.signature = RCO_SIGNATURE;
  header.version =
      (opts.packHeader == RCO_DATA_COMPRESSION_RLZ ? 0x95 : opts.packHeader ==
      RCO_DATA_COMPRESSION_ZLIB ? 0x90 : 0x71);
  if (rco->verId) {		// we won't actually use specified value,
    // rather, we'll require using the minimum
    // version from above
    if (rco->verId > header.version)
      header.version = rco->verId;
  }
  header.null = 0;
  header.compression = (opts.packHeader << 4) | (rco->umdFlag & 0xF);

  header.pMainTable = 0xA4;	// pretty much always the case
  // set other sections to nothing for now
  header.pVSMXTable = header.pTextTable = header.pSoundTable =
      header.pModelTable = header.pImgTable = header.pObjTable =
      header.pAnimTable = RCO_NULL_PTR;
  header.pUnknown = header.pFontTable = RCO_NULL_PTR;

  // don't know positions of text/label/event data too, but we do know the
  // lengths for label/events
  // header.pTextData = header.pLabelData = header.pEventData = 0;
  header.lLabelData = rco->labelsLen;
  header.lEventData = rco->eventsLen;
  header.lTextData = 0;

  // set pointer sections to blank too
  header.pTextPtrs = header.pImgPtrs = header.pModelPtrs = header.pSoundPtrs =
      header.pObjPtrs = header.pAnimPtrs = RCO_NULL_PTR;

  header.lTextPtrs = header.lImgPtrs = header.lModelPtrs = header.lSoundPtrs =
      header.lObjPtrs = header.lAnimPtrs = 0;

  // also blank...
  header.pImgData = header.pSoundData = header.pModelData = RCO_NULL_PTR;
  header.lImgData = header.lSoundData = header.lModelData = 0;

  header.unknown[0] = header.unknown[1] = header.unknown[2] = 0xFFFFFFFF;

  // write resources to a separate file to get around the issue of unknown
  // packed size when writing the header (and you can't change it backed after
  // the header is packed...)
  FILE *fTmp = NULL;

  if ((rco->tblImage && rco->tblImage->numSubentries)
      || (rco->tblSound && rco->tblSound->numSubentries)
      || (rco->tblModel && rco->tblModel->numSubentries)) {
    uint32_t totalPackedLen = 0;
    rRCOEntry *rcoNode;

    fTmp = tmpfile ();

    if (rco->tblImage && rco->tblImage->numSubentries) {
      for (rcoNode = rco->tblImage->firstChild; rcoNode;
	  rcoNode = rcoNode->next) {
	// our compression decision thing
	uint32_t c = ((rRCOImgModelEntry *) (rcoNode->extra))->compression;

	if (((rRCOImgModelEntry *) (rcoNode->extra))->format < RCO_IMG_BMP) {
	  if (opts.packImgCompr != -1)
	    c = opts.packImgCompr;
	} else {
	  if (opts.packImg != -1)
	    c = opts.packImg;
	}

	if (rcoNode->srcLenUnpacked) {
	  rcoNode->srcLen = rco_write_resource (fTmp, rcoNode, c, &opts, rco);
	  if (!rcoNode->srcLen && rcoNode->labelOffset != RCO_NULL_PTR)
	    warning ("[resource] Can't write image resource '%s'!",
		rco->labels + rcoNode->labelOffset);
	}
	rcoNode->srcCompression = c;
	rcoNode->srcAddr = totalPackedLen;

	totalPackedLen +=
	    (rcoNode->srcLen % 4 ? (rcoNode->srcLen / 4) * 4 +
	    4 : rcoNode->srcLen);
      }
      header.lImgData = totalPackedLen;
    }

    totalPackedLen = 0;
    if (rco->tblSound && rco->tblSound->numSubentries) {
      for (rcoNode = rco->tblSound->firstChild; rcoNode;
	  rcoNode = rcoNode->next) {
	if (rcoNode->srcLenUnpacked) {
	  uint32_t packedLen = rco_write_resource (fTmp, rcoNode,
	      RCO_DATA_COMPRESSION_NONE,
	      &opts,
	      rco);

	  if (!packedLen && rcoNode->labelOffset != RCO_NULL_PTR)
	    warning ("[resource] Can't write sound resource '%s'!",
		rco->labels + rcoNode->labelOffset);
	  totalPackedLen += ALIGN_TO_4 (packedLen);
	  // if(totalPackedLen %4) totalPackedLen += 4-(totalPackedLen%4);
	}
      }
      header.lSoundData = totalPackedLen;
    }

    totalPackedLen = 0;
    if (rco->tblModel && rco->tblModel->numSubentries) {
      for (rcoNode = rco->tblModel->firstChild; rcoNode;
	  rcoNode = rcoNode->next) {
	uint32_t c = ((rRCOImgModelEntry *) (rcoNode->extra))->compression;

	if (opts.packModel != -1)
	  c = opts.packModel;

	if (rcoNode->srcLenUnpacked) {
	  rcoNode->srcLen = rco_write_resource (fTmp, rcoNode, c, &opts, rco);
	  if (!rcoNode->srcLen && rcoNode->labelOffset != RCO_NULL_PTR)
	    warning ("[resource] Can't write model resource '%s'!",
		rco->labels + rcoNode->labelOffset);
	}
	rcoNode->srcCompression = c;
	rcoNode->srcAddr = totalPackedLen;

	totalPackedLen +=
	    (rcoNode->srcLen % 4 ? (rcoNode->srcLen / 4) * 4 +
	    4 : rcoNode->srcLen);
      }
      header.lModelData = totalPackedLen;
    }

    rewind (fTmp);
  }

  filewrite (rcoH.fp, &header, sizeof (header));

  rcoH.tables = 0;

  // if compressing, write to memory
  if (opts.packHeader) {
    rcoH.tables = malloc (RCO_WRITE_MEM_BUFFER);
    rcoH.memPos = rcoH.tablesSize = 0;
    rcoH.tablesBuffered = RCO_WRITE_MEM_BUFFER;
    rcoH.memOffset = ftell (rcoH.fp);
  }

  rcoH.sizeImg = rcoH.sizeModel = rcoH.sizeSound = rcoH.sizeText = 0;
  rcoH.longestLangData = 0;

  write_entry (&rcoH, &(rco->tblMain), 0xA4	/* typically where the main
						 * table is written to */ , 0,
      TRUE);

  // fix up object/anim extra data
  {
    if (rco->tblObj)
      rco_write_fix_refs (rco->tblObj, &rcoH, rco, RCO_OBJ_EXTRA_LEN,
	  RCO_OBJ_EXTRA_LEN_NUM, TRUE);
    if (rco->tblAnim)
      rco_write_fix_refs (rco->tblAnim, &rcoH, rco, RCO_ANIM_EXTRA_LEN,
	  RCO_ANIM_EXTRA_LEN_NUM, FALSE);
  }

  {				// write hashtable data

    /* { // special case for text hashes if(rco->numPtrText) { header.pTextPtrs
     * = rcowrite_ftell(&rcoH); for(i=0; i<rco->numPtrText; i++) { uint32_t
     * writePtr = 0; if(rco->ptrText[i].textEntry && rco->ptrText[i].index)
     * writePtr = rco->ptrText[i].textEntry->offset + sizeof(RCOEntry) +
     * sizeof(RCOTextEntry) + (rco->ptrText[i].index -
     * ((rRCOTextEntry*)(rco->ptrText[i].textEntry->extra))->indexes)*sizeof(RCOTextIndex);
     * rco_fwrite(&rcoH, &writePtr, sizeof(uint32_t)); } } } */
    if (rco->tblText) {
      header.pTextPtrs = rcowrite_ftell (&rcoH);
      header.lTextPtrs = 0;

      // generate sorted list of text entries, sorted by languageID
      rRCOEntry **sList = make_sorted_list_of_subentries (rco->tblText,
	  text_hash_table_qsort);

      for (i = 0; i < rco->tblText->numSubentries; i++)
	header.lTextPtrs += write_text_hash_table (&rcoH, sList[i], rco);
      free (sList);

      header.lTextPtrs *= sizeof (uint32_t);
    }

    if (rco->tblImage) {
      header.pImgPtrs = rcowrite_ftell (&rcoH);
      header.lImgPtrs =
	  write_hash_table (&rcoH, rco->tblImage, rco) * sizeof (uint32_t);
    }
    if (rco->tblModel) {
      header.pModelPtrs = rcowrite_ftell (&rcoH);
      header.lModelPtrs =
	  write_hash_table (&rcoH, rco->tblModel, rco) * sizeof (uint32_t);
    }
    if (rco->tblSound) {
      header.pSoundPtrs = rcowrite_ftell (&rcoH);
      header.lSoundPtrs =
	  write_hash_table (&rcoH, rco->tblSound, rco) * sizeof (uint32_t);
    }
    if (rco->tblObj) {
      header.pObjPtrs = rcowrite_ftell (&rcoH);
      header.lObjPtrs =
	  write_hash_table (&rcoH, rco->tblObj, rco) * sizeof (uint32_t);
    }
    if (rco->tblAnim) {
      header.pAnimPtrs = rcowrite_ftell (&rcoH);
      header.lAnimPtrs =
	  write_hash_table (&rcoH, rco->tblAnim, rco) * sizeof (uint32_t);
    }
    /*
     * #define RCO_WRITERCO_WRITE_PTR_SECT(pd, pl, hp) { \ if(pl) { \ hp =
     * rcowrite_ftell(&rcoH); \ for(i=0; i<pl; i++) { \ if(pd[i]) \
     * rco_fwrite(&rcoH, &(((rRCOEntry*)(pd[i]))->offset), sizeof(uint32_t)); \
     * else { \ uint32_t zero = 0; \ rco_fwrite(&rcoH, &zero, sizeof(uint32_t)); \
     * } \ } \ } \ } //RCO_WRITERCO_WRITE_PTR_SECT(rco->ptrText,
     * rco->numPtrText, header.pTextPtrs);
     * RCO_WRITERCO_WRITE_PTR_SECT(rco->ptrImg, rco->numPtrImg,
     * header.pImgPtrs); RCO_WRITERCO_WRITE_PTR_SECT(rco->ptrModel,
     * rco->numPtrModel, header.pModelPtrs);
     * RCO_WRITERCO_WRITE_PTR_SECT(rco->ptrSound, rco->numPtrSound,
     * header.pSoundPtrs); RCO_WRITERCO_WRITE_PTR_SECT(rco->ptrObj,
     * rco->numPtrObj, header.pObjPtrs);
     * RCO_WRITERCO_WRITE_PTR_SECT(rco->ptrAnim, rco->numPtrAnim,
     * header.pAnimPtrs); */
  }

  {				// write label/event data (and text if
    // applicable)

    // write text (note, old behaviour - newer RCOs have text written in a
    // different location)
    if (!opts.packText && rco->tblText && rco->tblText->numSubentries) {
      rRCOEntry *rcoNode;

      header.pTextData = rcowrite_ftell (&rcoH);
      header.lTextData = rcoH.sizeText;
      for (rcoNode = rco->tblText->firstChild; rcoNode; rcoNode = rcoNode->next) {
	rco_write_text_resource (&rcoH, rcoNode, RCO_DATA_COMPRESSION_NONE,
	    &opts, ((rRCOTextEntry *) (rcoNode->extra))->lang,
	    (rco->tblText->lastChild == rcoNode));
      }
    }
    // write label+event data
    header.pLabelData = rcowrite_ftell (&rcoH);
    if (rco->labelsLen)
      rco_fwrite (&rcoH, rco->labels, rco->labelsLen);
    header.pEventData = rcowrite_ftell (&rcoH);
    if (rco->eventsLen)
      rco_fwrite (&rcoH, rco->events, rco->eventsLen);
    else if (rco->tblObj || rco->tblAnim) {	// weird case: if there's
      // object entries, there will
      // be 4 bytes for events; I'll
      // assume this covers anim as
      // well (although there isn't
      // an RCO with anim that
      // doesn't have objects)
      uint32_t zero = 0;

      rco_fwrite (&rcoH, &zero, sizeof (zero));
      header.lEventData = sizeof (zero);
    }
    // the text pointer is weird in that if there's no text, it's set equal to
    // the label pointer; even weirder, some RCOs have a null pointer (for
    // FW5.00 all except lftv_* RCOs have null pointers for pTextData if
    // there's no text)
    // my theory: if compressing, it will be RCO_NULL_PTR, otherwise it'll =
    // header.pLabelData
    // if(!header.lTextData) header.pTextData = RCO_NULL_PTR;
    // if(!header.lTextData) header.pTextData = header.pLabelData;
    if (!header.lTextData)
      header.pTextData = (opts.packHeader ? RCO_NULL_PTR : header.pLabelData);
  }

  // flush compression stuff here
  HeaderComprInfo ci;

  if (opts.packHeader) {
    uint8_t *bufferOut = NULL;

    ci.lenLongestText = rcoH.longestLangData;
    ci.lenUnpacked = rcoH.tablesSize;
    ci.lenPacked = 0;

    if (opts.packHeader == RCO_DATA_COMPRESSION_ZLIB) {
      uint32_t bound = compressBound (rcoH.tablesSize);

      bufferOut = (uint8_t *) malloc (bound);
      ci.lenPacked =
	  zlib_compress (rcoH.tables, rcoH.tablesSize, bufferOut, bound,
	  opts.zlibLevel, opts.zlibMethod);
    } else if (opts.packHeader == RCO_DATA_COMPRESSION_RLZ) {
      bufferOut = (uint8_t *) malloc (rcoH.tablesSize);
      ci.lenPacked =
	  rlz_compress (rcoH.tables, rcoH.tablesSize, bufferOut,
	  rcoH.tablesSize, opts.rlzMode);
    } else {
      error ("lulwut?");
      exit (1);
    }
    int comprMisalign = ci.lenPacked % 4;
    uint32_t packedLen = ci.lenPacked;

    if (rco->eSwap)
      es_headerComprInfo (&ci);
    filewrite (rcoH.fp, &ci, sizeof (ci));
    filewrite (rcoH.fp, bufferOut, packedLen);
    free (bufferOut);

    if (comprMisalign) {	// 4 byte align
      uint32_t zero = 0;

      filewrite (rcoH.fp, &zero, 4 - comprMisalign);
    }
  }
  // write text if packing header
  if (opts.packText && rco->tblText && rco->tblText->numSubentries) {
    rRCOEntry *rcoNode;

    // header.pTextData = rcowrite_ftell(&rcoH);
    header.pTextData = ftell (rcoH.fp);
    header.lTextData = 0;	// rcoH.sizeText;
    for (rcoNode = rco->tblText->firstChild; rcoNode; rcoNode = rcoNode->next) {
      header.lTextData +=
	  rco_write_text_resource (&rcoH, rcoNode, opts.packHeader, &opts,
	  ((rRCOTextEntry *) (rcoNode->extra))->lang,
	  (rco->tblText->lastChild == rcoNode));
    }
  }
  // write resources
  /* { uint32_t totalPackedLen = 0; if(rco->tblImage) { header.pImgData =
   * rcowrite_ftell(&rcoH); header.lImgData = rcoH.sizeImg; // TOxDO: this
   * model actually won't work - we have to update the offsets of ALL the
   * entries after packing... for(i=0; i<rco->tblImage->numSubentries; i++) {
   * uint32_t packedSize = rco_write_resource(&rcoH,
   * &(rco->tblImage->subentries[i]), RCO_DATA_COMPRESSION_NONE); // TOxDO:
   * change this // TOxDO: update packed size value uint32_t curFpos =
   * rcowrite_ftell(rcoH.fp); totalPackedLen += (packedSize % 4 ?
   * (packedSize/4)*4+4 : packedSize); } header.lImgData = totalPackedLen; }
   * totalPackedLen = 0; if(rco->tblSound) { header.pSoundData =
   * rcowrite_ftell(&rcoH); header.lSoundData = rcoH.sizeSound; for(i=0;
   * i<rco->tblSound->numSubentries; i++) { totalPackedLen +=
   * rco_write_resource(&rcoH, &(rco->tblSound->subentries[i]),
   * RCO_DATA_COMPRESSION_NONE); if(totalPackedLen %4) totalPackedLen +=
   * 4-(totalPackedLen%4); } header.lSoundData = totalPackedLen; } // TOxDO:
   * write model resources } */

  if ((rco->tblImage && rco->tblImage->numSubentries)
      || (rco->tblSound && rco->tblSound->numSubentries)
      || (rco->tblModel && rco->tblModel->numSubentries)) {
    // update data pointers
    uint32_t pos = ftell (rcoH.fp);

    if (rco->tblImage && rco->tblImage->numSubentries) {
      header.pImgData = pos;
      pos += header.lImgData;
    }
    if (rco->tblSound && rco->tblSound->numSubentries) {
      header.pSoundData = pos;
      pos += header.lSoundData;
    }
    if (rco->tblModel && rco->tblModel->numSubentries) {
      header.pModelData = pos;
      pos += header.lModelData;
    }
    // copy contents of fTmp across (uses a simple buffered copy)
    uint32_t len = header.lImgData + header.lSoundData + header.lModelData;
    uint8_t buffer[65536];

    while (len) {
      uint32_t readAmt = (len > 65536 ? 65536 : len);

      fileread (fTmp, buffer, readAmt);
      filewrite (rcoH.fp, buffer, readAmt);
      len -= readAmt;
    }

    fclose (fTmp);		// this deletes our temp file
  }
  // fix header
  if (rco->tblVSMX)
    header.pVSMXTable = rco->tblVSMX->offset;
  if (rco->tblText)
    header.pTextTable = rco->tblText->offset;
  if (rco->tblSound)
    header.pSoundTable = rco->tblSound->offset;
  if (rco->tblModel)
    header.pModelTable = rco->tblModel->offset;
  if (rco->tblImage)
    header.pImgTable = rco->tblImage->offset;
  if (rco->tblFont)
    header.pFontTable = rco->tblFont->offset;
  if (rco->tblObj)
    header.pObjTable = rco->tblObj->offset;
  if (rco->tblAnim)
    header.pAnimTable = rco->tblAnim->offset;

  rewind (rcoH.fp);
  if (rco->eSwap)
    es_rcoHeader (&header);
  filewrite (rcoH.fp, &header, sizeof (header));

  // TODO: fix resource pointers?
  // TODO: tie things up etc??

  fclose (rcoH.fp);

  return TRUE;
}
Esempio n. 16
0
static void put_data(int fd, char *null_buf, const CELL * cell,
		     int row, int n, int zeros_r_nulls)
{
    struct fileinfo *fcb = &R__.fileinfo[fd];
    int compressed = fcb->cellhd.compressed;
    int len = compressed ? sizeof(CELL) : fcb->nbytes;
    unsigned char *work_buf, *wk;
    ssize_t nwrite;

    if (row < 0 || row >= fcb->cellhd.rows)
	return;

    if (n <= 0)
	return;

    work_buf = G__alloca(fcb->cellhd.cols * sizeof(CELL) + 1);
    wk = work_buf;

    if (compressed)
	set_file_pointer(fd, row);

    if (compressed)
	wk++;

    convert_int(wk, null_buf, cell, n, len, zeros_r_nulls);

    if (compressed) {
	unsigned char *wk = work_buf + 1;
	int nbytes = count_bytes(wk, n, len);
	unsigned char *compressed_buf;
	int total;

	if (fcb->nbytes < nbytes)
	    fcb->nbytes = nbytes;

	/* first trim away zero high bytes */
	if (nbytes < len)
	    trim_bytes(wk, n, len, len - nbytes);

	total = nbytes * n;
	compressed_buf = G__alloca(total + 1);

	compressed_buf[0] = work_buf[0] = nbytes;

	/* then compress the data */
	nwrite = compressed == 1
	    ? rle_compress(compressed_buf + 1, work_buf + 1, n, nbytes)
	    : zlib_compress(compressed_buf + 1, work_buf + 1, n, nbytes);

	if (nwrite > 0) {
	    nwrite++;

	    if (write(fd, compressed_buf, nwrite) != nwrite)
		G_fatal_error(_("Error writing compressed data for row %d of <%s>"),
			      row, fcb->name);
	}
	else {
	    nwrite = nbytes * n + 1;
	    if (write(fd, work_buf, nwrite) != nwrite)
		G_fatal_error(_("Error writing compressed data for row %d of <%s>"),
			      row, fcb->name);
	}

	G__freea(compressed_buf);
    }
    else {
	nwrite = fcb->nbytes * n;

	if (write(fd, work_buf, nwrite) != nwrite)
	    G_fatal_error(_("Error writing uncompressed data for row %d of <%s>"),
			  row, fcb->name);
    }

    G__freea(work_buf);
}
Esempio n. 17
0
uint32_t
rco_write_text_resource (rRCOFile_writehelper * rcoH, rRCOEntry * entry,
    uint32_t destCompression, writerco_options * opts, uint32_t lang,
    uint8_t isLast)
{

  uint32_t len = 0;
  uint8_t *bufferMid = (uint8_t *) read_resource (entry, &len);

  if (!bufferMid)
    return 0;

  if (len != entry->srcLenUnpacked) {
    free (bufferMid);
    return 0;
  }

  rRCOTextEntry *extra = (rRCOTextEntry *) (entry->extra);

  TextComprInfo tci;
  char *textBuffer = NULL;
  uint32_t textBufferPos = 0;

  if (destCompression) {
    tci.lang = lang;
    tci.unknown = 1;
    tci.unpackedLen = 0;
    // textBuffer = (char*)malloc(1);
  }

  uint32_t i;

  for (i = 0; i < extra->numIndexes; i++) {
    uint32_t len = extra->indexes[i].length;

    if (!len)
      continue;

    if (destCompression) {
      tci.unpackedLen += ALIGN_TO_4 (len);
      textBuffer = (char *) realloc (textBuffer, tci.unpackedLen);
      memcpy (textBuffer + textBufferPos, bufferMid + extra->indexes[i].offset,
	  len);

      if (len % 4) {
	memset (textBuffer + textBufferPos + len, 0, 4 - (len % 4));
      }
      textBufferPos += ALIGN_TO_4 (len);
    } else {
      rco_fwrite (rcoH, bufferMid + extra->indexes[i].offset, len);
    }
  }

  free (bufferMid);

  if (destCompression) {
    uint8_t success = TRUE;
    uint8_t *bufferOut = NULL;

    if (destCompression == RCO_DATA_COMPRESSION_ZLIB) {
      uint32_t compSize = compressBound (tci.unpackedLen);

      bufferOut = (uint8_t *) malloc (compSize);
      tci.packedLen =
	  zlib_compress (textBuffer, tci.unpackedLen, bufferOut, compSize,
	  opts->zlibLevel, opts->zlibMethod);
    } else if (destCompression == RCO_DATA_COMPRESSION_RLZ) {
#ifdef DISABLE_RLZ
      error ("RLZ compression not supported.");
      exit (1);
#endif
      bufferOut = (uint8_t *) malloc (tci.unpackedLen);
      tci.packedLen =
	  rlz_compress (textBuffer, tci.unpackedLen, bufferOut, tci.unpackedLen,
	  opts->rlzMode);
    }

    if (!tci.packedLen) {	// compression failed
      free (bufferOut);
      bufferOut = NULL;
      success = FALSE;
    } else if (bufferOut) {
      if (isLast)
	tci.nextOffset = 0;
      else {
	tci.nextOffset = sizeof (tci) + tci.packedLen;
	tci.nextOffset = ALIGN_TO_4 (tci.nextOffset);
      }
      if (entry->rco->eSwap)
	es_textComprInfo (&tci);
      filewrite (rcoH->fp, &tci, sizeof (tci));
      if (entry->rco->eSwap)
	es_textComprInfo (&tci);

      filewrite (rcoH->fp, bufferOut, tci.packedLen);
      free (bufferOut);

      if (tci.packedLen % 4) {
	uint32_t zero = 0;

	filewrite (rcoH->fp, &zero, 4 - (tci.packedLen % 4));
      }
    } else
      success = FALSE;

    free (textBuffer);
    if (!success)
      return 0;
    return ALIGN_TO_4 (tci.packedLen) + sizeof (tci);
  }

  return 1;
}