예제 #1
0
void mochilo_pack_str(mochilo_buf *buf, VALUE rb_str)
{
	long size = RSTRING_LEN(rb_str);
	rb_encoding *encoding;

	const struct mochilo_enc_map *enc2id;
	const char *enc_name;

	if (size < 0x10000) {
		uint16_t lead = size;
		mochilo_buf_putc(buf, MSGPACK_T_STR16);
		mochilo_buf_put16be(buf, &lead);
	}

	else {
		mochilo_buf_putc(buf, MSGPACK_T_STR32);
		mochilo_buf_put32be(buf, &size);
	}

	encoding = rb_enc_get(rb_str);
	enc_name = rb_enc_name(encoding);
	enc2id = mochilo_encoding_to_id(enc_name, (unsigned int)strlen(enc_name));

	mochilo_buf_putc(buf, enc2id ? enc2id->id : 0);
	mochilo_buf_put(buf, RSTRING_PTR(rb_str), size);
}
예제 #2
0
void mochilo_pack_str(mochilo_buf *buf, VALUE rb_str)
{
	long size = RSTRING_LEN(rb_str);
	rb_encoding *encoding;

	const struct mochilo_enc_map *enc2id;
	const char *enc_name;

	encoding = rb_enc_get(rb_str);
	enc_name = rb_enc_name(encoding);

	if (encoding == rb_utf8_encoding()) {
		// use str type from msgpack spec
		if (size < 0x20) {
			uint8_t lead = 0xa0 | size;
			mochilo_buf_putc(buf, lead);
		} else if (size < 0x100) {
			uint8_t lead = size;
			mochilo_buf_putc(buf, MSGPACK_T_STR8);
			mochilo_buf_putc(buf, lead);
		} else if (size < 0x10000) {
			uint16_t lead = size;
			mochilo_buf_putc(buf, MSGPACK_T_STR16);
			mochilo_buf_put16be(buf, &lead);
		} else if (size < 0x100000000) {
			mochilo_buf_putc(buf, MSGPACK_T_STR32);
			mochilo_buf_put32be(buf, &size);
		} else {
			// there is no str 64
			rb_raise(rb_eMochiloPackError,
				"String cannot be larger than %ld bytes", 0x100000000);
		}
	} else {
		// if another encoding is used we need to use our custom types
		if (size < 0x100) {
			uint8_t lead = size;
			mochilo_buf_putc(buf, MSGPACK_T_ENC8);
			mochilo_buf_putc(buf, lead);
		} else if (size < 0x10000) {
			uint16_t lead = size;
			mochilo_buf_putc(buf, MSGPACK_T_ENC16);
			mochilo_buf_put16be(buf, &lead);
		} else if (size < 0x100000000) {
			mochilo_buf_putc(buf, MSGPACK_T_ENC32);
			mochilo_buf_put32be(buf, &size);
		} else {
			// there is no ext 64
			rb_raise(rb_eMochiloPackError,
				"String cannot be larger than %ld bytes", 0x100000000);
		}

		enc2id = mochilo_encoding_to_id(enc_name, (unsigned int)strlen(enc_name));
		mochilo_buf_putc(buf, enc2id ? enc2id->id : 0);
	}

	mochilo_buf_put(buf, RSTRING_PTR(rb_str), size);
}