10 #ifndef MSGPACK_V1_PACK_HPP
11 #define MSGPACK_V1_PACK_HPP
32 template <
typename Stream>
604 template <
typename T>
605 void pack_imp_uint8(T d);
606 template <
typename T>
607 void pack_imp_uint16(T d);
608 template <
typename T>
609 void pack_imp_uint32(T d);
610 template <
typename T>
611 void pack_imp_uint64(T d);
612 template <
typename T>
613 void pack_imp_int8(T d);
614 template <
typename T>
615 void pack_imp_int16(T d);
616 template <
typename T>
617 void pack_imp_int32(T d);
618 template <
typename T>
619 void pack_imp_int64(T d);
621 void append_buffer(
const char* buf,
size_t len)
623 append_buffer(&Stream::write, buf, len);
626 template <
typename Ret,
typename Cls,
typename SizeType>
627 void append_buffer(Ret (Cls::*)(
const char*, SizeType),
const char* buf,
size_t len)
629 m_stream.write(buf,
static_cast<SizeType
>(len));
635 #if defined(MSGPACK_USE_CPP03)
659 template <
typename Stream,
typename T>
660 inline void pack(Stream* s,
const T& v)
672 template <
typename Stream,
typename T>
673 inline void pack(Stream& s,
const T& v)
679 #if MSGPACK_ENDIAN_LITTLE_BYTE
680 template <
typename T>
681 inline char take8_8(T d) {
682 return static_cast<char>(
reinterpret_cast<uint8_t*
>(&d)[0]);
684 template <
typename T>
685 inline char take8_16(T d) {
686 return static_cast<char>(
reinterpret_cast<uint8_t*
>(&d)[0]);
688 template <
typename T>
689 inline char take8_32(T d) {
690 return static_cast<char>(
reinterpret_cast<uint8_t*
>(&d)[0]);
692 template <
typename T>
693 inline char take8_64(T d) {
694 return static_cast<char>(
reinterpret_cast<uint8_t*
>(&d)[0]);
697 #elif MSGPACK_ENDIAN_BIG_BYTE
699 template <
typename T>
700 inline char take8_8(T d) {
701 return static_cast<char>(
reinterpret_cast<uint8_t*
>(&d)[0]);
703 template <
typename T>
704 inline char take8_16(T d) {
705 return static_cast<char>(
reinterpret_cast<uint8_t*
>(&d)[1]);
707 template <
typename T>
708 inline char take8_32(T d) {
709 return static_cast<char>(
reinterpret_cast<uint8_t*
>(&d)[3]);
711 template <
typename T>
712 inline char take8_64(T d) {
713 return static_cast<char>(
reinterpret_cast<uint8_t*
>(&d)[7]);
717 #error msgpack-c supports only big endian and little endian
720 template <
typename Stream>
723 template <
typename Stream>
727 template <
typename Stream>
729 { pack_imp_uint8(d);
return *
this; }
731 template <
typename Stream>
733 { pack_imp_uint16(d);
return *
this; }
735 template <
typename Stream>
737 { pack_imp_uint32(d);
return *
this; }
739 template <
typename Stream>
741 { pack_imp_uint64(d);
return *
this; }
743 template <
typename Stream>
745 { pack_imp_int8(d);
return *
this; }
747 template <
typename Stream>
749 { pack_imp_int16(d);
return *
this; }
751 template <
typename Stream>
753 { pack_imp_int32(d);
return *
this; }
755 template <
typename Stream>
757 { pack_imp_int64(d);
return *
this;}
760 template <
typename Stream>
763 char buf[2] = {
static_cast<char>(0xccu), take8_8(d)};
764 append_buffer(buf, 2);
768 template <
typename Stream>
773 append_buffer(buf, 3);
777 template <
typename Stream>
782 append_buffer(buf, 5);
786 template <
typename Stream>
791 append_buffer(buf, 9);
795 template <
typename Stream>
798 char buf[2] = {
static_cast<char>(0xd0u), take8_8(d)};
799 append_buffer(buf, 2);
803 template <
typename Stream>
808 append_buffer(buf, 3);
812 template <
typename Stream>
817 append_buffer(buf, 5);
821 template <
typename Stream>
826 append_buffer(buf, 9);
831 template <
typename Stream>
834 #if defined(CHAR_MIN)
841 #error CHAR_MIN is not defined
846 template <
typename Stream>
850 pack_imp_int64(
static_cast<int64_t
>(d));
853 pack_imp_uint64(
static_cast<uint64_t
>(d));
858 template <
typename Stream>
865 template <
typename Stream>
868 #if defined(SIZEOF_SHORT)
869 #if SIZEOF_SHORT == 2
871 #elif SIZEOF_SHORT == 4
877 #elif defined(SHRT_MAX)
878 #if SHRT_MAX == 0x7fff
880 #elif SHRT_MAX == 0x7fffffff
887 if(
sizeof(
short) == 2) {
889 }
else if(
sizeof(
short) == 4) {
898 template <
typename Stream>
901 #if defined(SIZEOF_INT)
904 #elif SIZEOF_INT == 4
910 #elif defined(INT_MAX)
911 #if INT_MAX == 0x7fff
913 #elif INT_MAX == 0x7fffffff
920 if(
sizeof(
int) == 2) {
922 }
else if(
sizeof(
int) == 4) {
931 template <
typename Stream>
934 #if defined(SIZEOF_LONG)
937 #elif SIZEOF_LONG == 4
943 #elif defined(LONG_MAX)
944 #if LONG_MAX == 0x7fffL
946 #elif LONG_MAX == 0x7fffffffL
953 if(
sizeof(
long) == 2) {
955 }
else if(
sizeof(
long) == 4) {
964 template <
typename Stream>
967 #if defined(SIZEOF_LONG_LONG)
968 #if SIZEOF_LONG_LONG == 2
970 #elif SIZEOF_LONG_LONG == 4
976 #elif defined(LLONG_MAX)
977 #if LLONG_MAX == 0x7fffL
979 #elif LLONG_MAX == 0x7fffffffL
986 if(
sizeof(
long long) == 2) {
988 }
else if(
sizeof(
long long) == 4) {
998 template <
typename Stream>
1005 template <
typename Stream>
1008 #if defined(SIZEOF_SHORT)
1009 #if SIZEOF_SHORT == 2
1011 #elif SIZEOF_SHORT == 4
1017 #elif defined(USHRT_MAX)
1018 #if USHRT_MAX == 0xffffU
1020 #elif USHRT_MAX == 0xffffffffU
1027 if(
sizeof(
unsigned short) == 2) {
1029 }
else if(
sizeof(
unsigned short) == 4) {
1038 template <
typename Stream>
1041 #if defined(SIZEOF_INT)
1044 #elif SIZEOF_INT == 4
1050 #elif defined(UINT_MAX)
1051 #if UINT_MAX == 0xffffU
1053 #elif UINT_MAX == 0xffffffffU
1060 if(
sizeof(
unsigned int) == 2) {
1062 }
else if(
sizeof(
unsigned int) == 4) {
1071 template <
typename Stream>
1074 #if defined(SIZEOF_LONG)
1075 #if SIZEOF_LONG == 2
1077 #elif SIZEOF_LONG == 4
1083 #elif defined(ULONG_MAX)
1084 #if ULONG_MAX == 0xffffUL
1086 #elif ULONG_MAX == 0xffffffffUL
1093 if(
sizeof(
unsigned long) == 2) {
1095 }
else if(
sizeof(
unsigned long) == 4) {
1104 template <
typename Stream>
1107 #if defined(SIZEOF_LONG_LONG)
1108 #if SIZEOF_LONG_LONG == 2
1110 #elif SIZEOF_LONG_LONG == 4
1116 #elif defined(ULLONG_MAX)
1117 #if ULLONG_MAX == 0xffffUL
1119 #elif ULLONG_MAX == 0xffffffffUL
1126 if(
sizeof(
unsigned long long) == 2) {
1128 }
else if(
sizeof(
unsigned long long) == 4) {
1138 template <
typename Stream>
1141 union {
float f; uint32_t i; } mem;
1145 append_buffer(buf, 5);
1149 template <
typename Stream>
1152 union {
double f; uint64_t i; } mem;
1155 buf[0] =
static_cast<char>(0xcbu);
1157 #if defined(TARGET_OS_IPHONE)
1159 #elif defined(__arm__) && !(__ARM_EABI__)
1161 mem.i = (mem.i & 0xFFFFFFFFUL) << 32UL | (mem.i >> 32UL);
1164 append_buffer(buf, 9);
1169 template <
typename Stream>
1172 const char d =
static_cast<char>(0xc0u);
1173 append_buffer(&d, 1);
1177 template <
typename Stream>
1180 const char d =
static_cast<char>(0xc3u);
1181 append_buffer(&d, 1);
1185 template <
typename Stream>
1188 const char d =
static_cast<char>(0xc2u);
1189 append_buffer(&d, 1);
1194 template <
typename Stream>
1198 char d =
static_cast<char>(0x90u | n);
1199 append_buffer(&d, 1);
1200 }
else if(n < 65536) {
1202 buf[0] =
static_cast<char>(0xdcu);
_msgpack_store16(&buf[1],
static_cast<uint16_t
>(n));
1203 append_buffer(buf, 3);
1206 buf[0] =
static_cast<char>(0xddu);
_msgpack_store32(&buf[1],
static_cast<uint32_t
>(n));
1207 append_buffer(buf, 5);
1212 template <
typename Stream>
1216 unsigned char d =
static_cast<unsigned char>(0x80u | n);
1217 char buf = take8_8(d);
1218 append_buffer(&buf, 1);
1219 }
else if(n < 65536) {
1221 buf[0] =
static_cast<char>(0xdeu);
_msgpack_store16(&buf[1],
static_cast<uint16_t
>(n));
1222 append_buffer(buf, 3);
1225 buf[0] =
static_cast<char>(0xdfu);
_msgpack_store32(&buf[1],
static_cast<uint32_t
>(n));
1226 append_buffer(buf, 5);
1231 template <
typename Stream>
1235 unsigned char d =
static_cast<uint8_t
>(0xa0u | l);
1236 char buf = take8_8(d);
1237 append_buffer(&buf, 1);
1238 }
else if(l < 256) {
1240 buf[0] =
static_cast<char>(0xd9u); buf[1] =
static_cast<char>(l);
1241 append_buffer(buf, 2);
1242 }
else if(l < 65536) {
1244 buf[0] =
static_cast<char>(0xdau);
_msgpack_store16(&buf[1],
static_cast<uint16_t
>(l));
1245 append_buffer(buf, 3);
1248 buf[0] =
static_cast<char>(0xdbu);
_msgpack_store32(&buf[1],
static_cast<uint32_t
>(l));
1249 append_buffer(buf, 5);
1254 template <
typename Stream>
1257 append_buffer(b, l);
1263 template <
typename Stream>
1267 unsigned char d =
static_cast<uint8_t
>(0xa0u | l);
1268 char buf = take8_8(d);
1269 append_buffer(&buf, 1);
1270 }
else if(l < 65536) {
1272 buf[0] =
static_cast<char>(0xdau);
_msgpack_store16(&buf[1],
static_cast<uint16_t
>(l));
1273 append_buffer(buf, 3);
1276 buf[0] =
static_cast<char>(0xdbu);
_msgpack_store32(&buf[1],
static_cast<uint32_t
>(l));
1277 append_buffer(buf, 5);
1282 template <
typename Stream>
1285 append_buffer(b, l);
1289 template <
typename Stream>
1294 buf[0] =
static_cast<char>(0xc4u); buf[1] =
static_cast<char>(l);
1295 append_buffer(buf, 2);
1296 }
else if(l < 65536) {
1298 buf[0] =
static_cast<char>(0xc5u);
_msgpack_store16(&buf[1],
static_cast<uint16_t
>(l));
1299 append_buffer(buf, 3);
1302 buf[0] =
static_cast<char>(0xc6u);
_msgpack_store32(&buf[1],
static_cast<uint32_t
>(l));
1303 append_buffer(buf, 5);
1308 template <
typename Stream>
1311 append_buffer(b, l);
1315 template <
typename Stream>
1321 buf[0] =
static_cast<char>(0xd4u);
1322 buf[1] =
static_cast<char>(type);
1323 append_buffer(buf, 2);
1327 buf[0] =
static_cast<char>(0xd5u);
1328 buf[1] =
static_cast<char>(type);
1329 append_buffer(buf, 2);
1333 buf[0] =
static_cast<char>(0xd6u);
1334 buf[1] =
static_cast<char>(type);
1335 append_buffer(buf, 2);
1339 buf[0] =
static_cast<char>(0xd7u);
1340 buf[1] =
static_cast<char>(type);
1341 append_buffer(buf, 2);
1345 buf[0] =
static_cast<char>(0xd8u);
1346 buf[1] =
static_cast<char>(type);
1347 append_buffer(buf, 2);
1352 buf[0] =
static_cast<char>(0xc7u);
1353 buf[1] =
static_cast<char>(l);
1354 buf[2] =
static_cast<char>(type);
1355 append_buffer(buf, 3);
1356 }
else if(l < 65536) {
1358 buf[0] =
static_cast<char>(0xc8u);
1360 buf[3] =
static_cast<char>(type);
1361 append_buffer(buf, 4);
1364 buf[0] =
static_cast<char>(0xc9u);
1366 buf[5] =
static_cast<char>(type);
1367 append_buffer(buf, 6);
1374 template <
typename Stream>
1377 append_buffer(b, l);
1381 template <
typename Stream>
1382 template <
typename T>
1387 char buf = take8_8(d);
1388 append_buffer(&buf, 1);
1391 char buf[2] = {
static_cast<char>(0xccu), take8_8(d)};
1392 append_buffer(buf, 2);
1396 template <
typename Stream>
1397 template <
typename T>
1398 inline void packer<Stream>::pack_imp_uint16(T d)
1402 char buf = take8_16(d);
1403 append_buffer(&buf, 1);
1404 }
else if(d < (1<<8)) {
1406 char buf[2] = {
static_cast<char>(0xccu), take8_16(d)};
1407 append_buffer(buf, 2);
1411 buf[0] =
static_cast<char>(0xcdu);
_msgpack_store16(&buf[1],
static_cast<uint16_t
>(d));
1412 append_buffer(buf, 3);
1416 template <
typename Stream>
1417 template <
typename T>
1418 inline void packer<Stream>::pack_imp_uint32(T d)
1423 char buf = take8_32(d);
1424 append_buffer(&buf, 1);
1427 char buf[2] = {
static_cast<char>(0xccu), take8_32(d)};
1428 append_buffer(buf, 2);
1434 buf[0] =
static_cast<char>(0xcdu);
_msgpack_store16(&buf[1],
static_cast<uint16_t
>(d));
1435 append_buffer(buf, 3);
1439 buf[0] =
static_cast<char>(0xceu);
_msgpack_store32(&buf[1],
static_cast<uint32_t
>(d));
1440 append_buffer(buf, 5);
1445 template <
typename Stream>
1446 template <
typename T>
1447 inline void packer<Stream>::pack_imp_uint64(T d)
1452 char buf = take8_64(d);
1453 append_buffer(&buf, 1);
1456 char buf[2] = {
static_cast<char>(0xccu), take8_64(d)};
1457 append_buffer(buf, 2);
1460 if(d < (1ULL<<16)) {
1463 buf[0] =
static_cast<char>(0xcdu);
_msgpack_store16(&buf[1],
static_cast<uint16_t
>(d));
1464 append_buffer(buf, 3);
1465 }
else if(d < (1ULL<<32)) {
1468 buf[0] =
static_cast<char>(0xceu);
_msgpack_store32(&buf[1],
static_cast<uint32_t
>(d));
1469 append_buffer(buf, 5);
1474 append_buffer(buf, 9);
1479 template <
typename Stream>
1480 template <
typename T>
1481 inline void packer<Stream>::pack_imp_int8(T d)
1485 char buf[2] = {
static_cast<char>(0xd0u), take8_8(d)};
1486 append_buffer(buf, 2);
1489 char buf = take8_8(d);
1490 append_buffer(&buf, 1);
1494 template <
typename Stream>
1495 template <
typename T>
1496 inline void packer<Stream>::pack_imp_int16(T d)
1502 buf[0] =
static_cast<char>(0xd1u);
_msgpack_store16(&buf[1],
static_cast<int16_t
>(d));
1503 append_buffer(buf, 3);
1506 char buf[2] = {
static_cast<char>(0xd0u), take8_16(d)};
1507 append_buffer(buf, 2);
1509 }
else if(d < (1<<7)) {
1511 char buf = take8_16(d);
1512 append_buffer(&buf, 1);
1516 char buf[2] = {
static_cast<char>(0xccu), take8_16(d)};
1517 append_buffer(buf, 2);
1521 buf[0] =
static_cast<char>(0xcdu);
_msgpack_store16(&buf[1],
static_cast<uint16_t
>(d));
1522 append_buffer(buf, 3);
1527 template <
typename Stream>
1528 template <
typename T>
1529 inline void packer<Stream>::pack_imp_int32(T d)
1535 buf[0] =
static_cast<char>(0xd2u);
_msgpack_store32(&buf[1],
static_cast<int32_t
>(d));
1536 append_buffer(buf, 5);
1537 }
else if(d < -(1<<7)) {
1540 buf[0] =
static_cast<char>(0xd1u);
_msgpack_store16(&buf[1],
static_cast<int16_t
>(d));
1541 append_buffer(buf, 3);
1544 char buf[2] = {
static_cast<char>(0xd0u), take8_32(d)};
1545 append_buffer(buf, 2);
1547 }
else if(d < (1<<7)) {
1549 char buf = take8_32(d);
1550 append_buffer(&buf, 1);
1554 char buf[2] = {
static_cast<char>(0xccu), take8_32(d)};
1555 append_buffer(buf, 2);
1556 }
else if(d < (1<<16)) {
1559 buf[0] =
static_cast<char>(0xcdu);
_msgpack_store16(&buf[1],
static_cast<uint16_t
>(d));
1560 append_buffer(buf, 3);
1564 buf[0] =
static_cast<char>(0xceu);
_msgpack_store32(&buf[1],
static_cast<uint32_t
>(d));
1565 append_buffer(buf, 5);
1570 template <
typename Stream>
1571 template <
typename T>
1572 inline void packer<Stream>::pack_imp_int64(T d)
1575 if(d < -(1LL<<15)) {
1576 if(d < -(1LL<<31)) {
1580 append_buffer(buf, 9);
1584 buf[0] =
static_cast<char>(0xd2u);
_msgpack_store32(&buf[1],
static_cast<int32_t
>(d));
1585 append_buffer(buf, 5);
1591 buf[0] =
static_cast<char>(0xd1u);
_msgpack_store16(&buf[1],
static_cast<int16_t
>(d));
1592 append_buffer(buf, 3);
1595 char buf[2] = {
static_cast<char>(0xd0u), take8_64(d)};
1596 append_buffer(buf, 2);
1599 }
else if(d < (1<<7)) {
1601 char buf = take8_64(d);
1602 append_buffer(&buf, 1);
1607 char buf[2] = {
static_cast<char>(0xccu), take8_64(d)};
1608 append_buffer(buf, 2);
1612 buf[0] =
static_cast<char>(0xcdu);
_msgpack_store16(&buf[1],
static_cast<uint16_t
>(d));
1613 append_buffer(buf, 3);
1619 buf[0] =
static_cast<char>(0xceu);
_msgpack_store32(&buf[1],
static_cast<uint32_t
>(d));
1620 append_buffer(buf, 5);
1625 append_buffer(buf, 9);
The class template that supports continuous packing.
Definition: pack.hpp:33
packer< Stream > & pack_short(short d)
Packing short.
Definition: pack.hpp:866
packer< Stream > & pack_v4raw(uint32_t l)
Packing raw (v4) header and length.
Definition: pack.hpp:1264
packer(const packer &)=delete
packer< Stream > & pack_int(int d)
Packing int.
Definition: pack.hpp:899
packer< Stream > & pack_uint32(uint32_t d)
Packing uint32.
Definition: pack.hpp:736
packer< Stream > & pack_int32(int32_t d)
Packing int32.
Definition: pack.hpp:752
packer< Stream > & pack_fix_int64(int64_t d)
Packing uint8 (fixed packed type).
Definition: pack.hpp:822
packer< Stream > & pack_fix_uint64(uint64_t d)
Packing uint8 (fixed packed type).
Definition: pack.hpp:787
packer< Stream > & pack_int16(int16_t d)
Packing int16.
Definition: pack.hpp:748
packer< Stream > & pack_bin(uint32_t l)
Packing bin header and length.
Definition: pack.hpp:1290
packer< Stream > & pack_unsigned_short(unsigned short d)
Packing unsigned short.
Definition: pack.hpp:1006
packer & operator=(const packer &)=delete
packer< Stream > & pack_double(double d)
Packing double.
Definition: pack.hpp:1150
packer< Stream > & pack_uint8(uint8_t d)
Packing uint8.
Definition: pack.hpp:728
packer< Stream > & pack_map(uint32_t n)
Packing map header and size.
Definition: pack.hpp:1213
packer< Stream > & pack_fix_int8(int8_t d)
Packing uint8 (fixed packed type).
Definition: pack.hpp:796
packer< Stream > & pack_signed_char(signed char d)
Packing signed char.
Definition: pack.hpp:859
packer< Stream > & pack_wchar(wchar_t d)
Packing wchar_t.
Definition: pack.hpp:847
packer< Stream > & pack_v4raw_body(const char *b, uint32_t l)
Packing raw (v4) body.
Definition: pack.hpp:1283
packer< Stream > & pack_unsigned_int(unsigned int d)
Packing unsigned int.
Definition: pack.hpp:1039
packer< Stream > & pack_true()
Packing true.
Definition: pack.hpp:1178
packer< Stream > & pack_unsigned_char(unsigned char d)
Packing unsigned char.
Definition: pack.hpp:999
packer< Stream > & pack_false()
Packing false.
Definition: pack.hpp:1186
packer< Stream > & pack_nil()
Packing nil.
Definition: pack.hpp:1170
packer< Stream > & pack_str_body(const char *b, uint32_t l)
Packing str body.
Definition: pack.hpp:1255
packer< Stream > & pack_ext(size_t l, int8_t type)
Packing ext header, type, and length.
Definition: pack.hpp:1316
packer< Stream > & pack_fix_int32(int32_t d)
Packing uint8 (fixed packed type).
Definition: pack.hpp:813
packer< Stream > & pack_bin_body(const char *b, uint32_t l)
Packing bin body.
Definition: pack.hpp:1309
packer< Stream > & pack_fix_uint16(uint16_t d)
Packing uint8 (fixed packed type).
Definition: pack.hpp:769
packer< Stream > & pack_long_long(long long d)
Packing long long.
Definition: pack.hpp:965
packer< Stream > & pack_int8(int8_t d)
Packing int8.
Definition: pack.hpp:744
packer< Stream > & pack_char(char d)
Packing char.
Definition: pack.hpp:832
packer< Stream > & pack_fix_uint32(uint32_t d)
Packing uint8 (fixed packed type).
Definition: pack.hpp:778
packer< Stream > & pack_fix_int16(int16_t d)
Packing uint8 (fixed packed type).
Definition: pack.hpp:804
packer< Stream > & pack_unsigned_long_long(unsigned long long d)
Packing unsigned long long.
Definition: pack.hpp:1105
packer< Stream > & pack_str(uint32_t l)
Packing str header and length.
Definition: pack.hpp:1232
packer< Stream > & pack_uint16(uint16_t d)
Packing uint16.
Definition: pack.hpp:732
packer< Stream > & pack_ext_body(const char *b, uint32_t l)
Packing ext body.
Definition: pack.hpp:1375
packer< Stream > & pack_array(uint32_t n)
Packing array header and size.
Definition: pack.hpp:1195
packer< Stream > & pack_unsigned_long(unsigned long d)
Packing unsigned long.
Definition: pack.hpp:1072
packer< Stream > & pack_float(float d)
Packing float.
Definition: pack.hpp:1139
packer< Stream > & pack(const T &v)
Packing function template.
packer< Stream > & pack_long(long d)
Packing long.
Definition: pack.hpp:932
packer< Stream > & pack_int64(int64_t d)
Packing int32.
Definition: pack.hpp:756
packer< Stream > & pack_uint64(uint64_t d)
Packing uint16.
Definition: pack.hpp:740
packer< Stream > & pack_fix_uint8(uint8_t d)
Packing uint8 (fixed packed type).
Definition: pack.hpp:761
Definition: adaptor_base.hpp:15
void pack(msgpack::packer< Stream > &o, const T &v)
Definition: object.hpp:1180
#define _msgpack_store32(to, num)
Definition: sysdep.hpp:179
#define _msgpack_store64(to, num)
Definition: sysdep.hpp:181
#define _msgpack_store16(to, num)
Definition: sysdep.hpp:177
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:66