int test_ret_attr_cut(pn_engine_t *e) { pn_int rc = -1; sdb_ret_attr_t *av; pn_int i; av = (sdb_ret_attr_t *)e->data.data; i = 0; e->raw->buf->last -= 15; while (PN_OK != rc && 20 > ++i) { rc = pn_engine_parse(e); if (PN_OK != rc) { pnlogerr("parse failed with rc[%x]", rc); } ++e->raw->buf->last; } pnlog("uid:%.*s, domain:%.*s, itemname:%.*s, attrname:%.*s, size:%d, attrval_str:%.*s", strp(av->uid), strp(av->domain), strp(av->itemname), strp(av->attrname), av->size, strp(av->attrval_str)); }
int Hsp3ExtLibInit( HSP3TYPEINFO *info ) { int i; STRUCTDAT *st; char tmp[1024]; hspctx = info->hspctx; exinfo = info->hspexinfo; pmpval = exinfo->mpval; libmax = hspctx->hsphed->max_linfo / sizeof(LIBDAT); prmmax = hspctx->hsphed->max_finfo / sizeof(STRUCTDAT); hpidat = NULL; if ( Hsp3ExtAddPlugin() ) return 1; for(i=0;i<prmmax;i++) { st = GetPRM(i); if ( BindFUNC( st, NULL ) == 1 ) { sprintf( tmp,"No FUNC:%s",strp(st->nameidx) ); Alert( tmp ); } } return 0; }
static int BindFUNC( STRUCTDAT *st, char *name ) { // ファンクションのバインドを行なう // (name:後から与える時のファンクション名) // int i; char *n; LIBDAT *lib; HINSTANCE hd; if (( st->subid != STRUCTPRM_SUBID_DLL )&&( st->subid != STRUCTPRM_SUBID_OLDDLL )) return 4; i = st->nameidx; if ( i < 0 ) { if ( name == NULL ) return 3; n = name; } else { n = strp(i); } lib = GetLIB( st->index ); if ( lib->flag != LIBDAT_FLAG_DLLINIT ) { BindLIB( lib, NULL ); if ( lib->flag != LIBDAT_FLAG_DLLINIT ) return 2; } hd = (HINSTANCE)(lib->hlib); st->proc = (void *)GetProcAddress( hd, n ); if ( hd == NULL ) return 1; st->subid--; return 0; }
static int Hsp3ExtAddPlugin( void ) { // プラグインの登録 // int i; HSPHED *hed; char *ptr; char *libname; char *funcname; HPIDAT *hpi; HSP3TYPEINFO *info; HINSTANCE hd; char tmp[512]; hed = hspctx->hsphed; ptr = (char *)hed; hpi = hpidat = (HPIDAT *)( ptr + hed->pt_hpidat ); hpimax = hed->max_hpi / sizeof( HPIDAT ); for ( i=0;i<hpimax;i++ ) { libname = strp(hpi->libname); funcname = strp(hpi->funcname); info = code_gettypeinfo(-1); if ( hpi->flag == HPIDAT_FLAG_TYPEFUNC ) { hd = DllManager().load_library( libname ); if ( hd == NULL ) { sprintf( tmp,"No DLL:%s",libname ); Alert( tmp ); return 1; } hpi->libptr = (void *)hd; func = (DLLFUNC)GetProcAddress( hd, funcname ); if ( func == NULL ) { sprintf( tmp,"No DLL:%s:%s", libname, funcname ); Alert( tmp ); return 1; } func( info ); code_enable_typeinfo( info ); //Alertf( "%d_%d [%s][%s]", i, info->type, libname, funcname ); } hpi++; } return 0; }
static void BindLIB( LIBDAT *lib, char *name ) { // ライブラリのバインドを行なう // (name:後から与える時のライブラリ名) // int i; char *n; HINSTANCE hd; if ( lib->flag != LIBDAT_FLAG_DLL ) return; i = lib->nameidx; if ( i < 0 ) { if ( name == NULL ) return; n = name; } else { n = strp(i); } hd = DllManager().load_library( n ); if ( hd == NULL ) return; lib->hlib = (void *)hd; lib->flag = LIBDAT_FLAG_DLLINIT; }
int call_method2( char *prmbuf, const STRUCTDAT *st ) { // 指定 IID を取得してメソッド呼び出し // (code_expand_next() から呼ばれる) // const LIBDAT *lib; const IID *piid; IUnknown *punk, *punk2; int result; HRESULT hr; // IID 情報を取ってくる lib = &hspctx->mem_linfo[ st->index ]; piid = (IID *)strp( lib->nameidx ); punk = *(IUnknown **)prmbuf; if ( st->otindex < 0 || punk == NULL ) throw ( HSPERR_COMDLL_ERROR ); hr = punk->QueryInterface( *piid, (void**)&punk2 ); if ( FAILED(hr) || punk2 == NULL ) throw ( HSPERR_COMDLL_ERROR ); *(IUnknown **)prmbuf = punk2; result = call_method( punk2, st->otindex, (int*)prmbuf, st->size / 4 ); punk2->Release(); return result; }
static int BindFUNC( STRUCTDAT *st, char *name ) { // ファンクションのバインドを行なう // (name:後から与える時のファンクション名) // int i; char *n; LIBDAT *lib; HINSTANCE hd; if (( st->subid != STRUCTPRM_SUBID_DLL )&&( st->subid != STRUCTPRM_SUBID_OLDDLL )) return 4; i = st->nameidx; if ( i < 0 ) { if ( name == NULL ) return 3; n = name; } else { n = strp(i); } lib = GetLIB( st->index ); if ( lib->flag != LIBDAT_FLAG_DLLINIT ) { BindLIB( lib, NULL ); if ( lib->flag != LIBDAT_FLAG_DLLINIT ) return 2; } hd = (HINSTANCE)(lib->hlib); if ( hd == NULL ) return 1; #ifdef HSPUTF8 HSPAPICHAR *hactmp1; char tmp1[512]; chartoapichar(n,&hactmp1); cnvsjis(tmp1,(char*)hactmp1,512); st->proc = (void *)GetProcAddress( hd, tmp1 ); freehac(&hactmp1); #else st->proc = (void *)GetProcAddress( hd, n ); #endif if ( st->proc == NULL ) return 1; st->subid--; return 0; }
int main(int argv, char **args){ pn_engine_t *engine = NULL; sdb_ret_attr_t av; /* pn_str_t raw = pn_string("ATTR uid domain item1 color 3\r\nred_green\r\n"); */ pn_str_t raw = pn_string("ATTR uid domain item1 color 3\r\nred\r\n"); /* pn_str_t raw = pn_string("ATTR uid domain item1 colo"); */ pn_chain_t ch; pn_buf_t buf; pn_int rc; rc = pn_engine_create(NULL, &engine, its_attr); if (PN_OK != rc) { pnlogerr("create engine failed"); return rc; } memset(&av, 0, sizeof(sdb_ret_attr_t)); pn_engine_set_data(engine, &av, sizeof(sdb_ret_attr_t)); buf.pos = raw.data; buf.last = raw.data + raw.len; ch.buf = &buf; ch.next = NULL; pn_engine_set_raw(engine, &ch); test_ret_attr_cut(engine); pnlog("test done"); exit(0); rc = pn_engine_parse(engine); if (PN_OK != rc) { pnlogerr("parse failed with rc[%d]", rc); return rc; } pnlog("uid:%.*s, domain:%.*s, itemname:%.*s, attrname:%.*s, size:%d, attrval_str:%.*s", strp(av.uid), strp(av.domain), strp(av.itemname), strp(av.attrname), av.size, strp(av.attrval_str)); return 0; }
static int Hsp3ExtAddPlugin( void ) { // プラグインの登録 // int i; HSPHED *hed; char *ptr; char *libname; char *funcname; HPIDAT *org_hpi; MEM_HPIDAT *hpi; HSP3TYPEINFO *info; HINSTANCE hd; TCHAR tmp[512]; hed = hspctx->hsphed; ptr = (char *)hed; org_hpi = (HPIDAT *)(ptr + hed->pt_hpidat); hpimax = hed->max_hpi / sizeof(HPIDAT); if ( hpimax == 0 ) return 0; hpidat = (MEM_HPIDAT *)malloc(hpimax * sizeof(MEM_HPIDAT)); hpi = hpidat; for ( i=0;i<hpimax;i++ ) { hpi->flag = org_hpi->flag; hpi->option = org_hpi->option; hpi->libname = org_hpi->libname; hpi->funcname = org_hpi->funcname; hpi->libptr = NULL; libname = strp(hpi->libname); funcname = strp(hpi->funcname); info = code_gettypeinfo(-1); if ( hpi->flag == HPIDAT_FLAG_TYPEFUNC ) { hd = DllManager().load_library( libname ); if ( hd == NULL ) { #ifdef HSPUTF8 TCHAR tmp[512]; HSPAPICHAR *haclibname; chartoapichar(libname, &haclibname); _stprintf(tmp, TEXT("No DLL:%s"), haclibname); freehac(&haclibname); AlertW(tmp); #else Alertf( "No DLL:%s", libname ); #endif return 1; } hpi->libptr = (void *)hd; #ifdef HSPUTF8 HSPAPICHAR *hacfuncname; char tmp2[512]; chartoapichar(funcname,&hacfuncname); cnvsjis(tmp2,(char*)hacfuncname,512); func = (DLLFUNC)GetProcAddress( hd, tmp2 ); #else func = (DLLFUNC)GetProcAddress( hd, funcname ); #endif if ( func == NULL ) { #ifdef HSPUTF8 TCHAR tmp[512]; HSPAPICHAR *haclibname; chartoapichar(libname, &haclibname); _stprintf(tmp, TEXT("No DLL:%s:%s"), haclibname, hacfuncname); freehac(&haclibname); AlertW(tmp); freehac(&hacfuncname); #else Alertf("No DLL:%s:%s", libname, funcname); #endif return 1; } func( info ); code_enable_typeinfo( info ); //Alertf( "%d_%d [%s][%s]", i, info->type, libname, funcname ); #ifdef HSPUTF8 freehac(&hacfuncname); #endif } hpi++; org_hpi++; } return 0; }
static int cmdfunc_ctrlcmd( int cmd ) { // cmdfunc : TYPE_DLLCTRL // (拡張DLLコントロールコマンド) // code_next(); // 次のコードを取得(最初に必ず必要です) if ( cmd >= TYPE_OFFSET_COMOBJ ) { #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else // COM インターフェースメソッドの呼び出し STRUCTDAT *st; st = GetPRM( cmd - TYPE_OFFSET_COMOBJ ); hspctx->stat = code_expand_and_call( st ); return RUNMODE_RUN; #endif } switch( cmd ) { // サブコマンドごとの分岐 case 0x00: // newcom #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else { PVal *pval; APTR aptr; IUnknown **ppunkNew, *punkDef; CLSID clsid; char *clsid_name; const IID *piid, *piid2; void *iptr; LIBDAT *lib; STRUCTDAT *st; int inimode; // 第1パラメータ:新しいインターフェースポインタを格納する変数 // (変数にNULLポインタを格納) aptr = code_getva( &pval ); iptr = NULL; code_setva( pval, aptr, TYPE_COMOBJ, &iptr ); ppunkNew = (IUnknown **)HspVarCorePtrAPTR( pval, aptr ); // CLSID / IID 情報を取得 if ( !code_getexflg() && *type == TYPE_DLLCTRL ) { // 第2パラメータ:#usecom 登録情報 st = code_getcomst(); if ( st->otindex != -1 ) throw HSPERR_TYPE_MISMATCH; lib = &hspctx->mem_linfo[ st->index ]; if ( lib->clsid == -1 ) throw HSPERR_INVALID_PARAMETER; clsid_name = strp(lib->clsid); piid = (IID *)strp( lib->nameidx ); piid2 = NULL; } else { // 第2パラメータ:文字列 CLSID // (IID はデフォルトで IID_IDispatch, サポートされていなければ IID_IUnknown ) clsid_name = code_getds(""); piid = &IID_IDispatch; piid2 = &IID_IUnknown; } inimode = code_getdi(0); // 初期化モード punkDef = (IUnknown *)code_getdi(0); // デフォルトオブジェクト // 新規CLSIDからインスタンスを作成 hspctx->stat = 0; switch ( inimode ) { case 0: // 新規にロード if ( clsid_name[0]!='\0' ) { if ( GetIIDFromString(&clsid,clsid_name,true) != FALSE && SUCCEEDED( CoCreateInstance( clsid, NULL, CLSCTX_SERVER, *piid, (void**)ppunkNew )) && *ppunkNew != NULL ) { break; } if ( piid2 != NULL && SUCCEEDED( CoCreateInstance( clsid, NULL, CLSCTX_SERVER, *piid2, (void**)ppunkNew )) && *ppunkNew != NULL ) { break; } hspctx->stat = 1; } break; case -2: // オブジェクトを明示的に指定する場合 ( AddRef() あり) if ( punkDef != NULL ) punkDef->AddRef(); case -1: // オブジェクトを明示的に指定する場合 ( AddRef() なし) *ppunkNew = punkDef; break; default: throw HSPERR_UNSUPPORTED_FUNCTION; } #ifdef HSP_COMOBJ_DEBUG COM_DBG_MSG( "newcom : pObj=%p : &pObj=%p\n", *ppunkNew, ppunkNew); #endif break; } #endif // HSP_COM_UNSUPPORTED case 0x01: // querycom #ifdef HSP_COM_UNSUPPORTED throw HSPERR_UNSUPPORTED_FUNCTION; #else { PVal *pval, *pvalNew; APTR aptr, aptrNew; IUnknown **ppunkDst, **ppunkSrc; IID iid; const IID *piid; void *iptr; STRUCTDAT *st; LIBDAT *lib; // 第1パラメータ:新しいインターフェースポインタを格納する変数 aptrNew = code_getva( &pvalNew ); // 第2パラメータ:既存のCOMオブジェクト aptr = code_getva( &pval ); if ( pval->flag != TYPE_COMOBJ ) throw ( HSPERR_TYPE_MISMATCH ); ppunkSrc = (IUnknown **)HspVarCorePtrAPTR( pval, aptr ); if ( ! IsVaridComPtr(ppunkSrc) ) throw ( HSPERR_COMDLL_ERROR ); // IID 情報を取得 if ( *type == TYPE_DLLCTRL ) { // 第3パラメータ:#usecom 登録情報 st = code_getcomst(); if ( st->otindex != -1 ) throw ( HSPERR_TYPE_MISMATCH ); lib = &hspctx->mem_linfo[ st->index ]; piid = (IID *)strp( lib->nameidx ); } else { // 第3パラメータ:文字列 IID GetIIDFromString( &iid, code_gets() ); piid = &iid; } if ( pvalNew->flag != TYPE_COMOBJ ) { // 代入により型変換 iptr = NULL; code_setva( pvalNew, aptrNew, TYPE_COMOBJ, &iptr ); } ppunkDst = (IUnknown **)HspVarCorePtrAPTR( pvalNew, aptrNew ); // query によりインスタンスを得る QueryComPtr( ppunkDst, *ppunkSrc, piid ); if ( IsVaridComPtr(ppunkSrc) ) hspctx->stat = 0; else hspctx->stat = 1; break; } #endif // HSP_COM_UNSUPPORTED case 0x02: // delcom #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else { PVal *pval; APTR aptr; IUnknown **ppunk; VARIANT *var; void *ptr; // 第1パラメータ:解放するCOMオブジェクト変数 aptr = code_getva( &pval ); ptr = HspVarCorePtrAPTR( pval, aptr ); switch ( pval->flag ) { case TYPE_COMOBJ: ppunk = (IUnknown **)ptr; ReleaseComPtr( ppunk ); break; case TYPE_VARIANT: var = (VARIANT *)ptr; VariantClear( var ); break; default: throw HSPERR_TYPE_MISMATCH; } // このタイミングで一時オブジェクトも削除しちゃう if ( comconv_var.vt != VT_EMPTY ) VariantClear( &comconv_var ); break; } #endif // HSP_COM_UNSUPPORTED case 0x03: // cnvstow { PVal *pval; char *ptr; char *ps; int size; ptr = code_getvptr( &pval, &size ); ps = code_gets(); cnvwstr( ptr, ps, size/2 ); break; } case 0x04: // comres #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else if ( code_getexflg() ) { comres_pval = NULL; comres_aptr = 0; } else { comres_aptr = code_getva( &comres_pval ); } break; #endif // HSP_COM_UNSUPPORTED case 0x05: // axobj #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else { PVal *pval; APTR aptr; const IID *piid; void *iptr; BMSCR *bm; HWND hwnd; int id,sx,sy; char clsid_name[1024]; IUnknown **ppunk, *punkObj, *punkObj2; STRUCTDAT *st; LIBDAT *lib; HRESULT hr; bm = GetBMSCR(); // 第1パラメータ:新しいインターフェースポインタを格納する変数 // (あらかじめ変数にNULLを格納) aptr = code_getva( &pval ); iptr = NULL; code_setva( pval, aptr, TYPE_COMOBJ, &iptr ); ppunk = (IUnknown **)HspVarCorePtrAPTR( pval, aptr ); // オブジェクトの CLSID, ProgID, etc. if ( *type == TYPE_DLLCTRL ) { // 第2パラメータ:#usecom 登録情報から取得 st = code_getcomst(); if ( st->otindex != -1 ) throw ( HSPERR_TYPE_MISMATCH ); lib = &hspctx->mem_linfo[ st->index ]; piid = (IID *)strp( lib->nameidx ); if ( lib->clsid == -1 ) throw ( HSPERR_INVALID_PARAMETER ); strncpy( clsid_name, strp(lib->clsid), sizeof(clsid_name)-1 ); } else { // 第2パラメータ:文字列 CLSID or ProgID を取得 (IID は IDispatch) piid = &IID_IDispatch; strncpy( clsid_name, code_gets(), sizeof(clsid_name)-1 ); } // コントロールのサイズ sx = code_getdi( bm->sx ); sy = code_getdi( bm->sy ); // ActiveXとしてロード // if ( fn_atxinit == NULL ) throw ( HSPERR_UNSUPPORTED_FUNCTION ); hwnd = CreateWindow( atxwndclass, clsid_name, WS_CHILD, // 最初は WS_VISIBLE なし (後で ShowWindow() ) bm->cx, bm->cy, sx, sy, bm->hwnd, (HMENU)0, (HINSTANCE)hspctx->instance, NULL ); punkObj2 = NULL; if ( hwnd ) { punkObj = NULL; fn_atxgetctrl( hwnd, (void**)&punkObj ); if ( punkObj ) { // 指定 IID が存在するかどうか hr = punkObj->QueryInterface( *piid, (void**)&punkObj2 ); punkObj->Release(); } } if ( punkObj2 == NULL ) { // 目的オブジェクトではないときコントロールを削除 if (hwnd) { DestroyWindow( hwnd ); } hspctx->stat = -1; break; } // COM 型変数に格納 *ppunk = punkObj2; // HSPのウインドゥオブジェクトとして登録する ShowWindow( hwnd, SW_SHOW ); id = AddHSPObject( hwnd, HSPOBJ_TAB_SKIP, sy ); #ifdef HSP_COMOBJ_DEBUG Alertf( "axobj : pObj=%p : &pObj=%p\n", *ppunk, ppunk); #endif break; } #endif // HSP_COM_UNSUPPORTED case 0x06: // winobj { #ifdef HSPDISH throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else char clsname[1024]; char winname[1024]; HWND hwnd; char *ps; BMSCR *bm; int i; int prm[6]; ps = code_gets(); strncpy( clsname, ps, 1023 ); ps = code_gets(); strncpy( winname, ps, 1023 ); bm = GetBMSCR(); for(i=0;i<6;i++) { prm[i] = code_getdi(0); } if ( prm[2] <= 0 ) prm[2] = bm->ox; if ( prm[3] <= 0 ) prm[3] = bm->oy; hwnd = CreateWindowEx( (DWORD) prm[0], // 拡張ウィンドウスタイル clsname, // ウィンドウクラス名 winname, // ウィンドウ名 (DWORD) prm[1], // ウィンドウスタイル bm->cx, bm->cy, prm[2], prm[3], // X,Y,SIZEX,SIZEY bm->hwnd, // 親ウィンドウのハンドル (HMENU) prm[4], // メニューハンドルまたは子ウィンドウID bm->hInst, // インスタンスハンドル (PVOID) prm[5] // ウィンドウ作成データ ); // AddHSPObject( hwnd, HSPOBJ_TAB_SKIP, prm[3], NULL, 0 ); // HSPのウインドゥオブジェクトとして登録する AddHSPObject( hwnd, HSPOBJ_TAB_SKIP, prm[3] ); break; #endif // HSPDISH } case 0x07: // sendmsg { int hw,p1,p2,p3,p4,fl,sz; char *vptr; hw = code_getdi(0); p1 = code_getdi(0); vptr = code_getsptr( &fl ); if ( fl == TYPE_STRING ) { p2 = (int)code_stmpstr( vptr ); } else { p2 = *(int *)vptr; } vptr = code_getsptr( &fl ); if ( fl == TYPE_STRING ) { p3 = (int)vptr; } else { p3 = *(int *)vptr; } //Alertf( "SEND[%x][%x][%x]",p1,p2,p3 ); hspctx->stat = (int)SendMessage( (HWND)hw, p1, p2, p3 ); break; } case 0x08: // comevent #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else { PVal *pval; APTR aptr; void* iptr; char *ps; IID iid, *piid; unsigned short *subr; IUnknown **ppunk, **ppunkEvent; // 第1パラメータ:イベントハンドラオブジェクト (IEventHandler) を格納する変数 // (あらかじめ NULL で初期化) aptr = code_getva( &pval ); iptr = NULL; code_setva( pval, aptr, TYPE_COMOBJ, &iptr ); ppunkEvent = (IUnknown **)HspVarCorePtrAPTR( pval, aptr ); // 第2パラメータ:COMオブジェクトを格納した変数 aptr = code_getva( &pval ); if ( pval->flag != TYPE_COMOBJ ) throw ( HSPERR_TYPE_MISMATCH ); ppunk = (IUnknown **)HspVarCorePtrAPTR( pval, aptr ); if ( ! IsVaridComPtr(ppunk) ) throw ( HSPERR_COMDLL_ERROR ); // 第3パラメータ:コネクションポイントIID (文字列形式) ps = code_getds(""); if ( ps[0] != '\0' ) { piid = &iid; GetIIDFromString( piid, ps ); } else { piid = NULL; // NULL のときデフォルトIID が自動的に取得される } // 第4パラメータ:コールバック用のサブルーチンラベル subr = code_getlb2(); // イベントハンドラ作成・接続 SetComEvent( ppunkEvent, ppunk, piid, subr ); #ifdef HSP_COMOBJ_DEBUG COM_DBG_MSG( "comevent : pEvent=%p : pObj=%p\n", *ppunkEvent, *ppunk); #endif break; } #endif // HSP_COM_UNSUPPORTED case 0x09: // comevarg #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else { PVal *pval, *pval2; APTR aptr, aptr2; VARIANT *v; void *ptr; int p1,p2; int res; IUnknown **ppunk; VARIANT varTemp; // 第1パラメータ:イベントのパラメータを格納する変数 aptr = code_getva( &pval ); // 第2パラメータ:イベントハンドラオブジェクト変数 aptr2 = code_getva( &pval2 ); if ( pval2->flag != TYPE_COMOBJ ) throw ( HSPERR_TYPE_MISMATCH ); ppunk = (IUnknown **)HspVarCorePtrAPTR( pval2, aptr2 ); if ( ! IsVaridComPtr(ppunk) ) throw ( HSPERR_COMDLL_ERROR ); // 第3パラメータ:パラメータインデックス p1 = code_getdi(0); // 第4パラメータ:文字列変換フラグ p2 = code_getdi(0); // イベントのパラメータ取得 v = GetEventArg( *ppunk, p1 ); if ( v == NULL ) throw ( HSPERR_ILLEGAL_FUNCTION ); switch ( p2 ) { case 0: VariantInit( &varTemp ); VariantCopyInd( &varTemp, v ); ptr = comget_variant( &varTemp, &res ); VariantClear( &varTemp ); break; case 1: VariantInit( &varTemp ); if FAILED( VariantChangeType( &varTemp, v, VARIANT_ALPHABOOL, VT_BSTR ) ) throw ( HSPERR_TYPE_INITALIZATION_FAILED ); ptr = comget_variant( &varTemp, &res ); VariantClear( &varTemp ); break; case 2: ptr = v; res = HSPVAR_FLAG_VARIANT; break; default: throw ( HSPERR_ILLEGAL_FUNCTION ); } code_setva( pval, aptr, res, ptr ); hspctx->stat = res; break; } #endif // HSP_COM_UNSUPPORTED case 0x0a: // sarrayconv #ifdef HSP_COM_UNSUPPORTED throw ( HSPERR_UNSUPPORTED_FUNCTION ); #else { PVal *pval1, *pval2; APTR aptr1, aptr2; int convdir, size; VARIANT *variant, varTemp; VARTYPE vt; SAFEARRAY *psa; long lbound, ubound; HRESULT hr; aptr1 = code_getva( &pval1 ); aptr2 = code_getva( &pval2 ); convdir = code_getdi(0); size = code_getdi(0); switch ( convdir ) { case 0: case 2: case 4: // 配列変数から SafeArray に変換 VariantInit( &varTemp ); code_setva( pval1, aptr1, HSPVAR_FLAG_VARIANT, &varTemp ); variant = (VARIANT *)HspVarCorePtrAPTR( pval1, aptr1 ); VariantClear( variant ); // 一応 if ( convdir == 2 ) { // バイナリデータ(一次元のみ) void *ptr = HspVarCorePtrAPTR( pval2, aptr2 ); psa = CreateBinarySafeArray( ptr, size, &vt ); } else { BOOL bVariant = ( convdir == 4 ); psa = ConvVar2SafeArray( pval2, bVariant, &vt ); } variant->vt = vt | VT_ARRAY; variant->parray = psa; break; case 1: case 3: // SafeArray から配列変数に変換 if ( pval2->flag != HSPVAR_FLAG_VARIANT ) throw HSPERR_INVALID_TYPE; variant = (VARIANT *)HspVarCorePtrAPTR( pval2, aptr2 ); if ( (variant->vt & VT_ARRAY) == 0 ) throw HSPERR_INVALID_TYPE; psa = variant->parray; if ( psa == NULL ) throw HSPERR_ARRAY_OVERFLOW; vt = variant->vt & VT_TYPEMASK; if ( vt == VT_EMPTY ) { hr = SafeArrayGetVartype( psa, &vt ); if ( FAILED(hr) || vt == VT_EMPTY ) throw HSPERR_INVALID_ARRAYSTORE; } if ( convdir == 1 ) { ConvSafeArray2Var( pval1, psa, vt ); } else { // バイナリデータ(一次元のみ) int varsize; void *ptr = HspVarCorePtrAPTR( pval1, aptr1 ); if ( vt != VT_UI1 && vt != VT_I1 ) throw HSPERR_INVALID_TYPE; SafeArrayGetLBound( psa, 1, &lbound ); hr = SafeArrayGetUBound( psa, 1, &ubound ); if ( FAILED(hr) ) throw HSPERR_ARRAY_OVERFLOW; size = ubound - lbound + 1; HspVarCoreGetBlockSize( pval1, (PDAT*)ptr, &varsize ); if ( varsize < size ) throw HSPERR_BUFFER_OVERFLOW; GetBinarySafeArray( ptr, size, psa ); } break; default: throw ( HSPERR_UNSUPPORTED_FUNCTION ); } break; } #endif // HSP_COM_UNSUPPORTED default: throw ( HSPERR_SYNTAX ); } return RUNMODE_RUN; }