source: asp3_tinet_ecnl_rx/trunk/asp3_dcre/tecsgen/tecs/mruby/TECSPointer.h@ 337

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

ASP3版ECNLを追加

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