source: EcnlProtoTool/trunk/asp3_dcre/tecsgen/tecs/mruby/TECSPointer.h@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-chdr
File size: 23.6 KB
RevLine 
[270]1/*
2 * mruby => TECS brige
3 *
4 * Copyright (C) 2008-2012 by TOPPERS Project
5 *--
6 * 上記著作権者
7は,以下の(1)(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再é…
10å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
11 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
12 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
13 * スコード中に含まれていること.
14 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
15 * 用できる形で再é…
16å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
17å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
18 * 者
19マニュアルなど)に,上記の著作権表示,この利用条件および下記
20 * の無保証規定を掲載すること.
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再é…
23å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
24 * と.
25 * (a) 再é…
26å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
27マニュアルなど)に,上記の著
28 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
29 * (b) 再é…
30å¸ƒã®å½¢æ…
31‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
32 * 報告すること.
33 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
34 * 害からも,上記著作権者
35およびTOPPERSプロジェクトをå…
36è²¬ã™ã‚‹ã“と.
37 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
38 * 由に基づく請求からも,上記著作権者
39およびTOPPERSプロジェクトを
40 * å…
41è²¬ã™ã‚‹ã“と.
42 *
43 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
44お
45 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
46 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
47 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
48 * の責任を負わない.
49 *
50 * $Id: TECSPointer.h 270 2017-02-09 04:03:47Z coas-nagasima $
51 */
52
53#ifndef TECSPointer_h__
54#define TECSPointer_h__
55
56#include <string.h>
57#include <stdint.h>
58#include <limits.h>
59
60#ifndef CHAR_T_DEFINED
61typedef int bool_t;
62typedef char char_t;
63typedef double double64_t;
64typedef float float32_t;
65#endif /* CHAR_T_DEFINED */
66
67//// define Pointer classes ////
68#define POINTER_BODY( Type, TYPE ) \
69 \
70 struct Type ## PointerBody { \
71 uint32_t length; \
72 TYPE buf[ /* length */ ]; \
73 };
74
75
76// struct TypePointerBody
77POINTER_BODY( Bool, bool_t ) /* struct BoolPointerBody */
78POINTER_BODY( Double64, double64_t )/* struct Double64PointerBody */
79POINTER_BODY( Float32, float32_t ) /* struct Float32PointerBody */
80
81POINTER_BODY( Int8, int8_t ) /* struct Int8PointerBody */
82POINTER_BODY( Int16, int16_t ) /* struct Int16PointerBody */
83POINTER_BODY( Int32, int32_t ) /* struct Int32PointerBody */
84POINTER_BODY( Int64, int64_t ) /* struct Int64PointerBody */
85POINTER_BODY( Char, char_t ) /* struct CharPointerBody */
86POINTER_BODY( Int, int ) /* struct IntPointerBody */
87POINTER_BODY( Short, short ) /* struct ShortPointerBody */
88POINTER_BODY( Long, long ) /* struct LongPointerBody */
89
90POINTER_BODY( UInt8, uint8_t ) /* struct UInt8PointerBody */
91POINTER_BODY( UInt16, uint16_t ) /* struct UInt16PointerBody */
92POINTER_BODY( UInt32, uint32_t ) /* struct UInt32PointerBody */
93POINTER_BODY( UInt64, uint64_t ) /* struct UInt64PointerBody */
94POINTER_BODY( UChar, uint8_t ) /* struct UCharPointerBody */
95POINTER_BODY( UInt, unsigned int ) /* struct UIntPointerBody */
96POINTER_BODY( UShort, unsigned short ) /* struct UShortPointerBody */
97POINTER_BODY( ULong, unsigned long ) /* struct ULongPointerBody */
98
99POINTER_BODY( SChar, char_t ) /* struct SCharPointerBody */
100
101// ■ TECS_NO_VAL_CHECK を define すると、値チェックを省略する
102#ifndef TECS_NO_VAL_CHECK
103#define VALCHECK_INT(Type, TYPE, type ) \
104 /* check before assigning mrb_int val to intN_t */ \
105 static inline void \
106 VALCHECK_ ## Type( mrb_state *mrb, mrb_int val ) \
107 { \
108 if( sizeof( mrb_int ) > sizeof( type ) ){ \
109 if( val > TYPE ## _MAX || val < TYPE ## _MIN ) \
110 mrb_raise(mrb, E_ARGUMENT_ERROR, "too large or too small for " #type "_t"); \
111 } \
112 }
113#define VALCHECK_MRB_INT(Type, TYPE, type ) \
114 /* check before assigning val (intN_t) to mrb_int */ \
115 static inline void \
116 VALCHECK_MRB_ ## Type( mrb_state *mrb, type val ) \
117 { \
118 if( sizeof( type ) > sizeof( mrb_int ) ){ \
119 if( val >= (((type)1) << (sizeof(mrb_int)*8-1)) \
120 || val < -(((type)1) << (sizeof(mrb_int)*8-1)) ) \
121 /* '=' unecessary for negative value */ \
122 /* ignore warning on int32_t */ \
123 mrb_raise(mrb, E_ARGUMENT_ERROR, "too large or too small for mrb_int"); \
124 } \
125 }
126
127#define VALCHECK_UINT(Type, TYPE, type ) \
128 /* check before assigning mrb_int val to intN_t */ \
129 static inline void \
130 VALCHECK_ ## Type( mrb_state *mrb, mrb_int val ) \
131 { \
132 if( sizeof( mrb_int ) > sizeof( type ) ){ \
133 if( val > TYPE ## _MAX || val < 0 ) \
134 mrb_raise(mrb, E_ARGUMENT_ERROR, "too large or too small for " #type "_t"); \
135 } \
136 }
137#define VALCHECK_MRB_UINT(Type, TYPE, type ) \
138 /* check before assigning val (intN_t) to mrb_int */ \
139 static inline void \
140 VALCHECK_MRB_ ## Type( mrb_state *mrb, type val ) \
141 { \
142 if( sizeof( type ) > sizeof( mrb_int ) ){ \
143 if( val >= (((type)1) << (sizeof(mrb_int)*8))) \
144 /* '=' unecessary for negative value */ \
145 /* ignore warning on int32_t */ \
146 mrb_raise(mrb, E_ARGUMENT_ERROR, "too large or too small for mrb_int"); \
147 } \
148 }
149#else // TECS_NO_VAL_CHECK
150
151#define VALCHECK_INT(Type, TYPE, type )
152#define VALCHECK_UINT(Type, TYPE, type )
153
154#endif // TECS_NO_VAL_CHECK
155
156// define VALCHECK function
157#define VALCHECK_Bool( mrb, val )
158#define VALCHECK_MRB_Bool( mrb, val )
159
160VALCHECK_INT( Int8, INT8, int8_t )
161VALCHECK_MRB_INT( Int8, INT8, int8_t )
162VALCHECK_INT( Int16, INT16, int16_t )
163VALCHECK_MRB_INT( Int16, INT16, int16_t )
164VALCHECK_UINT( UInt8, UINT8, uint8_t )
165#define VALCHECK_MRB_UInt8
166VALCHECK_UINT( UInt16, UINT16, uint16_t )
167#define VALCHECK_MRB_UInt16
168VALCHECK_INT( Int32, INT32, int32_t )
169#define VALCHECK_MRB_Int32
170VALCHECK_UINT( UInt32, UINT32, uint32_t )
171#define VALCHECK_MRB_UInt32
172
173VALCHECK_INT( Int64, INT64, int64_t )
174VALCHECK_UINT( UInt64, UINT64, uint64_t )
175#ifndef mrb_int_IS_int64
176 // ■ int 32 bit を仮定している. 64 bit であれば mrb_int_IS_64 を define する
177VALCHECK_MRB_INT( Int64, INT64, int64_t )
178VALCHECK_MRB_UINT( UInt64, UINT64, uint64_t )
179#else
180#define VALCHECK_MRB_Int64 // 範囲チェックが無意味であるため、警告が出るのを回避する
181#define VALCHECK_MRB_UInt64 // 範囲チェックが無意味であるため、警告が出るのを回避する
182#endif
183
184#ifndef TECS_NO_VAL_CHECK
185 // ■ char_t は unsigned とみなす
186static inline void
187VALCHECK_Char( mrb_state *mrb, mrb_int val )
188{
189 if( val > 0xff || val < 0 )
190 mrb_raise(mrb, E_ARGUMENT_ERROR, "too large or too small for char_t");
191}
192#define VALCHECK_MRB_Char( mrb, val )
193
194VALCHECK_INT( Short, SHRT, short )
195#define VALCHECK_MRB_Short( mrb, val )
196
197VALCHECK_INT( Int, INT, int )
198#define VALCHECK_MRB_Int( mrb, val )
199
200VALCHECK_INT( Long, LONG, long )
201#define VALCHECK_MRB_Long( mrb, val )
202
203VALCHECK_INT( SChar, SCHAR, signed char )
204#define VALCHECK_MRB_SChar( mrb, val )
205
206VALCHECK_UINT( UChar, UCHAR, unsigned char )
207#define VALCHECK_MRB_UChar( mrb, val )
208
209VALCHECK_UINT( UInt, UINT, unsigned int )
210#define VALCHECK_MRB_UInt( mrb, val )
211
212VALCHECK_UINT( UShort, USHRT, unsigned short )
213#define VALCHECK_MRB_UShort( mrb, val )
214
215VALCHECK_UINT( ULong, ULONG, unsigned long )
216#define VALCHECK_MRB_ULong( mrb, val )
217
218#else // TECS_NO_VAL_CHECK
219
220#define VALCHECK_Char( mrb, val )
221#define VALCHECK_MRB_Char( mrb, val )
222#define VALCHECK_Int( mrb, val )
223#define VALCHECK_MRB_Int( mrb, val )
224#define VALCHECK_Short( mrb, val )
225#define VALCHECK_MRB_Short( mrb, val )
226#define VALCHECK_Long( mrb, val )
227#define VALCHECK_MRB_Long( mrb, val )
228#define VALCHECK_SChar( mrb, val )
229#define VALCHECK_MRB_SChar( mrb, val )
230#define VALCHECK_UChar( mrb, val )
231#define VALCHECK_MRB_UChar( mrb, val )
232#define VALCHECK_UInt( mrb, val )
233#define VALCHECK_MRB_UInt( mrb, val )
234#define VALCHECK_UShort( mrb, val )
235#define VALCHECK_MRB_UShort( mrb, val )
236#define VALCHECK_ULong( mrb, val )
237#define VALCHECK_MRB_ULong( mrb, val )
238
239#endif // TECS_NO_VAL_CHECK
240
241#define CHECK_AND_GET_POINTER( Type, type ) \
242 type *CheckAndGet ## Type ## Pointer( mrb_state *mrb, mrb_value value, int32_t len ) \
243 { \
244 if( mrb_type(value) != MRB_TT_DATA \
245 || DATA_TYPE( value ) == 0 \
246 || strcmp( DATA_TYPE( value )->struct_name, "TECS::" #Type "Pointer" ) ) \
247 mrb_raise(mrb, E_TYPE_ERROR, "not PointerType or unexpected PointerType"); \
248 if( len != -1 && ((struct Type ## PointerBody *)DATA_PTR( value ))->length < len ) \
249 mrb_raise(mrb, E_ARGUMENT_ERROR, "size_is too short"); \
250 return ((struct Type##PointerBody*)(DATA_PTR(value)))->buf; \
251 } \
252 \
253 type *CheckAndGet ## Type ## PointerNullable( mrb_state *mrb, mrb_value value, int32_t len ) \
254 { \
255 if( mrb_nil_p(value) ) \
256 return NULL; \
257 return CheckAndGet ## Type ## Pointer( mrb, value, len ); \
258 }
259
260
261/*
262 * CHECK_AND_GET_CHAR_POINTER & CHECK_AND_GET_CHAR_POINTER_MOD are used
263 * in case that the macro TECS_Use_MrbString_for_CharPointer is defined.
264 * This does not work as str_modify is static funcion.
265 */
266#define CHECK_AND_GET_CHAR_POINTER( Type, type ) \
267 type *CheckAndGet ## Type ## Pointer( mrb_state *mrb, mrb_value value, int32_t len ) \
268 { \
269 if( mrb_type(value) != MRB_TT_STRING ) \
270 mrb_raise(mrb, E_TYPE_ERROR, "not String Type"); \
271 if( len != -1 && RSTRING_LEN(value) < len ) \
272 mrb_raise(mrb, E_ARGUMENT_ERROR, "size_is too short"); \
273 return RSTRING_PTR(value); \
274 } \
275 \
276 type *CheckAndGet ## Type ## PointerNullable( mrb_state *mrb, mrb_value value, int32_t len ) \
277 { \
278 if( mrb_nil_p(value) ) \
279 return NULL; \
280 return CheckAndGet ## Type ## Pointer( mrb, value, len ); \
281 }
282
283#define CHECK_AND_GET_CHAR_POINTER_MOD( Type, type ) \
284 type *CheckAndGet ## Type ## PointerMod( mrb_state *mrb, mrb_value value, int32_t len ) \
285 { \
286 char *ptr; \
287 if( mrb_type(value) != MRB_TT_STRING ) \
288 mrb_raise(mrb, E_TYPE_ERROR, "not String Type"); \
289 str_modify(mrb,RSTRING(value)); \
290 if( len == -1 || RSTRING_LEN(value) < len ) \
291 mrb_raise(mrb, E_ARGUMENT_ERROR, "size_is too short"); \
292 ptr = RSTRING_PTR(value); \
293 ptr[len] = '\0'; \
294 return (type *)ptr; \
295 } \
296 \
297 type *CheckAndGet ## Type ## PointerModNullable( mrb_state *mrb, mrb_value value, int32_t len ) \
298 { \
299 if( mrb_nil_p(value) ) \
300 return NULL; \
301 return CheckAndGet ## Type ## Pointer( mrb, value, len ); \
302 }
303
304#define CHECK_AND_GET_POINTER_PROTO( Type, type ) \
305 type *CheckAndGet ## Type ## Pointer( mrb_state *mrb, mrb_value value, int32_t len ); \
306 type *CheckAndGet ## Type ## PointerNullable( mrb_state *mrb, mrb_value value, int32_t len )
307#define CHECK_AND_GET_POINTER_MOD_PROTO( Type, type ) \
308 type *CheckAndGet ## Type ## PointerMod( mrb_state *mrb, mrb_value value, int32_t len ); \
309 type *CheckAndGet ## Type ## PointerModNullable( mrb_state *mrb, mrb_value value, int32_t len )
310
311CHECK_AND_GET_POINTER_PROTO( Bool, bool_t ); /* Bool pointer */
312CHECK_AND_GET_POINTER_PROTO( Double64, double64_t );/* Double64 pointer */
313CHECK_AND_GET_POINTER_PROTO( Float32, float32_t ); /* Float32 pointer */
314
315CHECK_AND_GET_POINTER_PROTO( Int8, int8_t ); /* Int8 pointer */
316CHECK_AND_GET_POINTER_PROTO( Int16, int16_t ); /* Int16 pointer */
317CHECK_AND_GET_POINTER_PROTO( Int32, int32_t ); /* Int32 pointer */
318CHECK_AND_GET_POINTER_PROTO( Int64, int64_t ); /* Int64 pointer */
319CHECK_AND_GET_POINTER_PROTO( Int, int ); /* Int pointer */
320CHECK_AND_GET_POINTER_PROTO( Short, short ); /* Short pointer */
321CHECK_AND_GET_POINTER_PROTO( Long, long ); /* Long pointer */
322
323CHECK_AND_GET_POINTER_PROTO( UInt8, uint8_t ); /* UInt8 pointer */
324CHECK_AND_GET_POINTER_PROTO( UInt16, uint16_t ); /* UInt16 pointer */
325CHECK_AND_GET_POINTER_PROTO( UInt32, uint32_t ); /* UInt32 pointer */
326CHECK_AND_GET_POINTER_PROTO( UInt64, uint64_t ); /* UInt64 pointer */
327CHECK_AND_GET_POINTER_PROTO( UInt, unsigned int );/* UInt pointer */
328CHECK_AND_GET_POINTER_PROTO( UShort, unsigned short ); /* UShort pointer */
329CHECK_AND_GET_POINTER_PROTO( ULong, unsigned long ); /* ULong pointer */
330
331#ifndef TECS_Use_MrbString_for_CharPointer
332CHECK_AND_GET_POINTER_PROTO( Char, char_t ); /* Char pointer */
333CHECK_AND_GET_POINTER_PROTO( SChar, char_t ); /* SChar pointer */
334//CHECK_AND_GET_POINTER_PROTO( SChar, schar_t ); /* SChar pointer */
335CHECK_AND_GET_POINTER_PROTO( UChar, uint8_t ); /* UChar pointer */
336//CHECK_AND_GET_POINTER_PROTO( UChar, uchar_t ); /* UChar pointer */
337#define CheckAndGetCharPointerMod CheckAndGetCharPointer
338#define CheckAndGetSCharPointerMod CheckAndGetSCharPointer
339#define CheckAndGetUCharPointerMod CheckAndGetUCharPointer
340#define CheckAndGetCharPointerModNullable CheckAndGetCharPointerNullable
341#define CheckAndGetSCharPointerModNullable CheckAndGetSCharPointerNullable
342#define CheckAndGetUCharPointerModNullable CheckAndGetUCharPointerNullable
343#else
344CHECK_AND_GET_POINTER_PROTO( Char, char_t ); /* Char pointer */
345CHECK_AND_GET_POINTER_PROTO( SChar, char_t ); /* SChar pointer */
346CHECK_AND_GET_POINTER_PROTO( UChar, uint8_t ); /* UChar pointer */
347CHECK_AND_GET_POINTER_MOD_PROTO( Char, char_t ); /* Char pointer */
348CHECK_AND_GET_POINTER_MOD_PROTO( SChar, char_t ); /* SChar pointer */
349CHECK_AND_GET_POINTER_MOD_PROTO( UChar, uint8_t ); /* UChar pointer */
350#endif /* TECS_Use_MrbString_for_CharPointer */
351
352#define GET_SET_BOOL( Type, TYPE ) \
353 static mrb_value \
354 Type ## Pointer_aget(mrb_state *mrb, mrb_value self) \
355 { \
356 struct Type ## PointerBody *pointerBody = DATA_PTR( self ); \
357 mrb_int subscript; \
358 TYPE val; \
359 \
360 mrb_get_args(mrb, "i", &subscript ); \
361 if( subscript < 0 || subscript >= pointerBody->length ) \
362 mrb_raise(mrb, E_INDEX_ERROR, "index is out of array (get)"); \
363 val = pointerBody->buf[ subscript ]; \
364 VALCHECK_MRB_ ## Type( mrb, val ); \
365 return val ? mrb_true_value() : mrb_false_value(); \
366 } \
367 \
368 static mrb_value \
369 Type ## Pointer_aset(mrb_state *mrb, mrb_value self) \
370 { \
371 struct Type ## PointerBody *pointerBody = DATA_PTR( self ); \
372 mrb_int subscript; \
373 mrb_value val; \
374 \
375 mrb_get_args(mrb, "io", &subscript, &val ); \
376 \
377 if( subscript < 0 || subscript >= pointerBody->length ) \
378 mrb_raise(mrb, E_INDEX_ERROR, "index is out of array (set)"); \
379 pointerBody->buf[ subscript ] = mrb_test( val ); \
380 \
381 return self; \
382 } \
383 \
384 static mrb_value \
385 Type ## Pointer_get_val(mrb_state *mrb, mrb_value self) \
386 { \
387 struct Type ## PointerBody *pointerBody = DATA_PTR( self ); \
388 TYPE val; \
389 \
390 val = *pointerBody->buf; \
391 VALCHECK_MRB_ ## Type( mrb, val ); \
392 return val ? mrb_true_value() : mrb_false_value(); \
393 } \
394 \
395 static mrb_value \
396 Type ## Pointer_set_val(mrb_state *mrb, mrb_value self) \
397 { \
398 struct Type ## PointerBody *pointerBody = DATA_PTR( self ); \
399 mrb_value val; \
400 \
401 mrb_get_args(mrb, "o", &val ); \
402 \
403 *pointerBody->buf = mrb_test( val ); \
404 return self; \
405 }
406
407#define GET_SET_CHAR( Type, TYPE ) GET_SET_INT( Type, TYPE )
408#define GET_SET_INT( Type, TYPE ) \
409 static mrb_value \
410 Type ## Pointer_aget(mrb_state *mrb, mrb_value self) \
411 { \
412 struct Type ## PointerBody *pointerBody = DATA_PTR( self ); \
413 mrb_int subscript; \
414 TYPE val; \
415 \
416 mrb_get_args(mrb, "i", &subscript ); \
417 if( subscript < 0 || subscript >= pointerBody->length ) \
418 mrb_raise(mrb, E_INDEX_ERROR, "index is out of array (get)"); \
419 val = pointerBody->buf[ subscript ]; \
420 VALCHECK_MRB_ ## Type( mrb, val ); \
421 return mrb_fixnum_value( val ); \
422 } \
423 \
424 static mrb_value \
425 Type ## Pointer_aset(mrb_state *mrb, mrb_value self) \
426 { \
427 struct Type ## PointerBody *pointerBody = DATA_PTR( self ); \
428 mrb_int subscript; \
429 mrb_int val; \
430 \
431 mrb_get_args(mrb, "ii", &subscript, &val ); \
432 \
433 if( subscript < 0 || subscript >= pointerBody->length ) \
434 mrb_raise(mrb, E_INDEX_ERROR, "index is out of array (set)"); \
435 VALCHECK_ ## Type ( mrb, val ); \
436 pointerBody->buf[ subscript ] = val; \
437 \
438 return self; \
439 } \
440 \
441 static mrb_value \
442 Type ## Pointer_get_val(mrb_state *mrb, mrb_value self) \
443 { \
444 struct Type ## PointerBody *pointerBody = DATA_PTR( self ); \
445 TYPE val; \
446 \
447 val = *pointerBody->buf; \
448 VALCHECK_MRB_ ## Type( mrb, val ); \
449 return mrb_fixnum_value( val ); \
450 } \
451 \
452 static mrb_value \
453 Type ## Pointer_set_val(mrb_state *mrb, mrb_value self) \
454 { \
455 struct Type ## PointerBody *pointerBody = DATA_PTR( self ); \
456 mrb_int val; \
457 \
458 mrb_get_args(mrb, "i", &val ); \
459 \
460 VALCHECK_ ## Type ( mrb, val ); \
461 *pointerBody->buf = val; \
462 \
463 return self; \
464 }
465
466#define GET_SET_FLOAT( Type, TYPE ) \
467 static mrb_value \
468 Type ## Pointer_aget(mrb_state *mrb, mrb_value self) \
469 { \
470 struct Type ## PointerBody *pointerBody = DATA_PTR( self ); \
471 mrb_int subscript; \
472 \
473 mrb_get_args(mrb, "i", &subscript ); \
474 if( subscript < 0 || subscript >= pointerBody->length ) \
475 mrb_raise(mrb, E_INDEX_ERROR, "index is out of array (get)"); \
476 return mrb_float_value( mrb, pointerBody->buf[ subscript ] ); \
477 } \
478 \
479 static mrb_value \
480 Type ## Pointer_aset(mrb_state *mrb, mrb_value self) \
481 { \
482 struct Type ## PointerBody *pointerBody = DATA_PTR( self ); \
483 mrb_int subscript; \
484 mrb_float val; \
485 \
486 mrb_get_args(mrb, "if", &subscript, &val ); \
487 \
488 if( subscript < 0 || subscript >= pointerBody->length ) \
489 mrb_raise(mrb, E_INDEX_ERROR, "index is out of array (set)"); \
490 pointerBody->buf[ subscript ] = val; \
491 \
492 return self; \
493 } \
494 \
495 static mrb_value \
496 Type ## Pointer_get_val(mrb_state *mrb, mrb_value self) \
497 { \
498 struct Type ## PointerBody *pointerBody = DATA_PTR( self ); \
499 \
500 return mrb_float_value( mrb, *pointerBody->buf ); \
501 } \
502 \
503 static mrb_value \
504 Type ## Pointer_set_val(mrb_state *mrb, mrb_value self) \
505 { \
506 struct Type ## PointerBody *pointerBody = DATA_PTR( self ); \
507 mrb_float val; \
508 \
509 mrb_get_args(mrb, "f", &val ); \
510 \
511 *pointerBody->buf = val; \
512 \
513 return self; \
514 }
515
516//// define Pointer classes ////
517#define POINTER_CLASS( Type, TYPE ) \
518 \
519 static void \
520 Type ## PointerBody_free( mrb_state *mrb, void *p ) \
521 { \
522 (void)mrb_free( mrb, p ); \
523 } \
524 \
525 struct mrb_data_type Type ## PointerBody_mrb_data_type = \
526 { \
527 "TECS::" #Type "Pointer", \
528 Type ## PointerBody_free \
529 }; \
530 \
531 static mrb_value \
532 Type ## Pointer_initialize( mrb_state *mrb, mrb_value self) \
533 { \
534 mrb_int length; \
535 struct Type ## PointerBody *pointerBody; \
536 \
537 mrb_get_args(mrb, "i", &length ); \
538 if( length < 0 ) \
539 mrb_raise(mrb, E_INDEX_ERROR, "negative length"); \
540 DATA_TYPE( self ) = &Type ## PointerBody_mrb_data_type; \
541 pointerBody = (struct Type ## PointerBody *)mrb_malloc(mrb, sizeof(struct Type ## PointerBody) + length * sizeof( TYPE ) ); \
542 pointerBody->length = length; \
543 DATA_PTR( self ) = (void *)pointerBody; \
544 \
545 return self; \
546 } \
547 \
548 static mrb_value \
549 Type ## Pointer_size(mrb_state *mrb, mrb_value self) \
550 { \
551 struct Type ## PointerBody *pointerBody = DATA_PTR( self ); \
552 \
553 return mrb_fixnum_value( pointerBody->length ); \
554 } \
555 \
556 struct RClass * \
557 tecs_init_## Type ## Pointer(mrb_state *mrb, struct RClass *TECS) \
558 { \
559 struct RClass *a; \
560 \
561 a = mrb_define_class_under(mrb, TECS, #Type "Pointer", mrb->object_class); \
562 MRB_SET_INSTANCE_TT(a, MRB_TT_DATA); \
563 \
564 mrb_define_method(mrb, a, "initialize", Type ## Pointer_initialize, MRB_ARGS_REQ(1)); \
565 mrb_define_method(mrb, a, "[]", Type ## Pointer_aget, MRB_ARGS_REQ(1)); \
566 mrb_define_method(mrb, a, "value", Type ## Pointer_get_val, MRB_ARGS_NONE()); \
567 mrb_define_method(mrb, a, "[]=", Type ## Pointer_aset, MRB_ARGS_REQ(2)); \
568 mrb_define_method(mrb, a, "value=", Type ## Pointer_set_val, MRB_ARGS_REQ(1)); \
569 mrb_define_method(mrb, a, "size", Type ## Pointer_size, MRB_ARGS_NONE()); \
570 mrb_define_method(mrb, a, "length", Type ## Pointer_size, MRB_ARGS_NONE()); \
571 return a; \
572 }
573
574static inline mrb_value
575CharPointer_to_s( mrb_state *mrb, mrb_value self )
576{
577 struct CharPointerBody *pointerBody = DATA_PTR( self );
578 return mrb_str_new( mrb, pointerBody->buf, strnlen( pointerBody->buf, pointerBody->length ) );
579}
580
581static inline mrb_value
582CharPointer_from_s( mrb_state *mrb, mrb_value self )
583{
584 mrb_value str;
585 struct CharPointerBody *pointerBody = DATA_PTR( self );
586
587 mrb_get_args(mrb, "o", &str );
588 if( mrb_type( str ) != MRB_TT_STRING ){
589 mrb_raise(mrb, E_ARGUMENT_ERROR, "Not String");
590 }
591
592 strncpy( pointerBody->buf, RSTRING_PTR(str), pointerBody->length );
593 return self;
594}
595
596/* Initialize TECSPointer classes */
597void init_TECSPointer( mrb_state *mrb, struct RClass *TECS );
598
599#endif /* TECSPointer_h__ */
600
Note: See TracBrowser for help on using the repository browser.