MPACK은 MessagePack Serialization 형식에 대한 인코더 및 디코더의 C 구현입니다. 그것은:
MPACK의 핵심에는 완충 된 독자와 작가와 동적으로 입력 된 노드의 트리로 디코딩하는 트리 스타일 파서가 포함되어 있습니다. 도우미 기능을 사용하면 예상 유형의 값을 읽고, 파일로 작업하고, 버퍼를 키우거나 문자열을 자동으로 할당하고, UTF-8 인코딩 등을 확인하는 등을 사용할 수 있습니다.
MPACK 코드는 코드베이스에 직접 내장 될 정도로 작습니다. Amalgamation 패키지를 다운로드하고 프로젝트에 mpack.h 및 mpack.c 추가하십시오.
MPACK은 모든 최신 컴파일러, 모든 데스크탑 및 스마트 폰 OS, WebAssembly, Linux 커널 내부 및 Arduino와 같은 8 비트 마이크로 컨트롤러를 지원합니다. MPACK FeatiationET은 컴파일 타임에 사용자 정의하여 어떤 기능, 구성 요소 및 디버그 점검을 컴파일하고 사용 가능한 종속성을 설정할 수 있습니다.
노드 API는 MessagePack 데이터 덩어리를 동적으로 유형 된 노드의 불변 트리에 구문 분석합니다. 일련의 도우미 기능을 사용하여 각 노드에서 특정 유형의 데이터를 추출 할 수 있습니다.
// parse a file into a node tree
mpack_tree_t tree ;
mpack_tree_init_filename ( & tree , "homepage-example.mp" , 0 );
mpack_tree_parse ( & tree );
mpack_node_t root = mpack_tree_root ( & tree );
// extract the example data on the msgpack homepage
bool compact = mpack_node_bool ( mpack_node_map_cstr ( root , "compact" ));
int schema = mpack_node_i32 ( mpack_node_map_cstr ( root , "schema" ));
// clean up and check for errors
if ( mpack_tree_destroy ( & tree ) != mpack_ok ) {
fprintf ( stderr , "An error occurred decoding the data!n" );
return ;
}위의 코드에는 추가 오류 처리가 필요하지 않습니다. 파일이 없거나 손상된 경우, 맵 키가 없거나 노드가 예상 유형에 있지 않은 경우 특수 "NIL"노드 및 False/Zero 값이 반환되고 트리가 오류 상태에 배치됩니다. 오류 확인은 데이터를 사용하기 전에만 필요합니다.
위의 예는 노드를 자동으로 할당합니다. 고정 노드 풀을 메모리 제한된 환경에서 대신 파서에 제공 할 수 있습니다. 최대 성능 및 최소 메모리 사용을 위해 기대 API를 사용하여 사전 정의 된 스키마의 데이터를 구문 분석 할 수 있습니다.
쓰기 API는 구조화 된 데이터를 MessagePack으로 인코딩합니다.
// encode to memory buffer
char * data ;
size_t size ;
mpack_writer_t writer ;
mpack_writer_init_growable ( & writer , & data , & size );
// write the example on the msgpack homepage
mpack_build_map ( & writer );
mpack_write_cstr ( & writer , "compact" );
mpack_write_bool ( & writer , true);
mpack_write_cstr ( & writer , "schema" );
mpack_write_uint ( & writer , 0 );
mpack_complete_map ( & writer );
// finish writing
if ( mpack_writer_destroy ( & writer ) != mpack_ok ) {
fprintf ( stderr , "An error occurred encoding the data!n" );
return ;
}
// use the data
do_something_with_data ( data , size );
free ( data );위의 예에서는 성장 가능한 메모리 버퍼를 인코딩합니다. 작가는 대신 메모리 할당이 필요하지 않으면 서 사전에 할당되거나 스택-할당 된 버퍼 (화합물 유형에 대한 상향 크기)에 쓸 수 있습니다. 작가는 또한 버퍼가 가득 차있을 때 또는 쓰기가 완료 될 때 호출 할 수있는 플러시 기능 (예 : 파일 또는 소켓 쓰기 기능)이 제공 될 수 있습니다.
오류가 발생하면 작가는 오류 상태에 배치됩니다. 너무 많은 데이터가 작성되면, 잘못된 수의 요소가 작성된 경우, 데이터를 플러시 할 수없는 경우 할당 실패가 발생하는 경우, 위의 코드에는 추가 오류 처리가 필요하지 않습니다. 작가가 오류 상태에있을 때 후속 쓰기는 무시되므로 모든 쓰기에 오류가 있는지 확인할 필요가 없습니다.
위의 예는 mpack_build_map() 사용하여 포함 된 키 값 쌍의 수를 자동으로 결정합니다. 필요한 요소 수를 최초로 알고 있다면 대신 mpack_start_map() 로 전달할 수 있습니다. 이 경우 해당 mpack_finish_map() 는 디버그 모드에서 예상 요소 수가 실제로 작성되었다고 주장합니다. 이는 다른 MessagePack C/C ++ 라이브러리가하지 않을 수있는 것입니다.
MPack은 매우 고성능과 소형 코드 풋 프린트를 유지하면서 기능이 풍부합니다. 다음은 다른 C 파서와 비교하는 짧은 기능 테이블입니다.
| mpack (v1.1) | msgpack-c (v3.3.0) | CMP (v19) | cwpack (v1.3.1) | |
|---|---|---|---|---|
| LIBC 요구 사항이 없습니다 | ✓ | ✓ | ✓ | |
| 성장할 수있는 메모리 작가 | ✓ | ✓ | ✓* | |
| 파일 I/O 헬퍼 | ✓ | ✓ | ✓* | |
| 상태가 높은 오류 처리 | ✓ | ✓ | ||
| 증분 파서 | ✓ | ✓ | ✓ | |
| 트리 스트림 파서 | ✓ | ✓ | ||
| 화합물 크기 추적 | ✓ | |||
| 자동 화합물 크기 | ✓ |
테이블의 다양한 항목에 대한 설명이 포함 된 더 큰 기능 비교 테이블을 여기에서 사용할 수 있습니다.
이 벤치마킹 제품군은 MPACK의 성능을 다른 Schemaless 직렬화 형식의 다른 구현과 비교합니다. MPACK은 모든 JSON 및 MessagePack 라이브러리 (CWPACK 제외)를 능가하며 일부 테스트에서는 동등한 데이터에 대해 RapidJson보다 몇 배 빠릅니다.
개념적으로 MessagePack은 JSON과 유사하게 데이터를 저장합니다. 둘 다 숫자 및 문자열과 같은 간단한 값으로 구성되어 있으며 맵과 어레이에 계층 적으로 저장됩니다. 그렇다면 왜 JSON을 대신 사용하지 않습니까? 주된 이유는 JSON이 인간으로 읽을 수 있도록 설계되었으므로 이진 직렬화 형식만큼 효율적이지 않기 때문입니다.
문자열, 맵 및 어레이와 같은 복합 유형은 구분되므로 적절한 저장소는 선결제 할 수 없습니다. 크기를 결정하려면 전체 물체를 구문 분석해야합니다.
문자열은 기본 인코딩에 저장되지 않습니다. 인용문 및 백 슬래시와 같은 특수 문자는 읽을 때 작성되고 변환 될 때 탈출해야합니다.
숫자는 특히 비효율적이며 (특히 플로트를 구문 분석 할 때) JSON을 많은 숫자를 포함하는 구조화 된 데이터의 기본 형식으로 부적절하게 만듭니다.
이진 데이터는 JSON이 전혀 지원하지 않습니다. 아이콘 및 썸네일과 같은 작은 이진 블로브는 Base64 인코딩 또는 대역 밖으로 전달되어야합니다.
위의 문제는 디코더의 복잡성을 크게 증가시킵니다. 전체 기능을 갖춘 JSON 디코더는 상당히 크며 최소한의 디코더는 문자열을 벗어난 기능 및 플로트 파싱과 같은 기능을 제거하는 경향이 있습니다. 이로 인해 찾기 어려운 플랫폼 별 및 로케일 관련 버그가 발생할 수 있으며 보안 취약점에 대한 잠재력이 높아질 수 있습니다. 또한 성능이 크게 줄어들어 JSON은 모바일 게임과 같은 응용 프로그램에서 사용하기 위해 매력적이지 않습니다.
JSON의 공간 비효율은 미니 화 및 압축을 통해 부분적으로 완화 될 수 있지만 성능 비 효율성은 할 수 없습니다. 더 중요한 것은 데이터를 미정화하고 압축하는 경우 왜 인간이 읽을 수있는 형식을 처음 사용 하는가?
MPACK 빌드 프로세스는 MPACK을 라이브러리로 구축하지 않습니다. 단위 테스트를 구축하고 실행하는 데 사용됩니다. MPACK을 사용하려면 MPACK 또는 장치 테스트 스위트를 구축 할 필요가 없습니다.
MPACK을 테스트하는 방법에 대한 정보는 Test/Readme.md를 참조하십시오.