aboutsummaryrefslogtreecommitdiffstats
path: root/ext/win32ole/win32ole.c
diff options
context:
space:
mode:
authorsuke <suke@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-08-13 15:28:26 +0000
committersuke <suke@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-08-13 15:28:26 +0000
commit96b27e5a977eab8818769a533a2c1c225b07efea (patch)
treebc28cf576555d05baa44cb12c07cafcbac17f6cf /ext/win32ole/win32ole.c
parent77db03023cf2e126e82643f47fb93f12366a66f8 (diff)
downloadruby-96b27e5a977eab8818769a533a2c1c225b07efea.tar.gz
* ext/win32ole/win32ole.c: seperate WIN32OLE_RECORD src from
win32ole.c * ext/win32ole/win32ole.h: ditto. * ext/win32ole/win32ole_record.c: ditto. * ext/win32ole/win32ole_record.h: ditto. * ext/win32ole/depend: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47174 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/win32ole/win32ole.c')
-rw-r--r--ext/win32ole/win32ole.c575
1 files changed, 3 insertions, 572 deletions
diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c
index 9008155222..24cc184fcb 100644
--- a/ext/win32ole/win32ole.c
+++ b/ext/win32ole/win32ole.c
@@ -33,7 +33,6 @@ const IID IID_IMultiLanguage2 = {0xDCCFC164, 0x2B38, 0x11d2, {0xB7, 0xEC, 0x00,
}\
}
-
#define WIN32OLE_VERSION "1.7.7"
typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
@@ -93,7 +92,6 @@ typedef struct tagIEVENTSINKOBJ {
VALUE cWIN32OLE;
VALUE cWIN32OLE_EVENT;
-VALUE cWIN32OLE_RECORD;
static VALUE ary_ole_event;
static ID id_events;
@@ -139,7 +137,6 @@ struct oledata {
IDispatch *pDispatch;
};
-
struct oleeventdata {
DWORD dwCookie;
IConnectionPoint *pConnectionPoint;
@@ -151,10 +148,6 @@ struct oleparam {
OLECHAR** pNamedArgs;
};
-struct olerecorddata {
- IRecordInfo *pri;
- void *pdata;
-};
static HRESULT ( STDMETHODCALLTYPE QueryInterface )(IDispatch __RPC_FAR *, REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject);
static ULONG ( STDMETHODCALLTYPE AddRef )(IDispatch __RPC_FAR * This);
@@ -185,8 +178,6 @@ static void * get_ptr_of_variant(VARIANT *pvar);
static void ole_set_safe_array(long n, SAFEARRAY *psa, LONG *pid, long *pub, VALUE val, long dim, VARTYPE vt);
static long dimension(VALUE val);
static long ary_len_of_dim(VALUE ary, long dim);
-static int hash2olerec(VALUE key, VALUE val, VALUE rec);
-static void ole_rec2variant(VALUE rec, VARIANT *var);
static void ole_val2ptr_variant(VALUE val, VARIANT *var);
static VALUE ole_set_member(VALUE self, IDispatch *dispatch);
static VALUE fole_s_allocate(VALUE klass);
@@ -280,20 +271,6 @@ static VALUE evs_delete(long i);
static VALUE evs_entry(long i);
static VALUE evs_length(void);
-static HRESULT typelib_from_val(VALUE obj, ITypeLib **pTypeLib);
-static HRESULT recordinfo_from_itypelib(ITypeLib *pTypeLib, VALUE name, IRecordInfo **ppri);
-static void olerecord_set_ivar(VALUE obj, IRecordInfo *pri, void *prec);
-static void olerecord_free(struct olerecorddata *pvar);
-static VALUE folerecord_s_allocate(VALUE klass);
-static VALUE folerecord_initialize(VALUE self, VALUE typename, VALUE oleobj);
-static VALUE folerecord_to_h(VALUE self);
-static VALUE folerecord_typename(VALUE self);
-static VALUE olerecord_ivar_get(VALUE self, VALUE name);
-static VALUE olerecord_ivar_set(VALUE self, VALUE name, VALUE val);
-static VALUE folerecord_method_missing(int argc, VALUE *argv, VALUE self);
-static VALUE folerecord_ole_instance_variable_get(VALUE self, VALUE name);
-static VALUE folerecord_ole_instance_variable_set(VALUE self, VALUE name, VALUE val);
-static VALUE folerecord_inspect(VALUE self);
static void init_enc2cp(void);
static void free_enc2cp(void);
@@ -1319,67 +1296,6 @@ ole_val_ary2variant_ary(VALUE val, VARIANT *var, VARTYPE vt)
return hr;
}
-static int
-hash2olerec(VALUE key, VALUE val, VALUE rec)
-{
- VARIANT var;
- OLECHAR *pbuf;
- struct olerecorddata *prec;
- IRecordInfo *pri;
- HRESULT hr;
-
- if (val != Qnil) {
- Data_Get_Struct(rec, struct olerecorddata, prec);
- pri = prec->pri;
- VariantInit(&var);
- ole_val2variant(val, &var);
- pbuf = ole_vstr2wc(key);
- hr = pri->lpVtbl->PutField(pri, INVOKE_PROPERTYPUT, prec->pdata, pbuf, &var);
- SysFreeString(pbuf);
- VariantClear(&var);
- if (FAILED(hr)) {
- ole_raise(hr, eWIN32OLERuntimeError, "failed to putfield of `%s`", StringValuePtr(key));
- }
- }
- return ST_CONTINUE;
-}
-
-static void
-ole_rec2variant(VALUE rec, VARIANT *var)
-{
- struct olerecorddata *prec;
- ULONG size = 0;
- IRecordInfo *pri;
- HRESULT hr;
- VALUE fields;
- Data_Get_Struct(rec, struct olerecorddata, prec);
- pri = prec->pri;
- if (pri) {
- hr = pri->lpVtbl->GetSize(pri, &size);
- if (FAILED(hr)) {
- ole_raise(hr, eWIN32OLERuntimeError, "failed to get size for allocation of VT_RECORD object");
- }
- if (prec->pdata) {
- free(prec->pdata);
- }
- prec->pdata = ALLOC_N(char, size);
- if (!prec->pdata) {
- rb_raise(rb_eRuntimeError, "failed to memory allocation of %lu bytes", (unsigned long)size);
- }
- hr = pri->lpVtbl->RecordInit(pri, prec->pdata);
- if (FAILED(hr)) {
- ole_raise(hr, eWIN32OLERuntimeError, "failed to initialize VT_RECORD object");
- }
- fields = folerecord_to_h(rec);
- rb_hash_foreach(fields, hash2olerec, rec);
- V_RECORDINFO(var) = pri;
- V_RECORD(var) = prec->pdata;
- V_VT(var) = VT_RECORD;
- } else {
- rb_raise(eWIN32OLERuntimeError, "failed to retrieve IRecordInfo interface");
- }
-}
-
void
ole_val2variant(VALUE val, VARIANT *var)
{
@@ -1864,8 +1780,7 @@ ole_variant2val(VARIANT *pvar)
{
IRecordInfo *pri = V_RECORDINFO(pvar);
void *prec = V_RECORD(pvar);
- obj = folerecord_s_allocate(cWIN32OLE_RECORD);
- olerecord_set_ivar(obj, pri, prec);
+ obj = create_win32ole_record(pri, prec);
break;
}
@@ -5118,7 +5033,7 @@ fev_get_handler(VALUE self)
return rb_ivar_get(self, rb_intern("handler"));
}
-static HRESULT
+HRESULT
typelib_from_val(VALUE obj, ITypeLib **pTypeLib)
{
LCID lcid = cWIN32OLE_lcid;
@@ -5137,480 +5052,6 @@ typelib_from_val(VALUE obj, ITypeLib **pTypeLib)
return hr;
}
-static HRESULT
-recordinfo_from_itypelib(ITypeLib *pTypeLib, VALUE name, IRecordInfo **ppri)
-{
-
- unsigned int count;
- unsigned int i;
- ITypeInfo *pTypeInfo;
- HRESULT hr = OLE_E_LAST;
- BSTR bstr;
-
- count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
- for (i = 0; i < count; i++) {
- hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
- &bstr, NULL, NULL, NULL);
- if (FAILED(hr))
- continue;
-
- hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
- if (FAILED(hr))
- continue;
-
- if (rb_str_cmp(WC2VSTR(bstr), name) == 0) {
- hr = GetRecordInfoFromTypeInfo(pTypeInfo, ppri);
- OLE_RELEASE(pTypeInfo);
- return hr;
- }
- OLE_RELEASE(pTypeInfo);
- }
- hr = OLE_E_LAST;
- return hr;
-}
-
-static void
-olerecord_set_ivar(VALUE obj, IRecordInfo *pri, void *prec)
-{
- HRESULT hr;
- BSTR bstr;
- BSTR *bstrs;
- ULONG count = 0;
- ULONG i;
- VALUE fields;
- VALUE val;
- VARIANT var;
- void *pdata = NULL;
- struct olerecorddata *pvar;
-
- Data_Get_Struct(obj, struct olerecorddata, pvar);
- OLE_ADDREF(pri);
- OLE_RELEASE(pvar->pri);
- pvar->pri = pri;
-
- hr = pri->lpVtbl->GetName(pri, &bstr);
- if (SUCCEEDED(hr)) {
- rb_ivar_set(obj, rb_intern("typename"), WC2VSTR(bstr));
- }
-
- hr = pri->lpVtbl->GetFieldNames(pri, &count, NULL);
- if (FAILED(hr) || count == 0)
- return;
- bstrs = ALLOCA_N(BSTR, count);
- hr = pri->lpVtbl->GetFieldNames(pri, &count, bstrs);
- if (FAILED(hr)) {
- return;
- }
-
- fields = rb_hash_new();
- rb_ivar_set(obj, rb_intern("fields"), fields);
- for (i = 0; i < count; i++) {
- pdata = NULL;
- VariantInit(&var);
- val = Qnil;
- if (prec) {
- hr = pri->lpVtbl->GetFieldNoCopy(pri, prec, bstrs[i], &var, &pdata);
- if (SUCCEEDED(hr)) {
- val = ole_variant2val(&var);
- }
- }
- rb_hash_aset(fields, WC2VSTR(bstrs[i]), val);
- }
-}
-
-/*
- * Document-class: WIN32OLE_RECORD
- *
- * <code>WIN32OLE_RECORD</code> objects represents VT_RECORD OLE variant.
- * Win32OLE returns WIN32OLE_RECORD object if the result value of invoking
- * OLE methods.
- *
- * If COM server in VB.NET ComServer project is the following:
- *
- * Imports System.Runtime.InteropServices
- * Public Class ComClass
- * Public Structure Book
- * <MarshalAs(UnmanagedType.BStr)> _
- * Public title As String
- * Public cost As Integer
- * End Structure
- * Public Function getBook() As Book
- * Dim book As New Book
- * book.title = "The Ruby Book"
- * book.cost = 20
- * Return book
- * End Function
- * End Class
- *
- * then, you can retrieve getBook return value from the following
- * Ruby script:
- *
- * require 'win32ole'
- * obj = WIN32OLE.new('ComServer.ComClass')
- * book = obj.getBook
- * book.class # => WIN32OLE_RECORD
- * book.title # => "The Ruby Book"
- * book.cost # => 20
- *
- */
-
-static void
-olerecord_free(struct olerecorddata *pvar) {
- OLE_FREE(pvar->pri);
- if (pvar->pdata) {
- free(pvar->pdata);
- }
- free(pvar);
-}
-
-static VALUE
-folerecord_s_allocate(VALUE klass) {
- VALUE obj = Qnil;
- struct olerecorddata *pvar;
- obj = Data_Make_Struct(klass, struct olerecorddata, 0, olerecord_free, pvar);
- pvar->pri = NULL;
- pvar->pdata = NULL;
- return obj;
-}
-
-/*
- * call-seq:
- * WIN32OLE_RECORD.new(typename, obj) -> WIN32OLE_RECORD object
- *
- * Returns WIN32OLE_RECORD object. The first argument is struct name (String
- * or Symbol).
- * The second parameter obj should be WIN32OLE object or WIN32OLE_TYPELIB object.
- * If COM server in VB.NET ComServer project is the following:
- *
- * Imports System.Runtime.InteropServices
- * Public Class ComClass
- * Public Structure Book
- * <MarshalAs(UnmanagedType.BStr)> _
- * Public title As String
- * Public cost As Integer
- * End Structure
- * End Class
- *
- * then, you can create WIN32OLE_RECORD object is as following:
- *
- * require 'win32ole'
- * obj = WIN32OLE.new('ComServer.ComClass')
- * book1 = WIN32OLE_RECORD.new('Book', obj) # => WIN32OLE_RECORD object
- * tlib = obj.ole_typelib
- * book2 = WIN32OLE_RECORD.new('Book', tlib) # => WIN32OLE_RECORD object
- *
- */
-static VALUE
-folerecord_initialize(VALUE self, VALUE typename, VALUE oleobj) {
- HRESULT hr;
- ITypeLib *pTypeLib = NULL;
- IRecordInfo *pri = NULL;
-
- if (!RB_TYPE_P(typename, T_STRING) && !RB_TYPE_P(typename, T_SYMBOL)) {
- rb_raise(rb_eArgError, "1st argument should be String or Symbol");
- }
- if (RB_TYPE_P(typename, T_SYMBOL)) {
- typename = rb_sym_to_s(typename);
- }
-
- hr = S_OK;
- if(rb_obj_is_kind_of(oleobj, cWIN32OLE)) {
- hr = typelib_from_val(oleobj, &pTypeLib);
- } else if (rb_obj_is_kind_of(oleobj, cWIN32OLE_TYPELIB)) {
- pTypeLib = itypelib(oleobj);
- OLE_ADDREF(pTypeLib);
- if (pTypeLib) {
- hr = S_OK;
- } else {
- hr = E_FAIL;
- }
- } else {
- rb_raise(rb_eArgError, "2nd argument should be WIN32OLE object or WIN32OLE_TYPELIB object");
- }
-
- if (FAILED(hr)) {
- ole_raise(hr, eWIN32OLERuntimeError, "fail to query ITypeLib interface");
- }
-
- hr = recordinfo_from_itypelib(pTypeLib, typename, &pri);
- OLE_RELEASE(pTypeLib);
- if (FAILED(hr)) {
- ole_raise(hr, eWIN32OLERuntimeError, "fail to query IRecordInfo interface for `%s'", StringValuePtr(typename));
- }
-
- olerecord_set_ivar(self, pri, NULL);
-
- return self;
-}
-
-/*
- * call-seq:
- * WIN32OLE_RECORD#to_h #=> Ruby Hash object.
- *
- * Returns Ruby Hash object which represents VT_RECORD variable.
- * The keys of Hash object are member names of VT_RECORD OLE variable and
- * the values of Hash object are values of VT_RECORD OLE variable.
- *
- * If COM server in VB.NET ComServer project is the following:
- *
- * Imports System.Runtime.InteropServices
- * Public Class ComClass
- * Public Structure Book
- * <MarshalAs(UnmanagedType.BStr)> _
- * Public title As String
- * Public cost As Integer
- * End Structure
- * Public Function getBook() As Book
- * Dim book As New Book
- * book.title = "The Ruby Book"
- * book.cost = 20
- * Return book
- * End Function
- * End Class
- *
- * then, the result of WIN32OLE_RECORD#to_h is the following:
- *
- * require 'win32ole'
- * obj = WIN32OLE.new('ComServer.ComClass')
- * book = obj.getBook
- * book.to_h # => {"title"=>"The Ruby Book", "cost"=>20}
- *
- */
-static VALUE
-folerecord_to_h(VALUE self)
-{
- return rb_ivar_get(self, rb_intern("fields"));
-}
-
-/*
- * call-seq:
- * WIN32OLE_RECORD#typename #=> String object
- *
- * Returns the type name of VT_RECORD OLE variable.
- *
- * If COM server in VB.NET ComServer project is the following:
- *
- * Imports System.Runtime.InteropServices
- * Public Class ComClass
- * Public Structure Book
- * <MarshalAs(UnmanagedType.BStr)> _
- * Public title As String
- * Public cost As Integer
- * End Structure
- * Public Function getBook() As Book
- * Dim book As New Book
- * book.title = "The Ruby Book"
- * book.cost = 20
- * Return book
- * End Function
- * End Class
- *
- * then, the result of WIN32OLE_RECORD#typename is the following:
- *
- * require 'win32ole'
- * obj = WIN32OLE.new('ComServer.ComClass')
- * book = obj.getBook
- * book.typename # => "Book"
- *
- */
-static VALUE
-folerecord_typename(VALUE self)
-{
- return rb_ivar_get(self, rb_intern("typename"));
-}
-
-static VALUE
-olerecord_ivar_get(VALUE self, VALUE name)
-{
- VALUE fields;
- fields = rb_ivar_get(self, rb_intern("fields"));
- return rb_hash_fetch(fields, name);
-}
-
-static VALUE
-olerecord_ivar_set(VALUE self, VALUE name, VALUE val)
-{
- long len;
- char *p;
- VALUE fields;
- len = RSTRING_LEN(name);
- p = RSTRING_PTR(name);
- if (p[len-1] == '=') {
- name = rb_str_subseq(name, 0, len-1);
- }
- fields = rb_ivar_get(self, rb_intern("fields"));
- rb_hash_fetch(fields, name);
- return rb_hash_aset(fields, name, val);
-}
-
-/*
- * call-seq:
- * WIN32OLE_RECORD#method_missing(name)
- *
- * Returns value specified by the member name of VT_RECORD OLE variable.
- * Or sets value specified by the member name of VT_RECORD OLE variable.
- * If the member name is not correct, KeyError exception is raised.
- *
- * If COM server in VB.NET ComServer project is the following:
- *
- * Imports System.Runtime.InteropServices
- * Public Class ComClass
- * Public Structure Book
- * <MarshalAs(UnmanagedType.BStr)> _
- * Public title As String
- * Public cost As Integer
- * End Structure
- * End Class
- *
- * Then getting/setting value from Ruby is as the following:
- *
- * obj = WIN32OLE.new('ComServer.ComClass')
- * book = WIN32OLE_RECORD.new('Book', obj)
- * book.title # => nil ( book.method_missing(:title) is invoked. )
- * book.title = "Ruby" # ( book.method_missing(:title=, "Ruby") is invoked. )
- */
-static VALUE
-folerecord_method_missing(int argc, VALUE *argv, VALUE self)
-{
- VALUE name;
- rb_check_arity(argc, 1, 2);
- name = rb_sym_to_s(argv[0]);
-
-#if SIZEOF_SIZE_T > SIZEOF_LONG
- {
- size_t n = strlen(StringValueCStr(name));
- if (n >= LONG_MAX) {
- rb_raise(rb_eRuntimeError, "too long member name");
- }
- }
-#endif
-
- if (argc == 1) {
- return olerecord_ivar_get(self, name);
- } else if (argc == 2) {
- return olerecord_ivar_set(self, name, argv[1]);
- }
- return Qnil;
-}
-
-/*
- * call-seq:
- * WIN32OLE_RECORD#ole_instance_variable_get(name)
- *
- * Returns value specified by the member name of VT_RECORD OLE object.
- * If the member name is not correct, KeyError exception is raised.
- * If you can't access member variable of VT_RECORD OLE object directly,
- * use this method.
- *
- * If COM server in VB.NET ComServer project is the following:
- *
- * Imports System.Runtime.InteropServices
- * Public Class ComClass
- * Public Structure ComObject
- * Public object_id As Ineger
- * End Structure
- * End Class
- *
- * and Ruby Object class has title attribute:
- *
- * then accessing object_id of ComObject from Ruby is as the following:
- *
- * srver = WIN32OLE.new('ComServer.ComClass')
- * obj = WIN32OLE_RECORD.new('ComObject', server)
- * # obj.object_id returns Ruby Object#object_id
- * obj.ole_instance_variable_get(:object_id) # => nil
- *
- */
-static VALUE
-folerecord_ole_instance_variable_get(VALUE self, VALUE name)
-{
- VALUE sname;
- if(!RB_TYPE_P(name, T_STRING) && !RB_TYPE_P(name, T_SYMBOL)) {
- rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
- }
- sname = name;
- if (RB_TYPE_P(name, T_SYMBOL)) {
- sname = rb_sym_to_s(name);
- }
- return olerecord_ivar_get(self, sname);
-}
-
-/*
- * call-seq:
- * WIN32OLE_RECORD#ole_instance_variable_set(name, val)
- *
- * Sets value specified by the member name of VT_RECORD OLE object.
- * If the member name is not correct, KeyError exception is raised.
- * If you can't set value of member of VT_RECORD OLE object directly,
- * use this method.
- *
- * If COM server in VB.NET ComServer project is the following:
- *
- * Imports System.Runtime.InteropServices
- * Public Class ComClass
- * <MarshalAs(UnmanagedType.BStr)> _
- * Public title As String
- * Public cost As Integer
- * End Class
- *
- * then setting value of the `title' member is as following:
- *
- * srver = WIN32OLE.new('ComServer.ComClass')
- * obj = WIN32OLE_RECORD.new('Book', server)
- * obj.ole_instance_variable_set(:title, "The Ruby Book")
- *
- */
-static VALUE
-folerecord_ole_instance_variable_set(VALUE self, VALUE name, VALUE val)
-{
- VALUE sname;
- if(!RB_TYPE_P(name, T_STRING) && !RB_TYPE_P(name, T_SYMBOL)) {
- rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
- }
- sname = name;
- if (RB_TYPE_P(name, T_SYMBOL)) {
- sname = rb_sym_to_s(name);
- }
- return olerecord_ivar_set(self, sname, val);
-}
-
-/*
- * call-seq:
- * WIN32OLE_RECORD#inspect -> String
- *
- * Returns the OLE struct name and member name and the value of member
- *
- * If COM server in VB.NET ComServer project is the following:
- *
- * Imports System.Runtime.InteropServices
- * Public Class ComClass
- * <MarshalAs(UnmanagedType.BStr)> _
- * Public title As String
- * Public cost As Integer
- * End Class
- *
- * then
- *
- * srver = WIN32OLE.new('ComServer.ComClass')
- * obj = WIN32OLE_RECORD.new('Book', server)
- * obj.inspect # => <WIN32OLE_RECORD(ComClass) {"title" => nil, "cost" => nil}>
- *
- */
-static VALUE
-folerecord_inspect(VALUE self)
-{
- VALUE tname;
- VALUE field;
- tname = folerecord_typename(self);
- if (tname == Qnil) {
- tname = rb_inspect(tname);
- }
- field = rb_inspect(folerecord_to_h(self));
- return rb_sprintf("#<WIN32OLE_RECORD(%"PRIsVALUE") %"PRIsVALUE">",
- tname,
- field);
-}
-
static void
init_enc2cp(void)
{
@@ -5801,17 +5242,7 @@ Init_win32ole(void)
rb_define_method(cWIN32OLE_EVENT, "handler", fev_get_handler, 0);
Init_win32ole_variant();
-
- cWIN32OLE_RECORD = rb_define_class("WIN32OLE_RECORD", rb_cObject);
- rb_define_alloc_func(cWIN32OLE_RECORD, folerecord_s_allocate);
- rb_define_method(cWIN32OLE_RECORD, "initialize", folerecord_initialize, 2);
- rb_define_method(cWIN32OLE_RECORD, "to_h", folerecord_to_h, 0);
- rb_define_method(cWIN32OLE_RECORD, "typename", folerecord_typename, 0);
- rb_define_method(cWIN32OLE_RECORD, "method_missing", folerecord_method_missing, -1);
- rb_define_method(cWIN32OLE_RECORD, "ole_instance_variable_get", folerecord_ole_instance_variable_get, 1);
- rb_define_method(cWIN32OLE_RECORD, "ole_instance_variable_set", folerecord_ole_instance_variable_set, 2);
- rb_define_method(cWIN32OLE_RECORD, "inspect", folerecord_inspect, 0);
-
+ Init_win32ole_record();
Init_win32ole_error();
init_enc2cp();