merge in JNI-114 - Callback And Retry for methods that might need a passphrase Release_2.1.0-RC11
authorheck <heck@pep.foundation>
Wed, 29 Jul 2020 16:15:56 +0200
changeset 9116bd79b9d0d4e
parent 909 f418da1d7265
parent 910 aeaef3595855
child 912 c162efdb567c
merge in JNI-114 - Callback And Retry for methods that might need a passphrase
     1.1 --- a/android/build.gradle	Tue Jul 28 21:35:17 2020 +0200
     1.2 +++ b/android/build.gradle	Wed Jul 29 16:15:56 2020 +0200
     1.3 @@ -2,7 +2,8 @@
     1.4  
     1.5  def pEpEngineSrc = hasProperty('pEpEngineSrc') ? pEpEngineSrc : "../../pEpEngine"
     1.6  def buildAutomatic = hasProperty('buildAutomatic') ? buildAutomatic : "true"
     1.7 -def threadsToUse = hasProperty('threadsToUse') ? threadsToUse : 1
     1.8 +def threadsToUse = hasProperty('threadsToUse') ?
     1.9 +        threadsToUse : Runtime.getRuntime().availableProcessors()
    1.10  
    1.11  def pEpEngineDB = new File(new File(pEpEngineSrc), 'db')
    1.12  
    1.13 @@ -77,7 +78,7 @@
    1.14              jniDebuggable true
    1.15              externalNativeBuild {
    1.16                  ndkBuild {
    1.17 -                    arguments "-j${threadsToUse}", 'NDK_LOG=1'
    1.18 +                    arguments "-j${threadsToUse}", 'NDK_LOG=1', 'NDK_DEBUG=1', 'NDEBUG=null'
    1.19                     // arguments '-B', 'NDK_DEBUG=1', 'NDEBUG=null', 'NDK_LOG=1'
    1.20                  }
    1.21              }
     2.1 --- a/android/external/Makefile.conf	Tue Jul 28 21:35:17 2020 +0200
     2.2 +++ b/android/external/Makefile.conf	Wed Jul 29 16:15:56 2020 +0200
     2.3 @@ -20,7 +20,7 @@
     2.4  
     2.5  ### Git deps repos
     2.6  EXTERNAL_GIT_REPOS += libetpan|https://github.com/fdik/libetpan.git?HEAD
     2.7 -EXTERNAL_GIT_REPOS += sequoia|https://gitlab.com/sequoia-pgp/sequoia.git?b5b783f58c9b6fdb26163cb7b236ee71cfef339e
     2.8 +EXTERNAL_GIT_REPOS += sequoia|https://gitlab.com/sequoia-pgp/sequoia.git?de497f59570437d448b293769eb57bf7a9741f30
     2.9  
    2.10  ### Common variables
    2.11  #### Source code targets
     3.1 --- a/src/basic_api.cc	Tue Jul 28 21:35:17 2020 +0200
     3.2 +++ b/src/basic_api.cc	Wed Jul 29 16:15:56 2020 +0200
     3.3 @@ -9,6 +9,7 @@
     3.4  
     3.5  #include "throw_pEp_exception.hh"
     3.6  #include "jniutils.hh"
     3.7 +#include "passphrase_callback.hh"
     3.8  
     3.9  extern "C" {
    3.10      using namespace pEp::JNIAdapter;
    3.11 @@ -33,11 +34,18 @@
    3.12      char *words;
    3.13      size_t wsize;
    3.14  
    3.15 +    PEP_STATUS status = PEP_STATUS_OK;
    3.16 +
    3.17      if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
    3.18          if (_ident->me)
    3.19 -            ::myself(session(), _ident);
    3.20 +            status = passphraseWrap(::myself, session(), _ident);
    3.21          else
    3.22 -            ::update_identity(session(), _ident);
    3.23 +            status = passphraseWrap(::update_identity, session(), _ident);
    3.24 +    }
    3.25 +
    3.26 +    if (status != PEP_STATUS_OK) {
    3.27 +        throw_pEp_Exception(env, status);
    3.28 +        return NULL;
    3.29      }
    3.30  
    3.31      if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
    3.32 @@ -51,7 +59,9 @@
    3.33      else
    3.34          lang = "en";
    3.35  
    3.36 -    PEP_STATUS status = ::trustwords(session(), _ident->fpr, lang, &words, &wsize, 10);
    3.37 +    status = passphraseWrap(::trustwords,
    3.38 +            session(), (const char *) _ident->fpr, lang, &words, &wsize, 10);
    3.39 +
    3.40      if (status != PEP_STATUS_OK) {
    3.41          throw_pEp_Exception(env, status);
    3.42          return NULL;
    3.43 @@ -76,7 +86,7 @@
    3.44  
    3.45      pEp_identity *_ident = to_identity(env, ident);
    3.46  
    3.47 -    PEP_STATUS status = ::myself(session(), _ident);
    3.48 +    PEP_STATUS status = passphraseWrap(::myself, session(), _ident);
    3.49  
    3.50      if (status != PEP_STATUS_OK) {
    3.51          LOGD("Failed Myself: 0x%04x\\n", status);
    3.52 @@ -102,7 +112,7 @@
    3.53  
    3.54      pEp_identity *_ident = to_identity(env, ident);
    3.55  
    3.56 -    ::update_identity(session(), _ident);
    3.57 +    passphraseWrap(::update_identity, session(), _ident);
    3.58  
    3.59      return from_identity(env, _ident);
    3.60  }
    3.61 @@ -123,9 +133,9 @@
    3.62      std::lock_guard<std::mutex> l(*mutex_local);
    3.63  
    3.64      pEp_identity *_ident = to_identity(env, ident);
    3.65 -    char *_fpr = to_string(env, fpr);
    3.66 +    const char *_fpr = to_string(env, fpr);
    3.67  
    3.68 -    PEP_STATUS status = ::set_own_key(session(), _ident, _fpr);
    3.69 +    PEP_STATUS status = passphraseWrap(::set_own_key, session(), _ident, _fpr);
    3.70  
    3.71      if (status != PEP_STATUS_OK) {
    3.72          LOGD("Failed setOwnKey: 0x%04x\\n", status);
    3.73 @@ -152,11 +162,18 @@
    3.74  
    3.75      pEp_identity *_ident = to_identity(env, ident);
    3.76  
    3.77 +    PEP_STATUS status = PEP_STATUS_OK;
    3.78 +
    3.79      if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
    3.80          if (_ident->me)
    3.81 -            ::myself(session(), _ident);
    3.82 +            status = passphraseWrap(::myself, session(), _ident);
    3.83          else
    3.84 -            ::update_identity(session(), _ident);
    3.85 +            status = passphraseWrap(::update_identity, session(), _ident);
    3.86 +    }
    3.87 +
    3.88 +    if (status != PEP_STATUS_OK) {
    3.89 +        throw_pEp_Exception(env, status);
    3.90 +        return;
    3.91      }
    3.92  
    3.93      if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
    3.94 @@ -164,7 +181,7 @@
    3.95          return;
    3.96      }
    3.97  
    3.98 -    ::key_mistrusted(session(), _ident);
    3.99 +    passphraseWrap(::key_mistrusted, session(), _ident);
   3.100  }
   3.101  
   3.102  JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1keyResetTrust(
   3.103 @@ -183,11 +200,18 @@
   3.104  
   3.105      pEp_identity *_ident = to_identity(env, ident);
   3.106  
   3.107 +    PEP_STATUS status = PEP_STATUS_OK;
   3.108 +
   3.109      if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
   3.110          if (_ident->me)
   3.111 -            ::myself(session(), _ident);
   3.112 +            status = passphraseWrap(::myself, session(), _ident);
   3.113          else
   3.114 -            ::update_identity(session(), _ident);
   3.115 +            status = passphraseWrap(::update_identity, session(), _ident);
   3.116 +    }
   3.117 +
   3.118 +    if (status != PEP_STATUS_OK) {
   3.119 +        throw_pEp_Exception(env, status);
   3.120 +        return;
   3.121      }
   3.122  
   3.123      if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
   3.124 @@ -195,7 +219,7 @@
   3.125          return;
   3.126      }
   3.127  
   3.128 -    ::key_reset_trust(session(), _ident);
   3.129 +    passphraseWrap(::key_reset_trust, session(), _ident);
   3.130  }
   3.131  
   3.132  JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1trustPersonalKey(
   3.133 @@ -214,11 +238,18 @@
   3.134  
   3.135      pEp_identity *_ident = to_identity(env, ident);
   3.136  
   3.137 +    PEP_STATUS status = PEP_STATUS_OK;
   3.138 +
   3.139      if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
   3.140          if (_ident->me)
   3.141 -            ::myself(session(), _ident);
   3.142 +            status = passphraseWrap(::myself, session(), _ident);
   3.143          else
   3.144 -            ::update_identity(session(), _ident);
   3.145 +            status = passphraseWrap(::update_identity, session(), _ident);
   3.146 +    }
   3.147 +
   3.148 +    if (status != PEP_STATUS_OK) {
   3.149 +        throw_pEp_Exception(env, status);
   3.150 +        return;
   3.151      }
   3.152  
   3.153      if (_ident->fpr == NULL || _ident->fpr[0] == 0) {
   3.154 @@ -226,7 +257,7 @@
   3.155          return;
   3.156      }
   3.157  
   3.158 -    ::trust_personal_key(session(), _ident);
   3.159 +    passphraseWrap(::trust_personal_key, session(), _ident);
   3.160  }
   3.161  
   3.162  JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1trustOwnKey(
   3.163 @@ -250,7 +281,7 @@
   3.164          return;
   3.165      }
   3.166  
   3.167 -    ::trust_own_key(session(), _ident);
   3.168 +    passphraseWrap(::trust_own_key, session(), _ident);
   3.169  }
   3.170  
   3.171  JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine__1importKey(
   3.172 @@ -268,7 +299,7 @@
   3.173      std::lock_guard<std::mutex> l(*mutex_local);
   3.174  
   3.175      size_t _size = (size_t) env->GetArrayLength(key);
   3.176 -    char *_key = (char *) env->GetByteArrayElements(key, NULL);
   3.177 +    const char *_key = (char *) env->GetByteArrayElements(key, NULL);
   3.178  
   3.179      if(_key == NULL){
   3.180          throw_pEp_Exception(env, PEP_OUT_OF_MEMORY);
   3.181 @@ -277,7 +308,7 @@
   3.182  
   3.183      identity_list *_identities;
   3.184  
   3.185 -    PEP_STATUS status = ::import_key(session(), _key, _size, &_identities);
   3.186 +    PEP_STATUS status =  passphraseWrap(::import_key, session(), _key, _size, &_identities);
   3.187      if (status != PEP_STATUS_OK && status != PEP_KEY_IMPORTED) {
   3.188          throw_pEp_Exception(env, status);
   3.189          return NULL;
   3.190 @@ -342,14 +373,14 @@
   3.191      }
   3.192      std::lock_guard<std::mutex> l(*mutex_local);
   3.193  
   3.194 -    char *_fpr = to_string(env, fpr);
   3.195 +    const char *_fpr = to_string(env, fpr);
   3.196  
   3.197      if(_fpr == NULL){
   3.198          throw_pEp_Exception(env, PEP_OUT_OF_MEMORY);
   3.199          return;
   3.200      }
   3.201  
   3.202 -    PEP_STATUS status = ::blacklist_add(session(), _fpr);
   3.203 +    PEP_STATUS status = passphraseWrap(::blacklist_add, session(), _fpr);
   3.204      if (status != PEP_STATUS_OK) {
   3.205          throw_pEp_Exception(env, status);
   3.206          return;
   3.207 @@ -371,14 +402,14 @@
   3.208      }
   3.209      std::lock_guard<std::mutex> l(*mutex_local);
   3.210  
   3.211 -    char *_fpr = to_string(env, fpr);
   3.212 +    const char *_fpr = to_string(env, fpr);
   3.213  
   3.214      if(_fpr == NULL){
   3.215          throw_pEp_Exception(env, PEP_OUT_OF_MEMORY);
   3.216          return;
   3.217      }
   3.218  
   3.219 -    PEP_STATUS status = ::blacklist_delete(session(), _fpr);
   3.220 +    PEP_STATUS status = passphraseWrap(::blacklist_delete, session(), _fpr);
   3.221      if (status != PEP_STATUS_OK) {
   3.222          throw_pEp_Exception(env, status);
   3.223          return;
   3.224 @@ -400,7 +431,7 @@
   3.225      }
   3.226      std::lock_guard<std::mutex> l(*mutex_local);
   3.227  
   3.228 -    char *_fpr = to_string(env, fpr);
   3.229 +    const char *_fpr = to_string(env, fpr);
   3.230      bool _listed = 0;
   3.231  
   3.232      if(_fpr == NULL){
   3.233 @@ -408,7 +439,7 @@
   3.234          return 0;
   3.235      }
   3.236  
   3.237 -    PEP_STATUS status = ::blacklist_is_listed(session(), _fpr, &_listed);
   3.238 +    PEP_STATUS status = passphraseWrap(::blacklist_is_listed, session(), _fpr, &_listed);
   3.239      if (status != PEP_STATUS_OK) {
   3.240          throw_pEp_Exception(env, status);
   3.241          return 0;
   3.242 @@ -435,7 +466,7 @@
   3.243      int _maxlines = (int) maxlines;
   3.244      char *_logdata;
   3.245  
   3.246 -    PEP_STATUS status = ::get_crashdump_log(session(), _maxlines, &_logdata);
   3.247 +    PEP_STATUS status = passphraseWrap(::get_crashdump_log, session(), _maxlines, &_logdata);
   3.248      if ((status > PEP_STATUS_OK && status < PEP_UNENCRYPTED) ||
   3.249              status < PEP_STATUS_OK ||
   3.250              status >= PEP_TRUSTWORD_NOT_FOUND) {
   3.251 @@ -525,6 +556,7 @@
   3.252          return ;
   3.253      }
   3.254  
   3.255 +
   3.256  }
   3.257  
   3.258  } // extern "C"
     4.1 --- a/src/gen_cpp_Engine.ysl2	Tue Jul 28 21:35:17 2020 +0200
     4.2 +++ b/src/gen_cpp_Engine.ysl2	Wed Jul 29 16:15:56 2020 +0200
     4.3 @@ -270,6 +270,7 @@
     4.4          const "dir", "name(*[1])";
     4.5          const "type", "name(*[2])";
     4.6          const "name", "name(*[3])";
     4.7 +        const "const", "name(*[4])";
     4.8  
     4.9          choose {
    4.10              when "$type = 'message'"
    4.11 @@ -280,10 +281,18 @@
    4.12                  | bool _«$name» = (bool) «$name»;
    4.13              when "$type='int'"
    4.14                  | int _«$name» = (int) «$name»;
    4.15 +            when "$type='uint'"
    4.16 +                | auto _«$name» = (unsigned int) «$name»;
    4.17              when "$type='string'"
    4.18                  | const char *_«$name» = to_string(env, «$name»);
    4.19 -            otherwise
    4.20 -                | √$type *_«$name» = to_«$type»(env, «$name»);
    4.21 +            otherwise {
    4.22 +                choose {
    4.23 +                    when "$const"
    4.24 +                        | const √$type *_«$name» = to_«$type»(env, «$name»);
    4.25 +                    otherwise
    4.26 +                        | √$type *_«$name» = to_«$type»(env, «$name»);
    4.27 +                }
    4.28 +            }
    4.29          }
    4.30      }
    4.31  
     5.1 --- a/src/pEp.yml2	Tue Jul 28 21:35:17 2020 +0200
     5.2 +++ b/src/pEp.yml2	Wed Jul 29 16:15:56 2020 +0200
     5.3 @@ -119,14 +119,14 @@
     5.4                  inout int flags
     5.5              );
     5.6  
     5.7 -        method re_evaluate_message_rating(
     5.8 +        method cached=true re_evaluate_message_rating(
     5.9                  in message src,
    5.10 -                Cconst stringlist x_keylist "NULL",
    5.11 +                Cconst stringlist x_keylist "static_cast<stringlist_t*>(nullptr)",
    5.12                  Cconst Rating x_enc_status "PEP_rating_undefined",
    5.13                  returns Rating rating
    5.14              );
    5.15  
    5.16 -        method outgoing_message_rating(
    5.17 +        method cached=true outgoing_message_rating(
    5.18                  in message msg,
    5.19                  returns Rating rating
    5.20              );
    5.21 @@ -136,18 +136,18 @@
    5.22                  returns Rating rating
    5.23              );
    5.24  
    5.25 -        method get_identity(
    5.26 +        method cached=true get_identity(
    5.27                  in string address,
    5.28                  in string userid,
    5.29                  returns identity ident
    5.30              );
    5.31  
    5.32 -        method identity_rating(
    5.33 +        method cached=true identity_rating(
    5.34                  in identity ident,
    5.35                  returns Rating rating
    5.36              );
    5.37  
    5.38 -        method blacklist_retrieve(
    5.39 +        method cached=true blacklist_retrieve(
    5.40                  returns stringlist blacklist
    5.41              );
    5.42  
    5.43 @@ -157,34 +157,36 @@
    5.44                  returns identity ident 
    5.45              );
    5.46  
    5.47 -        method OpenPGP_list_keyinfo(
    5.48 +        method cached=true OpenPGP_list_keyinfo(
    5.49                  in string pattern,
    5.50                  returns stringpairlist keyinfoList
    5.51              );
    5.52  
    5.53 -        method set_identity_flags(
    5.54 +        //TODO Move to use IdentityFlag instead of ints
    5.55 +        method cached=true set_identity_flags(
    5.56                  in identity ident,
    5.57 -                in int flags
    5.58 +                in uint flags
    5.59              );
    5.60  
    5.61 -        method unset_identity_flags(
    5.62 +        method cached=true unset_identity_flags(
    5.63                  in identity ident,
    5.64 -                in int flags
    5.65 +                in uint flags
    5.66              );
    5.67  
    5.68 -        method own_identities_retrieve(
    5.69 +        method cached=true own_identities_retrieve(
    5.70                  returns identitylist identities
    5.71              );
    5.72  
    5.73 -        method get_trustwords(
    5.74 -                in identity id1,
    5.75 -                in identity id2,
    5.76 +
    5.77 +        method cached=true get_trustwords(
    5.78 +                in identity id1 const,
    5.79 +                in identity id2 const,
    5.80                  in string lang,
    5.81                  returns sstring words,
    5.82                  in bool full
    5.83              );
    5.84  
    5.85 -        method get_trustwords_for_fprs(
    5.86 +        method cached=true get_trustwords_for_fprs(
    5.87                  in string fpr1,
    5.88                  in string fpr2,
    5.89                  in string lang,
    5.90 @@ -201,13 +203,13 @@
    5.91                  in bool full
    5.92              );
    5.93  
    5.94 -        method get_languagelist(
    5.95 +        method cached=true get_languagelist(
    5.96                  returns string languagelist
    5.97              );
    5.98  
    5.99          // this function is not related to key reset
   5.100  
   5.101 -        method key_reset_trust(
   5.102 +        method cached=true key_reset_trust(
   5.103                  in identity ident
   5.104              );
   5.105  
   5.106 @@ -223,14 +225,14 @@
   5.107  
   5.108          method cached=true key_reset_all_own_keys();
   5.109                  
   5.110 -        method deliverHandshakeResult(
   5.111 +        method cached=true deliverHandshakeResult(
   5.112                  in SyncHandshakeResult shr,
   5.113 -                in identitylist identities
   5.114 +                in identitylist identities const
   5.115              );
   5.116  
   5.117 -        method leave_device_group();
   5.118 +        method cached=true leave_device_group();
   5.119  
   5.120 -        method enable_identity_for_sync(
   5.121 +        method cached=true enable_identity_for_sync(
   5.122                  in identity ident
   5.123              );
   5.124  
     6.1 --- a/src/passphrase_callback.hh	Tue Jul 28 21:35:17 2020 +0200
     6.2 +++ b/src/passphrase_callback.hh	Wed Jul 29 16:15:56 2020 +0200
     6.3 @@ -1,3 +1,5 @@
     6.4 +#pragma once
     6.5 +#include <pEp/passphrase_cache.hh>
     6.6  
     6.7  
     6.8  namespace pEp {
     6.9 @@ -5,5 +7,9 @@
    6.10  
    6.11      char* passphraseRequiredCallback();
    6.12  
    6.13 +        template<typename... A> PEP_STATUS passphraseWrap(
    6.14 +                PEP_STATUS f(PEP_SESSION, A...), PEP_SESSION session, A... a);
    6.15      };
    6.16 -};
    6.17 \ No newline at end of file
    6.18 +};
    6.19 +
    6.20 +#include "passphrase_callback.hxx"
    6.21 \ No newline at end of file
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/passphrase_callback.hxx	Wed Jul 29 16:15:56 2020 +0200
     7.3 @@ -0,0 +1,41 @@
     7.4 +#pragma once
     7.5 +
     7.6 +#include "passphrase_callback.hh"
     7.7 +
     7.8 +namespace pEp {
     7.9 +    namespace JNIAdapter {
    7.10 +
    7.11 +        template<typename... A> PEP_STATUS passphraseWrap(
    7.12 +                PEP_STATUS f(PEP_SESSION, A...), PEP_SESSION session, A... a) {
    7.13 +            pEpLog("cached passphrase mode");
    7.14 +            bool retryAgain = false;
    7.15 +            int maxRetries = 3;
    7.16 +            int retryCount = 0;
    7.17 +            PEP_STATUS status;
    7.18 +            do {
    7.19 +                // the actual target function
    7.20 +                pEpLog("calling passphrase_cache.api from basic_api");
    7.21 +                status = passphrase_cache.api(f, session, a...);
    7.22 +                pEpLog("PEP_STATUS:" << status);
    7.23 +                if (status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE) {
    7.24 +                    pEpLog("none of the cached passphrases worked");
    7.25 +                    if (retryCount < maxRetries) {
    7.26 +                        // call the app
    7.27 +                        char *_passphrase = passphraseRequiredCallback();
    7.28 +                        pEpLog("callback returned, config_passphrase() with new passphrase");
    7.29 +                        PEP_STATUS status = ::config_passphrase(session,
    7.30 +                                                                passphrase_cache.add(_passphrase));
    7.31 +                        retryAgain = true;
    7.32 +                        retryCount++;
    7.33 +                    } else {
    7.34 +                        pEpLog("max retries reached:" << maxRetries);
    7.35 +                        retryAgain = false;
    7.36 +                    }
    7.37 +                } else {
    7.38 +                    retryAgain = false;
    7.39 +                }
    7.40 +            } while (retryAgain);
    7.41 +            return status;
    7.42 +        }
    7.43 +    }
    7.44 +}
    7.45 \ No newline at end of file
     8.1 --- a/src/types_c.ysl2	Tue Jul 28 21:35:17 2020 +0200
     8.2 +++ b/src/types_c.ysl2	Wed Jul 29 16:15:56 2020 +0200
     8.3 @@ -17,6 +17,7 @@
     8.4          when "$type='Rating'" > PEP_rating
     8.5          when "$type='SyncHandshakeResult'" > sync_handshake_result
     8.6          when "$type='CipherSuite'" > PEP_CIPHER_SUITE
     8.7 +        when "$type='uint'" > uint
     8.8  
     8.9          otherwise value "$type";
    8.10      }
    8.11 @@ -31,6 +32,7 @@
    8.12          when "$type = 'string' or $type = 'sstring'" > jbyteArray
    8.13          when "$type='bool'" > jboolean
    8.14          when "$type='int'" > jint
    8.15 +        when "$type='uint'" > jint
    8.16          otherwise > jobject
    8.17      }
    8.18  }
     9.1 --- a/src/types_java.ysl2	Tue Jul 28 21:35:17 2020 +0200
     9.2 +++ b/src/types_java.ysl2	Wed Jul 29 16:15:56 2020 +0200
     9.3 @@ -4,6 +4,7 @@
     9.4      choose {
     9.5          when "$type='bool'" > Boolean
     9.6          when "$type='int'" > int
     9.7 +        when "$type='uint'" > int
     9.8          when "$type='string' or $type='sstring'" > String
     9.9          when "$type='timestamp'" > Date
    9.10          when "$type='void'" > void