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); }
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); }
void mochilo_pack_symbol(mochilo_buf *buf, VALUE rb_symbol) { long size; const char *name; name = rb_id2name(SYM2ID(rb_symbol)); size = strlen(name); if (size < 0x100) { uint8_t lead = size; mochilo_buf_putc(buf, MSGPACK_T_SYM); mochilo_buf_putc(buf, lead); } else { rb_raise(rb_eMochiloPackError, "Symbol too long: must be under %d bytes, %ld given", 0x100, size); } mochilo_buf_put(buf, name, size); }
void mochilo_pack_bytes(mochilo_buf *buf, VALUE rb_bytes) { long size = RSTRING_LEN(rb_bytes); if (size < 0x20) { uint8_t lead = 0xA0 | size; mochilo_buf_putc(buf, lead); } else if (size < 0x10000) { uint16_t lead = size; mochilo_buf_putc(buf, MSGPACK_T_RAW16); mochilo_buf_put16be(buf, &lead); } else { mochilo_buf_putc(buf, MSGPACK_T_RAW32); mochilo_buf_put32be(buf, &size); } mochilo_buf_put(buf, RSTRING_PTR(rb_bytes), size); }
void mochilo_pack_bytes(mochilo_buf *buf, VALUE rb_bytes) { long size = RSTRING_LEN(rb_bytes); if (size < 0x100) { uint8_t lead = size; mochilo_buf_putc(buf, MSGPACK_T_BIN8); mochilo_buf_putc(buf, lead); } else if (size < 0x10000) { uint16_t lead = size; mochilo_buf_putc(buf, MSGPACK_T_BIN16); mochilo_buf_put16be(buf, &lead); } else if (size < 0x100000000) { mochilo_buf_putc(buf, MSGPACK_T_BIN32); mochilo_buf_put32be(buf, &size); } else { // there is no bin 64 rb_raise(rb_eMochiloPackError, "Binary string cannot be larger than %ld bytes", 0x100000000); } mochilo_buf_put(buf, RSTRING_PTR(rb_bytes), size); }