Exemple #1
0
int get_head(struct protocol_head *head, void **p, int *left)
{
    NEG_RET_LN(get_uint8(p, left, &head->result));
    NEG_RET_LN(get_uint8(p, left, &head->command));
    NEG_RET_LN(get_uint32(p, left, &head->sequence));
    
    static void   *echo_buf;
    static size_t echo_buf_len;
    int echo_len = 0;
    NEG_RET_LN(echo_len = get_bin2(p, left, &echo_buf, &echo_buf_len));
    head->echo_len = (uint16_t)echo_len;
    head->echo = echo_buf;

    return 0;
}
Exemple #2
0
static void
test_util_format_unaligned_accessors(void *ignored)
{
  (void)ignored;
  char buf[9] = "onionsoup"; // 6f6e696f6e736f7570

  tt_u64_op(get_uint64(buf+1), OP_EQ, htonll(U64_LITERAL(0x6e696f6e736f7570)));
  tt_uint_op(get_uint32(buf+1), OP_EQ, htonl(0x6e696f6e));
  tt_uint_op(get_uint16(buf+1), OP_EQ, htons(0x6e69));
  tt_uint_op(get_uint8(buf+1), OP_EQ, 0x6e);

  set_uint8(buf+7, 0x61);
  tt_mem_op(buf, OP_EQ, "onionsoap", 9);

  set_uint16(buf+6, htons(0x746f));
  tt_mem_op(buf, OP_EQ, "onionstop", 9);

  set_uint32(buf+1, htonl(0x78696465));
  tt_mem_op(buf, OP_EQ, "oxidestop", 9);

  set_uint64(buf+1, htonll(U64_LITERAL(0x6266757363617465)));
  tt_mem_op(buf, OP_EQ, "obfuscate", 9);
 done:
  ;
}
uint8 HCI_SET_EVENT_FILTER_T_PDU::get_filter_condition_type() const
{
    if ( size() > HCI_SET_EVENT_FILTER_T_filter_condition_type )
        return get_uint8 ( HCI_SET_EVENT_FILTER_T_filter_condition_type );
    else
        return 0xFF;
}
Exemple #4
0
static void
test_routerkeys_rsa_ed_crosscert(void *arg)
{
  (void)arg;
  ed25519_public_key_t ed;
  crypto_pk_t *rsa = pk_generate(2);

  uint8_t *cc = NULL;
  ssize_t cc_len;
  time_t expires_in = 1470846177;

  tt_int_op(0, OP_EQ, ed25519_public_from_base64(&ed,
                        "ThisStringCanContainAnythingSoNoKeyHereNowX"));
  cc_len = tor_make_rsa_ed25519_crosscert(&ed, rsa, expires_in, &cc);

  tt_int_op(cc_len, OP_GT, 0);
  tt_int_op(cc_len, OP_GT, 37); /* key, expires, siglen */
  tt_mem_op(cc, OP_EQ, ed.pubkey, 32);
  time_t expires_out = 3600 * ntohl(get_uint32(cc+32));
  tt_int_op(expires_out, OP_GE, expires_in);
  tt_int_op(expires_out, OP_LE, expires_in + 3600);

  tt_int_op(cc_len, OP_EQ, 37 + get_uint8(cc+36));

  tt_int_op(0, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len, rsa, &ed,
                                                  expires_in - 10));

  /* Now try after it has expired */
  tt_int_op(-4, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len, rsa, &ed,
                                                  expires_out + 1));

  /* Truncated object */
  tt_int_op(-2, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len - 2, rsa, &ed,
                                                  expires_in - 10));

  /* Key not as expected */
  cc[0] ^= 3;
  tt_int_op(-3, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len, rsa, &ed,
                                                  expires_in - 10));
  cc[0] ^= 3;

  /* Bad signature */
  cc[40] ^= 3;
  tt_int_op(-5, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len, rsa, &ed,
                                                   expires_in - 10));
  cc[40] ^= 3;

  /* Signature of wrong data */
  cc[0] ^= 3;
  ed.pubkey[0] ^= 3;
  tt_int_op(-6, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len, rsa, &ed,
                                                  expires_in - 10));
  cc[0] ^= 3;
  ed.pubkey[0] ^= 3;

 done:
  crypto_pk_free(rsa);
  tor_free(cc);
}
Exemple #5
0
static
int _vlsctlc_unpack_cmd(struct vlsctlc* lsctlc, void* buf, int len)
{
    struct vlsctlc_unpack_cmd_desc* desc = lsctlc_unpack_cmd_desc;
    uint32_t magic = 0;
    int tsz = 0;
    int bsz = 0;
    int csz = 0;
    int ret = 0;

    vassert(lsctlc);
    vassert(buf);
    vassert(len > 0);

    tsz += sizeof(uint8_t); // skip version;
    lsctlc->type = get_uint8(buf + tsz);
    tsz += sizeof(uint8_t);
    bsz  = (int)get_uint16(buf + tsz);
    tsz += sizeof(uint16_t);
    magic = get_uint32(buf + tsz);
    tsz += sizeof(uint32_t);

//    _aux_vhexbuf_dump(buf, bsz);

    if (magic != VLSCTL_MAGIC) {
        return -1;
    }

    while(bsz - csz > 0) {
        uint16_t cmd_id = 0;
        int cmd_len = 0;
        int i = 0;

        cmd_id = get_uint16(buf + tsz);
        tsz += sizeof(uint16_t);
        csz += sizeof(uint16_t);
        cmd_len = get_uint16(buf + tsz);
        tsz += sizeof(uint16_t);
        csz += sizeof(uint16_t);
        lsctlc->bound_cmd = cmd_id;
        while(cmd_len > 0) {
            for (i = 0; desc[i].cmd; i++) {
                ret = desc[i].cmd(lsctlc, buf + tsz, cmd_len);
                if (ret < 0) {
                    return -1;
                } else if (ret > 0) {
                    tsz += ret;
                    csz += ret;
                    cmd_len -= ret;
                    break;
                }else {
                    //do nothing;
                }
            }
        }
    }
    return 0;
}
Exemple #6
0
int get_str1(void **buf, int *len, char **value, size_t *n)
{
    GET_STR_ARG_CHECK;

    uint8_t slen = 0;
    if (get_uint8(buf, len, &slen) < 0)
        return -2;

    GET_STR(slen);
}
Exemple #7
0
int get_bin1(void **buf, int *len, void **value, size_t *n)
{
    GET_BIN_ARG_CHECK;

    uint8_t blen = 0;
    if (get_uint8(buf, len, &blen) < 0)
        return -2;

    GET_BIN(blen);
}
static ast::TransposeExp::Kind get_TransposeExp_Kind(void)
{
  int code = get_uint8();
  switch(code){
  case 1 : return ast::TransposeExp::_Conjugate_;
  case 2 : return ast::TransposeExp::_NonConjugate_;
  }
  std::cerr << "Unknown get_TransposeExp_Kind code " << code << std::endl;
  exit(2);
}
Exemple #9
0
void print_u8(cbuf_t* in, int n)
{
    int i;
    for (i = 0; i < n; i++) {
	u_int8_t val;
	get_uint8(in, &val);
	printf("%u ", val);
    }
    printf("\n");
}
static ast::VarDec::Kind get_VarDec_Kind(void)
{
  int code = get_uint8();
  switch(code){
  case 1 : return ast::VarDec::invalid_kind;
  case 2 : return ast::VarDec::evaluation_kind;
  case 3 : return ast::VarDec::assignment_kind;
  }
  std::cerr << "Unknown get_VarDec_Kind code " << code << std::endl;
  exit(2);
}
static ast::IntExp::Prec get_IntExp_Prec(void)
{
  int code = get_uint8();
  switch(code){
  case 1: return ast::IntExp::_8_;
  case 2: return ast::IntExp::_16_;
  case 3: return ast::IntExp::_32_;
  case 4: return ast::IntExp::_64_;
  }
  std::cerr << "Unknown get_IntExp_Prec code " << code << std::endl;
  exit(2);
}
static ast::IfExp::Kind get_IfExp_Kind(void)
{
  int code = get_uint8();
  switch(code){
  case 1 : return ast::IfExp::invalid_kind ;
  case 2 : return ast::IfExp::instruction_kind;
  case 3 : return ast::IfExp::expression_kind;
  case 4 : return (ast::IfExp::Kind)0;
  }
  std::cerr << "Unknown get_IfExp_Kind code " << code << std::endl;
  exit(2);
}
bool HCI_SET_EVENT_FILTER_T_PDU::get_condition ( uint8& auto_accept_flag ) const
{
    bool ok = (get_filter_type() == 2);
    if ( ok )
    {
        switch ( get_filter_condition_type() )
        {
        case 0:
            auto_accept_flag = get_uint8(HCI_SET_EVENT_FILTER_T_AAF_all );
            break;
        case 1:
            auto_accept_flag = get_uint8(HCI_SET_EVENT_FILTER_T_AAF_COD );
            break;
        case 2:
            auto_accept_flag = get_uint8(HCI_SET_EVENT_FILTER_T_AAF_BDA );
            break;
        default:
            ok = false;
            break;
        }
    }
    return ok;
}
static ast::OpExp::Oper get_OpExp_Oper(void)
{
  int code = get_uint8();
  switch(code){
   case 1 : return  ast::OpExp::plus;
    case 2 : return  ast::OpExp::minus;
    case 3 : return  ast::OpExp::times;
    case 4 : return  ast::OpExp::rdivide;
    case 5 : return  ast::OpExp::ldivide;
    case 6 : return  ast::OpExp::power;

    case 7 : return  ast::OpExp::dottimes;
    case 8 : return  ast::OpExp::dotrdivide;
    case 9 : return  ast::OpExp::dotldivide;
    case 10 : return  ast::OpExp::dotpower;

    case 11 : return  ast::OpExp::krontimes;
    case 12 : return  ast::OpExp::kronrdivide;
    case 13 : return  ast::OpExp::kronldivide;

    case 14 : return  ast::OpExp::controltimes;
    case 15 : return  ast::OpExp::controlrdivide;
    case 16 : return  ast::OpExp::controlldivide;

    case 17 : return  ast::OpExp::eq;
    case 18 : return  ast::OpExp::ne;
    case 19 : return  ast::OpExp::lt;
    case 20 : return  ast::OpExp::le;
    case 21 : return  ast::OpExp::gt;
    case 22 : return  ast::OpExp::ge;

    case 23 : return  ast::OpExp::unaryMinus;

    case 24 : return  ast::OpExp::logicalAnd;
    case 25 : return  ast::OpExp::logicalOr;
    case 26 : return  ast::OpExp::logicalShortCutAnd;
    case 27 : return  ast::OpExp::logicalShortCutOr;
   }
  std::cerr << "Unknown get_OpExp_Oper code " << code << std::endl;
  exit(2);
}
Exemple #15
0
static
int _aux_vlsctlc_unpack_vaddr(void* buf, int len, struct vsockaddr_in* addr)
{
    int tsz = 0;

    vassert(addr);
    vassert(buf);
    vassert(len > 0);

    memset(addr, 0, sizeof(*addr));

    tsz += sizeof(uint8_t);
    addr->addr.sin_family = get_uint8(buf + tsz);
    tsz += sizeof(uint8_t);
    addr->addr.sin_port = get_uint16(buf + tsz);
    tsz += sizeof(uint16_t);
    addr->addr.sin_addr.s_addr = get_uint32(buf + tsz);
    tsz += sizeof(uint32_t);
    addr->type = get_uint32(buf + tsz);
    tsz += sizeof(uint32_t);

    return tsz;
}
Exemple #16
0
/** Check <b>buf</b> for a variable-length cell according to the rules of link
 * protocol version <b>linkproto</b>.  If one is found, pull it off the buffer
 * and assign a newly allocated var_cell_t to *<b>out</b>, and return 1.
 * Return 0 if whatever is on the start of buf_t is not a variable-length
 * cell.  Return 1 and set *<b>out</b> to NULL if there seems to be the start
 * of a variable-length cell on <b>buf</b>, but the whole thing isn't there
 * yet. */
