티스토리 뷰

시작하기 전에...
Tizen 공부를 시작하며 에도 썼듯이 혼자 공부하며 서술합니다.
실제 사실과 다를 수도 있고, 보이는 대로 사견을 서술할 예정입니다.
잘못되었다 싶은 부분은 댓글이나, 메일로 알려주세요.
Tizen 2.4 Native 기준으로 포스팅 합니다.


App 간 Data를 주고 받거나, 다른 Device 간에, 혹은 Data를 Backup 하는 등의 목적을 위해서는 Serialization 이 필요로 합니다.

개인 적인 생각으로는 특히나 Device Convergence를 고려하는 App / Service를 설계하는 데에 있어
Data Serialization는 아주 중요하고 최하단에 반드시 뒷받침 되어야하는 기본 기술이라고 생각합니다.

Java에서는 Serialization을 위해 Serializable 이라는 Interface가 존재합니다.
이 Interface를 Implemants 한다면, 그 Class Object는 직렬화 될 수 있습니다.
(※여기서 유의할 점은 단순 '직렬화'만 한다는 점입니다. 가이드에서는 항상 보안성은 제공하지 않음을 경고하고 있습니다.)
따라서, Java 언어를 사용하는 Android Platform에서도 Serializable을 사용할 수 있습니다.
Class를 통으로 Serialization할 수 있다는 점, Java를 사용하면 Closs- Platform 간에도 Data 전달이 된다는 점 때문에 요긴하게 쓸 수 있습니다.
(※대학 과제에서 단순한 Server(PC) - Client(Phone) 모델을 시연할 때, 주로 이것을 사용했던 기억이 있네요...)

