wrb 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README +28 -0
- data/Rakefile +66 -0
- data/bin/wrb +41 -0
- data/bin/wrb.bat +6 -0
- data/ext/rwin/aatree.c +192 -0
- data/ext/rwin/aatree.h +55 -0
- data/ext/rwin/extconf.rb +47 -0
- data/ext/rwin/rw_api.c +2058 -0
- data/ext/rwin/rw_devices.c +215 -0
- data/ext/rwin/rw_gdiplus.h +278 -0
- data/ext/rwin/rw_graphics.c +1583 -0
- data/ext/rwin/rw_resources.c +1988 -0
- data/ext/rwin/rw_ubfuncs.c +281 -0
- data/ext/rwin/rw_windows.c +1936 -0
- data/ext/rwin/rwin.c +451 -0
- data/ext/rwin/rwin.h +442 -0
- data/lib/rwin.rb +820 -0
- data/lib/wrb.rb +20 -0
- data/lib/wrb/applications/frmdesigner/angle.cur +0 -0
- data/lib/wrb/applications/frmdesigner/angle2.cur +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Button.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Button.rb +34 -0
- data/lib/wrb/applications/frmdesigner/controls/Checkbox.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Checkbox.rb +10 -0
- data/lib/wrb/applications/frmdesigner/controls/Combobox.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Combobox.rb +88 -0
- data/lib/wrb/applications/frmdesigner/controls/ComboboxEx.rb +97 -0
- data/lib/wrb/applications/frmdesigner/controls/Comboboxex.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/DateTimePicker.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/DateTimePicker.rb +11 -0
- data/lib/wrb/applications/frmdesigner/controls/Edit.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Edit.rb +8 -0
- data/lib/wrb/applications/frmdesigner/controls/Groupbox.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Groupbox.rb +9 -0
- data/lib/wrb/applications/frmdesigner/controls/Hotkeyctrl.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Hotkeyctrl.rb +9 -0
- data/lib/wrb/applications/frmdesigner/controls/Imagelist.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Imagelist.rb +115 -0
- data/lib/wrb/applications/frmdesigner/controls/Listbox.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Listbox.rb +77 -0
- data/lib/wrb/applications/frmdesigner/controls/Listview.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Listview.rb +157 -0
- data/lib/wrb/applications/frmdesigner/controls/Menu.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Menu.rb +198 -0
- data/lib/wrb/applications/frmdesigner/controls/Menubar.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Menubar.rb +9 -0
- data/lib/wrb/applications/frmdesigner/controls/MonthCalender.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Monthcalender.rb +9 -0
- data/lib/wrb/applications/frmdesigner/controls/Panel.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Panel.rb +30 -0
- data/lib/wrb/applications/frmdesigner/controls/Progressbar.rb +10 -0
- data/lib/wrb/applications/frmdesigner/controls/Radiobutton.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Radiobutton.rb +13 -0
- data/lib/wrb/applications/frmdesigner/controls/Rebar.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Rebar.rb +162 -0
- data/lib/wrb/applications/frmdesigner/controls/Splitter.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Splitter.rb +66 -0
- data/lib/wrb/applications/frmdesigner/controls/Static.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Static.rb +9 -0
- data/lib/wrb/applications/frmdesigner/controls/Statusbar.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Statusbar.rb +103 -0
- data/lib/wrb/applications/frmdesigner/controls/Tabctrl.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Tabctrl.rb +136 -0
- data/lib/wrb/applications/frmdesigner/controls/Timer.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Timer.rb +36 -0
- data/lib/wrb/applications/frmdesigner/controls/Toolbar.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Toolbar.rb +165 -0
- data/lib/wrb/applications/frmdesigner/controls/Trackbar.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Trackbar.rb +34 -0
- data/lib/wrb/applications/frmdesigner/controls/Treeview.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Treeview.rb +107 -0
- data/lib/wrb/applications/frmdesigner/controls/Updown.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/Updown.rb +31 -0
- data/lib/wrb/applications/frmdesigner/controls/default.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/progressbar.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/controls/unselect.bmp +0 -0
- data/lib/wrb/applications/frmdesigner/fddialogs.rb +87 -0
- data/lib/wrb/applications/frmdesigner/fdesign.rb +1315 -0
- data/lib/wrb/applications/frmdesigner/fdmodules.rb +1394 -0
- data/lib/wrb/applications/frmdesigner/fdparseform.rb +197 -0
- data/lib/wrb/applications/frmdesigner/img13.bmp +0 -0
- data/lib/wrb/base.rb +1294 -0
- data/lib/wrb/combocommon.rb +77 -0
- data/lib/wrb/commctrlconst.rb +139 -0
- data/lib/wrb/commdlg.rb +77 -0
- data/lib/wrb/components/animate.rb +114 -0
- data/lib/wrb/components/bitmap.rb +116 -0
- data/lib/wrb/components/button.rb +134 -0
- data/lib/wrb/components/canvas.rb +266 -0
- data/lib/wrb/components/checkbox.rb +118 -0
- data/lib/wrb/components/choosecolordlg.rb +87 -0
- data/lib/wrb/components/choosefontdlg.rb +142 -0
- data/lib/wrb/components/clipboard.rb +174 -0
- data/lib/wrb/components/combobox.rb +282 -0
- data/lib/wrb/components/comboboxex.rb +574 -0
- data/lib/wrb/components/cursor.rb +91 -0
- data/lib/wrb/components/datetimepicker.rb +197 -0
- data/lib/wrb/components/ddeclient.rb +180 -0
- data/lib/wrb/components/ddeserver.rb +131 -0
- data/lib/wrb/components/dialog.rb +228 -0
- data/lib/wrb/components/edit.rb +412 -0
- data/lib/wrb/components/font.rb +35 -0
- data/lib/wrb/components/form.rb +65 -0
- data/lib/wrb/components/groupbox.rb +122 -0
- data/lib/wrb/components/header.rb +479 -0
- data/lib/wrb/components/hotkeyctrl.rb +72 -0
- data/lib/wrb/components/icon.rb +109 -0
- data/lib/wrb/components/imagelist.rb +396 -0
- data/lib/wrb/components/inifile.rb +97 -0
- data/lib/wrb/components/listbox.rb +149 -0
- data/lib/wrb/components/listview.rb +1467 -0
- data/lib/wrb/components/menu.rb +592 -0
- data/lib/wrb/components/menubar.rb +84 -0
- data/lib/wrb/components/monthcalender.rb +164 -0
- data/lib/wrb/components/openfilenamedlg.rb +147 -0
- data/lib/wrb/components/pager.rb +199 -0
- data/lib/wrb/components/panel.rb +103 -0
- data/lib/wrb/components/picture.rb +55 -0
- data/lib/wrb/components/printdlg.rb +148 -0
- data/lib/wrb/components/printdlgex.rb +117 -0
- data/lib/wrb/components/printer.rb +97 -0
- data/lib/wrb/components/progressbar.rb +140 -0
- data/lib/wrb/components/radiobutton.rb +49 -0
- data/lib/wrb/components/rebar.rb +830 -0
- data/lib/wrb/components/registry.rb +408 -0
- data/lib/wrb/components/richedit.rb +1181 -0
- data/lib/wrb/components/savefilenamedlg.rb +27 -0
- data/lib/wrb/components/scintilla.rb +1298 -0
- data/lib/wrb/components/scrollbar.rb +239 -0
- data/lib/wrb/components/splitter.rb +494 -0
- data/lib/wrb/components/static.rb +198 -0
- data/lib/wrb/components/statusbar.rb +490 -0
- data/lib/wrb/components/tabctrl.rb +686 -0
- data/lib/wrb/components/timer.rb +117 -0
- data/lib/wrb/components/toolbar.rb +1107 -0
- data/lib/wrb/components/tooltip.rb +651 -0
- data/lib/wrb/components/trackbar.rb +298 -0
- data/lib/wrb/components/treeview.rb +845 -0
- data/lib/wrb/components/updown.rb +198 -0
- data/lib/wrb/ddeml.rb +241 -0
- data/lib/wrb/documents/animate.html +46 -0
- data/lib/wrb/documents/bitmap.html +69 -0
- data/lib/wrb/documents/button.html +78 -0
- data/lib/wrb/documents/canvas.html +137 -0
- data/lib/wrb/documents/checkbox.html +77 -0
- data/lib/wrb/documents/choosecolordlg.html +29 -0
- data/lib/wrb/documents/choosefontdlg.html +31 -0
- data/lib/wrb/documents/clipboard.html +31 -0
- data/lib/wrb/documents/combobox.html +117 -0
- data/lib/wrb/documents/comboboxex.html +139 -0
- data/lib/wrb/documents/control.html +53 -0
- data/lib/wrb/documents/cursor.html +45 -0
- data/lib/wrb/documents/datetimepicker.html +70 -0
- data/lib/wrb/documents/ddeclient.html +33 -0
- data/lib/wrb/documents/ddeserver.html +26 -0
- data/lib/wrb/documents/dialog.html +78 -0
- data/lib/wrb/documents/edit.html +169 -0
- data/lib/wrb/documents/empty.html +11 -0
- data/lib/wrb/documents/favicon.png +0 -0
- data/lib/wrb/documents/font.html +38 -0
- data/lib/wrb/documents/form.html +63 -0
- data/lib/wrb/documents/groupbox.html +57 -0
- data/lib/wrb/documents/header.html +85 -0
- data/lib/wrb/documents/hotkeyctrl.html +42 -0
- data/lib/wrb/documents/icon.html +45 -0
- data/lib/wrb/documents/imagelist.html +101 -0
- data/lib/wrb/documents/images/button.png +0 -0
- data/lib/wrb/documents/images/checkbox.png +0 -0
- data/lib/wrb/documents/images/combobox.png +0 -0
- data/lib/wrb/documents/images/comboboxex.png +0 -0
- data/lib/wrb/documents/images/datetimepicker.png +0 -0
- data/lib/wrb/documents/images/edit.png +0 -0
- data/lib/wrb/documents/images/groupbox.png +0 -0
- data/lib/wrb/documents/images/hotkeyctrl.png +0 -0
- data/lib/wrb/documents/images/listbox.png +0 -0
- data/lib/wrb/documents/images/listview.png +0 -0
- data/lib/wrb/documents/images/menu.png +0 -0
- data/lib/wrb/documents/images/menubar.png +0 -0
- data/lib/wrb/documents/images/monthcalender.png +0 -0
- data/lib/wrb/documents/images/progressbar.png +0 -0
- data/lib/wrb/documents/images/radiobutton.png +0 -0
- data/lib/wrb/documents/images/rebar.png +0 -0
- data/lib/wrb/documents/images/richedit.png +0 -0
- data/lib/wrb/documents/images/splitter.png +0 -0
- data/lib/wrb/documents/images/static.png +0 -0
- data/lib/wrb/documents/images/statusbar.png +0 -0
- data/lib/wrb/documents/images/tabctrl.png +0 -0
- data/lib/wrb/documents/images/toolbar.png +0 -0
- data/lib/wrb/documents/images/tooltip.png +0 -0
- data/lib/wrb/documents/images/trackbar.png +0 -0
- data/lib/wrb/documents/images/treeview.png +0 -0
- data/lib/wrb/documents/images/updown.png +0 -0
- data/lib/wrb/documents/index.html +155 -0
- data/lib/wrb/documents/inifile.html +36 -0
- data/lib/wrb/documents/license.txt +22 -0
- data/lib/wrb/documents/listbox.html +96 -0
- data/lib/wrb/documents/listview.html +277 -0
- data/lib/wrb/documents/make_doc.rb +596 -0
- data/lib/wrb/documents/menu.html +144 -0
- data/lib/wrb/documents/menubar.html +54 -0
- data/lib/wrb/documents/monthcalender.html +48 -0
- data/lib/wrb/documents/openfilenamedlg.html +36 -0
- data/lib/wrb/documents/pager.html +63 -0
- data/lib/wrb/documents/panel.html +32 -0
- data/lib/wrb/documents/picture.html +48 -0
- data/lib/wrb/documents/printdlg.html +35 -0
- data/lib/wrb/documents/printdlgex.html +35 -0
- data/lib/wrb/documents/printer.html +40 -0
- data/lib/wrb/documents/progressbar.html +69 -0
- data/lib/wrb/documents/radiobutton.html +51 -0
- data/lib/wrb/documents/rebar.html +143 -0
- data/lib/wrb/documents/registry.html +36 -0
- data/lib/wrb/documents/richedit.html +232 -0
- data/lib/wrb/documents/samples/editimg.bmp +0 -0
- data/lib/wrb/documents/samples/editimg.iml +0 -0
- data/lib/wrb/documents/samples/fileimg.bmp +0 -0
- data/lib/wrb/documents/samples/fileimg.iml +0 -0
- data/lib/wrb/documents/samples/sample_button.rb +21 -0
- data/lib/wrb/documents/samples/sample_checkbox.rb +18 -0
- data/lib/wrb/documents/samples/sample_combobox.rb +18 -0
- data/lib/wrb/documents/samples/sample_comboboxex.rb +23 -0
- data/lib/wrb/documents/samples/sample_datetimepicker.rb +11 -0
- data/lib/wrb/documents/samples/sample_edit.rb +25 -0
- data/lib/wrb/documents/samples/sample_groupbox.rb +19 -0
- data/lib/wrb/documents/samples/sample_hotkeyctrl.rb +12 -0
- data/lib/wrb/documents/samples/sample_listbox.rb +12 -0
- data/lib/wrb/documents/samples/sample_listview.rb +32 -0
- data/lib/wrb/documents/samples/sample_menu.rb +21 -0
- data/lib/wrb/documents/samples/sample_menubar.rb +23 -0
- data/lib/wrb/documents/samples/sample_monthcalender.rb +11 -0
- data/lib/wrb/documents/samples/sample_progressbar.rb +14 -0
- data/lib/wrb/documents/samples/sample_radiobutton.rb +14 -0
- data/lib/wrb/documents/samples/sample_rebar.rb +25 -0
- data/lib/wrb/documents/samples/sample_richedit.rb +60 -0
- data/lib/wrb/documents/samples/sample_splitter.rb +33 -0
- data/lib/wrb/documents/samples/sample_static.rb +15 -0
- data/lib/wrb/documents/samples/sample_statusbar.rb +17 -0
- data/lib/wrb/documents/samples/sample_tabctrl.rb +19 -0
- data/lib/wrb/documents/samples/sample_toolbar.rb +29 -0
- data/lib/wrb/documents/samples/sample_tooltip.rb +50 -0
- data/lib/wrb/documents/samples/sample_trackbar.rb +30 -0
- data/lib/wrb/documents/samples/sample_treeview.rb +19 -0
- data/lib/wrb/documents/samples/sample_updown.rb +18 -0
- data/lib/wrb/documents/samples/sampleimg16.iml +0 -0
- data/lib/wrb/documents/samples/sampleimg32.iml +0 -0
- data/lib/wrb/documents/samples/samplemg16.png +0 -0
- data/lib/wrb/documents/samples/samplemg32.png +0 -0
- data/lib/wrb/documents/samples/wrb.ico +0 -0
- data/lib/wrb/documents/savefilenamedlg.html +19 -0
- data/lib/wrb/documents/scrollbar.html +60 -0
- data/lib/wrb/documents/splitter.html +96 -0
- data/lib/wrb/documents/static.html +84 -0
- data/lib/wrb/documents/statusbar.html +110 -0
- data/lib/wrb/documents/tabctrl.html +151 -0
- data/lib/wrb/documents/timer.html +43 -0
- data/lib/wrb/documents/toolbar.html +181 -0
- data/lib/wrb/documents/tooltip.html +131 -0
- data/lib/wrb/documents/trackbar.html +107 -0
- data/lib/wrb/documents/treeview.html +210 -0
- data/lib/wrb/documents/updown.html +85 -0
- data/lib/wrb/documents/wincontrol.html +258 -0
- data/lib/wrb/documents/window.html +499 -0
- data/lib/wrb/documents/wrb.css +228 -0
- data/lib/wrb/gmem.rb +26 -0
- data/lib/wrb/imecommon.rb +59 -0
- data/lib/wrb/listcommon.rb +185 -0
- data/lib/wrb/lzss.rb +126 -0
- data/lib/wrb/scrollinfo.rb +142 -0
- data/lib/wrb/toplevelcommon.rb +634 -0
- metadata +315 -0
data/ext/rwin/rw_api.c
ADDED
|
@@ -0,0 +1,2058 @@
|
|
|
1
|
+
/*
|
|
2
|
+
# Project WRB was forked from Project VisualuRuby(temp-name).
|
|
3
|
+
# Author of this project: BANJO Koyu <banjokoyu at gmail.com>
|
|
4
|
+
# The URL of this project: https://bitbucket.org/wrb/
|
|
5
|
+
#
|
|
6
|
+
# This is a ext-library part of WRB.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include "rwin.h"
|
|
10
|
+
|
|
11
|
+
/* ##################### local structures ##################### */
|
|
12
|
+
|
|
13
|
+
typedef struct {
|
|
14
|
+
AAtree *libs;
|
|
15
|
+
} ApiFuncLibs;
|
|
16
|
+
|
|
17
|
+
/* ####################### destructors ######################## */
|
|
18
|
+
|
|
19
|
+
void
|
|
20
|
+
aa_callback_libs(const AAnode *node, void *arg){
|
|
21
|
+
FreeLibrary((HMODULE)node->key);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
void
|
|
25
|
+
destruct_libs(ApiFuncLibs *libs){
|
|
26
|
+
if(libs->libs) {
|
|
27
|
+
aaForeach(libs->libs, aa_callback_libs, NULL);
|
|
28
|
+
freeAAtree(libs->libs);
|
|
29
|
+
}
|
|
30
|
+
free(libs);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* ###################### global variables ##################### */
|
|
34
|
+
VALUE mRwAPI;
|
|
35
|
+
VALUE cRwAPIfunc;
|
|
36
|
+
VALUE cRwAPIstruct;
|
|
37
|
+
VALUE cRwAPIstructArrayPart;
|
|
38
|
+
VALUE apifunc_class_libs;
|
|
39
|
+
|
|
40
|
+
AAtree *apifunc_libs;
|
|
41
|
+
|
|
42
|
+
static HMODULE current_hModule;
|
|
43
|
+
|
|
44
|
+
int _id_cstruct_size;
|
|
45
|
+
int _id_cstruct_template;
|
|
46
|
+
int _id_cstruct_s_offsets;
|
|
47
|
+
int _id_cstruct_s_classes;
|
|
48
|
+
|
|
49
|
+
/* ##################### static prototypes ##################### */
|
|
50
|
+
static VALUE cstruct_cast_(VALUE klass, VALUE parent, int offset, int len);
|
|
51
|
+
static VALUE cstruct1_newptr(int argc, VALUE *argv, VALUE klass);
|
|
52
|
+
static VALUE cstruct1_alloc_int(VALUE klass, VALUE arg);
|
|
53
|
+
static VALUE cstruct1_alloc_int_ptr(VALUE klass, VALUE arg);
|
|
54
|
+
static VALUE cstruct_set_idx_value__(int argc, VALUE *argv, VALUE self);
|
|
55
|
+
|
|
56
|
+
/* ######################## CStruct type definition ######################## */
|
|
57
|
+
const VALUE v_zero = INT2FIX(0);
|
|
58
|
+
const VALUE v_one = INT2FIX(1);
|
|
59
|
+
|
|
60
|
+
void cstructdata_mark(void *ptr){
|
|
61
|
+
if(ptr) {
|
|
62
|
+
CStructData *data = ptr;
|
|
63
|
+
if (data->dtparent) rb_gc_mark(data->dtparent);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
void cstructdata_free(void *ptr){
|
|
68
|
+
if(ptr){
|
|
69
|
+
CStructData *data = ptr;
|
|
70
|
+
if (data->dtstr && !data->dtwrapped){ free(data->dtstr);}
|
|
71
|
+
free(data);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static size_t
|
|
76
|
+
cstruct_memsize(const void *ptr){
|
|
77
|
+
return ptr ? sizeof(CStructData) : 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const rb_data_type_t cstruct_data_type = {
|
|
81
|
+
"Cstruct",
|
|
82
|
+
{NULL, cstructdata_free, cstruct_memsize}, NULL, NULL
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
static const rb_data_type_t cstruct_data_type_default_free = {
|
|
86
|
+
"Cstruct_df",
|
|
87
|
+
{cstructdata_mark, RUBY_TYPED_DEFAULT_FREE, cstruct_memsize}, &cstruct_data_type, NULL
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
#define CStruct_Data_Make_Struct_Default_Free(obj, sval) \
|
|
91
|
+
TypedData_Make_Struct(obj, CStructData, &cstruct_data_type_default_free, sval)
|
|
92
|
+
|
|
93
|
+
/* ######################## Callback Macros ######################## */
|
|
94
|
+
|
|
95
|
+
#define DEFINE_CALLBACK_FUNC(m, n) \
|
|
96
|
+
static LRESULT CALLBACK \
|
|
97
|
+
ap_cb ##n##_0(LONG_PTR a0){\
|
|
98
|
+
VALUE r = rb_proc_call(rw_api_callback_procs[0*m+n], rb_ary_new());\
|
|
99
|
+
return NUM2LONG(r);\
|
|
100
|
+
}\
|
|
101
|
+
static LRESULT CALLBACK \
|
|
102
|
+
ap_cb ##n##_1(LONG_PTR a0){\
|
|
103
|
+
VALUE r = rb_proc_call(rw_api_callback_procs[1*m+n], rb_ary_new3(1, LONG_PTR2NUM(a0)));\
|
|
104
|
+
return NUM2LONG_PTR(r);\
|
|
105
|
+
}\
|
|
106
|
+
static LRESULT CALLBACK \
|
|
107
|
+
ap_cb ##n##_2(LONG_PTR a0,LONG_PTR a1){\
|
|
108
|
+
VALUE r = rb_proc_call(rw_api_callback_procs[2*m+n], rb_ary_new3(2, LONG_PTR2NUM(a0), LONG_PTR2NUM(a1)));\
|
|
109
|
+
return NUM2LONG_PTR(r);\
|
|
110
|
+
}\
|
|
111
|
+
static LRESULT CALLBACK \
|
|
112
|
+
ap_cb ##n##_3(LONG_PTR a0,LONG_PTR a1,LONG_PTR a2){\
|
|
113
|
+
VALUE r = rb_proc_call(rw_api_callback_procs[3*m+n], rb_ary_new3(3, LONG_PTR2NUM(a0), LONG_PTR2NUM(a1), LONG_PTR2NUM(a2)));\
|
|
114
|
+
return NUM2LONG_PTR(r);\
|
|
115
|
+
}\
|
|
116
|
+
static LRESULT CALLBACK \
|
|
117
|
+
ap_cb ##n##_4(LONG_PTR a0,LONG_PTR a1,LONG_PTR a2,LONG_PTR a3){\
|
|
118
|
+
VALUE r = rb_proc_call(rw_api_callback_procs[4*m+n], rb_ary_new3(4, LONG_PTR2NUM(a0), LONG_PTR2NUM(a1), LONG_PTR2NUM(a2), LONG_PTR2NUM(a3)));\
|
|
119
|
+
return NUM2LONG_PTR(r);\
|
|
120
|
+
}\
|
|
121
|
+
static LRESULT CALLBACK \
|
|
122
|
+
ap_cb ##n##_5(LONG_PTR a0,LONG_PTR a1,LONG_PTR a2,LONG_PTR a3,LONG_PTR a4){\
|
|
123
|
+
VALUE r = rb_proc_call(rw_api_callback_procs[5*m+n], rb_ary_new3(5, LONG_PTR2NUM(a0), LONG_PTR2NUM(a1), LONG_PTR2NUM(a2), LONG_PTR2NUM(a3), LONG_PTR2NUM(a4)));\
|
|
124
|
+
return NUM2LONG_PTR(r);\
|
|
125
|
+
}\
|
|
126
|
+
static LRESULT CALLBACK \
|
|
127
|
+
ap_cb ##n##_6(LONG_PTR a0,LONG_PTR a1,LONG_PTR a2,LONG_PTR a3,LONG_PTR a4,LONG_PTR a5){\
|
|
128
|
+
VALUE r = rb_proc_call(rw_api_callback_procs[6*m+n], rb_ary_new3(6, LONG_PTR2NUM(a0), LONG_PTR2NUM(a1), LONG_PTR2NUM(a2), LONG_PTR2NUM(a3), LONG_PTR2NUM(a4), LONG_PTR2NUM(a5)));\
|
|
129
|
+
return NUM2LONG_PTR(r);\
|
|
130
|
+
}\
|
|
131
|
+
static LRESULT CALLBACK \
|
|
132
|
+
ap_cb ##n##_7(LONG_PTR a0,LONG_PTR a1,LONG_PTR a2,LONG_PTR a3,LONG_PTR a4,LONG_PTR a5,LONG_PTR a6){\
|
|
133
|
+
VALUE r = rb_proc_call(rw_api_callback_procs[7*m+n], rb_ary_new3(7, LONG_PTR2NUM(a0), LONG_PTR2NUM(a1), LONG_PTR2NUM(a2), LONG_PTR2NUM(a3), LONG_PTR2NUM(a4), LONG_PTR2NUM(a5), LONG_PTR2NUM(a6)));\
|
|
134
|
+
return NUM2LONG_PTR(r);\
|
|
135
|
+
}\
|
|
136
|
+
static LRESULT CALLBACK \
|
|
137
|
+
ap_cb ##n##_8(LONG_PTR a0,LONG_PTR a1,LONG_PTR a2,LONG_PTR a3,LONG_PTR a4,LONG_PTR a5,LONG_PTR a6,LONG_PTR a7){\
|
|
138
|
+
VALUE r = rb_proc_call(rw_api_callback_procs[8*m+n], rb_ary_new3(8, LONG_PTR2NUM(a0), LONG_PTR2NUM(a1), LONG_PTR2NUM(a2), LONG_PTR2NUM(a3), LONG_PTR2NUM(a4), LONG_PTR2NUM(a5), LONG_PTR2NUM(a6), LONG_PTR2NUM(a7)));\
|
|
139
|
+
return NUM2LONG_PTR(r);\
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
#define MAX_CALLBACK_ARITY 9
|
|
143
|
+
#define MAX_CALLBACK_ENTRY 10
|
|
144
|
+
|
|
145
|
+
#define CREATE_CALLBACK_ENTRIES(n) \
|
|
146
|
+
rw_api_callback_funcs[MAX_CALLBACK_ENTRY*0 + n] = (ULONG_PTR)ap_cb ##n##_0;\
|
|
147
|
+
rw_api_callback_funcs[MAX_CALLBACK_ENTRY*1 + n] = (ULONG_PTR)ap_cb ##n##_1;\
|
|
148
|
+
rw_api_callback_funcs[MAX_CALLBACK_ENTRY*2 + n] = (ULONG_PTR)ap_cb ##n##_2;\
|
|
149
|
+
rw_api_callback_funcs[MAX_CALLBACK_ENTRY*3 + n] = (ULONG_PTR)ap_cb ##n##_3;\
|
|
150
|
+
rw_api_callback_funcs[MAX_CALLBACK_ENTRY*4 + n] = (ULONG_PTR)ap_cb ##n##_4;\
|
|
151
|
+
rw_api_callback_funcs[MAX_CALLBACK_ENTRY*5 + n] = (ULONG_PTR)ap_cb ##n##_5;\
|
|
152
|
+
rw_api_callback_funcs[MAX_CALLBACK_ENTRY*6 + n] = (ULONG_PTR)ap_cb ##n##_6;\
|
|
153
|
+
rw_api_callback_funcs[MAX_CALLBACK_ENTRY*7 + n] = (ULONG_PTR)ap_cb ##n##_7;\
|
|
154
|
+
rw_api_callback_funcs[MAX_CALLBACK_ENTRY*8 + n] = (ULONG_PTR)ap_cb ##n##_8;\
|
|
155
|
+
|
|
156
|
+
ULONG_PTR rw_api_callback_funcs[MAX_CALLBACK_ENTRY * MAX_CALLBACK_ARITY];
|
|
157
|
+
VALUE rw_api_callback_procs[MAX_CALLBACK_ENTRY * MAX_CALLBACK_ARITY];
|
|
158
|
+
|
|
159
|
+
DEFINE_CALLBACK_FUNC(MAX_CALLBACK_ENTRY, 0);
|
|
160
|
+
DEFINE_CALLBACK_FUNC(MAX_CALLBACK_ENTRY, 1);
|
|
161
|
+
DEFINE_CALLBACK_FUNC(MAX_CALLBACK_ENTRY, 2);
|
|
162
|
+
DEFINE_CALLBACK_FUNC(MAX_CALLBACK_ENTRY, 3);
|
|
163
|
+
DEFINE_CALLBACK_FUNC(MAX_CALLBACK_ENTRY, 4);
|
|
164
|
+
DEFINE_CALLBACK_FUNC(MAX_CALLBACK_ENTRY, 5);
|
|
165
|
+
DEFINE_CALLBACK_FUNC(MAX_CALLBACK_ENTRY, 6);
|
|
166
|
+
DEFINE_CALLBACK_FUNC(MAX_CALLBACK_ENTRY, 7);
|
|
167
|
+
DEFINE_CALLBACK_FUNC(MAX_CALLBACK_ENTRY, 8);
|
|
168
|
+
DEFINE_CALLBACK_FUNC(MAX_CALLBACK_ENTRY, 9);
|
|
169
|
+
|
|
170
|
+
static void
|
|
171
|
+
api_init_CallbackProcs(){
|
|
172
|
+
rb_define_const(cRwAPIfunc, "MaxCallbackFuncEntry", INT2FIX(MAX_CALLBACK_ENTRY));
|
|
173
|
+
rb_define_const(cRwAPIfunc, "MaxCallbackFuncArity", INT2FIX(MAX_CALLBACK_ARITY));
|
|
174
|
+
|
|
175
|
+
CREATE_CALLBACK_ENTRIES(0);
|
|
176
|
+
CREATE_CALLBACK_ENTRIES(1);
|
|
177
|
+
CREATE_CALLBACK_ENTRIES(2);
|
|
178
|
+
CREATE_CALLBACK_ENTRIES(3);
|
|
179
|
+
CREATE_CALLBACK_ENTRIES(4);
|
|
180
|
+
CREATE_CALLBACK_ENTRIES(5);
|
|
181
|
+
CREATE_CALLBACK_ENTRIES(6);
|
|
182
|
+
CREATE_CALLBACK_ENTRIES(7);
|
|
183
|
+
CREATE_CALLBACK_ENTRIES(8);
|
|
184
|
+
CREATE_CALLBACK_ENTRIES(9);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* ################ RWin::API::CFuncs ################ */
|
|
188
|
+
|
|
189
|
+
static size_t
|
|
190
|
+
cfunc_memsize(const void *ptr){
|
|
191
|
+
return ptr ? sizeof(CFuncData) : 0;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const rb_data_type_t cfunc_data_type = {
|
|
195
|
+
"CFunc", {NULL, NULL, cfunc_memsize}, NULL, NULL
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
static VALUE
|
|
199
|
+
api_cfunc1_loadlib(VALUE klass, VALUE dllname){
|
|
200
|
+
HANDLE hdl;
|
|
201
|
+
VALUE hdll;
|
|
202
|
+
AAnode *node;
|
|
203
|
+
hdl = LoadLibraryA(RSTRING_PTR(dllname));
|
|
204
|
+
if (hdl==0) rb_raise( rb_eRuntimeError, "Can't load: %s\n", RSTRING_PTR(dllname));
|
|
205
|
+
hdll = ULONG_PTR2NUM((ULONG_PTR)hdl);
|
|
206
|
+
node = aaSearch(apifunc_libs, (ULONG_PTR)hdl);
|
|
207
|
+
if (node) {
|
|
208
|
+
FreeLibrary(hdl);
|
|
209
|
+
} else { //fprintf(stderr, "%s, %d\n", RSTRING_PTR(dllname), (ULONG_PTR)hdl);
|
|
210
|
+
aaInsert(apifunc_libs, (ULONG_PTR)hdl, 0);
|
|
211
|
+
}
|
|
212
|
+
current_hModule = hdl;
|
|
213
|
+
return hdll;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
static VALUE
|
|
217
|
+
cfunc_alloc(VALUE klass){
|
|
218
|
+
CFuncData *cf;
|
|
219
|
+
VALUE obj = CFunc_Data_Make_Struct(klass, cf);
|
|
220
|
+
return obj;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
static void
|
|
224
|
+
aa_callback_search_libs(const AAnode *node, void *arg){
|
|
225
|
+
if (node->key != (ULONG_PTR)current_hModule) {
|
|
226
|
+
VALUE pair = (VALUE)arg;
|
|
227
|
+
FARPROC hproc = GetProcAddress((HMODULE)node->key, RSTRING_PTR(rb_ary_entry(pair, 0)));
|
|
228
|
+
if (hproc){
|
|
229
|
+
rb_ary_store(pair, 1, ULONG_PTR2NUM((ULONG_PTR)hproc));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
static VALUE
|
|
235
|
+
api_initialize(VALUE self, VALUE procname, VALUE nargs){
|
|
236
|
+
CFuncData *cf;
|
|
237
|
+
VALUE v_procaddress;
|
|
238
|
+
FARPROC hproc = NULL;
|
|
239
|
+
if(current_hModule) hproc = GetProcAddress(current_hModule, RSTRING_PTR(procname));
|
|
240
|
+
if (hproc){
|
|
241
|
+
cf = DATA_PTR(self);
|
|
242
|
+
cf->nargs = FIX2INT(nargs);
|
|
243
|
+
cf->procaddress = (ULONG_PTR)hproc;
|
|
244
|
+
v_procaddress = ULONG_PTR2NUM((ULONG_PTR)hproc);
|
|
245
|
+
} else {
|
|
246
|
+
VALUE pair = rb_ary_new3(2, procname, Qnil);
|
|
247
|
+
aaForeach(apifunc_libs, aa_callback_search_libs, (void*)pair);
|
|
248
|
+
v_procaddress = rb_ary_entry(pair, 1);
|
|
249
|
+
if (NIL_P(v_procaddress)) {
|
|
250
|
+
rb_raise(rb_eRuntimeError,"Can't GetProcAddress: `%s'\r\n", RSTRING_PTR(procname));
|
|
251
|
+
}
|
|
252
|
+
cf = DATA_PTR(self);
|
|
253
|
+
cf->nargs = FIX2INT(nargs);
|
|
254
|
+
cf->procaddress = NUM2ULONG_PTR(v_procaddress);
|
|
255
|
+
}
|
|
256
|
+
return v_procaddress;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
static VALUE
|
|
260
|
+
api_cfunc1_getfunc(VALUE klass, VALUE procname, VALUE nargs){
|
|
261
|
+
VALUE obj;
|
|
262
|
+
CFuncData *cf;
|
|
263
|
+
FARPROC hproc = NULL;
|
|
264
|
+
if(current_hModule) hproc = GetProcAddress(current_hModule, RSTRING_PTR(procname));
|
|
265
|
+
if (hproc){
|
|
266
|
+
obj = CFunc_Data_Make_Struct(klass, cf);
|
|
267
|
+
cf->nargs = FIX2INT(nargs);
|
|
268
|
+
cf->procaddress = (ULONG_PTR)hproc;
|
|
269
|
+
} else {
|
|
270
|
+
VALUE v_procaddress;
|
|
271
|
+
VALUE pair = rb_ary_new3(2, procname, Qnil);
|
|
272
|
+
aaForeach(apifunc_libs, aa_callback_search_libs, (void*)pair);
|
|
273
|
+
v_procaddress = rb_ary_entry(pair, 1);
|
|
274
|
+
if (NIL_P(v_procaddress)) return Qnil;
|
|
275
|
+
obj = CFunc_Data_Make_Struct(klass, cf);
|
|
276
|
+
cf->nargs = FIX2INT(nargs);
|
|
277
|
+
cf->procaddress = NUM2ULONG_PTR(v_procaddress);
|
|
278
|
+
}
|
|
279
|
+
return obj;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
//static long
|
|
283
|
+
static ULONG_PTR
|
|
284
|
+
api_bind_callback_proc_core(VALUE proc){
|
|
285
|
+
int n;
|
|
286
|
+
int nfree = MAX_CALLBACK_ENTRY;
|
|
287
|
+
int arity = rb_proc_arity(proc);
|
|
288
|
+
for(n=0; n<MAX_CALLBACK_ENTRY; n++){
|
|
289
|
+
int i = arity * MAX_CALLBACK_ENTRY + n;
|
|
290
|
+
VALUE obj = rw_api_callback_procs[i];
|
|
291
|
+
if(proc == obj) return rw_api_callback_funcs[i];
|
|
292
|
+
if(obj==0){
|
|
293
|
+
if (n < nfree) nfree = n;
|
|
294
|
+
} else if(RBASIC(obj)->flags==0){
|
|
295
|
+
rw_api_callback_procs[i] = 0;
|
|
296
|
+
if (n < nfree) nfree = n;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
if(nfree < MAX_CALLBACK_ENTRY){
|
|
300
|
+
int i = arity * MAX_CALLBACK_ENTRY + nfree;
|
|
301
|
+
rw_api_callback_procs[i] = proc;
|
|
302
|
+
return rw_api_callback_funcs[i];
|
|
303
|
+
}
|
|
304
|
+
rb_raise(rb_eRuntimeError,
|
|
305
|
+
"Can't register callback proc any more (over %d)", MAX_CALLBACK_ENTRY);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
static VALUE
|
|
309
|
+
api_bind_callback_proc(VALUE klass, VALUE proc){
|
|
310
|
+
return ULONG_PTR2NUM(api_bind_callback_proc_core(proc));
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
static VALUE
|
|
314
|
+
api_release_callback_proc(VALUE klass, VALUE proc){
|
|
315
|
+
int i;
|
|
316
|
+
int arity = rb_proc_arity(proc);
|
|
317
|
+
for(i=arity*MAX_CALLBACK_ARITY; i<(arity+1)*MAX_CALLBACK_ARITY; i++){
|
|
318
|
+
VALUE obj = rw_api_callback_procs[i];
|
|
319
|
+
if(proc == obj) {
|
|
320
|
+
rw_api_callback_procs[i] = 0;
|
|
321
|
+
return Qtrue;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return Qfalse;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
static ULONG_PTR api_call_get_proc(VALUE self, int argc){
|
|
328
|
+
CFuncData *cf = DATA_PTR(self);
|
|
329
|
+
if(cf->nargs != argc){
|
|
330
|
+
rb_raise( rb_eRuntimeError,
|
|
331
|
+
"Num of args is different : expected %d, but got %d\n", cf->nargs, argc);
|
|
332
|
+
}
|
|
333
|
+
return cf->procaddress;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
static void
|
|
337
|
+
api_call_set_args(VALUE self, int argc, VALUE *argv, ULONG_PTR *calldata){
|
|
338
|
+
int i;
|
|
339
|
+
VALUE arg;
|
|
340
|
+
CStructData *data;
|
|
341
|
+
for (i = 0; i < argc; i++){
|
|
342
|
+
arg = argv[i];
|
|
343
|
+
switch (TYPE(arg)){
|
|
344
|
+
case T_DATA:
|
|
345
|
+
if (rb_typeddata_is_kind_of(arg, &cstruct_data_type)){
|
|
346
|
+
CStruct_Data_Get_Struct(arg, data);
|
|
347
|
+
calldata[i+1] = (ULONG_PTR)(data->dtstr+data->dtoffset);
|
|
348
|
+
} else if (rb_obj_is_proc(arg)) {
|
|
349
|
+
calldata[i+1] = api_bind_callback_proc_core(arg);
|
|
350
|
+
} else {
|
|
351
|
+
rb_raise(rb_eRuntimeError, "Argument is neither a CStruct nor a Proc");
|
|
352
|
+
}
|
|
353
|
+
break;
|
|
354
|
+
case T_STRING:
|
|
355
|
+
calldata[i+1] = (ENCODING_IS_ASCII8BIT(arg)) ? (ULONG_PTR)RSTRING_PTR(arg) :
|
|
356
|
+
(ULONG_PTR)rw_str2tchar(arg);
|
|
357
|
+
break;
|
|
358
|
+
case T_NIL:
|
|
359
|
+
calldata[i+1] = (ULONG_PTR)0;
|
|
360
|
+
break;
|
|
361
|
+
case T_FIXNUM:
|
|
362
|
+
case T_BIGNUM:
|
|
363
|
+
calldata[i+1] = NUM2ULONG_PTR(arg);
|
|
364
|
+
break;
|
|
365
|
+
default:
|
|
366
|
+
rb_raise(rb_eRuntimeError, "Unrecognised type of argument");
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
static VALUE
|
|
372
|
+
api_call(int argc, VALUE *argv, VALUE self){
|
|
373
|
+
ULONG_PTR proc_address = api_call_get_proc(self, argc);
|
|
374
|
+
ULONG_PTR *calldata = alloca((argc+2)*sizeof(ULONG_PTR));
|
|
375
|
+
calldata[0] = proc_address;
|
|
376
|
+
api_call_set_args(self, argc, argv, calldata);
|
|
377
|
+
switch (argc){
|
|
378
|
+
case 0:
|
|
379
|
+
return ULONG_PTR2NUM(rw_call_std_func_0(calldata));
|
|
380
|
+
case 1:
|
|
381
|
+
return ULONG_PTR2NUM(rw_call_std_func_1(calldata));
|
|
382
|
+
case 2:
|
|
383
|
+
return ULONG_PTR2NUM(rw_call_std_func_2(calldata));
|
|
384
|
+
case 3:
|
|
385
|
+
return ULONG_PTR2NUM(rw_call_std_func_3(calldata));
|
|
386
|
+
case 4:
|
|
387
|
+
return ULONG_PTR2NUM(rw_call_std_func_4(calldata));
|
|
388
|
+
case 5:
|
|
389
|
+
return ULONG_PTR2NUM(rw_call_std_func_5(calldata));
|
|
390
|
+
case 6:
|
|
391
|
+
return ULONG_PTR2NUM(rw_call_std_func_6(calldata));
|
|
392
|
+
case 7:
|
|
393
|
+
return ULONG_PTR2NUM(rw_call_std_func_7(calldata));
|
|
394
|
+
case 8:
|
|
395
|
+
return ULONG_PTR2NUM(rw_call_std_func_8(calldata));
|
|
396
|
+
case 9:
|
|
397
|
+
return ULONG_PTR2NUM(rw_call_std_func_9(calldata));
|
|
398
|
+
case 10:
|
|
399
|
+
return ULONG_PTR2NUM(rw_call_std_func_10(calldata));
|
|
400
|
+
case 11:
|
|
401
|
+
return ULONG_PTR2NUM(rw_call_std_func_11(calldata));
|
|
402
|
+
case 12:
|
|
403
|
+
return ULONG_PTR2NUM(rw_call_std_func_12(calldata));
|
|
404
|
+
default:
|
|
405
|
+
rb_raise(rb_eArgError, "Too many args: %d > 12.", argc);
|
|
406
|
+
return Qnil;
|
|
407
|
+
}
|
|
408
|
+
return Qnil;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/*
|
|
412
|
+
DO NOT USE "call_ubf" easely, otherwise you'll get SEGV easely.
|
|
413
|
+
(only for function similar to SendMessage)
|
|
414
|
+
*/
|
|
415
|
+
|
|
416
|
+
static VALUE
|
|
417
|
+
api_call_ubf(int argc, VALUE *argv, VALUE self){
|
|
418
|
+
ULONG_PTR proc_address = api_call_get_proc(self, argc);
|
|
419
|
+
ULONG_PTR *calldata = alloca((argc+1)*sizeof(ULONG));
|
|
420
|
+
//ULONG calldata[argc+1];
|
|
421
|
+
calldata[0] = proc_address;
|
|
422
|
+
api_call_set_args(self, argc, argv, calldata);
|
|
423
|
+
switch (argc){
|
|
424
|
+
case 0:
|
|
425
|
+
return ULONG_PTR2NUM(CALL_NON_GVL_FUNC(rw_call_std_func_0, calldata));
|
|
426
|
+
case 1:
|
|
427
|
+
return ULONG_PTR2NUM(CALL_NON_GVL_FUNC(rw_call_std_func_1, calldata));
|
|
428
|
+
case 2:
|
|
429
|
+
return ULONG_PTR2NUM(CALL_NON_GVL_FUNC(rw_call_std_func_2, calldata));
|
|
430
|
+
case 3:
|
|
431
|
+
return ULONG_PTR2NUM(CALL_NON_GVL_FUNC(rw_call_std_func_3, calldata));
|
|
432
|
+
case 4:
|
|
433
|
+
return ULONG_PTR2NUM(CALL_NON_GVL_FUNC(rw_call_std_func_4, calldata));
|
|
434
|
+
case 5:
|
|
435
|
+
return ULONG_PTR2NUM(CALL_NON_GVL_FUNC(rw_call_std_func_5, calldata));
|
|
436
|
+
case 6:
|
|
437
|
+
return ULONG_PTR2NUM(CALL_NON_GVL_FUNC(rw_call_std_func_6, calldata));
|
|
438
|
+
case 7:
|
|
439
|
+
return ULONG_PTR2NUM(CALL_NON_GVL_FUNC(rw_call_std_func_7, calldata));
|
|
440
|
+
case 8:
|
|
441
|
+
return ULONG_PTR2NUM(CALL_NON_GVL_FUNC(rw_call_std_func_8, calldata));
|
|
442
|
+
case 9:
|
|
443
|
+
return ULONG_PTR2NUM(CALL_NON_GVL_FUNC(rw_call_std_func_9, calldata));
|
|
444
|
+
case 10:
|
|
445
|
+
return ULONG_PTR2NUM(CALL_NON_GVL_FUNC(rw_call_std_func_10, calldata));
|
|
446
|
+
case 11:
|
|
447
|
+
return ULONG_PTR2NUM(CALL_NON_GVL_FUNC(rw_call_std_func_11, calldata));
|
|
448
|
+
case 12:
|
|
449
|
+
return ULONG_PTR2NUM(CALL_NON_GVL_FUNC(rw_call_std_func_12, calldata));
|
|
450
|
+
default:
|
|
451
|
+
rb_raise(rb_eArgError, "Too many args: %d > 12.)", argc);
|
|
452
|
+
return Qnil;
|
|
453
|
+
}
|
|
454
|
+
return Qnil;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
/* additional definition of API functions */
|
|
459
|
+
|
|
460
|
+
static VALUE
|
|
461
|
+
api_message_core(FARPROC msgproc, VALUE hwnd, VALUE umsg, VALUE wparam, VALUE lparam){
|
|
462
|
+
HWND hw = (HWND)NUM2ULONG_PTR(hwnd);
|
|
463
|
+
ULONG um = NUM2UINT(umsg);
|
|
464
|
+
WPARAM wp = NUM2ULONG_PTR(wparam);
|
|
465
|
+
LPARAM lp;
|
|
466
|
+
if (TYPE(lparam) == T_STRING){
|
|
467
|
+
lp = (ULONG_PTR)(ENCODING_IS_ASCII8BIT(lparam) ? RSTRING_PTR(lparam) :
|
|
468
|
+
(char*)rw_str2tchar(lparam));
|
|
469
|
+
}else{
|
|
470
|
+
lp = NUM2ULONG_PTR(lparam);
|
|
471
|
+
}
|
|
472
|
+
return INT2NUM(rw_call_without_gvl_4(0, msgproc, (ULONG_PTR)hw, um, wp, lp));
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
static VALUE
|
|
476
|
+
api_sendmessage(VALUE klass, VALUE hwnd, VALUE umsg, VALUE wparam, VALUE lparam){
|
|
477
|
+
return api_message_core((FARPROC)SendMessage, (ULONG_PTR)hwnd, umsg, wparam, lparam);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
static VALUE
|
|
481
|
+
api_postmessage(VALUE klass, VALUE hwnd, VALUE umsg, VALUE wparam, VALUE lparam){
|
|
482
|
+
return api_message_core((FARPROC)PostMessage, hwnd, umsg, wparam, lparam);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
static VALUE
|
|
487
|
+
api_g_alloc_str(VALUE klass,VALUE uFlags, VALUE text){
|
|
488
|
+
int len = RSTRING_LEN(text);
|
|
489
|
+
HGLOBAL hmem = GlobalAlloc(NUM2UINT(uFlags), len+1);
|
|
490
|
+
char* ptr = GlobalLock(hmem);
|
|
491
|
+
if (!ptr) rb_raise(rb_eRuntimeError, "Global Lock failed");
|
|
492
|
+
memcpy(ptr, RSTRING_PTR(text), len);
|
|
493
|
+
ptr[len+1] = 0;
|
|
494
|
+
GlobalUnlock(hmem);
|
|
495
|
+
return ULONG_PTR2NUM((ULONG_PTR)hmem);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
static VALUE
|
|
499
|
+
api_g_get_str(VALUE klass, VALUE hMem){
|
|
500
|
+
VALUE val;
|
|
501
|
+
int len;
|
|
502
|
+
HGLOBAL hmem = (HGLOBAL)NUM2ULONG_PTR(hMem);
|
|
503
|
+
char* ptr = GlobalLock(hmem);
|
|
504
|
+
if (!ptr) rb_raise(rb_eRuntimeError, "Global Lock failed");
|
|
505
|
+
len = GlobalSize(hmem);
|
|
506
|
+
val = rb_str_new(ptr, len);
|
|
507
|
+
GlobalUnlock(hmem);
|
|
508
|
+
return val;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/* ################### RWin::API::CStruct ################## */
|
|
512
|
+
/* enums */
|
|
513
|
+
typedef enum{
|
|
514
|
+
dt_B=1, dt_C, dt_H, dt_W, dt_L, dt_U, dt_S,
|
|
515
|
+
dt_s, dt_l, dt_u, dt_i, dt_q, dt_I, dt_Q, dt_K, dt_P
|
|
516
|
+
} CST_GET_FUNCS;
|
|
517
|
+
|
|
518
|
+
/* structures */
|
|
519
|
+
typedef struct {
|
|
520
|
+
WORD offset;
|
|
521
|
+
BYTE ifunc;
|
|
522
|
+
BYTE mblen;
|
|
523
|
+
WORD nth;
|
|
524
|
+
WORD klsidx;
|
|
525
|
+
} RWOffsetData;
|
|
526
|
+
|
|
527
|
+
typedef struct {
|
|
528
|
+
WORD size;
|
|
529
|
+
WORD realsize;
|
|
530
|
+
WORD cmembers;
|
|
531
|
+
BYTE maxmblen;
|
|
532
|
+
BYTE packed;
|
|
533
|
+
} RWCSAttribute;
|
|
534
|
+
|
|
535
|
+
/* inlines */
|
|
536
|
+
static inline RWCSAttribute*
|
|
537
|
+
cs_get_offset_attribute(VALUE klass){
|
|
538
|
+
char *ptr = RSTRING_PTR(rb_const_get(klass, _id_cstruct_s_offsets));
|
|
539
|
+
return (RWCSAttribute*)ptr;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
static inline RWOffsetData*
|
|
543
|
+
cs_get_offset_data(VALUE klass, int index){
|
|
544
|
+
char *ptr = RSTRING_PTR(rb_const_get(klass, _id_cstruct_s_offsets));
|
|
545
|
+
return (RWOffsetData*)(ptr+sizeof(RWCSAttribute)+index*sizeof(RWOffsetData));
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
static inline void
|
|
549
|
+
rw_set_offdata(RWOffsetData *offdata, WORD offset, BYTE ifunc, BYTE mblen, WORD nth, WORD kidx){
|
|
550
|
+
offdata->offset = offset;
|
|
551
|
+
offdata->ifunc = ifunc;
|
|
552
|
+
offdata->mblen = mblen;
|
|
553
|
+
offdata->nth = nth;
|
|
554
|
+
offdata->klsidx = kidx;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
static inline ULONG
|
|
558
|
+
rw_num2ulong(VALUE x) {
|
|
559
|
+
if(FIXNUM_P(x)) return FIX2ULONG(x);
|
|
560
|
+
else if(RB_TYPE_P(x, T_BIGNUM)) return rb_big2ulong(x);
|
|
561
|
+
else rb_raise(rb_eTypeError, "%s is not an Integer", RSTRING_PTR(rb_inspect(x)));
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
static inline LONG
|
|
565
|
+
rw_num2long(VALUE x) {
|
|
566
|
+
if(FIXNUM_P(x)) return FIX2LONG(x);
|
|
567
|
+
else if(RB_TYPE_P(x, T_BIGNUM)) return rb_big2long(x);
|
|
568
|
+
else rb_raise(rb_eTypeError, "%s is not an Integer", RSTRING_PTR(rb_inspect(x)));
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
static inline int
|
|
572
|
+
cst_adjust_align(int offset, int sz){
|
|
573
|
+
return offset ? ((offset/sz) + ((offset%sz) ? 1 : 0)) * sz : 0;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/* common funcs */
|
|
577
|
+
static int
|
|
578
|
+
cs_get_count(VALUE self){
|
|
579
|
+
int n;
|
|
580
|
+
CStructData *cd = DATA_PTR(self);
|
|
581
|
+
if(cd->bifunc) { /* ArrayPart */
|
|
582
|
+
VALUE klass = rb_class_of(cd->dtparent ? cd->dtparent : self);
|
|
583
|
+
n = cd->dtlen / cs_get_offset_data(klass, cd->prindex)->mblen;
|
|
584
|
+
}else{
|
|
585
|
+
VALUE klass = rb_class_of(self);
|
|
586
|
+
n = cs_get_offset_attribute(klass)->cmembers;
|
|
587
|
+
if (n==1){
|
|
588
|
+
n = cd->dtlen / cs_get_offset_data(klass, 0)->mblen;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
return n;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/* ############## alloc functions ################ */
|
|
595
|
+
|
|
596
|
+
static VALUE
|
|
597
|
+
cstruct_alloc(VALUE klass){
|
|
598
|
+
CStructData *cd;
|
|
599
|
+
VALUE obj = CStruct_Data_Make_Struct(klass, cd);
|
|
600
|
+
if(cs_get_offset_attribute(klass)->cmembers==1){
|
|
601
|
+
cd->bifunc = cs_get_offset_data(klass, 0)->ifunc;
|
|
602
|
+
}
|
|
603
|
+
return obj;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/* for internal use */
|
|
607
|
+
VALUE
|
|
608
|
+
api_cstruct_new(VALUE klass){
|
|
609
|
+
char *data;
|
|
610
|
+
VALUE obj = cstruct_alloc(klass);
|
|
611
|
+
CStructData *cd = DATA_PTR(obj);
|
|
612
|
+
int len = FIX2INT(rb_const_get(klass, _id_cstruct_size));
|
|
613
|
+
RW_CALLOC(data, len);
|
|
614
|
+
cd->dtstr = data;
|
|
615
|
+
cd->dtlen = len;
|
|
616
|
+
return obj;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/* data manipulation functions */
|
|
620
|
+
/* ############ gets ########## */
|
|
621
|
+
|
|
622
|
+
static VALUE
|
|
623
|
+
cst_get_a_dt_L(CStructData *cd, int offset){
|
|
624
|
+
char *ptr;
|
|
625
|
+
if(offset+sizeof(LONG) > cd->dtlen) rb_bug("Out of bounds.");
|
|
626
|
+
ptr = cd->dtstr + cd->dtoffset + offset;
|
|
627
|
+
return INT2NUM(*(int*)ptr);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
static VALUE
|
|
631
|
+
cst_get_a_dt_U(CStructData *cd, int offset){
|
|
632
|
+
char *ptr;
|
|
633
|
+
if(offset+sizeof(LONG) > cd->dtlen) rb_bug("Out of bounds.");
|
|
634
|
+
ptr = cd->dtstr + cd->dtoffset + offset;
|
|
635
|
+
return UINT2NUM(*(int*)ptr);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
static VALUE
|
|
639
|
+
cst_get_a_dt_H(CStructData *cd, int offset){
|
|
640
|
+
char *ptr;
|
|
641
|
+
if(offset+sizeof(short) > cd->dtlen) rb_bug("Out of bounds.");
|
|
642
|
+
ptr = cd->dtstr + cd->dtoffset + offset;
|
|
643
|
+
return UINT2NUM(*(short*)ptr & 0x0000ffff);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
static VALUE
|
|
647
|
+
cst_get_a_dt_C(CStructData *cd, int offset){
|
|
648
|
+
char *ptr;
|
|
649
|
+
if(offset+sizeof(char) > cd->dtlen) rb_bug("Out of bounds.");
|
|
650
|
+
ptr = cd->dtstr + cd->dtoffset + offset;
|
|
651
|
+
return UINT2NUM(*(char*)ptr & 0x000000ff);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
static VALUE
|
|
655
|
+
cst_get_a_dt_Q(CStructData *cd, int offset){
|
|
656
|
+
char *ptr;
|
|
657
|
+
if(offset+sizeof(LONG_PTR) > cd->dtlen) rb_bug("Out of bounds.");
|
|
658
|
+
ptr = cd->dtstr + cd->dtoffset + offset;
|
|
659
|
+
return ULONG_PTR2NUM(*(ULONG_PTR*)ptr);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
static VALUE
|
|
663
|
+
cst_get_a_dt_I(CStructData *cd, int offset){
|
|
664
|
+
char *ptr;
|
|
665
|
+
if(offset+sizeof(LONG_PTR) > cd->dtlen) rb_bug("Out of bounds.");
|
|
666
|
+
ptr = cd->dtstr + cd->dtoffset + offset;
|
|
667
|
+
return LONG_PTR2NUM(*(LONG_PTR*)ptr);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
static VALUE
|
|
671
|
+
cst_get_a_dt_S(CStructData *cd, int offset){
|
|
672
|
+
char *ptr; ULONG_PTR ptr2data;
|
|
673
|
+
if(offset+sizeof(void*) > cd->dtlen) rb_bug("Out of bounds.");
|
|
674
|
+
ptr = cd->dtstr + cd->dtoffset + offset;
|
|
675
|
+
ptr2data = *(long*)ptr;
|
|
676
|
+
return ptr2data ? rw_encode_external((TCHAR*)ptr2data) : Qnil;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
static VALUE /* Get as un-encoded String */
|
|
680
|
+
cst_get_a_dt_s(CStructData *cd, int offset){
|
|
681
|
+
char *ptr; ULONG_PTR ptr2data;
|
|
682
|
+
if(offset+sizeof(void*) > cd->dtlen) rb_bug("Out of bounds.");
|
|
683
|
+
ptr = cd->dtstr + cd->dtoffset + offset;
|
|
684
|
+
ptr2data = *(long*)ptr;
|
|
685
|
+
return ptr2data ? rb_str_new2((char*)ptr2data) : Qnil;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
static VALUE
|
|
689
|
+
cst_get_a_dt_l(CStructData *cd, int offset){
|
|
690
|
+
char *ptr; ULONG_PTR ptr2data;
|
|
691
|
+
if(offset+sizeof(void*) > cd->dtlen) rb_bug("Out of bounds.");
|
|
692
|
+
ptr = cd->dtstr + cd->dtoffset + offset;
|
|
693
|
+
ptr2data = *(ULONG_PTR*)ptr;
|
|
694
|
+
if (!ptr2data) rb_raise(rb_eRuntimeError, "NULL pointer given");
|
|
695
|
+
return LONG2NUM(*(LONG*)ptr2data);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
static VALUE
|
|
699
|
+
cst_get_a_dt_u(CStructData *cd, int offset){
|
|
700
|
+
char *ptr; ULONG_PTR ptr2data;
|
|
701
|
+
if(offset+sizeof(void*) > cd->dtlen) rb_bug("Out of bounds.");
|
|
702
|
+
ptr = cd->dtstr + cd->dtoffset + offset;
|
|
703
|
+
ptr2data = *(ULONG_PTR*)ptr;
|
|
704
|
+
if (!ptr2data) rb_raise(rb_eRuntimeError, "NULL pointer given");
|
|
705
|
+
return ULONG2NUM(*(ULONG*)ptr2data);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
static VALUE
|
|
709
|
+
cst_get_a_dt_i(CStructData *cd, int offset){
|
|
710
|
+
char *ptr; ULONG_PTR ptr2data;
|
|
711
|
+
if(offset+sizeof(void*) > cd->dtlen) rb_bug("Out of bounds.");
|
|
712
|
+
ptr = cd->dtstr + cd->dtoffset + offset;
|
|
713
|
+
ptr2data = *(ULONG_PTR*)ptr;
|
|
714
|
+
if (!ptr2data) rb_raise(rb_eRuntimeError, "NULL pointer given");
|
|
715
|
+
return LONG_PTR2NUM(*(LONG_PTR*)ptr2data);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
static VALUE
|
|
719
|
+
cst_get_a_dt_q(CStructData *cd, int offset){
|
|
720
|
+
char *ptr; ULONG_PTR ptr2data;
|
|
721
|
+
if(offset+sizeof(void*) > cd->dtlen) rb_bug("Out of bounds.");
|
|
722
|
+
ptr = cd->dtstr + cd->dtoffset + offset;
|
|
723
|
+
ptr2data = *(ULONG_PTR*)ptr;
|
|
724
|
+
if (!ptr2data) rb_raise(rb_eRuntimeError, "NULL pointer given");
|
|
725
|
+
return ULONG_PTR2NUM(*(ULONG_PTR*)ptr2data);
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
static VALUE
|
|
729
|
+
cst_get_a_dt_K(VALUE self, int offset, VALUE klass){
|
|
730
|
+
return cstruct_cast_(klass, self, offset, //cs_get_class_size_of(klass));
|
|
731
|
+
FIX2INT(rb_const_get(klass, _id_cstruct_size)));
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
static VALUE
|
|
735
|
+
cst_get_a_dt_P(CStructData *cd, int offset, VALUE klass, VALUE self){
|
|
736
|
+
char *ptr; ULONG_PTR ptr2data;
|
|
737
|
+
if(offset+sizeof(void*) > cd->dtlen) rb_bug("Out of bounds.");
|
|
738
|
+
ptr = cd->dtstr + cd->dtoffset + offset;
|
|
739
|
+
ptr2data = *(long*)ptr;
|
|
740
|
+
if(ptr2data) return cstruct_wrapptr(klass, (char*)ptr2data, self);
|
|
741
|
+
return Qnil;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/* Array of functions */
|
|
745
|
+
static VALUE
|
|
746
|
+
(* cst_get_funcs[15])(CStructData*, int) = {
|
|
747
|
+
NULL,
|
|
748
|
+
cst_get_a_dt_C,
|
|
749
|
+
cst_get_a_dt_C,
|
|
750
|
+
cst_get_a_dt_H,
|
|
751
|
+
cst_get_a_dt_H,
|
|
752
|
+
cst_get_a_dt_L,
|
|
753
|
+
cst_get_a_dt_U,
|
|
754
|
+
cst_get_a_dt_S,
|
|
755
|
+
cst_get_a_dt_s,
|
|
756
|
+
cst_get_a_dt_l,
|
|
757
|
+
cst_get_a_dt_u,
|
|
758
|
+
cst_get_a_dt_i,
|
|
759
|
+
cst_get_a_dt_q,
|
|
760
|
+
cst_get_a_dt_I,
|
|
761
|
+
cst_get_a_dt_Q,
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
/* ############### sets ############# */
|
|
765
|
+
|
|
766
|
+
static VALUE
|
|
767
|
+
cst_set_a_dt_C(CStructData *cd, int offset, VALUE arg){
|
|
768
|
+
char *ptr = cd->dtstr + cd->dtoffset + offset;
|
|
769
|
+
if(offset+sizeof(BYTE) > cd->dtlen) rb_raise(rb_eRangeError, "Out of bounds.");
|
|
770
|
+
*(BYTE*)ptr = (BYTE)rw_num2ulong(arg);
|
|
771
|
+
return arg;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
static VALUE
|
|
775
|
+
cst_set_a_dt_H(CStructData *cd, int offset, VALUE arg){
|
|
776
|
+
char *ptr = cd->dtstr + cd->dtoffset + offset;
|
|
777
|
+
if(offset+sizeof(WORD) > cd->dtlen) rb_raise(rb_eRangeError, "Out of bounds.");
|
|
778
|
+
*(WORD*)ptr = (WORD)rw_num2ulong(arg);
|
|
779
|
+
return arg;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
static VALUE
|
|
783
|
+
cst_set_a_dt_L(CStructData *cd, int offset, VALUE arg){
|
|
784
|
+
char *ptr = cd->dtstr + cd->dtoffset + offset;
|
|
785
|
+
if(offset+sizeof(DWORD) > cd->dtlen) rb_raise(rb_eRangeError, "Out of bounds.");
|
|
786
|
+
*(DWORD*)ptr = (DWORD)rw_num2long(arg);
|
|
787
|
+
return arg;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
static VALUE
|
|
791
|
+
cst_set_a_dt_U(CStructData *cd, int offset, VALUE arg){
|
|
792
|
+
char *ptr = cd->dtstr + cd->dtoffset + offset;
|
|
793
|
+
if(offset+sizeof(DWORD) > cd->dtlen) rb_raise(rb_eRangeError, "Out of bounds.");
|
|
794
|
+
*(DWORD*)ptr = (DWORD)rw_num2ulong(arg);
|
|
795
|
+
return arg;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
static VALUE
|
|
799
|
+
cst_set_a_dt_S(CStructData *cd, int offset, VALUE arg){
|
|
800
|
+
CStructData* ptr2arg; void * ptr2data;
|
|
801
|
+
char *ptr = cd->dtstr + cd->dtoffset + offset;
|
|
802
|
+
if(offset+sizeof(void*) > cd->dtlen) rb_raise(rb_eRangeError, "Out of bounds.");
|
|
803
|
+
if(rb_typeddata_is_kind_of(arg, &cstruct_data_type)){
|
|
804
|
+
CStruct_Data_Get_Struct(arg, ptr2arg);
|
|
805
|
+
ptr2data = ptr2arg->dtstr + ptr2arg->dtoffset;
|
|
806
|
+
}else{
|
|
807
|
+
switch (TYPE(arg)){
|
|
808
|
+
case T_STRING:
|
|
809
|
+
if (!ENCODING_IS_ASCII8BIT(arg)){
|
|
810
|
+
VALUE text = rb_str_encode(arg, internal_encoding, 0, Qnil);
|
|
811
|
+
rb_str_shared_replace(arg, text); /* Replaces original object, so take care. */
|
|
812
|
+
}
|
|
813
|
+
ptr2data = RSTRING_PTR(arg);
|
|
814
|
+
break;
|
|
815
|
+
case T_FIXNUM:
|
|
816
|
+
case T_BIGNUM:
|
|
817
|
+
ptr2data = (void*)NUM2ULONG_PTR(arg);
|
|
818
|
+
break;
|
|
819
|
+
default:
|
|
820
|
+
rb_raise(rb_eArgError, "Pointer data must be a String or CStruct or address of it");
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
*(ULONG_PTR*)ptr = (ULONG_PTR)ptr2data;
|
|
824
|
+
return arg;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
static VALUE
|
|
828
|
+
cst_set_a_dt_u(CStructData *cd, int offset, VALUE arg){
|
|
829
|
+
CStructData* ptr2arg; void * ptr2data; VALUE obj;
|
|
830
|
+
char *ptr = cd->dtstr + cd->dtoffset + offset;
|
|
831
|
+
if(offset+sizeof(void*) > cd->dtlen) rb_raise(rb_eRangeError, "Out of bounds.");
|
|
832
|
+
|
|
833
|
+
if(rb_typeddata_is_kind_of(arg, &cstruct_data_type)){
|
|
834
|
+
CStruct_Data_Get_Struct(arg, ptr2arg);
|
|
835
|
+
ptr2data = ptr2arg->dtstr + ptr2arg->dtoffset;
|
|
836
|
+
} else if (TYPE(arg) == T_STRING) {
|
|
837
|
+
ptr2data = StringValuePtr(arg);
|
|
838
|
+
} else if (TYPE(arg) == T_FIXNUM || TYPE(arg) == T_BIGNUM) {
|
|
839
|
+
obj = cstruct1_alloc_int(cRwAPIstruct, arg);
|
|
840
|
+
CStruct_Data_Get_Struct(obj, ptr2arg);
|
|
841
|
+
ptr2data = ptr2arg->dtstr + ptr2arg->dtoffset;
|
|
842
|
+
} else {
|
|
843
|
+
rb_raise(rb_eArgError, "Pointer data must be a String or CStruct");
|
|
844
|
+
}
|
|
845
|
+
*(ULONG_PTR*)ptr = (ULONG_PTR)ptr2data;
|
|
846
|
+
return arg;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
static VALUE
|
|
850
|
+
cst_set_a_dt_q(CStructData *cd, int offset, VALUE arg){
|
|
851
|
+
CStructData* ptr2arg; void * ptr2data; VALUE obj;
|
|
852
|
+
char *ptr = cd->dtstr + cd->dtoffset + offset;
|
|
853
|
+
if(offset+sizeof(void*) > cd->dtlen) rb_raise(rb_eRangeError, "Out of bounds.");
|
|
854
|
+
|
|
855
|
+
if(rb_typeddata_is_kind_of(arg, &cstruct_data_type)){
|
|
856
|
+
CStruct_Data_Get_Struct(arg, ptr2arg);
|
|
857
|
+
ptr2data = ptr2arg->dtstr + ptr2arg->dtoffset;
|
|
858
|
+
} else if (TYPE(arg) == T_STRING) {
|
|
859
|
+
ptr2data = StringValuePtr(arg);
|
|
860
|
+
} else if (TYPE(arg) == T_FIXNUM || TYPE(arg) == T_BIGNUM) {
|
|
861
|
+
obj = cstruct1_alloc_int_ptr(cRwAPIstruct, arg);
|
|
862
|
+
CStruct_Data_Get_Struct(obj, ptr2arg);
|
|
863
|
+
ptr2data = ptr2arg->dtstr + ptr2arg->dtoffset;
|
|
864
|
+
} else {
|
|
865
|
+
rb_raise(rb_eArgError, "Pointer data must be a String or CStruct");
|
|
866
|
+
}
|
|
867
|
+
*(ULONG_PTR*)ptr = (ULONG_PTR)ptr2data;
|
|
868
|
+
return arg;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
static VALUE
|
|
872
|
+
cst_set_a_dt_Q(CStructData *cd, int offset, VALUE arg){
|
|
873
|
+
char *ptr = cd->dtstr + cd->dtoffset + offset;
|
|
874
|
+
if(offset+sizeof(void*) > cd->dtlen) rb_raise(rb_eRangeError, "Out of bounds.");
|
|
875
|
+
*(ULONG_PTR*)ptr = (ULONG_PTR)NUM2ULONG_PTR(arg);
|
|
876
|
+
return arg;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
static VALUE
|
|
880
|
+
cst_set_a_dt_K(CStructData *cd, int offset, VALUE klass, VALUE arg){
|
|
881
|
+
char *ptr = cd->dtstr + cd->dtoffset + offset;
|
|
882
|
+
if(rb_class_of(arg)==klass){
|
|
883
|
+
CStructData* ptr2arg;
|
|
884
|
+
CStruct_Data_Get_Struct(arg, ptr2arg);
|
|
885
|
+
memcpy(ptr, ptr2arg->dtstr + ptr2arg->dtoffset, ptr2arg->dtlen);
|
|
886
|
+
}else{
|
|
887
|
+
rb_raise(rb_eRuntimeError, "Struct type is differnt: expected %s, but got %s",
|
|
888
|
+
rb_class2name(klass), rb_obj_classname(arg));
|
|
889
|
+
}
|
|
890
|
+
return arg;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
// not work
|
|
894
|
+
static VALUE
|
|
895
|
+
cst_set_a_dt_P(CStructData *cd, int offset, VALUE klass, VALUE arg){
|
|
896
|
+
CStructData* ptr2arg;
|
|
897
|
+
char *ptr = cd->dtstr + cd->dtoffset + offset;
|
|
898
|
+
if(offset+sizeof(void*) > cd->dtlen) rb_raise(rb_eRangeError, "Out of bounds.");
|
|
899
|
+
if(klass!=rb_class_of(arg)) {
|
|
900
|
+
rb_raise(rb_eArgError, "Arg type is differnt: expected %s, but got %s",
|
|
901
|
+
rb_class2name(klass), rb_obj_classname(arg));
|
|
902
|
+
}
|
|
903
|
+
CStruct_Data_Get_Struct(arg, ptr2arg);
|
|
904
|
+
*(long*)ptr = (ULONG_PTR)(ptr2arg->dtstr + ptr2arg->dtoffset);
|
|
905
|
+
return arg;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
static VALUE
|
|
909
|
+
(* cst_set_funcs[15])(CStructData*, int, VALUE) = {
|
|
910
|
+
NULL,
|
|
911
|
+
cst_set_a_dt_C,
|
|
912
|
+
cst_set_a_dt_C,
|
|
913
|
+
cst_set_a_dt_H,
|
|
914
|
+
cst_set_a_dt_H,
|
|
915
|
+
cst_set_a_dt_L,
|
|
916
|
+
cst_set_a_dt_U,
|
|
917
|
+
cst_set_a_dt_S,
|
|
918
|
+
cst_set_a_dt_S,
|
|
919
|
+
cst_set_a_dt_u,
|
|
920
|
+
cst_set_a_dt_u,
|
|
921
|
+
cst_set_a_dt_q,
|
|
922
|
+
cst_set_a_dt_q,
|
|
923
|
+
cst_set_a_dt_Q,
|
|
924
|
+
cst_set_a_dt_Q,
|
|
925
|
+
};
|
|
926
|
+
|
|
927
|
+
/********************** Array ***********************/
|
|
928
|
+
static void
|
|
929
|
+
cst_str_copy_src_to_dest(CStructData *pd, VALUE arg, int offset2){
|
|
930
|
+
if (rb_typeddata_is_kind_of(arg, &cstruct_data_type)){
|
|
931
|
+
CStructData *sd;
|
|
932
|
+
size_t slen;
|
|
933
|
+
CStruct_Data_Get_Struct(arg, sd);
|
|
934
|
+
slen = sd->dtlen;
|
|
935
|
+
if(pd->dtlen+offset2 < slen) rb_raise(rb_eRangeError, "Reached the end of data");
|
|
936
|
+
memcpy(pd->dtstr, sd->dtstr+offset2, slen);
|
|
937
|
+
}else
|
|
938
|
+
rb_raise(rb_eArgError, "Argument must be a String or a CStruct");
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
static VALUE
|
|
942
|
+
cst_set_ary_dt_W(CStructData *cd, int offset, VALUE arg){
|
|
943
|
+
VALUE apistr;
|
|
944
|
+
wchar_t *buff;
|
|
945
|
+
size_t slen;
|
|
946
|
+
int offset2 = offset + cd->dtoffset;
|
|
947
|
+
char *ptr = cd->dtstr + offset2;
|
|
948
|
+
switch (TYPE(arg)){
|
|
949
|
+
case T_STRING:
|
|
950
|
+
apistr = rb_str_encode(arg, wchar_encoding, 0, Qnil);
|
|
951
|
+
buff = (wchar_t*)RSTRING_PTR(apistr);
|
|
952
|
+
slen = RSTRING_LEN(apistr);
|
|
953
|
+
if(slen+offset2 > cd->dtlen) rb_raise(rb_eRangeError, "Reached the end of data");
|
|
954
|
+
memcpy(ptr, buff, slen);
|
|
955
|
+
break;
|
|
956
|
+
case T_DATA:
|
|
957
|
+
cst_str_copy_src_to_dest(cd, arg, offset2);
|
|
958
|
+
break;
|
|
959
|
+
default:
|
|
960
|
+
rb_raise(rb_eArgError, "Argument must be a String or a CStruct");
|
|
961
|
+
}
|
|
962
|
+
return arg;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
static VALUE
|
|
966
|
+
cst_set_ary_dt_C(CStructData *cd, int offset, VALUE arg){
|
|
967
|
+
size_t slen;
|
|
968
|
+
int offset2 = offset + cd->dtoffset;
|
|
969
|
+
char *ptr = cd->dtstr + offset2;
|
|
970
|
+
switch (TYPE(arg)){
|
|
971
|
+
case T_STRING:
|
|
972
|
+
slen = RSTRING_LEN(arg);
|
|
973
|
+
if(slen+offset2 > cd->dtlen) rb_raise(rb_eRangeError, "Reached the end of data");
|
|
974
|
+
memcpy(ptr, RSTRING_PTR(arg), slen);
|
|
975
|
+
break;
|
|
976
|
+
case T_DATA:
|
|
977
|
+
cst_str_copy_src_to_dest(cd, arg, offset2);
|
|
978
|
+
break;
|
|
979
|
+
default:
|
|
980
|
+
rb_raise(rb_eArgError, "Argument must be a String or a CStruct");
|
|
981
|
+
}
|
|
982
|
+
return arg;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
/* ############## instance methods ################ */
|
|
986
|
+
|
|
987
|
+
static void
|
|
988
|
+
cstruct_set_args_(int argc, VALUE* argv, VALUE klass, VALUE self) { // set args
|
|
989
|
+
int i;
|
|
990
|
+
int len = cs_get_count(self);
|
|
991
|
+
if (len < argc)
|
|
992
|
+
rb_raise(rb_eRangeError, "Too many arguments, expected %d, but got %d", len, argc);
|
|
993
|
+
for (i=0; i<argc; i++){
|
|
994
|
+
if(NIL_P(argv[i])) {
|
|
995
|
+
continue;
|
|
996
|
+
} else {
|
|
997
|
+
VALUE v_arg[2];
|
|
998
|
+
v_arg[0] = INT2FIX(i);
|
|
999
|
+
v_arg[1] = argv[i];
|
|
1000
|
+
cstruct_set_idx_value__(2, v_arg, self);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
static VALUE cstruct_initialize_default(int argc, VALUE* argv, VALUE self){
|
|
1006
|
+
VALUE klass;
|
|
1007
|
+
int len;
|
|
1008
|
+
char* ptr;
|
|
1009
|
+
CStructData* cd = DATA_PTR(self);
|
|
1010
|
+
|
|
1011
|
+
/* create by default */
|
|
1012
|
+
klass = rb_class_of(self);
|
|
1013
|
+
len = FIX2INT(rb_const_get(klass, _id_cstruct_size));
|
|
1014
|
+
if (!len) rb_raise(rb_eRuntimeError, "Use 'CStruct.alloc' instead.");
|
|
1015
|
+
RW_CALLOC(ptr, len);
|
|
1016
|
+
cd->dtstr = ptr;
|
|
1017
|
+
cd->dtlen = len;
|
|
1018
|
+
if(argc > 0) cstruct_set_args_(argc, argv, klass, self);
|
|
1019
|
+
return Qnil;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
static VALUE
|
|
1023
|
+
cstruct_to_bstr(VALUE self){
|
|
1024
|
+
CStructData* cd = DATA_PTR(self);
|
|
1025
|
+
return rb_str_new(cd->dtstr + cd->dtoffset, cd->dtlen);
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
static VALUE
|
|
1029
|
+
cstruct_to_str(VALUE self){
|
|
1030
|
+
int l;
|
|
1031
|
+
VALUE str;
|
|
1032
|
+
CStructData* cd = DATA_PTR(self);
|
|
1033
|
+
VALUE klass = rb_class_of(self);
|
|
1034
|
+
int ifunc = 0;
|
|
1035
|
+
if(!cd->bifunc){
|
|
1036
|
+
ifunc = cs_get_offset_data(klass, 0)->ifunc;
|
|
1037
|
+
}
|
|
1038
|
+
if(cd->bifunc==dt_C || ifunc==dt_C){ /* CHAR[] */
|
|
1039
|
+
char *strptr = cd->dtstr + cd->dtoffset;
|
|
1040
|
+
for(l=cd->dtlen-1; l>0; l--){if(strptr[l]>0) break;}
|
|
1041
|
+
return rb_enc_str_new(strptr, strptr[0] ? l+1 : 0, rw_external_enc);
|
|
1042
|
+
} else if(cd->bifunc==dt_W || ifunc==dt_W){ /* WCHAR[] */
|
|
1043
|
+
wchar_t *strptr = (wchar_t*)(cd->dtstr + cd->dtoffset);
|
|
1044
|
+
for(l=cd->dtlen/2-1; l>0; l--){if(strptr[l]>0) break;}
|
|
1045
|
+
str = rb_enc_str_new((char*)strptr, strptr[0] ? (l+1)*2 : 0, rw_wchar_enc);
|
|
1046
|
+
return rb_str_encode(str, external_encoding, 0, Qnil);
|
|
1047
|
+
} else {
|
|
1048
|
+
return rb_str_new(cd->dtstr + cd->dtoffset, cd->dtlen);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
static VALUE
|
|
1053
|
+
cstruct_to_int(VALUE self){
|
|
1054
|
+
CStructData* cd = DATA_PTR(self);
|
|
1055
|
+
return INT2NUM((int)*(cd->dtstr + cd->dtoffset));
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
static VALUE
|
|
1059
|
+
cstruct_to_uint(VALUE self){
|
|
1060
|
+
CStructData* cd = DATA_PTR(self);
|
|
1061
|
+
return UINT2NUM((UINT)*(cd->dtstr + cd->dtoffset));
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
static VALUE
|
|
1065
|
+
cstruct_size(VALUE self){
|
|
1066
|
+
CStructData* cd = DATA_PTR(self);
|
|
1067
|
+
return INT2FIX(cd->dtlen);
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
static VALUE
|
|
1071
|
+
cstruct_count(VALUE self){
|
|
1072
|
+
return INT2FIX(cs_get_count(self));
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
static VALUE
|
|
1076
|
+
cstruct_pointer(VALUE self){
|
|
1077
|
+
CStructData* cd = DATA_PTR(self);
|
|
1078
|
+
return ULONG_PTR2NUM((ULONG_PTR)cd->dtstr + cd->dtoffset);
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
static VALUE
|
|
1082
|
+
cstruct1_newstr(int argc, VALUE *argv, VALUE klass){
|
|
1083
|
+
CStructData* cd;
|
|
1084
|
+
VALUE str; VALUE offset;
|
|
1085
|
+
char *target; char *ptr;
|
|
1086
|
+
int ofst;
|
|
1087
|
+
size_t strlen, len;
|
|
1088
|
+
|
|
1089
|
+
VALUE obj = CStruct_Data_Make_Struct(klass, cd);
|
|
1090
|
+
len = FIX2INT(rb_const_get(klass, _id_cstruct_size));
|
|
1091
|
+
rb_scan_args(argc, argv, "11", &str, &offset);
|
|
1092
|
+
ofst = NIL_P(offset) ? 0 : FIX2INT(offset);
|
|
1093
|
+
strlen = RSTRING_LEN(str);
|
|
1094
|
+
if(len + ofst > strlen) rb_raise(rb_eRuntimeError,"Too short sting");
|
|
1095
|
+
target = (char*)(RSTRING_PTR(str) + ofst);
|
|
1096
|
+
RW_CALLOC(ptr, len);
|
|
1097
|
+
memcpy(ptr, target, len);
|
|
1098
|
+
cd->dtstr = ptr;
|
|
1099
|
+
cd->dtlen = len;
|
|
1100
|
+
return obj;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
static VALUE
|
|
1104
|
+
cstruct1_newptr(int argc, VALUE *argv, VALUE klass){
|
|
1105
|
+
CStructData* cd;
|
|
1106
|
+
VALUE pointer; VALUE len;
|
|
1107
|
+
size_t ln;
|
|
1108
|
+
char *target; char *ptr;
|
|
1109
|
+
VALUE obj = CStruct_Data_Make_Struct(klass, cd);
|
|
1110
|
+
|
|
1111
|
+
rb_scan_args(argc, argv, "11", &pointer, &len);
|
|
1112
|
+
ln = FIX2INT(NIL_P(len) ? rb_const_get(klass, _id_cstruct_size) : len);
|
|
1113
|
+
target = (char*)NUM2ULONG_PTR(pointer);
|
|
1114
|
+
RW_CALLOC(ptr, ln);
|
|
1115
|
+
memcpy(ptr, target, ln);
|
|
1116
|
+
cd->dtstr = ptr;
|
|
1117
|
+
cd->dtlen = ln;
|
|
1118
|
+
return obj;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
VALUE
|
|
1122
|
+
cstruct_wrapptr(VALUE klass, char* pointer, VALUE v_parent){
|
|
1123
|
+
CStructData* cd;
|
|
1124
|
+
VALUE obj = CStruct_Data_Make_Struct(klass, cd);
|
|
1125
|
+
int len = FIX2INT(rb_const_get(klass, _id_cstruct_size));
|
|
1126
|
+
cd->dtstr = pointer;
|
|
1127
|
+
cd->dtlen = len;
|
|
1128
|
+
cd->dtparent = v_parent;
|
|
1129
|
+
cd->dtwrapped = 1;
|
|
1130
|
+
return obj;
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
static VALUE
|
|
1134
|
+
cstruct1_wrapptr(VALUE klass, VALUE v_pointer){
|
|
1135
|
+
return cstruct_wrapptr(klass, (char*)NUM2ULONG_PTR(v_pointer), 0);
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
static VALUE
|
|
1139
|
+
cstruct1_wrapstr(VALUE klass, VALUE str){
|
|
1140
|
+
CStructData* cd;
|
|
1141
|
+
VALUE obj = CStruct_Data_Make_Struct_Default_Free(klass, cd);
|
|
1142
|
+
int len = FIX2INT(rb_const_get(klass, _id_cstruct_size));
|
|
1143
|
+
if (RSTRING_LEN(str) != len){
|
|
1144
|
+
rb_raise(rb_eRuntimeError,
|
|
1145
|
+
"Struct size mismatch: expected %d, but got %d", len, (int)RSTRING_LEN(str));
|
|
1146
|
+
}
|
|
1147
|
+
cd->dtstr = (char*)RSTRING_PTR(str);
|
|
1148
|
+
cd->dtlen = len;
|
|
1149
|
+
cd->dtwrapped = 1;
|
|
1150
|
+
return obj;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
static VALUE
|
|
1154
|
+
cstruct1_alloc(VALUE klass, VALUE arg){
|
|
1155
|
+
char *ptr;
|
|
1156
|
+
size_t len;
|
|
1157
|
+
VALUE obj = cstruct_alloc(klass);
|
|
1158
|
+
CStructData* sdtptr = DATA_PTR(obj);
|
|
1159
|
+
|
|
1160
|
+
if (FIXNUM_P(arg)){ /* initialize memory to 0 */
|
|
1161
|
+
len = FIX2INT(arg);
|
|
1162
|
+
RW_CALLOC(ptr, len);
|
|
1163
|
+
}else if(TYPE(arg) == T_STRING){ /* copy string data to memory */
|
|
1164
|
+
StringValue(arg);
|
|
1165
|
+
len = RSTRING_LEN(arg);
|
|
1166
|
+
RW_CALLOC(ptr, len);
|
|
1167
|
+
memcpy(ptr, RSTRING_PTR(arg), len);
|
|
1168
|
+
}else if (rb_typeddata_is_kind_of(arg, &cstruct_data_type)){/*copy cstruct data to memory */
|
|
1169
|
+
CStructData *src;
|
|
1170
|
+
CStruct_Data_Get_Struct(arg, src);
|
|
1171
|
+
len = src->dtlen;
|
|
1172
|
+
RW_CALLOC(ptr, len);
|
|
1173
|
+
memcpy(ptr, src->dtstr, len);
|
|
1174
|
+
}else{
|
|
1175
|
+
rb_raise(rb_eArgError, "Argument must be a Integer or String or Cstruct.");
|
|
1176
|
+
}
|
|
1177
|
+
sdtptr->dtstr = ptr;
|
|
1178
|
+
sdtptr->dtlen = len;
|
|
1179
|
+
return obj;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
static VALUE
|
|
1183
|
+
cstruct1_alloc_int(VALUE klass, VALUE arg){
|
|
1184
|
+
CStructData* sdtptr;
|
|
1185
|
+
char *ptr;
|
|
1186
|
+
size_t len = sizeof(LONG);
|
|
1187
|
+
VALUE obj = CStruct_Data_Make_Struct(klass, sdtptr);
|
|
1188
|
+
RW_CALLOC(ptr, len);
|
|
1189
|
+
*(LONG*)ptr = NUM2ULONG(arg);
|
|
1190
|
+
sdtptr->dtstr = ptr;
|
|
1191
|
+
sdtptr->dtlen = len;
|
|
1192
|
+
sdtptr->dtparent = 8;
|
|
1193
|
+
return obj;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
static VALUE
|
|
1197
|
+
cstruct1_alloc_int_ptr(VALUE klass, VALUE arg){
|
|
1198
|
+
CStructData* sdtptr;
|
|
1199
|
+
char *ptr;
|
|
1200
|
+
size_t len = sizeof(LONG_PTR);
|
|
1201
|
+
VALUE obj = CStruct_Data_Make_Struct(klass, sdtptr);
|
|
1202
|
+
RW_CALLOC(ptr, len);
|
|
1203
|
+
*(LONG_PTR*)ptr = NUM2LONG_PTR(arg);
|
|
1204
|
+
sdtptr->dtstr = ptr;
|
|
1205
|
+
sdtptr->dtlen = len;
|
|
1206
|
+
sdtptr->dtparent = 8;
|
|
1207
|
+
return obj;
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
static VALUE
|
|
1211
|
+
cstruct_cast_(VALUE klass, VALUE parent, int offset, int len){
|
|
1212
|
+
CStructData* sdtptr;
|
|
1213
|
+
CStructData* srcptr;
|
|
1214
|
+
VALUE obj = CStruct_Data_Make_Struct_Default_Free(klass, sdtptr);
|
|
1215
|
+
CStruct_Data_Get_Struct(parent, srcptr);
|
|
1216
|
+
sdtptr->dtstr = srcptr->dtstr;
|
|
1217
|
+
sdtptr->dtoffset = srcptr->dtoffset + offset;
|
|
1218
|
+
sdtptr->dtlen = len;
|
|
1219
|
+
sdtptr->dtparent = parent;
|
|
1220
|
+
sdtptr->dtwrapped = 1;
|
|
1221
|
+
return obj;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
static VALUE
|
|
1225
|
+
cstruct1_cast(VALUE klass, VALUE parent, VALUE v_offset, VALUE v_len){
|
|
1226
|
+
return cstruct_cast_(klass, parent, FIX2INT(v_offset), FIX2INT(v_len));
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
static VALUE
|
|
1230
|
+
cstruct_clear(int argc, VALUE* argv, VALUE self){ //[args...]
|
|
1231
|
+
CStructData* cd = DATA_PTR(self);
|
|
1232
|
+
memset(cd->dtstr, 0, cd->dtlen);
|
|
1233
|
+
if(argc > 0) cstruct_set_args_(argc, argv, rb_obj_class(self), self);
|
|
1234
|
+
return self;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
static VALUE
|
|
1238
|
+
cstruct_get_array_part(VALUE self, CStructData* cd, int idx, int nth){// Data is an ArrayPart
|
|
1239
|
+
VALUE v_apart;
|
|
1240
|
+
int ub, len;
|
|
1241
|
+
VALUE kls = Qnil;
|
|
1242
|
+
int offset = 0;
|
|
1243
|
+
int ifunc = cd->bifunc;
|
|
1244
|
+
VALUE klass = rb_class_of(cd->dtparent ? cd->dtparent : self);
|
|
1245
|
+
RWOffsetData *od = cs_get_offset_data(klass, cd->prindex);
|
|
1246
|
+
if (ifunc==dt_K || ifunc==dt_P) {
|
|
1247
|
+
kls = rb_ary_entry(rb_const_get(klass, _id_cstruct_s_classes), od->klsidx);
|
|
1248
|
+
}
|
|
1249
|
+
len = od->mblen;
|
|
1250
|
+
ub = cd->dtlen / len;
|
|
1251
|
+
if (idx+nth>ub || nth<0){
|
|
1252
|
+
rb_raise(rb_eRangeError, "@%d: Out of index: [%d, %d]", __LINE__, idx, nth);
|
|
1253
|
+
}
|
|
1254
|
+
offset += idx*len;
|
|
1255
|
+
if(nth==1) {
|
|
1256
|
+
if(ifunc<dt_K) return cst_get_funcs[ifunc](cd, offset);
|
|
1257
|
+
else if (ifunc==dt_K) return cst_get_a_dt_K(self, offset, kls);
|
|
1258
|
+
else if (ifunc==dt_P) return cst_get_a_dt_P(cd, offset, kls, self);
|
|
1259
|
+
else rb_bug("@%d: ifunc:%d is not allowed.", __LINE__, ifunc);
|
|
1260
|
+
} else {
|
|
1261
|
+
int i;
|
|
1262
|
+
VALUE r;
|
|
1263
|
+
v_apart = rb_ary_new2(nth);
|
|
1264
|
+
for(i=0; i<nth; i++){
|
|
1265
|
+
if(ifunc<dt_K) r = cst_get_funcs[ifunc](cd, offset);
|
|
1266
|
+
else if(ifunc==dt_K) r = cst_get_a_dt_K(self, offset, kls);
|
|
1267
|
+
else if (ifunc==dt_P) r = cst_get_a_dt_P(cd, offset, kls, self);
|
|
1268
|
+
else rb_bug("@%d: ifunc:%d is not allowed.", __LINE__, ifunc);
|
|
1269
|
+
rb_ary_store(v_apart, i, r);
|
|
1270
|
+
offset += len;
|
|
1271
|
+
}
|
|
1272
|
+
return v_apart;
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
static VALUE
|
|
1277
|
+
cstruct_get_idx_value__(int argc, VALUE *argv, VALUE self){
|
|
1278
|
+
CStructData* cd = DATA_PTR(self);
|
|
1279
|
+
if(cd->bifunc){ // data is array part
|
|
1280
|
+
int idx, nth;
|
|
1281
|
+
switch (argc){
|
|
1282
|
+
case 1:
|
|
1283
|
+
idx = FIX2INT(argv[0]);
|
|
1284
|
+
nth = 1;
|
|
1285
|
+
break;
|
|
1286
|
+
case 2:
|
|
1287
|
+
idx = FIX2INT(argv[0]);
|
|
1288
|
+
nth = FIX2INT(argv[1]);
|
|
1289
|
+
break;
|
|
1290
|
+
default :
|
|
1291
|
+
rb_raise(rb_eArgError, "Num of arguemnts must br 1 or 2 but %d", argc);
|
|
1292
|
+
}
|
|
1293
|
+
return cstruct_get_array_part(self, cd, idx, nth);
|
|
1294
|
+
} else {
|
|
1295
|
+
int ub, idx, ifunc, nth, offset;
|
|
1296
|
+
VALUE kls, klass, s_offsets;
|
|
1297
|
+
char *ods;
|
|
1298
|
+
RWCSAttribute *attr;
|
|
1299
|
+
RWOffsetData *od;
|
|
1300
|
+
if (argc!=1) rb_raise(rb_eArgError, "Num of arguemnts must be 1 but %d", argc);
|
|
1301
|
+
klass=rb_class_of(self);
|
|
1302
|
+
s_offsets = rb_const_get(klass, _id_cstruct_s_offsets);
|
|
1303
|
+
ods = RSTRING_PTR(s_offsets);
|
|
1304
|
+
attr = (RWCSAttribute*)ods;
|
|
1305
|
+
idx = FIX2INT(argv[0]);
|
|
1306
|
+
od = cs_get_offset_data(klass, idx);
|
|
1307
|
+
ub = attr->cmembers;
|
|
1308
|
+
if (idx>ub-1)rb_raise(rb_eRangeError, "Out of index: %d > %d", idx, ub-1);
|
|
1309
|
+
offset = od->offset;
|
|
1310
|
+
ifunc = od->ifunc;
|
|
1311
|
+
nth = od->nth;
|
|
1312
|
+
kls = (ifunc==dt_K || ifunc==dt_P) ?
|
|
1313
|
+
rb_ary_entry(rb_const_get(klass, _id_cstruct_s_classes), od->klsidx) : Qnil;
|
|
1314
|
+
|
|
1315
|
+
if(nth){
|
|
1316
|
+
VALUE v_apart;
|
|
1317
|
+
CStructData *ap;
|
|
1318
|
+
int dtlen;
|
|
1319
|
+
if (idx==ub-1) dtlen = cd->dtlen - offset; /* variable length termination */
|
|
1320
|
+
else dtlen = od->mblen * nth;
|
|
1321
|
+
v_apart = cstruct_cast_(cRwAPIstructArrayPart, self, offset, dtlen);
|
|
1322
|
+
ap = DATA_PTR(v_apart);
|
|
1323
|
+
ap->bifunc = ifunc;
|
|
1324
|
+
ap->prindex = idx;
|
|
1325
|
+
return v_apart;
|
|
1326
|
+
}else{
|
|
1327
|
+
if(ifunc<dt_K) return cst_get_funcs[ifunc](cd, offset);
|
|
1328
|
+
else if (ifunc==dt_K) return cst_get_a_dt_K(self, offset, kls);
|
|
1329
|
+
else if (ifunc==dt_P) return cst_get_a_dt_P(cd, offset, kls, self);
|
|
1330
|
+
else rb_bug("@%d: ifunc:%d is not allowed.", __LINE__, ifunc);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
static VALUE
|
|
1336
|
+
cstruct_set_array_part(VALUE self, CStructData* cd, int idx, int nth, VALUE v_val){
|
|
1337
|
+
int len, offset, ub;
|
|
1338
|
+
VALUE klass;
|
|
1339
|
+
RWOffsetData *od;
|
|
1340
|
+
VALUE kls = 0;
|
|
1341
|
+
int ifunc = cd->bifunc;
|
|
1342
|
+
offset = 0;
|
|
1343
|
+
if (RB_TYPE_P(v_val, T_STRING)) {
|
|
1344
|
+
switch(ifunc){
|
|
1345
|
+
case dt_C:
|
|
1346
|
+
return cst_set_ary_dt_C(cd, offset, v_val);
|
|
1347
|
+
case dt_W:
|
|
1348
|
+
return cst_set_ary_dt_W(cd, offset, v_val);
|
|
1349
|
+
default:
|
|
1350
|
+
rb_raise(rb_eTypeError, "ifunc: %d is not allowed for String.", ifunc);
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
klass = rb_class_of(cd->dtparent ? cd->dtparent : self);
|
|
1355
|
+
od = cs_get_offset_data(klass, cd->prindex);
|
|
1356
|
+
if (ifunc==dt_K || ifunc==dt_P) {
|
|
1357
|
+
kls = rb_ary_entry(rb_const_get(klass, _id_cstruct_s_classes), od->klsidx);
|
|
1358
|
+
}
|
|
1359
|
+
len = od->mblen;
|
|
1360
|
+
ub = cd->dtlen / len;
|
|
1361
|
+
if (idx+nth>ub || nth<0){
|
|
1362
|
+
rb_raise(rb_eRangeError, "@%d: Out of index: [%d, %d]", __LINE__, idx, nth);
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
offset += idx*len;
|
|
1366
|
+
if(RB_TYPE_P(v_val, T_ARRAY)) {
|
|
1367
|
+
int i;
|
|
1368
|
+
int alen = RARRAY_LEN(v_val);
|
|
1369
|
+
if (len*(idx+alen)>(int)cd->dtlen || len*(idx+nth)>(int)cd->dtlen){
|
|
1370
|
+
rb_raise(rb_eRangeError, "@%d: Reached the end of data.", __LINE__);
|
|
1371
|
+
} else if (nth>alen){
|
|
1372
|
+
rb_raise(rb_eRangeError, "@%d: Too few arguments: %d, expected %d or more.",
|
|
1373
|
+
__LINE__, alen, nth);
|
|
1374
|
+
}
|
|
1375
|
+
if(ifunc<dt_K) {
|
|
1376
|
+
for(i=0; i<nth; i++){
|
|
1377
|
+
cst_set_funcs[ifunc](cd, offset, rb_ary_entry(v_val, i));
|
|
1378
|
+
offset += len;
|
|
1379
|
+
}
|
|
1380
|
+
} else if(ifunc==dt_K) {
|
|
1381
|
+
for(i=0; i<nth; i++){
|
|
1382
|
+
cst_set_a_dt_K(cd, offset, kls, rb_ary_entry(v_val, i));
|
|
1383
|
+
offset += len;
|
|
1384
|
+
}
|
|
1385
|
+
} else rb_raise(rb_eTypeError, "ifunc: %d is not allowed for Array.", ifunc);
|
|
1386
|
+
return v_val;
|
|
1387
|
+
} else {
|
|
1388
|
+
if (nth > 1){
|
|
1389
|
+
rb_raise(rb_eRangeError, "@%d: Too few arguments: 1, expected %d or more.",
|
|
1390
|
+
__LINE__, nth);
|
|
1391
|
+
}
|
|
1392
|
+
if(ifunc<dt_K) {
|
|
1393
|
+
return cst_set_funcs[ifunc](cd, offset, v_val);
|
|
1394
|
+
} else if(ifunc==dt_K) {
|
|
1395
|
+
return cst_set_a_dt_K(cd, offset, kls, v_val);
|
|
1396
|
+
} else if(ifunc==dt_P) {
|
|
1397
|
+
return cst_set_a_dt_P(cd, offset, kls, v_val);
|
|
1398
|
+
} else rb_raise(rb_eTypeError, "ifunc:%d is not allowed.", ifunc);
|
|
1399
|
+
}
|
|
1400
|
+
return v_val;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
static VALUE
|
|
1404
|
+
cstruct_set_idx_value__(int argc, VALUE *argv, VALUE self){
|
|
1405
|
+
VALUE v_val;
|
|
1406
|
+
int ub, offset, ifunc, len, nth, idx;
|
|
1407
|
+
CStructData* cd = DATA_PTR(self);
|
|
1408
|
+
VALUE klass = rb_class_of(self);
|
|
1409
|
+
VALUE kls = 0;
|
|
1410
|
+
if(ifunc=cd->bifunc){// Data is an ArrayPart
|
|
1411
|
+
switch (argc){
|
|
1412
|
+
case 2:
|
|
1413
|
+
idx = FIX2INT(argv[0]);
|
|
1414
|
+
nth = 1;
|
|
1415
|
+
v_val = argv[1];
|
|
1416
|
+
break;
|
|
1417
|
+
case 3:
|
|
1418
|
+
idx = FIX2INT(argv[0]);
|
|
1419
|
+
nth = FIX2INT(argv[1]);
|
|
1420
|
+
v_val = argv[2];
|
|
1421
|
+
break;
|
|
1422
|
+
default :
|
|
1423
|
+
rb_raise(rb_eArgError, "Num of arguemnts must br 2 or 3 but %d", argc);
|
|
1424
|
+
}
|
|
1425
|
+
return cstruct_set_array_part(self, cd, idx, nth, v_val);
|
|
1426
|
+
} else {
|
|
1427
|
+
RWOffsetData *od;
|
|
1428
|
+
if (argc!=2) rb_raise(rb_eArgError, "Num of arguemnts must be 2 but %d", argc);
|
|
1429
|
+
idx = FIX2INT(argv[0]);
|
|
1430
|
+
v_val = argv[1];
|
|
1431
|
+
klass = rb_class_of(self);
|
|
1432
|
+
od = cs_get_offset_data(klass, idx);
|
|
1433
|
+
ub = cs_get_offset_attribute(klass)->cmembers;
|
|
1434
|
+
if (idx>ub-1)rb_raise(rb_eRangeError, "Out of index: %d > %d", idx, ub-1);
|
|
1435
|
+
offset = od->offset;
|
|
1436
|
+
ifunc = od->ifunc;
|
|
1437
|
+
nth = od->nth;
|
|
1438
|
+
// fprintf(stderr, "@%d: offset=%d, ifunc=%d, nth=%d, mblen=%d\n", __LINE__, od->offset, od->ifunc, od->nth, od->mblen);
|
|
1439
|
+
kls = (ifunc==dt_K || ifunc==dt_P) ?
|
|
1440
|
+
rb_ary_entry(rb_const_get(klass, _id_cstruct_s_classes), od->klsidx) : Qnil;
|
|
1441
|
+
len = od->mblen;
|
|
1442
|
+
}
|
|
1443
|
+
if(!nth){
|
|
1444
|
+
if(offset+len>(int)cd->dtlen){
|
|
1445
|
+
rb_raise(rb_eRangeError, "@%d: Out of index: %d",__LINE__, idx);
|
|
1446
|
+
}
|
|
1447
|
+
if(ifunc<dt_K) {
|
|
1448
|
+
return cst_set_funcs[ifunc](cd, offset, v_val);
|
|
1449
|
+
} else if(ifunc==dt_K) {
|
|
1450
|
+
return cst_set_a_dt_K(cd, offset, kls, v_val);
|
|
1451
|
+
} else if(ifunc==dt_P) {
|
|
1452
|
+
return cst_set_a_dt_P(cd, offset, kls, v_val);
|
|
1453
|
+
} else {
|
|
1454
|
+
rb_raise(rb_eTypeError, "ifunc:%d is not allowed.", ifunc);
|
|
1455
|
+
}
|
|
1456
|
+
} else {
|
|
1457
|
+
int i, n;
|
|
1458
|
+
if(offset+len*nth>(int)cd->dtlen){
|
|
1459
|
+
rb_raise(rb_eRangeError, "@%d: Out of index: %d",__LINE__, idx);
|
|
1460
|
+
}
|
|
1461
|
+
if(RB_TYPE_P(v_val, T_STRING)){
|
|
1462
|
+
switch(ifunc){
|
|
1463
|
+
case dt_C:
|
|
1464
|
+
return cst_set_ary_dt_C(cd, offset, v_val);
|
|
1465
|
+
case dt_W:
|
|
1466
|
+
return cst_set_ary_dt_W(cd, offset, v_val);
|
|
1467
|
+
default:
|
|
1468
|
+
rb_raise(rb_eTypeError, "Argument must be an String.");
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
if(!RB_TYPE_P(v_val, T_ARRAY)){
|
|
1472
|
+
rb_raise(rb_eTypeError, "Argument must be Array.");
|
|
1473
|
+
}
|
|
1474
|
+
n = RARRAY_LEN(v_val);
|
|
1475
|
+
if(ifunc<dt_K) {
|
|
1476
|
+
for (i=0;i<n;i++){
|
|
1477
|
+
cst_set_funcs[ifunc](cd, offset, rb_ary_entry(v_val, i));
|
|
1478
|
+
offset += len;
|
|
1479
|
+
}
|
|
1480
|
+
} else if(ifunc==dt_K) {
|
|
1481
|
+
for (i=0;i<n;i++){
|
|
1482
|
+
cst_set_a_dt_K(cd, offset, kls, rb_ary_entry(v_val, i));
|
|
1483
|
+
offset += len;
|
|
1484
|
+
}
|
|
1485
|
+
} else if(ifunc==dt_P) {
|
|
1486
|
+
for (i=0;i<n;i++){
|
|
1487
|
+
cst_set_a_dt_P(cd, offset, kls, rb_ary_entry(v_val, i));
|
|
1488
|
+
offset += len;
|
|
1489
|
+
}
|
|
1490
|
+
} else{
|
|
1491
|
+
rb_raise(rb_eTypeError, "ifunc:%d is not allowed.", ifunc);
|
|
1492
|
+
}
|
|
1493
|
+
return v_val;
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
static VALUE
|
|
1498
|
+
cstruct_getvalue(VALUE self){
|
|
1499
|
+
CStructData *cd = DATA_PTR(self);
|
|
1500
|
+
if (cs_get_offset_attribute(rb_class_of(self))->cmembers!=1)
|
|
1501
|
+
rb_raise(rb_eRangeError, "Not a single member");
|
|
1502
|
+
else {
|
|
1503
|
+
int ifunc = cs_get_offset_data(rb_class_of(self), 0)->ifunc;
|
|
1504
|
+
VALUE v_arpart = cstruct_cast_(cRwAPIstructArrayPart, self, 0, cd->dtlen); /* entire data */
|
|
1505
|
+
CStructData *sl = DATA_PTR(v_arpart);
|
|
1506
|
+
sl->bifunc = ifunc;
|
|
1507
|
+
sl->prindex = 0;
|
|
1508
|
+
return v_arpart;
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
|
|
1513
|
+
static VALUE
|
|
1514
|
+
cstruct_setvalue(VALUE self, VALUE v_val){
|
|
1515
|
+
VALUE args[3];
|
|
1516
|
+
args[0] = v_zero;
|
|
1517
|
+
args[1] = RB_TYPE_P(v_val, T_ARRAY) ? INT2FIX(RARRAY_LEN(v_val)) : v_one;
|
|
1518
|
+
args[2] = v_val;
|
|
1519
|
+
return cstruct_set_idx_value__(3, args, self);
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
static VALUE
|
|
1523
|
+
cstruct1_new2(int argc, VALUE* argv, VALUE klass){ //[args...]
|
|
1524
|
+
CStructData* cd;
|
|
1525
|
+
char *ptr;
|
|
1526
|
+
size_t len;
|
|
1527
|
+
VALUE obj = CStruct_Data_Make_Struct(klass, cd);
|
|
1528
|
+
len = FIX2INT(rb_const_get(klass, _id_cstruct_size));
|
|
1529
|
+
RW_CALLOC(ptr, len);
|
|
1530
|
+
cd->dtstr = ptr;
|
|
1531
|
+
cd->dtlen = len;
|
|
1532
|
+
cd->dtparent = 9;
|
|
1533
|
+
if(argc > 0) cstruct_set_args_(argc, argv, klass, obj);
|
|
1534
|
+
return obj;
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
static VALUE
|
|
1538
|
+
cstruct_each(VALUE self){
|
|
1539
|
+
int i;
|
|
1540
|
+
int len = cs_get_count(self);
|
|
1541
|
+
for (i=0; i < len; i++){
|
|
1542
|
+
VALUE v_idx = INT2FIX(i);
|
|
1543
|
+
VALUE x = cstruct_get_idx_value__(1, &v_idx, self);
|
|
1544
|
+
rb_yield(x);
|
|
1545
|
+
}
|
|
1546
|
+
return self;
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
static VALUE
|
|
1550
|
+
cs_to_ary_core(VALUE self, VALUE rflag){
|
|
1551
|
+
int i;
|
|
1552
|
+
VALUE ret;
|
|
1553
|
+
int len = cs_get_count(self);
|
|
1554
|
+
ret = rb_ary_new2(len);
|
|
1555
|
+
for (i=0; i < len; i++){
|
|
1556
|
+
VALUE v_idx = INT2FIX(i);
|
|
1557
|
+
VALUE r = cstruct_get_idx_value__(1, &v_idx, self);
|
|
1558
|
+
if(rflag==Qtrue && rb_typeddata_is_kind_of(r, &cstruct_data_type)){
|
|
1559
|
+
r = cs_to_ary_core(r, rflag);
|
|
1560
|
+
}
|
|
1561
|
+
rb_ary_store(ret, i, r);
|
|
1562
|
+
}
|
|
1563
|
+
return ret;
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
static VALUE
|
|
1567
|
+
cstruct_to_ary(int argc, VALUE* argv, VALUE self){
|
|
1568
|
+
VALUE rflag;
|
|
1569
|
+
rb_scan_args(argc, argv, "01", &rflag);
|
|
1570
|
+
return cs_to_ary_core(self, rflag);
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
/* !!!DANGER!!! Do not use easily. */
|
|
1574
|
+
static VALUE
|
|
1575
|
+
cstruct_slice(VALUE self, VALUE v_offset, VALUE v_len){
|
|
1576
|
+
CStructData *cd;
|
|
1577
|
+
char *ptr;
|
|
1578
|
+
CStructData *cdsrc = DATA_PTR(self);
|
|
1579
|
+
|
|
1580
|
+
VALUE obj = CStruct_Data_Make_Struct(cRwAPIstruct, cd);
|
|
1581
|
+
int offset = FIX2INT(v_offset);
|
|
1582
|
+
int len = FIX2INT(v_len);
|
|
1583
|
+
|
|
1584
|
+
if (offset + len > (int)cdsrc->dtlen)
|
|
1585
|
+
rb_raise(rb_eRuntimeError, "Reached the end of data");
|
|
1586
|
+
ptr = malloc(len);
|
|
1587
|
+
if(!ptr) rb_raise(rb_eRuntimeError,"Failed to allocate memory");
|
|
1588
|
+
memcpy(ptr, cdsrc->dtstr + offset, len);
|
|
1589
|
+
cd->dtoffset = 0;
|
|
1590
|
+
cd -> dtlen = len;
|
|
1591
|
+
cd->dtstr = ptr;
|
|
1592
|
+
cd->dtreferences = 0;
|
|
1593
|
+
cd->dtwrapped = 0;
|
|
1594
|
+
return obj;
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
/* !!!DANGER!!! Do not use easily. */
|
|
1598
|
+
static VALUE
|
|
1599
|
+
cstruct_subst(VALUE self, VALUE roffset, VALUE rlen, VALUE robj){
|
|
1600
|
+
CStructData* pdata;
|
|
1601
|
+
CStructData* psrc;
|
|
1602
|
+
unsigned usrc;
|
|
1603
|
+
int len = 0;
|
|
1604
|
+
int offset = FIX2INT(roffset);
|
|
1605
|
+
int length = FIX2INT(rlen);
|
|
1606
|
+
CStruct_Data_Get_Struct(self, pdata);
|
|
1607
|
+
|
|
1608
|
+
switch (TYPE(robj)){
|
|
1609
|
+
case T_BIGNUM:
|
|
1610
|
+
case T_FIXNUM:
|
|
1611
|
+
if (offset + length > (int)pdata->dtlen)
|
|
1612
|
+
rb_raise(rb_eRuntimeError, "Reached the end of data");
|
|
1613
|
+
usrc = NUM2INT(robj);
|
|
1614
|
+
switch (length){
|
|
1615
|
+
case 1:
|
|
1616
|
+
*(char*)(pdata->dtstr + pdata->dtoffset + offset) = usrc;
|
|
1617
|
+
break;
|
|
1618
|
+
case 2:
|
|
1619
|
+
*(short*)(pdata->dtstr + pdata->dtoffset + offset) = usrc;
|
|
1620
|
+
break;
|
|
1621
|
+
case 4:
|
|
1622
|
+
*(long*)(pdata->dtstr + pdata->dtoffset + offset) = usrc;
|
|
1623
|
+
break;
|
|
1624
|
+
default:
|
|
1625
|
+
rb_raise(rb_eArgError,"Length of numeric data must be 1(byte), 2(short) or 4(long)");
|
|
1626
|
+
}
|
|
1627
|
+
break;
|
|
1628
|
+
case T_STRING:
|
|
1629
|
+
len = RSTRING_LEN(robj);
|
|
1630
|
+
if (offset + length > (int)pdata->dtlen)
|
|
1631
|
+
rb_raise(rb_eRuntimeError, "Reached the end of data");
|
|
1632
|
+
if (length < len) len = length;
|
|
1633
|
+
memcpy(pdata->dtstr + pdata->dtoffset + offset, RSTRING_PTR(robj), len);
|
|
1634
|
+
break;
|
|
1635
|
+
default:
|
|
1636
|
+
if(!rb_typeddata_is_kind_of(robj, &cstruct_data_type))
|
|
1637
|
+
rb_raise(rb_eTypeError, "Illegal type");
|
|
1638
|
+
CStruct_Data_Get_Struct(robj, psrc);
|
|
1639
|
+
len = psrc->dtlen;
|
|
1640
|
+
if (offset + length > (int)pdata->dtlen)
|
|
1641
|
+
rb_raise(rb_eRuntimeError, "Reached the end of data");
|
|
1642
|
+
if (length < len) len = length;
|
|
1643
|
+
memcpy(pdata->dtstr + pdata->dtoffset + offset, psrc->dtstr+psrc->dtoffset, len);
|
|
1644
|
+
break;
|
|
1645
|
+
}
|
|
1646
|
+
return self;
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
static VALUE
|
|
1650
|
+
api_getvalueptr(VALUE klass, VALUE obj){
|
|
1651
|
+
return INT2NUM((int)obj);
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
static VALUE
|
|
1655
|
+
api_getptrvalue(VALUE klass, VALUE num){
|
|
1656
|
+
return (VALUE)NUM2INT(num);
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
static VALUE
|
|
1660
|
+
api_ptr2str(VALUE klass, VALUE v_ptr, VALUE v_len){
|
|
1661
|
+
char* ptr = (char*)NUM2ULONG_PTR(v_ptr);
|
|
1662
|
+
if(!ptr) rb_raise(rb_eArgError, "NULL pointer given.");
|
|
1663
|
+
return rb_str_new(ptr, FIX2INT(v_len));
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1666
|
+
static VALUE
|
|
1667
|
+
api_getlasterrmsg(VALUE klass){
|
|
1668
|
+
TCHAR buff[1024];
|
|
1669
|
+
int err = GetLastError();
|
|
1670
|
+
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, err, 0, buff, sizeof(buff), NULL);
|
|
1671
|
+
return rw_encode_external(buff);
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
static VALUE
|
|
1675
|
+
cstruct1_deftemplate(int argc, VALUE *argv, VALUE klass){
|
|
1676
|
+
VALUE v_template, ar_classes, v_packed;
|
|
1677
|
+
char* template;
|
|
1678
|
+
int i, j, sz, maxsz, maxsz_k, nth, to, offset;
|
|
1679
|
+
CST_GET_FUNCS ifunc;
|
|
1680
|
+
char tp, c;
|
|
1681
|
+
BOOL packed;
|
|
1682
|
+
RWCSAttribute *csattr;
|
|
1683
|
+
VALUE s_offsets = rb_str_new_literal("\0\0\0\0\0\0\0\0");
|
|
1684
|
+
VALUE s_klasses = rb_ary_new();
|
|
1685
|
+
|
|
1686
|
+
rb_scan_args(argc, argv, "12", &v_template, &ar_classes, &v_packed);
|
|
1687
|
+
if (TYPE(v_template)!=T_STRING) rb_raise(rb_eArgError, "1st argument must be a String");
|
|
1688
|
+
switch (TYPE(ar_classes)){
|
|
1689
|
+
case T_NIL:
|
|
1690
|
+
ar_classes = rb_ary_new();
|
|
1691
|
+
case T_ARRAY:
|
|
1692
|
+
break;
|
|
1693
|
+
default:
|
|
1694
|
+
rb_raise(rb_eArgError, "2nd argument must be an Array");
|
|
1695
|
+
}
|
|
1696
|
+
rb_define_const(klass, "Packed", v_packed);
|
|
1697
|
+
packed = v_packed==Qtrue ? TRUE : FALSE;
|
|
1698
|
+
template = RSTRING_PTR(v_template);
|
|
1699
|
+
offset = 0;
|
|
1700
|
+
sz = 0;
|
|
1701
|
+
maxsz = 1;
|
|
1702
|
+
nth = 0;
|
|
1703
|
+
ifunc = 0;
|
|
1704
|
+
i = 0;
|
|
1705
|
+
j = 0;
|
|
1706
|
+
while(tp=template[0]){
|
|
1707
|
+
VALUE kls;
|
|
1708
|
+
RWOffsetData offdata;
|
|
1709
|
+
nth = 0;
|
|
1710
|
+
to = 0;
|
|
1711
|
+
while(isdigit(c=template[++to])){nth = nth*10+(c-'0');}
|
|
1712
|
+
template += to;
|
|
1713
|
+
|
|
1714
|
+
if (!nth) { /* Single v_member */
|
|
1715
|
+
switch(tp){
|
|
1716
|
+
case 'L':
|
|
1717
|
+
ifunc = dt_L;
|
|
1718
|
+
sz = sizeof(ULONG);
|
|
1719
|
+
if (!packed)offset = cst_adjust_align(offset, sz);
|
|
1720
|
+
break;
|
|
1721
|
+
case 'U':
|
|
1722
|
+
ifunc = dt_U;
|
|
1723
|
+
sz = sizeof(ULONG);
|
|
1724
|
+
if (!packed)offset = cst_adjust_align(offset, sz);
|
|
1725
|
+
break;
|
|
1726
|
+
case 'H':
|
|
1727
|
+
ifunc = dt_H;
|
|
1728
|
+
sz = sizeof(SHORT);
|
|
1729
|
+
if (!packed) offset = cst_adjust_align(offset, sz);
|
|
1730
|
+
break;
|
|
1731
|
+
case 'W':
|
|
1732
|
+
ifunc = dt_W;
|
|
1733
|
+
sz = sizeof(SHORT);
|
|
1734
|
+
if (!packed) offset = cst_adjust_align(offset, sz);
|
|
1735
|
+
break;
|
|
1736
|
+
case 'C':
|
|
1737
|
+
ifunc = dt_C;
|
|
1738
|
+
sz = sizeof(char);
|
|
1739
|
+
break;
|
|
1740
|
+
case 'B':
|
|
1741
|
+
ifunc = dt_B;
|
|
1742
|
+
sz = sizeof(char);
|
|
1743
|
+
break;
|
|
1744
|
+
case 'Q':
|
|
1745
|
+
ifunc = dt_Q;
|
|
1746
|
+
sz = sizeof(ULONG_PTR);
|
|
1747
|
+
if (!packed) offset = cst_adjust_align(offset, sz);
|
|
1748
|
+
break;
|
|
1749
|
+
case 'I':
|
|
1750
|
+
ifunc = dt_I;
|
|
1751
|
+
sz = sizeof(ULONG_PTR);
|
|
1752
|
+
if (!packed) offset = cst_adjust_align(offset, sz);
|
|
1753
|
+
break;
|
|
1754
|
+
case 'S':
|
|
1755
|
+
ifunc = dt_S;
|
|
1756
|
+
sz = sizeof(ULONG_PTR);
|
|
1757
|
+
if (!packed) offset = cst_adjust_align(offset, sz);
|
|
1758
|
+
break;
|
|
1759
|
+
case 'l':
|
|
1760
|
+
ifunc = dt_l;
|
|
1761
|
+
sz = sizeof(ULONG_PTR);
|
|
1762
|
+
if (!packed) offset = cst_adjust_align(offset, sz);
|
|
1763
|
+
break;
|
|
1764
|
+
case 'u':
|
|
1765
|
+
ifunc = dt_u;
|
|
1766
|
+
sz = sizeof(ULONG_PTR);
|
|
1767
|
+
if (!packed) offset = cst_adjust_align(offset, sz);
|
|
1768
|
+
break;
|
|
1769
|
+
case 'q':
|
|
1770
|
+
ifunc = dt_q;
|
|
1771
|
+
sz = sizeof(ULONG_PTR);
|
|
1772
|
+
if (!packed) offset = cst_adjust_align(offset, sz);
|
|
1773
|
+
break;
|
|
1774
|
+
case 'i':
|
|
1775
|
+
ifunc = dt_i;
|
|
1776
|
+
sz = sizeof(ULONG_PTR);
|
|
1777
|
+
if (!packed) offset = cst_adjust_align(offset, sz);
|
|
1778
|
+
break;
|
|
1779
|
+
case 's':
|
|
1780
|
+
ifunc = dt_s;
|
|
1781
|
+
sz = sizeof(ULONG_PTR);
|
|
1782
|
+
if (!packed) offset = cst_adjust_align(offset, sz);
|
|
1783
|
+
break;
|
|
1784
|
+
case 'P':
|
|
1785
|
+
kls = rb_ary_shift(ar_classes);
|
|
1786
|
+
ifunc = dt_P;
|
|
1787
|
+
if(NIL_P(kls)) rb_raise(rb_eArgError, "No class given for template `P'");
|
|
1788
|
+
sz = sizeof(ULONG_PTR);
|
|
1789
|
+
if (!packed) offset = cst_adjust_align(offset, sz);
|
|
1790
|
+
rw_set_offdata(&offdata, offset, ifunc, sz, 0, j++);
|
|
1791
|
+
rb_str_cat(s_offsets, (char*)&offdata, sizeof(RWOffsetData));
|
|
1792
|
+
if (maxsz < sz) maxsz = sz;
|
|
1793
|
+
offset += sz;
|
|
1794
|
+
rb_ary_push(s_klasses, kls);
|
|
1795
|
+
i++;
|
|
1796
|
+
continue;
|
|
1797
|
+
case 'K': /* modify maxsz */
|
|
1798
|
+
kls = rb_ary_shift(ar_classes);
|
|
1799
|
+
ifunc = dt_K;
|
|
1800
|
+
if (NIL_P(kls)) rb_raise(rb_eArgError, "No class given for template `K'");
|
|
1801
|
+
maxsz_k = cs_get_offset_attribute(kls)->maxmblen;
|
|
1802
|
+
sz = FIX2INT(rb_const_get(kls, _id_cstruct_size));
|
|
1803
|
+
if (!packed) offset = cst_adjust_align(offset, maxsz_k);
|
|
1804
|
+
rw_set_offdata(&offdata, offset, ifunc, sz, 0, j++);
|
|
1805
|
+
rb_str_cat(s_offsets, (char*)&offdata, sizeof(RWOffsetData));
|
|
1806
|
+
offset += sz;
|
|
1807
|
+
rb_ary_push(s_klasses, kls);
|
|
1808
|
+
if (maxsz < maxsz_k) maxsz = maxsz_k;
|
|
1809
|
+
i++;
|
|
1810
|
+
continue;
|
|
1811
|
+
case 'X':
|
|
1812
|
+
offset += 1; /* for padding */
|
|
1813
|
+
continue;
|
|
1814
|
+
default:
|
|
1815
|
+
rb_raise(rb_eArgError, "Unknown template: `%c' for v_member", tp);
|
|
1816
|
+
}
|
|
1817
|
+
rw_set_offdata(&offdata, offset, ifunc, sz, 0, 0);
|
|
1818
|
+
rb_str_cat(s_offsets, (char*)&offdata, sizeof(RWOffsetData));
|
|
1819
|
+
if (maxsz < sz) maxsz = sz;
|
|
1820
|
+
offset += sz;
|
|
1821
|
+
} else { /* Array */
|
|
1822
|
+
switch(tp){
|
|
1823
|
+
case 'L':
|
|
1824
|
+
ifunc = dt_L;
|
|
1825
|
+
sz = sizeof(ULONG);
|
|
1826
|
+
if(!packed) offset = cst_adjust_align(offset, sz);
|
|
1827
|
+
break;
|
|
1828
|
+
case 'U':
|
|
1829
|
+
ifunc = dt_U;
|
|
1830
|
+
sz = sizeof(ULONG);
|
|
1831
|
+
if(!packed) offset = cst_adjust_align(offset, sz);
|
|
1832
|
+
break;
|
|
1833
|
+
case 'H':
|
|
1834
|
+
ifunc = dt_H;
|
|
1835
|
+
sz = sizeof(SHORT);
|
|
1836
|
+
if(!packed) offset = cst_adjust_align(offset, sz);
|
|
1837
|
+
break;
|
|
1838
|
+
case 'W':
|
|
1839
|
+
ifunc = dt_W;
|
|
1840
|
+
sz = sizeof(SHORT);
|
|
1841
|
+
if(!packed) offset = cst_adjust_align(offset, sz);
|
|
1842
|
+
break;
|
|
1843
|
+
case 'C':
|
|
1844
|
+
ifunc = dt_C;
|
|
1845
|
+
sz = sizeof(char);
|
|
1846
|
+
break;
|
|
1847
|
+
case 'B':
|
|
1848
|
+
ifunc = dt_B;
|
|
1849
|
+
sz = sizeof(char);
|
|
1850
|
+
break;
|
|
1851
|
+
case 'K': /* modify maxsz */
|
|
1852
|
+
kls = rb_ary_shift(ar_classes);
|
|
1853
|
+
if(NIL_P(kls)) rb_raise(rb_eArgError, "No class given for template `K'");
|
|
1854
|
+
ifunc = dt_K;
|
|
1855
|
+
maxsz_k = cs_get_offset_attribute(kls)->maxmblen;
|
|
1856
|
+
if (!packed) offset = cst_adjust_align(offset, maxsz_k);
|
|
1857
|
+
sz = FIX2INT(rb_const_get(kls, _id_cstruct_size));
|
|
1858
|
+
rw_set_offdata(&offdata, offset, ifunc, sz, nth, j++);
|
|
1859
|
+
rb_str_cat(s_offsets, (char*)&offdata, sizeof(RWOffsetData));
|
|
1860
|
+
offset += sz*nth;
|
|
1861
|
+
rb_ary_push(s_klasses, kls);
|
|
1862
|
+
if (maxsz < maxsz_k) maxsz = maxsz_k;
|
|
1863
|
+
i++;
|
|
1864
|
+
continue;
|
|
1865
|
+
case 'X':
|
|
1866
|
+
offset += 1*nth; /* for padding */
|
|
1867
|
+
continue;
|
|
1868
|
+
default:
|
|
1869
|
+
rb_raise(rb_eArgError, "Unknown template: `%c%d' for array v_member.", tp, nth);
|
|
1870
|
+
}
|
|
1871
|
+
rw_set_offdata(&offdata, offset, ifunc, sz, nth, 0);
|
|
1872
|
+
rb_str_cat(s_offsets, (char*)&offdata, sizeof(RWOffsetData));
|
|
1873
|
+
if (maxsz < sz) maxsz = sz;
|
|
1874
|
+
offset += sz*nth;
|
|
1875
|
+
}
|
|
1876
|
+
i++;
|
|
1877
|
+
}
|
|
1878
|
+
if (i==1){
|
|
1879
|
+
rb_define_method(klass, "value", cstruct_getvalue, 0);
|
|
1880
|
+
rb_define_method(klass, "value=", cstruct_setvalue, 1);
|
|
1881
|
+
}
|
|
1882
|
+
csattr = (RWCSAttribute*)RSTRING_PTR(s_offsets);
|
|
1883
|
+
csattr->realsize = (WORD)offset;
|
|
1884
|
+
if(!packed && !nth && maxsz>1) offset = cst_adjust_align(offset, maxsz);
|
|
1885
|
+
rb_define_const(klass, "Size", INT2FIX(offset));
|
|
1886
|
+
csattr->size = (WORD)offset;
|
|
1887
|
+
rb_define_const(klass, "Template", v_template);
|
|
1888
|
+
rb_obj_freeze(v_template);
|
|
1889
|
+
rb_define_const(klass, "SOffsets", s_offsets);
|
|
1890
|
+
rb_obj_freeze(s_offsets);
|
|
1891
|
+
rb_define_const(klass, "SClasses", s_klasses);
|
|
1892
|
+
csattr->cmembers = i;
|
|
1893
|
+
csattr->maxmblen = maxsz;
|
|
1894
|
+
csattr->packed = packed;
|
|
1895
|
+
return klass;
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1898
|
+
VALUE ccsCHAR, ccsWCHAR, ccsTCHAR, ccsBYTE, ccsWORD, ccsDWORD, ccsPOINT, ccsSIZE, ccsRECT;
|
|
1899
|
+
VALUE ccsLOGBRUSH, ccsLOGFONT, ccsLOGPEN, ccsIMAGEINFO, ccsBITMAPINFO, ccsMENUITEMINFO;
|
|
1900
|
+
VALUE ccsDEVMODE;
|
|
1901
|
+
|
|
1902
|
+
VALUE
|
|
1903
|
+
cs_deftemplate_intern(VALUE *klass, const char* cname, const char *template){
|
|
1904
|
+
VALUE v_template;
|
|
1905
|
+
VALUE v_args[1];
|
|
1906
|
+
*klass = rb_define_class_under(mRwAPI, cname, cRwAPIstruct);
|
|
1907
|
+
v_template = rb_str_new2(template);
|
|
1908
|
+
v_args[0] = v_template;
|
|
1909
|
+
return cstruct1_deftemplate(1, v_args, *klass);
|
|
1910
|
+
}
|
|
1911
|
+
|
|
1912
|
+
void
|
|
1913
|
+
create_pre_defined_class(){
|
|
1914
|
+
cs_deftemplate_intern(&ccsCHAR, "CHAR", "C1");
|
|
1915
|
+
cs_deftemplate_intern(&ccsWCHAR, "WCHAR", "W1");
|
|
1916
|
+
cs_deftemplate_intern(&ccsBYTE, "BYTE", "B1");
|
|
1917
|
+
cs_deftemplate_intern(&ccsWORD, "WORD", "H1");
|
|
1918
|
+
cs_deftemplate_intern(&ccsDWORD, "DWORD", "L1");
|
|
1919
|
+
cs_deftemplate_intern(&ccsPOINT, "POINT", "LL");
|
|
1920
|
+
cs_deftemplate_intern(&ccsSIZE, "SIZE", "LL");
|
|
1921
|
+
cs_deftemplate_intern(&ccsRECT, "RECT", "LLLL");
|
|
1922
|
+
cs_deftemplate_intern(&ccsLOGBRUSH, "LOGBRUSH", "UUU");
|
|
1923
|
+
cs_deftemplate_intern(&ccsLOGPEN, "LOGPEN", "ULX4U");
|
|
1924
|
+
cs_deftemplate_intern(&ccsBITMAPINFO, "BITMAPINFO", "LLLHHLLLLLLL1");
|
|
1925
|
+
cs_deftemplate_intern(&ccsIMAGEINFO, "IMAGEINFO", "LLX8LLLL");
|
|
1926
|
+
cs_deftemplate_intern(&ccsMENUITEMINFO, "MENUITEMINFO", "UUUUUQQQQSUQ");
|
|
1927
|
+
#ifdef UNICODE
|
|
1928
|
+
cs_deftemplate_intern(&ccsTCHAR, "TCHAR", "W1");
|
|
1929
|
+
cs_deftemplate_intern(&ccsLOGFONT, "LOGFONT", "LLLLLBBBBBBBBW32");
|
|
1930
|
+
cs_deftemplate_intern(&ccsDEVMODE, "DEVMODE", "W32HHHHUHHHHHHHHHHHHHW32HUUUUUUUUUUUUU");
|
|
1931
|
+
#else
|
|
1932
|
+
cs_deftemplate_intern(&ccsTCHAR, "TCHAR", "C1");
|
|
1933
|
+
cs_deftemplate_intern(&ccsLOGFONT, "LOGFONT", "LLLLLBBBBBBBBC32");
|
|
1934
|
+
cs_deftemplate_intern(&ccsDEVMODE, "DEVMODE", "C32HHHHUHHHHHHHHHHHHHW32HUUUUUUUUUUUUU");
|
|
1935
|
+
#endif
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
/* // offset test
|
|
1939
|
+
//#include <comdlg32.h>
|
|
1940
|
+
static VALUE
|
|
1941
|
+
cstruct1_offset_test(){
|
|
1942
|
+
// return UINT2NUM(offsetof(CHARFORMAT2, sSpacing));
|
|
1943
|
+
return rb_ary_new3(2, UINT2NUM(offsetof(PRINTDLG, hInstance)), UINT2NUM(sizeof(PRINTDLG)));
|
|
1944
|
+
}
|
|
1945
|
+
*/
|
|
1946
|
+
|
|
1947
|
+
/* ###################### End of RWin::API::CStruct ####################### */
|
|
1948
|
+
|
|
1949
|
+
/* initialization */
|
|
1950
|
+
static void
|
|
1951
|
+
rw_init_CStruct(){ /* CStruct */
|
|
1952
|
+
cRwAPIstruct = rb_define_class_under(mRwAPI, "CStruct", rb_cData);
|
|
1953
|
+
cRwAPIstructArrayPart = rb_define_class_under(cRwAPIstruct, "ArrayPart", cRwAPIstruct);
|
|
1954
|
+
|
|
1955
|
+
rb_define_alloc_func(cRwAPIstruct, cstruct_alloc);
|
|
1956
|
+
|
|
1957
|
+
rb_define_singleton_method(cRwAPIstruct, "alloc", cstruct1_alloc, 1);
|
|
1958
|
+
rb_define_singleton_method(cRwAPIstruct, "alloc_int", cstruct1_alloc_int, 1);
|
|
1959
|
+
rb_define_singleton_method(cRwAPIstruct, "alloc_uint", cstruct1_alloc_int, 1);
|
|
1960
|
+
rb_define_singleton_method(cRwAPIstruct, "alloc_int_ptr", cstruct1_alloc_int_ptr, 1);
|
|
1961
|
+
rb_define_singleton_method(cRwAPIstruct, "alloc_uint_ptr", cstruct1_alloc_int_ptr, 1);
|
|
1962
|
+
rb_define_singleton_method(cRwAPIstruct, "[]", cstruct1_new2, -1);
|
|
1963
|
+
rb_define_singleton_method(cRwAPIstruct, "__new_and_set_args__", cstruct1_new2, -1);
|
|
1964
|
+
rb_define_singleton_method(cRwAPIstruct, "cast", cstruct1_cast, 3);
|
|
1965
|
+
rb_define_singleton_method(cRwAPIstruct, "new_from_string", cstruct1_newstr, -1);
|
|
1966
|
+
rb_define_singleton_method(cRwAPIstruct, "new_from_pointer", cstruct1_newptr, -1);
|
|
1967
|
+
rb_define_singleton_method(cRwAPIstruct, "wrap_pointer", cstruct1_wrapptr, 1);
|
|
1968
|
+
rb_define_singleton_method(cRwAPIstruct, "wrap_string", cstruct1_wrapstr, 1);
|
|
1969
|
+
rb_define_singleton_method(cRwAPIstruct, "deftemplate", cstruct1_deftemplate, -1);
|
|
1970
|
+
|
|
1971
|
+
rb_define_method(cRwAPIstruct, "initialize", cstruct_initialize_default, -1);
|
|
1972
|
+
rb_define_method(cRwAPIstruct, "to_bstr", cstruct_to_bstr, 0);
|
|
1973
|
+
rb_define_method(cRwAPIstruct, "to_b", cstruct_to_bstr, 0);
|
|
1974
|
+
rb_define_method(cRwAPIstruct, "to_str", cstruct_to_str, 0);
|
|
1975
|
+
rb_define_method(cRwAPIstruct, "to_s", cstruct_to_str, 0);
|
|
1976
|
+
rb_define_method(cRwAPIstruct, "to_int", cstruct_to_int, 0);
|
|
1977
|
+
rb_define_method(cRwAPIstruct, "to_i", cstruct_to_int, 0);
|
|
1978
|
+
rb_define_method(cRwAPIstruct, "to_uint", cstruct_to_uint, 0);
|
|
1979
|
+
rb_define_method(cRwAPIstruct, "to_u", cstruct_to_uint, 0);
|
|
1980
|
+
rb_define_method(cRwAPIstruct, "each", cstruct_each, 0);
|
|
1981
|
+
rb_define_method(cRwAPIstruct, "to_ary", cstruct_to_ary, -1);
|
|
1982
|
+
rb_define_method(cRwAPIstruct, "to_a", cstruct_to_ary, -1);
|
|
1983
|
+
|
|
1984
|
+
rb_define_method(cRwAPIstruct, "size", cstruct_size, 0);
|
|
1985
|
+
rb_define_method(cRwAPIstruct, "bytesize", cstruct_size, 0);
|
|
1986
|
+
rb_define_method(cRwAPIstruct, "count", cstruct_count, 0);
|
|
1987
|
+
rb_define_method(cRwAPIstruct, "pointer", cstruct_pointer, 0);
|
|
1988
|
+
rb_define_method(cRwAPIstruct, "slice", cstruct_slice, 2);
|
|
1989
|
+
rb_define_method(cRwAPIstruct, "subst", cstruct_subst, 3);
|
|
1990
|
+
rb_define_method(cRwAPIstruct, "clear", cstruct_clear, -1);
|
|
1991
|
+
rb_define_method(cRwAPIstruct, "[]", cstruct_get_idx_value__, -1);
|
|
1992
|
+
rb_define_method(cRwAPIstruct, "[]=", cstruct_set_idx_value__, -1);
|
|
1993
|
+
|
|
1994
|
+
/* internal name definition */
|
|
1995
|
+
_id_cstruct_size = rb_intern("Size");
|
|
1996
|
+
_id_cstruct_template = rb_intern("Template");
|
|
1997
|
+
_id_cstruct_s_classes = rb_intern("SClasses");
|
|
1998
|
+
_id_cstruct_s_offsets = rb_intern("SOffsets");
|
|
1999
|
+
|
|
2000
|
+
/* create pre-defined CStruct class */
|
|
2001
|
+
create_pre_defined_class();
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
|
|
2005
|
+
static VALUE
|
|
2006
|
+
api_test_func(int argc, VALUE* argv, VALUE klass){
|
|
2007
|
+
// fprintf(stderr, "NMHDR=%d, LOGFONT=%d, NONCLIENTMETRICS=%d\n", (int)sizeof(NMHDR), (int)sizeof(LOGFONT), (int)sizeof(NONCLIENTMETRICS));
|
|
2008
|
+
return INT2FIX(sizeof(NMTREEVIEW));
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
static void
|
|
2012
|
+
rw_init_CFunc(){ /* CFunc */
|
|
2013
|
+
ApiFuncLibs *libs;
|
|
2014
|
+
apifunc_class_libs = Data_Make_Struct(rb_cObject, ApiFuncLibs, 0, destruct_libs, libs);
|
|
2015
|
+
rb_global_variable(&apifunc_class_libs);
|
|
2016
|
+
apifunc_libs = newAAtree(NULL); /* destructor is not needed, by same reason as rwin. */
|
|
2017
|
+
libs->libs = apifunc_libs;
|
|
2018
|
+
|
|
2019
|
+
current_hModule = NULL;
|
|
2020
|
+
|
|
2021
|
+
cRwAPIfunc = rb_define_class_under(mRwAPI, "CFunc", rb_cData);
|
|
2022
|
+
rb_define_alloc_func(cRwAPIfunc, cfunc_alloc);
|
|
2023
|
+
|
|
2024
|
+
rb_define_singleton_method(cRwAPIfunc,"loadLibrary", api_cfunc1_loadlib, 1);
|
|
2025
|
+
rb_define_singleton_method(cRwAPIfunc,"getfunc", api_cfunc1_getfunc, 2);
|
|
2026
|
+
|
|
2027
|
+
rb_define_method(cRwAPIfunc, "initialize", api_initialize, 2);
|
|
2028
|
+
rb_define_method(cRwAPIfunc, "call", api_call, -1);
|
|
2029
|
+
rb_define_method(cRwAPIfunc, "call_ubf", api_call_ubf, -1);
|
|
2030
|
+
|
|
2031
|
+
/* additional definition of API-like module functions */
|
|
2032
|
+
rb_define_module_function(mRwAPI, "SendMessage", api_sendmessage, 4);
|
|
2033
|
+
rb_define_module_function(mRwAPI, "PostMessage", api_postmessage, 4);
|
|
2034
|
+
rb_define_module_function(mRwAPI, "GlobalAllocStr", api_g_alloc_str, 2);
|
|
2035
|
+
rb_define_module_function(mRwAPI, "GlobalGetStr", api_g_get_str, 1);
|
|
2036
|
+
rb_define_module_function(mRwAPI, "Obj2Ptr", api_getvalueptr, 1);
|
|
2037
|
+
rb_define_module_function(mRwAPI, "Ptr2Obj", api_getptrvalue, 1); /* DANGER function */
|
|
2038
|
+
rb_define_module_function(mRwAPI, "GetLastErrorMsg", api_getlasterrmsg, 0); /* not API */
|
|
2039
|
+
rb_define_module_function(mRwAPI, "Ptr2Str", api_ptr2str, 2); /* Not API; DANGER */
|
|
2040
|
+
/* for testing */
|
|
2041
|
+
rb_define_module_function(mRwAPI, "__test__", api_test_func, -1);
|
|
2042
|
+
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
static void
|
|
2046
|
+
rw_init_Callback(){ /* Callback */
|
|
2047
|
+
api_init_CallbackProcs();
|
|
2048
|
+
rb_define_singleton_method(mRwAPI,"bindCallbackProc", api_bind_callback_proc, 1);
|
|
2049
|
+
rb_define_singleton_method(mRwAPI,"releaseCallbackProc", api_release_callback_proc, 1);
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
void
|
|
2053
|
+
Init_rw_api(){
|
|
2054
|
+
mRwAPI = rb_define_module_under(mRwin, "API");
|
|
2055
|
+
rw_init_CStruct();
|
|
2056
|
+
rw_init_CFunc();
|
|
2057
|
+
rw_init_Callback(); /* Callback procs must be defined at last */
|
|
2058
|
+
}
|