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.
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
+ }