Source

yatce / erl_tc_driver.c

/**
 *   yatce
 *   Copyright (C) 2009   kuenishi+yatce@gmail.com

 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.

 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.

 *     You should have received a copy of the GNU General Public License
 *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **/

#include "erl_tc_driver.h"
#include "tc_wrapper.h"
#include <string.h> // for strncpy

static ErlDrvData tc_drv_start(ErlDrvPort port, char *buff){
  tc_data* d = (tc_data*)driver_alloc(sizeof(tc_data));
  d->port = port;
  d->adb  = tcadbnew();
  fprintf( stderr, "hello erl_tc_driver!\n" );
  return (ErlDrvData)d;
}

static void tc_drv_stop(ErlDrvData handle){
  tc_data* d = (tc_data*)handle;
  tcadbclose( d->adb );
  tcadbdel( d->adb );
  puts(__func__);
  driver_free((char*)handle);
}

// obsolete
static void tc_drv_output(ErlDrvData handle, char *buff, int bufflen){
  tc_data* d = (tc_data*)handle;
  
  ErlDrvTermData spec_pair[6] = { 
        ERL_DRV_ATOM, driver_mk_atom("nil"),
        ERL_DRV_ATOM, driver_mk_atom("nil"),
      ERL_DRV_TUPLE, 2
    };
  int spec_pair_size = sizeof(spec_pair) / sizeof(spec_pair[0]) ;
  
  driver_output_term(d->port, spec_pair, spec_pair_size );
  return;
}

// obsolete
static void tc_drv_outputv(ErlDrvData drv_data, ErlIOVec *ev){
  tc_data* d = (tc_data*)drv_data;
  //  int index;
  puts(__func__ );
  printf("%d %d %p %p \n", ev->vsize, ev->size, ev->iov, ev->binv );
  driver_outputv(d->port, NULL, 0,ev,0);
}

// inspired by http://rakuto.blogspot.com/2008/07/manipulate-erlang-binary-term-format-in.html
// this function only apportions the request == calls function depending on its command
static int tc_drv_control(ErlDrvData drv_data, unsigned int command, 
			  char * buf, int len, char ** rbuf, int rlen ){
  tc_data* d = (tc_data*)drv_data;
  int index, ver;
  index = 0;

  // assume all protocol includes tablename.
  // All ei_xxx functions return 0 if it will be success, else return -1
  if( ei_decode_version(buf, &index, &ver) != 0 )// Value of 'index' will become 1.
    return -1;
  //set_port_control_flags( d->port, PORT_CONTROL_FLAG_BINARY ); //あんまり関係ないみたい,むしろ入れたらバグる
  switch(command) {
  case TC_CLOSE:
    rlen = tc_wrapper_close( d->adb, buf+index, len-index, rbuf, rlen);
    break;
  case TC_OPEN_FILE:
    rlen = tc_wrapper_open( d->adb, buf+index, len-index, rbuf, rlen);
    break;
  case TC_LOOKUP:
    rlen = tc_wrapper_lookup( d->adb, buf+index, len-index, rbuf, rlen);
    break;
  case TC_INSERT:
    rlen = tc_wrapper_insert( d->adb, buf+index, len-index, rbuf, rlen);
    break;
    
  default:
    rlen = -1;
  }
#if 0 //#define DEBUG_MSG
  DEBUG_INFO( (*rbuf), rlen-1 );
#endif
  return rlen;
}