wrb 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (271) hide show
  1. checksums.yaml +7 -0
  2. data/README +28 -0
  3. data/Rakefile +66 -0
  4. data/bin/wrb +41 -0
  5. data/bin/wrb.bat +6 -0
  6. data/ext/rwin/aatree.c +192 -0
  7. data/ext/rwin/aatree.h +55 -0
  8. data/ext/rwin/extconf.rb +47 -0
  9. data/ext/rwin/rw_api.c +2058 -0
  10. data/ext/rwin/rw_devices.c +215 -0
  11. data/ext/rwin/rw_gdiplus.h +278 -0
  12. data/ext/rwin/rw_graphics.c +1583 -0
  13. data/ext/rwin/rw_resources.c +1988 -0
  14. data/ext/rwin/rw_ubfuncs.c +281 -0
  15. data/ext/rwin/rw_windows.c +1936 -0
  16. data/ext/rwin/rwin.c +451 -0
  17. data/ext/rwin/rwin.h +442 -0
  18. data/lib/rwin.rb +820 -0
  19. data/lib/wrb.rb +20 -0
  20. data/lib/wrb/applications/frmdesigner/angle.cur +0 -0
  21. data/lib/wrb/applications/frmdesigner/angle2.cur +0 -0
  22. data/lib/wrb/applications/frmdesigner/controls/Button.bmp +0 -0
  23. data/lib/wrb/applications/frmdesigner/controls/Button.rb +34 -0
  24. data/lib/wrb/applications/frmdesigner/controls/Checkbox.bmp +0 -0
  25. data/lib/wrb/applications/frmdesigner/controls/Checkbox.rb +10 -0
  26. data/lib/wrb/applications/frmdesigner/controls/Combobox.bmp +0 -0
  27. data/lib/wrb/applications/frmdesigner/controls/Combobox.rb +88 -0
  28. data/lib/wrb/applications/frmdesigner/controls/ComboboxEx.rb +97 -0
  29. data/lib/wrb/applications/frmdesigner/controls/Comboboxex.bmp +0 -0
  30. data/lib/wrb/applications/frmdesigner/controls/DateTimePicker.bmp +0 -0
  31. data/lib/wrb/applications/frmdesigner/controls/DateTimePicker.rb +11 -0
  32. data/lib/wrb/applications/frmdesigner/controls/Edit.bmp +0 -0
  33. data/lib/wrb/applications/frmdesigner/controls/Edit.rb +8 -0
  34. data/lib/wrb/applications/frmdesigner/controls/Groupbox.bmp +0 -0
  35. data/lib/wrb/applications/frmdesigner/controls/Groupbox.rb +9 -0
  36. data/lib/wrb/applications/frmdesigner/controls/Hotkeyctrl.bmp +0 -0
  37. data/lib/wrb/applications/frmdesigner/controls/Hotkeyctrl.rb +9 -0
  38. data/lib/wrb/applications/frmdesigner/controls/Imagelist.bmp +0 -0
  39. data/lib/wrb/applications/frmdesigner/controls/Imagelist.rb +115 -0
  40. data/lib/wrb/applications/frmdesigner/controls/Listbox.bmp +0 -0
  41. data/lib/wrb/applications/frmdesigner/controls/Listbox.rb +77 -0
  42. data/lib/wrb/applications/frmdesigner/controls/Listview.bmp +0 -0
  43. data/lib/wrb/applications/frmdesigner/controls/Listview.rb +157 -0
  44. data/lib/wrb/applications/frmdesigner/controls/Menu.bmp +0 -0
  45. data/lib/wrb/applications/frmdesigner/controls/Menu.rb +198 -0
  46. data/lib/wrb/applications/frmdesigner/controls/Menubar.bmp +0 -0
  47. data/lib/wrb/applications/frmdesigner/controls/Menubar.rb +9 -0
  48. data/lib/wrb/applications/frmdesigner/controls/MonthCalender.bmp +0 -0
  49. data/lib/wrb/applications/frmdesigner/controls/Monthcalender.rb +9 -0
  50. data/lib/wrb/applications/frmdesigner/controls/Panel.bmp +0 -0
  51. data/lib/wrb/applications/frmdesigner/controls/Panel.rb +30 -0
  52. data/lib/wrb/applications/frmdesigner/controls/Progressbar.rb +10 -0
  53. data/lib/wrb/applications/frmdesigner/controls/Radiobutton.bmp +0 -0
  54. data/lib/wrb/applications/frmdesigner/controls/Radiobutton.rb +13 -0
  55. data/lib/wrb/applications/frmdesigner/controls/Rebar.bmp +0 -0
  56. data/lib/wrb/applications/frmdesigner/controls/Rebar.rb +162 -0
  57. data/lib/wrb/applications/frmdesigner/controls/Splitter.bmp +0 -0
  58. data/lib/wrb/applications/frmdesigner/controls/Splitter.rb +66 -0
  59. data/lib/wrb/applications/frmdesigner/controls/Static.bmp +0 -0
  60. data/lib/wrb/applications/frmdesigner/controls/Static.rb +9 -0
  61. data/lib/wrb/applications/frmdesigner/controls/Statusbar.bmp +0 -0
  62. data/lib/wrb/applications/frmdesigner/controls/Statusbar.rb +103 -0
  63. data/lib/wrb/applications/frmdesigner/controls/Tabctrl.bmp +0 -0
  64. data/lib/wrb/applications/frmdesigner/controls/Tabctrl.rb +136 -0
  65. data/lib/wrb/applications/frmdesigner/controls/Timer.bmp +0 -0
  66. data/lib/wrb/applications/frmdesigner/controls/Timer.rb +36 -0
  67. data/lib/wrb/applications/frmdesigner/controls/Toolbar.bmp +0 -0
  68. data/lib/wrb/applications/frmdesigner/controls/Toolbar.rb +165 -0
  69. data/lib/wrb/applications/frmdesigner/controls/Trackbar.bmp +0 -0
  70. data/lib/wrb/applications/frmdesigner/controls/Trackbar.rb +34 -0
  71. data/lib/wrb/applications/frmdesigner/controls/Treeview.bmp +0 -0
  72. data/lib/wrb/applications/frmdesigner/controls/Treeview.rb +107 -0
  73. data/lib/wrb/applications/frmdesigner/controls/Updown.bmp +0 -0
  74. data/lib/wrb/applications/frmdesigner/controls/Updown.rb +31 -0
  75. data/lib/wrb/applications/frmdesigner/controls/default.bmp +0 -0
  76. data/lib/wrb/applications/frmdesigner/controls/progressbar.bmp +0 -0
  77. data/lib/wrb/applications/frmdesigner/controls/unselect.bmp +0 -0
  78. data/lib/wrb/applications/frmdesigner/fddialogs.rb +87 -0
  79. data/lib/wrb/applications/frmdesigner/fdesign.rb +1315 -0
  80. data/lib/wrb/applications/frmdesigner/fdmodules.rb +1394 -0
  81. data/lib/wrb/applications/frmdesigner/fdparseform.rb +197 -0
  82. data/lib/wrb/applications/frmdesigner/img13.bmp +0 -0
  83. data/lib/wrb/base.rb +1294 -0
  84. data/lib/wrb/combocommon.rb +77 -0
  85. data/lib/wrb/commctrlconst.rb +139 -0
  86. data/lib/wrb/commdlg.rb +77 -0
  87. data/lib/wrb/components/animate.rb +114 -0
  88. data/lib/wrb/components/bitmap.rb +116 -0
  89. data/lib/wrb/components/button.rb +134 -0
  90. data/lib/wrb/components/canvas.rb +266 -0
  91. data/lib/wrb/components/checkbox.rb +118 -0
  92. data/lib/wrb/components/choosecolordlg.rb +87 -0
  93. data/lib/wrb/components/choosefontdlg.rb +142 -0
  94. data/lib/wrb/components/clipboard.rb +174 -0
  95. data/lib/wrb/components/combobox.rb +282 -0
  96. data/lib/wrb/components/comboboxex.rb +574 -0
  97. data/lib/wrb/components/cursor.rb +91 -0
  98. data/lib/wrb/components/datetimepicker.rb +197 -0
  99. data/lib/wrb/components/ddeclient.rb +180 -0
  100. data/lib/wrb/components/ddeserver.rb +131 -0
  101. data/lib/wrb/components/dialog.rb +228 -0
  102. data/lib/wrb/components/edit.rb +412 -0
  103. data/lib/wrb/components/font.rb +35 -0
  104. data/lib/wrb/components/form.rb +65 -0
  105. data/lib/wrb/components/groupbox.rb +122 -0
  106. data/lib/wrb/components/header.rb +479 -0
  107. data/lib/wrb/components/hotkeyctrl.rb +72 -0
  108. data/lib/wrb/components/icon.rb +109 -0
  109. data/lib/wrb/components/imagelist.rb +396 -0
  110. data/lib/wrb/components/inifile.rb +97 -0
  111. data/lib/wrb/components/listbox.rb +149 -0
  112. data/lib/wrb/components/listview.rb +1467 -0
  113. data/lib/wrb/components/menu.rb +592 -0
  114. data/lib/wrb/components/menubar.rb +84 -0
  115. data/lib/wrb/components/monthcalender.rb +164 -0
  116. data/lib/wrb/components/openfilenamedlg.rb +147 -0
  117. data/lib/wrb/components/pager.rb +199 -0
  118. data/lib/wrb/components/panel.rb +103 -0
  119. data/lib/wrb/components/picture.rb +55 -0
  120. data/lib/wrb/components/printdlg.rb +148 -0
  121. data/lib/wrb/components/printdlgex.rb +117 -0
  122. data/lib/wrb/components/printer.rb +97 -0
  123. data/lib/wrb/components/progressbar.rb +140 -0
  124. data/lib/wrb/components/radiobutton.rb +49 -0
  125. data/lib/wrb/components/rebar.rb +830 -0
  126. data/lib/wrb/components/registry.rb +408 -0
  127. data/lib/wrb/components/richedit.rb +1181 -0
  128. data/lib/wrb/components/savefilenamedlg.rb +27 -0
  129. data/lib/wrb/components/scintilla.rb +1298 -0
  130. data/lib/wrb/components/scrollbar.rb +239 -0
  131. data/lib/wrb/components/splitter.rb +494 -0
  132. data/lib/wrb/components/static.rb +198 -0
  133. data/lib/wrb/components/statusbar.rb +490 -0
  134. data/lib/wrb/components/tabctrl.rb +686 -0
  135. data/lib/wrb/components/timer.rb +117 -0
  136. data/lib/wrb/components/toolbar.rb +1107 -0
  137. data/lib/wrb/components/tooltip.rb +651 -0
  138. data/lib/wrb/components/trackbar.rb +298 -0
  139. data/lib/wrb/components/treeview.rb +845 -0
  140. data/lib/wrb/components/updown.rb +198 -0
  141. data/lib/wrb/ddeml.rb +241 -0
  142. data/lib/wrb/documents/animate.html +46 -0
  143. data/lib/wrb/documents/bitmap.html +69 -0
  144. data/lib/wrb/documents/button.html +78 -0
  145. data/lib/wrb/documents/canvas.html +137 -0
  146. data/lib/wrb/documents/checkbox.html +77 -0
  147. data/lib/wrb/documents/choosecolordlg.html +29 -0
  148. data/lib/wrb/documents/choosefontdlg.html +31 -0
  149. data/lib/wrb/documents/clipboard.html +31 -0
  150. data/lib/wrb/documents/combobox.html +117 -0
  151. data/lib/wrb/documents/comboboxex.html +139 -0
  152. data/lib/wrb/documents/control.html +53 -0
  153. data/lib/wrb/documents/cursor.html +45 -0
  154. data/lib/wrb/documents/datetimepicker.html +70 -0
  155. data/lib/wrb/documents/ddeclient.html +33 -0
  156. data/lib/wrb/documents/ddeserver.html +26 -0
  157. data/lib/wrb/documents/dialog.html +78 -0
  158. data/lib/wrb/documents/edit.html +169 -0
  159. data/lib/wrb/documents/empty.html +11 -0
  160. data/lib/wrb/documents/favicon.png +0 -0
  161. data/lib/wrb/documents/font.html +38 -0
  162. data/lib/wrb/documents/form.html +63 -0
  163. data/lib/wrb/documents/groupbox.html +57 -0
  164. data/lib/wrb/documents/header.html +85 -0
  165. data/lib/wrb/documents/hotkeyctrl.html +42 -0
  166. data/lib/wrb/documents/icon.html +45 -0
  167. data/lib/wrb/documents/imagelist.html +101 -0
  168. data/lib/wrb/documents/images/button.png +0 -0
  169. data/lib/wrb/documents/images/checkbox.png +0 -0
  170. data/lib/wrb/documents/images/combobox.png +0 -0
  171. data/lib/wrb/documents/images/comboboxex.png +0 -0
  172. data/lib/wrb/documents/images/datetimepicker.png +0 -0
  173. data/lib/wrb/documents/images/edit.png +0 -0
  174. data/lib/wrb/documents/images/groupbox.png +0 -0
  175. data/lib/wrb/documents/images/hotkeyctrl.png +0 -0
  176. data/lib/wrb/documents/images/listbox.png +0 -0
  177. data/lib/wrb/documents/images/listview.png +0 -0
  178. data/lib/wrb/documents/images/menu.png +0 -0
  179. data/lib/wrb/documents/images/menubar.png +0 -0
  180. data/lib/wrb/documents/images/monthcalender.png +0 -0
  181. data/lib/wrb/documents/images/progressbar.png +0 -0
  182. data/lib/wrb/documents/images/radiobutton.png +0 -0
  183. data/lib/wrb/documents/images/rebar.png +0 -0
  184. data/lib/wrb/documents/images/richedit.png +0 -0
  185. data/lib/wrb/documents/images/splitter.png +0 -0
  186. data/lib/wrb/documents/images/static.png +0 -0
  187. data/lib/wrb/documents/images/statusbar.png +0 -0
  188. data/lib/wrb/documents/images/tabctrl.png +0 -0
  189. data/lib/wrb/documents/images/toolbar.png +0 -0
  190. data/lib/wrb/documents/images/tooltip.png +0 -0
  191. data/lib/wrb/documents/images/trackbar.png +0 -0
  192. data/lib/wrb/documents/images/treeview.png +0 -0
  193. data/lib/wrb/documents/images/updown.png +0 -0
  194. data/lib/wrb/documents/index.html +155 -0
  195. data/lib/wrb/documents/inifile.html +36 -0
  196. data/lib/wrb/documents/license.txt +22 -0
  197. data/lib/wrb/documents/listbox.html +96 -0
  198. data/lib/wrb/documents/listview.html +277 -0
  199. data/lib/wrb/documents/make_doc.rb +596 -0
  200. data/lib/wrb/documents/menu.html +144 -0
  201. data/lib/wrb/documents/menubar.html +54 -0
  202. data/lib/wrb/documents/monthcalender.html +48 -0
  203. data/lib/wrb/documents/openfilenamedlg.html +36 -0
  204. data/lib/wrb/documents/pager.html +63 -0
  205. data/lib/wrb/documents/panel.html +32 -0
  206. data/lib/wrb/documents/picture.html +48 -0
  207. data/lib/wrb/documents/printdlg.html +35 -0
  208. data/lib/wrb/documents/printdlgex.html +35 -0
  209. data/lib/wrb/documents/printer.html +40 -0
  210. data/lib/wrb/documents/progressbar.html +69 -0
  211. data/lib/wrb/documents/radiobutton.html +51 -0
  212. data/lib/wrb/documents/rebar.html +143 -0
  213. data/lib/wrb/documents/registry.html +36 -0
  214. data/lib/wrb/documents/richedit.html +232 -0
  215. data/lib/wrb/documents/samples/editimg.bmp +0 -0
  216. data/lib/wrb/documents/samples/editimg.iml +0 -0
  217. data/lib/wrb/documents/samples/fileimg.bmp +0 -0
  218. data/lib/wrb/documents/samples/fileimg.iml +0 -0
  219. data/lib/wrb/documents/samples/sample_button.rb +21 -0
  220. data/lib/wrb/documents/samples/sample_checkbox.rb +18 -0
  221. data/lib/wrb/documents/samples/sample_combobox.rb +18 -0
  222. data/lib/wrb/documents/samples/sample_comboboxex.rb +23 -0
  223. data/lib/wrb/documents/samples/sample_datetimepicker.rb +11 -0
  224. data/lib/wrb/documents/samples/sample_edit.rb +25 -0
  225. data/lib/wrb/documents/samples/sample_groupbox.rb +19 -0
  226. data/lib/wrb/documents/samples/sample_hotkeyctrl.rb +12 -0
  227. data/lib/wrb/documents/samples/sample_listbox.rb +12 -0
  228. data/lib/wrb/documents/samples/sample_listview.rb +32 -0
  229. data/lib/wrb/documents/samples/sample_menu.rb +21 -0
  230. data/lib/wrb/documents/samples/sample_menubar.rb +23 -0
  231. data/lib/wrb/documents/samples/sample_monthcalender.rb +11 -0
  232. data/lib/wrb/documents/samples/sample_progressbar.rb +14 -0
  233. data/lib/wrb/documents/samples/sample_radiobutton.rb +14 -0
  234. data/lib/wrb/documents/samples/sample_rebar.rb +25 -0
  235. data/lib/wrb/documents/samples/sample_richedit.rb +60 -0
  236. data/lib/wrb/documents/samples/sample_splitter.rb +33 -0
  237. data/lib/wrb/documents/samples/sample_static.rb +15 -0
  238. data/lib/wrb/documents/samples/sample_statusbar.rb +17 -0
  239. data/lib/wrb/documents/samples/sample_tabctrl.rb +19 -0
  240. data/lib/wrb/documents/samples/sample_toolbar.rb +29 -0
  241. data/lib/wrb/documents/samples/sample_tooltip.rb +50 -0
  242. data/lib/wrb/documents/samples/sample_trackbar.rb +30 -0
  243. data/lib/wrb/documents/samples/sample_treeview.rb +19 -0
  244. data/lib/wrb/documents/samples/sample_updown.rb +18 -0
  245. data/lib/wrb/documents/samples/sampleimg16.iml +0 -0
  246. data/lib/wrb/documents/samples/sampleimg32.iml +0 -0
  247. data/lib/wrb/documents/samples/samplemg16.png +0 -0
  248. data/lib/wrb/documents/samples/samplemg32.png +0 -0
  249. data/lib/wrb/documents/samples/wrb.ico +0 -0
  250. data/lib/wrb/documents/savefilenamedlg.html +19 -0
  251. data/lib/wrb/documents/scrollbar.html +60 -0
  252. data/lib/wrb/documents/splitter.html +96 -0
  253. data/lib/wrb/documents/static.html +84 -0
  254. data/lib/wrb/documents/statusbar.html +110 -0
  255. data/lib/wrb/documents/tabctrl.html +151 -0
  256. data/lib/wrb/documents/timer.html +43 -0
  257. data/lib/wrb/documents/toolbar.html +181 -0
  258. data/lib/wrb/documents/tooltip.html +131 -0
  259. data/lib/wrb/documents/trackbar.html +107 -0
  260. data/lib/wrb/documents/treeview.html +210 -0
  261. data/lib/wrb/documents/updown.html +85 -0
  262. data/lib/wrb/documents/wincontrol.html +258 -0
  263. data/lib/wrb/documents/window.html +499 -0
  264. data/lib/wrb/documents/wrb.css +228 -0
  265. data/lib/wrb/gmem.rb +26 -0
  266. data/lib/wrb/imecommon.rb +59 -0
  267. data/lib/wrb/listcommon.rb +185 -0
  268. data/lib/wrb/lzss.rb +126 -0
  269. data/lib/wrb/scrollinfo.rb +142 -0
  270. data/lib/wrb/toplevelcommon.rb +634 -0
  271. metadata +315 -0
@@ -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
+ }