또 Android 자체적으로도 Bundle 이라는 이름으로 API Set을 제공하고 있습니다.
(http://developer.android.com/intl/ko/reference/android/os/Bundle.html)


Tizen의 경우에는 제가 알기에 (박박 긁어 모으면) 세개 정도의 serialize API가 존재 합니다.

  1. GLib - GVariant
  2. JSON-GLib - Json
  3. Bundle - Bundle

1,2 번은 Tizen Platform에 GLib과 Json-GLib Library가 포함되어 있기 때문에 가능한 Open Source API이며,
3번은 Tizen의 Public API 입니다.

생각하는 장단점을 요약해보겠습니다.


 

 지원 Data type

 API

 그 외 장점

 GVariant

 매우 많음

 사용법이 어려움 (진입장벽)

 Type 에러 등에서 어영부영 넘어갈 데가 있음

 GDBus에서 Parameter로 사용 가능

 Json-GLib

 충분

 복잡한 Data가 들어왔을 때, Parsing 하는 API Step이 길어짐

 Data를 Parsing 없이도 사람이 읽을 수 있음
 Json 자체가 서버 Protocol 등에서 널리 사용됨

 Bundle

 적음 (str, byte)

 매우 쉽고 단순

 Tizen의 API 하위 호환 보장 가능


결국 제 주관으로 추천을 하자면,
서버까지 직접 개발해야 하는 상황에서의 Design이라면 Json을,
복잡한 Protocol 기반의 Structure가 오가야하는 IPC 에서는 GVariant를,
Tizen에서 App 간 단순한 Data를 주고받는 다면 Bundle을
추천 드리고 싶습니다.

그리고 추가로 Google의 Protobuf (Protocol Buffer) 라는 오픈소스 라이브러리가 있습니다.
이종 Platform, 이종 Language 간의 Data Structure를 공유 가능하게끔 하는 강력한 Serialization 라이브러리입니다.
Tizen에도 gerrit에서 검색이 되고 있긴 하는데, 공식적으로 포함시키고 지원하는 건지 모르겠습니다.
(2.4 에뮬레이터에서도 라이브러리가 검색은 되는데, 관련 문서는 존재하지 않습니다.)


developer.tizen.org -> Development -> API Reference


Bundle은 다음 Type들의 Data를 저장할 수 있습니다.

보시다시피, 기본이 String에 Byte 지원하는 정도입니다.
개발하기 편한 부분만 뚝딱 만든 느낌입니다.
byte형을 지원하기 때문에 원한다면 int, float 등도 형변환으로 Store할 수는 있습니다.
다만, 자기 혼자 짜고 칠때(?)만 정상적으로 사용이 가능하겠습니다.
자료형에 대한 명시성이 없기 때문에 유용하게 / 광범위하게 활용하기는 어렵습니다.

뭐 어쨌든 울며 겨자먹기로 저것만 써야합니다.

Encode / Decode 가 Serialization / Deserialization입니다.

Encode : bundle -> bundle_raw, len

bundle_rawunsiged char 입니다.
그냥 unsigned char로 사용해도 되며, Data를 duplicate 해주었기 때문에
bundle은 메모리를 해제할 수 있습니다.

※ Serialization 을 제공하는 API들 중에서는
이런 과정에서 handle과 동일한 Memory를 참조하는 Data를 Return하는 경우도 있으니
항상 이 부분을 유의해 보셔야합니다. (Gvariant의 경우가 그렇습니다.)


Decode : bundle_raw -> bundle

이 과정에서도 역시 Memory를 duplicate하고 있으니 원본 Data는 Free할 수 있습니다.
특이한 점은, 다른 Tizen API처럼 return값에 int로 result code를 주고 있지 않습니다.
필요할 경우 get_last_result() 함수를 이용합니다.
(※이 함수는 thread safe 하게 동작합니다.)


Encode / Decode는 다음과 같이 이루어집니다.

#include <bundle.h>

static void __data_store_example()
{
    bundle bd = bundle_create();
    // ...
    // Data store in here
    // ...

    unsigned char *data;
    int len = 0;
    int ret = bundle_encode(bd, &data, &len);
    // ...
    // Send or save data result
    // ...
    bundle_free(bd);
}

static void __data_put_example(unsigned *data, int len)
{
    bundle *bd = bundle_decode(data, len);
    // ...
    // Get data in here
    // ...
    bundle_free(bd);
}


Bundle에 Data 삽입

#include <bundle.h>
#include <stdint.h>

static void __add_data(bundle *b)
{
    char *name = "jack";
    char *hobbies[] = {"soccer", "basketball", "computer programming"};
    float *weight = 70.1;
    int age = 20;

    bundle_add_str(b, "name", name);
    bundle_add_str_attay(b, "hoobies", hoobies, 3);
    bundle_add_byte(b, "weight", (void *)weight, sizeof(float));
    bundle_add_byte(b, "age", (void *)(intptr_t)age, sizeof(int));
}


Bundle에서 Data get (여기서는 get한 data를 free하면 안됩니다.)

#include <bundle.h> #include <stdint.h> static void __bundle_iter(const char *key, const int type, const bundle_keyval_t *kv, void *user_data) { int type = bundle_keyval_get_type(kv); void *byte_val = NULL; char *char_val = NULL; size_t size; void **byte_arr = NULL; char **char_arr = NULL; unsigned int len = 0U; size_t *size_arr = NULL; switch (type) { case BUNDLE_TYPE_STR: bundle_keyval_get_basic_val(kv, &char_val, &size); // add your code here break; case BUNDLE_TYPE_STR_ARRAY: bundle_keyval_get_array_val(kv, &char_arr, &len, &size_arr); // add your code here break; case BUNDLE_TYPE_BYTE: bundle_keyval_get_basic_val(kv, &byte_val, &size); // add your code here break; case BUNDLE_TYPE_BYTE_ARRAY: bundle_keyval_get_array_val(kv, &byte_arr, &len, &size_arr); // add your code here break; default: dlog_print(LOG_WARN, LOG_TAG, "unexpected type"); break; } } static void __put_data(bundle *b) { // If promised data key-values char *name = NULL; bundle_get_str(b, "name", &name); // Do not free 'name' // For known data key-values bundle_foreach(b, __bundle_iter, NULL); }



댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함