int
fetch_var_cell_from_buf(buf_t *buf, var_cell_t **out, int linkproto)
{
  char hdr[VAR_CELL_MAX_HEADER_SIZE];
  var_cell_t *result;
  uint8_t command;
  uint16_t length;
  const int wide_circ_ids = linkproto >= MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS;
  const int circ_id_len = get_circ_id_size(wide_circ_ids);
  const unsigned header_len = get_var_cell_header_size(wide_circ_ids);
  *out = NULL;
  if (buf_datalen(buf) < header_len)
    return 0;
  buf_peek(buf, hdr, header_len);

  command = get_uint8(hdr + circ_id_len);
  if (!(cell_command_is_var_length(command, linkproto)))
    return 0;

  length = ntohs(get_uint16(hdr + circ_id_len + 1));
  if (buf_datalen(buf) < (size_t)(header_len+length))
    return 1;

  result = var_cell_new(length);
  result->command = command;
  if (wide_circ_ids)
    result->circ_id = ntohl(get_uint32(hdr));
  else
    result->circ_id = ntohs(get_uint16(hdr));

  buf_drain(buf, header_len);
  buf_peek(buf, (char*) result->payload, length);
  buf_drain(buf, length);

  *out = result;
  return 1;
}
static ast::OpExp::Kind get_OpExp_Kind(void)
{
  int code = get_uint8();
  switch(code){
  case 1 : return ast::OpExp::invalid_kind;
  case 2 : return ast::OpExp::bool_kind;
  case 3 : return ast::OpExp::string_kind;
  case 4 : return ast::OpExp::integer_kind;
  case 5 : return ast::OpExp::float_kind;
  case 6 : return ast::OpExp::double_kind;
  case 7 : return ast::OpExp::float_complex_kind;
  case 8 : return ast::OpExp::double_complex_kind;
      
  case 9 : return ast::OpExp::bool_matrix_kind;
  case 10 : return ast::OpExp::string_matrix_kind;
  case 11 : return ast::OpExp::integer_matrix_kind;
  case 12 : return ast::OpExp::float_matrix_kind;
  case 13 : return ast::OpExp::double_matrix_kind;
  case 14 : return ast::OpExp::float_complex_matrix_kind;
  case 15 : return ast::OpExp::double_complex_matrix_kind;
  }
  std::cerr << "Unknown get_OpExp_Kind code " << code << std::endl;
  exit(2);
}
uint8 HCIEventPDU::get_parameter_length() const
{
    return get_uint8(1) ;
}
uint8 HCIEventPDU::get_event_code() const
{
    /* the event code is the first thing in the pdu */
    return get_uint8(0) ;
}
uint8 BNEP_HCI_SWITCH_ROLE_RSP_T_PDU::get_status() const
{
    return get_uint8 ( BNEP_HCI_SWITCH_ROLE_RSP_T_status );
}
static ast::Exp* get_exp(void)
{
  ast::Exp* exp;
  // std::cerr << "get_exp at pos " << (buf - initial_buf) << std::endl;
  int code = get_uint8();
  // std::cerr << "    code = " << code << std::endl;
  Location *loc = get_location();
  int is_verbose = get_bool();
  int is_break = get_bool();
  int is_breakable = get_bool();
  int is_return = get_bool();
  int is_returnable = get_bool();
  int is_continue = get_bool();
  int is_continuable = get_bool();
  
  
  switch(code){
  case 1: {   
    std::list<ast::Exp *>* l_body = get_exps();
    exp = new ast::SeqExp(*loc, *l_body);
    break;
  }
  case 2: {
    std::wstring* s = get_wstring();
    exp = new ast::StringExp(*loc, *s);
    break;
  }
  case 3: {
    std::wstring* s = get_wstring();
    exp = new ast::CommentExp(*loc, s);
    break;
  }
  case 4: {
    ast::IntExp::Prec prec = get_IntExp_Prec();
    int value = get_int32();
    exp = new ast::IntExp(*loc, prec, value);
    break;
  }
  case 5: {
    double d = get_double();
    exp = new ast::FloatExp(*loc, d);
    break;
  }
  case 6: {
    double d = get_double();
    exp = new ast::DoubleExp(*loc,d);
    break;
  }
  case 7: {
    bool b = get_bool();
    exp = new ast::BoolExp(*loc, b);
    break;
  }
  case 8: {
    exp = new ast::NilExp(*loc);
    break;
  }
  case 9: {
    symbol::Symbol *name = get_Symbol();
    exp = new ast::SimpleVar(*loc, *name);
    break;
  }
  case 10: {
    exp = new ast::ColonVar(*loc);
    break;
  }
  case 11: {
    exp = new ast::DollarVar(*loc);
    break;
  }
  case 12: {
    std::list<ast::Var*>* vars = get_vars();
    exp = new ast::ArrayListVar(*loc, *vars);
    break;
  }
  case 13: {
    ast::Exp *head = get_exp();
    ast::Exp *tail = get_exp();
    exp = new ast::FieldExp(*loc, *head, *tail);
    break;
  }
  case 14: {
    ast::IfExp::Kind kind = get_IfExp_Kind();
    bool has_else = get_bool();
    ast::Exp* test = get_exp();
    ast::Exp* _then = get_exp();
    ast::IfExp* ifexp;
    if( has_else ){
      ast::Exp* _else = get_exp();
      ifexp = new ast::IfExp(*loc, *test, *_then, *_else);
    } else {
      ifexp = new ast::IfExp(*loc, *test, *_then);
    }
    ifexp->kind_set(kind);
    exp = ifexp;
    break;
  }
  case 15: {
    Location *try_location = get_location();
    Location *catch_location = get_location();
    std::list<ast::Exp *>* try_exps = get_exps();
    std::list<ast::Exp *>* catch_exps = get_exps();
    ast::SeqExp *_try = new ast::SeqExp(*try_location, *try_exps);
    ast::SeqExp *_catch = new ast::SeqExp(*catch_location, *catch_exps);
    exp = new ast::TryCatchExp(*loc, *_try, *_catch);
    break;
  }
  case 16: {
    ast::Exp* test = get_exp();
    ast::Exp* body = get_exp();
    exp = new ast::WhileExp(*loc, *test, *body);
    break;
  }
  case 17: {
    Location *vardec_location = get_location();
    ast::VarDec* vardec = get_VarDec(vardec_location);
    ast::Exp* body = get_exp();
    exp = new ast::ForExp(*loc, *vardec, *body);
    break;
  }
  case 18: {
    exp = new ast::BreakExp(*loc);
    break;
  }
  case 19: {
    exp = new ast::ContinueExp(*loc);
    break;
  }
  case 20: {
    bool is_global = get_bool();
    if( is_global ){
      exp = new ast::ReturnExp(*loc);
    } else {
      ast::Exp* returnExp_exp = get_exp();    
      exp = new ast::ReturnExp(*loc, returnExp_exp);
    }
    break;
  }
  case 21: {
    bool has_default = get_bool();
    ast::SeqExp * default_case = NULL;
    if( has_default ){
      Location *default_case_location = get_location();
      std::list<ast::Exp *>* default_case_exps = get_exps();
      default_case = new ast::SeqExp(*default_case_location, 
				     *default_case_exps);    
    }
    ast::Exp* select = get_exp();

    int nitems = get_uint32();
    std::list<ast::CaseExp*> *cases = new  std::list<ast::CaseExp*>;
    for(int i = 0; i < nitems; i++){

      Location *case_location = get_location();
      Location *body_location = get_location();
      ast::Exp* test = get_exp();
      std::list<ast::Exp *>* body_exps = get_exps();
      ast::SeqExp *body = new ast::SeqExp(*body_location,  *body_exps);

      ast::CaseExp* _case = new ast::CaseExp(*case_location, *test, *body);
      cases->push_back(_case);
    }
    

    if( has_default ){
      exp = new ast::SelectExp(*loc, *select, *cases, *default_case);
    } else {
      exp = new ast::SelectExp(*loc, *select, *cases);
    }
    break;
  }
    /* SHOULD NEVER HAPPEN
  case 22: {
    exp = new ast::CaseExp(*loc);
    break;
  }
    */
  case 23: {
    std::list<ast::MatrixLineExp *>* lines = get_MatrixLines();
    exp = new ast::CellExp(*loc, *lines);
    break;
  }
  case 24: {
    std::list<ast::Exp *>* exps = get_exps();
    exp = new ast::ArrayListExp(*loc, *exps);
    break;
  }
  case 25: {
    std::list<ast::Exp *>* exps = get_exps();
    exp = new ast::AssignListExp(*loc, *exps);
    break;
  }
  case 26: {
    ast::Exp* notexp = get_exp();
    exp = new ast::NotExp(*loc, *notexp);
    break;
  }
  case 27: {
    ast::TransposeExp::Kind kind = get_TransposeExp_Kind();
    ast::Exp* _exp = get_exp();    
    exp = new ast::TransposeExp(*loc, *_exp, kind);
    break;
  }
  case 28: {
    exp = get_VarDec(loc);
    break;
  }
  case 29: {
    symbol::Symbol* name = get_Symbol();
    Location *args_loc = get_location();
    Location *returns_loc = get_location();
    ast::Exp* body = get_exp();
    std::list <ast::Var*>* args_list = get_vars();
    std::list <ast::Var*>* returns_list = get_vars();
    ast::ArrayListVar *args = new ast::ArrayListVar(*args_loc, *args_list);
    ast::ArrayListVar *returns = new ast::ArrayListVar(*returns_loc, *returns_list);
    exp = new ast::FunctionDec(*loc, *name, *args, *returns, *body);
    break;
  }
  case 30: {
    ast::Exp* _start = get_exp();    
    ast::Exp* _step = get_exp();    
    ast::Exp* _end = get_exp();    
    exp = new ast::ListExp(*loc, *_start, *_step, *_end);
    break;
  }
  case 31: {
    ast::Exp* _left = get_exp();    
    ast::Exp* _right = get_exp();    
    exp = new ast::AssignExp(*loc, *_left, *_right);
    break;
  }
  case 32: {
    ast::OpExp::Kind kind = get_OpExp_Kind();
    ast::OpExp::Oper oper = get_OpExp_Oper();
    ast::Exp *left = get_exp();
    ast::Exp *right = get_exp(); 
    ast::OpExp *_opexp  = new ast::OpExp(*loc, *left, oper, *right);
    exp = _opexp;
    _opexp->kind_set(kind);
    break;
  }
  case 33: {
    ast::OpExp::Kind kind = get_OpExp_Kind();
    ast::OpExp::Oper oper = get_OpExp_Oper();
    ast::Exp *left = get_exp();
    ast::Exp *right = get_exp(); 
    ast::LogicalOpExp *_opexp  = 
      new ast::LogicalOpExp(*loc, *left, oper, *right);
    exp = _opexp;
    _opexp->kind_set(kind);
    break;
  }
  case 34: {
    std::list<ast::MatrixLineExp *>* lines = get_MatrixLines();
    exp = new ast::MatrixExp(*loc, *lines);
    break;
  }
  case 35: {
    ast::Exp* name = get_exp();    
    std::list<ast::Exp *> * args = get_exps();
    exp = new ast::CallExp(*loc, *name, *args);
    break;
  }
    /* SHOULD NEVER HAPPEN
  case 36: {
    exp = new ast::MatrixLineExp(*loc);
    break;
  }
    */
  case 37: {
    ast::Exp* name = get_exp();    
    std::list<ast::Exp *>* args = get_exps();
    exp = new ast::CellCallExp(*loc, *name, *args);
    break;
  }
  default: 
    std::cerr << "Unknown code " << code << std::endl;
    exit(2);
  }

  exp->set_verbose(is_verbose);
  if(is_break) exp->break_set();
  if(is_breakable) exp->breakable_set();
  if(is_return) exp->return_set();
  if(is_returnable) exp->returnable_set();
  if(is_continue) exp->continue_set();
  if(is_continuable) exp->continuable_set();
  
  return exp;
}
uint8 BNEP_HCI_SWITCH_ROLE_RSP_T_PDU::get_role() const
{
    return get_uint8 ( BNEP_HCI_SWITCH_ROLE_RSP_T_role );
}
uint8 HCICommandCompletePDU::get_num_hci_command_pkts () const
{
    return get_uint8 ( 2 );
}
uint8 HCICommandCompletePDU::get_status () const
{
    return get_uint8(5) ;
}
Exemple #25
0
static int
decode_data(double **data, const xmlChar * input, dataFormat data_format,
            codingTypes coding, byteOrder byte_order, int max_input_len)
{
    GArray *data_stream, *debase64_buf, *decoded_data;
    char *p, *end_ptr;
    unsigned int i;
    double val;
    int data_count = 0;

    gwy_debug("start.");

    if (input == NULL) {
        g_warning("SPML: decode_data(): NULL input");
        *data = NULL;
        return 0;
    }
    switch (coding) {
        case ZLIB_COMPR_BASE64:
            /*/ XXX: strlen() may not be nice there */
            if (decode_b64((char *)input, &debase64_buf, strlen(input)) != 0) {
                if (debase64_buf != NULL) {
                    g_array_free(debase64_buf, TRUE);
                }
                g_warning("Cannot decode data in BASE64 code.");
                *data = NULL;
                return 0;
            }
            if (inflate_dynamic_array(debase64_buf, &data_stream) != 0) {
                g_warning("Cannot inflate compressed data.");
                g_array_free(debase64_buf, TRUE);
                if (data_stream != NULL) {
                    g_array_free(data_stream, TRUE);
                }
                *data = NULL;
                return 0;
            }
            g_array_free(debase64_buf, TRUE);
            break;
        case BASE64:
            /*/ XXX: strlen() may not be nice there */
            if (decode_b64((char *)input, &data_stream, strlen(input)) != 0) {
                g_warning("Cannot decode data in BASE64 code.");
                if (data_stream != NULL) {
                    g_array_free(data_stream, TRUE);
                }
                *data = NULL;
                return 0;
            }
            break;
        case ASCII:
            p = (char *)input;
            data_stream = g_array_new(FALSE, FALSE, sizeof(double));
            while (p != NULL) {
                double num;

                if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') {
                    p++;
                    continue;
                }
                num = g_ascii_strtod(p, &end_ptr);
                if (num == 0 && end_ptr == p) {
                    g_warning("SPML: decode_data(): No conversion performed "
                              "from ASCII string.");
                    break;
                }
                g_array_append_val(data_stream, num);
                p = end_ptr;
                data_count++;
            }

            break;
            /*/ TODO: */
        case HEX:
        case BINARY:
            g_warning("SPML: decode_data(): Data coding 'HEX' and 'BINARY' "
                      "not supported.");
            break;
        case UNKNOWN_CODING:
            break;
    }
    if (coding == ASCII) {
        /* we have already decoded data */
        if (max_input_len != -1 && data_count != max_input_len) {
            /* not enough input data to fill array defined by length
             * max_input_len */
            g_warning("SPML: decode_data():\n"
                      "Input has not the same length as declared in "
                        "dimensions\n"
                      "(max:%d vs read:%d). Has the channel attribute\n"
                      "'channelReadMethodName'? The channel may be  one\n"
                      "dimensional data used for axis values but not as\n"
                      "a source of data for Gwyddion.",
                      max_input_len, data_count);
            g_array_free(data_stream, TRUE);
            *data = NULL;
            return 0;
        }
        else {
            *data = (double *)data_stream->data;
            /* we can free dynamic array, but not */
            g_array_free(data_stream, FALSE);
            /* containing data. */
            gwy_debug("Datacount: %d", data_count);
            return data_count;
        }
    }
    decoded_data = g_array_new(FALSE, FALSE, sizeof(double));
    p = data_stream->data;
    i = 0;
    switch (data_format) {
        case FLOAT32:
            while (i < data_stream->len) {
                val = get_float32(&p, byte_order);
                g_array_append_val(decoded_data, val);
                data_count++;
                i += sizeof(float);
            }
            break;
        case FLOAT64:
            while (i < data_stream->len) {
                val = get_float64(&p, byte_order);
                g_array_append_val(decoded_data, val);
                i += sizeof(double);
            }
            break;
        case INT8:
            while (i < data_stream->len) {
                val = get_int8(&p);
                g_array_append_val(decoded_data, val);
                i += sizeof(gint8);
            }
            break;
        case INT16:
            while (i < data_stream->len) {
                val = get_int16(&p, byte_order);
                g_array_append_val(decoded_data, val);
                i += sizeof(gint16);
            }
            break;
        case INT32:
            while (i < data_stream->len) {
                val = get_int32(&p, byte_order);
                g_array_append_val(decoded_data, val);
                i += sizeof(gint32);
            }
            break;
        case UINT32:
            while (i < data_stream->len) {
                val = get_uint32(&p, byte_order);
                g_array_append_val(decoded_data, val);
                i += sizeof(guint32);
            }
            break;
        case UINT8:
            while (i < data_stream->len) {
                val = get_uint8(&p);
                g_array_append_val(decoded_data, val);
                i += sizeof(guint8);
            }
            break;
        case UINT16:
            while (i < data_stream->len) {
                val = get_uint16(&p, byte_order);
                g_array_append_val(decoded_data, val);
                i += sizeof(guint16);
            }
            break;
        case STRING:
            g_warning
                ("SPML: decode_data(): Data format 'String' not supported.");
            break;
        case UNKNOWN_DATAFORMAT:
            g_warning("SPML: decode_data(): Unknown dataformat.");
            break;
    }
    g_array_free(data_stream, TRUE);
    data_count = decoded_data->len;
    if (max_input_len != -1 && data_count != max_input_len) {
        g_warning("SPML: decode_data():\n"
                  "Input has not the same length as declared in dimensions\n"
                  "(max:%d vs read:%d). Has the channel attribute\n"
                  "'channelReadMethodName'? The channel may be  one\n"
                  "dimensional data used for axis values but not as\n"
                  "a source of data for Gwyddion.", max_input_len, data_count);
        g_array_free(decoded_data, TRUE);
        *data = NULL;
        return 0;
    }
    *data = (double *)decoded_data->data;
    g_array_free(decoded_data, FALSE);  /* we can free dynamic array, but not */
    /* containing data. */
    gwy_debug("Datacount: %d", data_count);
    return data_count;

}
uint8 HCI_HOST_NUM_COMPLETED_PACKETS_T_PDU::get_num_handles(void) const
{
    return get_uint8(HCI_HOST_NUM_COMPLETED_PACKETS_T_num_handles) ;
}
uint8 HCI_WRITE_STORED_LINK_KEY_T_PDU::get_number_keys(void) const
{
    return get_uint8(HCI_WRITE_STORED_LINK_KEY_T_number_keys) ;
}
uint8 HCI_SET_EVENT_FILTER_T_PDU::get_filter_type() const
{
    return get_uint8 ( HCI_SET_EVENT_FILTER_T_filter_type );
}
uint8 HCI_WRITE_CURRENT_IAC_LAP_T_PDU::get_num_current_iac(void) const
{
    return get_uint8(HCI_WRITE_CURRENT_IAC_LAP_T_num_current_iac) ;
}
BluetoothDeviceAddress HCIPDU::get_BluetoothDeviceAddress(uint16 offset) const
{
    return BluetoothDeviceAddress ( get_uint16 ( offset + 4 ),
                                    get_uint8  ( offset + 3 ),
                                    get_uint24 ( offset ) ) ; 
}