nysol 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/blueKiller.rb +17 -0
- data/bin/mdistcopy.rb +89 -0
- data/bin/meach.rb +284 -0
- data/bin/meachc.rb +288 -0
- data/bin/msend.rb +95 -0
- data/bin/mtempclean.rb +33 -0
- data/ext/mcsvin/extconf.rb +14 -0
- data/ext/mcsvin/mcsvin.cpp +857 -0
- data/ext/mcsvout/extconf.rb +14 -0
- data/ext/mcsvout/mcsvout.cpp +401 -0
- data/ext/mmethods/extconf.rb +12 -0
- data/ext/mmethods/mmethods.cpp +259 -0
- data/ext/mtable/extconf.rb +12 -0
- data/ext/mtable/mtable.cpp +555 -0
- data/lib/nysol/margs.rb +402 -0
- data/lib/nysol/mcmd.rb +44 -0
- data/lib/nysol/mnettools.rb +220 -0
- data/lib/nysol/mparallel.rb +359 -0
- data/lib/nysol/mparallelmanager.rb +300 -0
- data/lib/nysol/mrubyparse.rb +538 -0
- data/lib/nysol/msysteminfo.rb +216 -0
- data/lib/nysol/mtemp.rb +268 -0
- data/lib/nysol/mutils.rb +218 -0
- metadata +89 -0
@@ -0,0 +1,555 @@
|
|
1
|
+
/* ////////// LICENSE INFO ////////////////////
|
2
|
+
|
3
|
+
* Copyright (C) 2013 by NYSOL CORPORATION
|
4
|
+
*
|
5
|
+
* Unless you have received this program directly from NYSOL pursuant
|
6
|
+
* to the terms of a commercial license agreement with NYSOL, then
|
7
|
+
* this program is licensed to you under the terms of the GNU Affero General
|
8
|
+
* Public License (AGPL) as published by the Free Software Foundation,
|
9
|
+
* either version 3 of the License, or (at your option) any later version.
|
10
|
+
*
|
11
|
+
* This program is distributed in the hope that it will be useful, but
|
12
|
+
* WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF
|
13
|
+
* NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
14
|
+
*
|
15
|
+
* Please refer to the AGPL (http://www.gnu.org/licenses/agpl-3.0.txt)
|
16
|
+
* for more details.
|
17
|
+
|
18
|
+
////////// LICENSE INFO ////////////////////*/
|
19
|
+
// =============================================================================
|
20
|
+
// mtable.cpp csv => 行列 クラス
|
21
|
+
// =============================================================================
|
22
|
+
#include <sstream>
|
23
|
+
#include <unistd.h>
|
24
|
+
#include <fcntl.h>
|
25
|
+
#include <sys/stat.h>
|
26
|
+
#include <sys/types.h>
|
27
|
+
#include <ruby.h>
|
28
|
+
#include <kgmod.h>
|
29
|
+
#include <kgMethod.h>
|
30
|
+
|
31
|
+
|
32
|
+
#define BUFSIZE 102400
|
33
|
+
|
34
|
+
using namespace std;
|
35
|
+
using namespace kglib;
|
36
|
+
|
37
|
+
extern "C" {
|
38
|
+
void Init_mtable(void);
|
39
|
+
}
|
40
|
+
|
41
|
+
// -----------------------------------------------------------------------------
|
42
|
+
// encodingを考慮した文字列生成
|
43
|
+
// -----------------------------------------------------------------------------
|
44
|
+
static VALUE str2rbstr(const char *ptr)
|
45
|
+
{
|
46
|
+
// rb_external_str_new_cstrが定義されているばそちらを使う
|
47
|
+
#if defined(rb_external_str_new_cstr)
|
48
|
+
return rb_external_str_new_cstr(ptr);
|
49
|
+
#else
|
50
|
+
return rb_str_new2(ptr);
|
51
|
+
#endif
|
52
|
+
|
53
|
+
}
|
54
|
+
|
55
|
+
// =============================================================================
|
56
|
+
// mtable クラス
|
57
|
+
// CSVファイルをメモリに読み込み,行と列の指定で自由にcell情報をセットする
|
58
|
+
// ためのkgMod継承クラス.
|
59
|
+
// =============================================================================
|
60
|
+
class mtable : public kgMod
|
61
|
+
{
|
62
|
+
kgAutoPtr2<char*> _nameStr_ap;
|
63
|
+
kgAutoPtr2<char*> _valStr_ap;
|
64
|
+
|
65
|
+
char* _buf; // 全データを格納するバッファ
|
66
|
+
int _blocks; // read回数。
|
67
|
+
vector<char*> _cell; // 全セルへのインデックス
|
68
|
+
string _fsName; // i=
|
69
|
+
bool _fldNameNo; // -nfn
|
70
|
+
char** _nameStr; // 項目名一覧
|
71
|
+
size_t _fldSize; // 項目数
|
72
|
+
size_t _recSize; // 行数
|
73
|
+
|
74
|
+
public:
|
75
|
+
|
76
|
+
mtable(void){ // コンストラクタ
|
77
|
+
_name = "mtable";
|
78
|
+
_version = "1.0";
|
79
|
+
_blocks = 0;
|
80
|
+
_fldSize = 0;
|
81
|
+
_recSize = 0;
|
82
|
+
};
|
83
|
+
virtual ~mtable() {}
|
84
|
+
//アクセッサ
|
85
|
+
void fname(string fn) { _fsName = fn ;}
|
86
|
+
void nfn(bool nfnf) { _fldNameNo = nfnf ;}
|
87
|
+
bool nfn(void) { return _fldNameNo;}
|
88
|
+
char* header(size_t i) { return *(_nameStr+i);}
|
89
|
+
size_t fldsize() { return _fldSize;}
|
90
|
+
size_t recsize() { return _recSize;}
|
91
|
+
|
92
|
+
int run();
|
93
|
+
|
94
|
+
char* cell(size_t col, size_t row){
|
95
|
+
return _cell.at(row*_fldSize+col);
|
96
|
+
}
|
97
|
+
};
|
98
|
+
|
99
|
+
// -----------------------------------------------------------------------------
|
100
|
+
// run
|
101
|
+
// -----------------------------------------------------------------------------
|
102
|
+
int mtable::run() try
|
103
|
+
{
|
104
|
+
// ファイルオープン
|
105
|
+
int fd = ::open(_fsName.c_str(), O_RDONLY );
|
106
|
+
if(fd == -1 ){
|
107
|
+
rb_raise(rb_eRuntimeError,"file open error");
|
108
|
+
}
|
109
|
+
|
110
|
+
// 全行読み込む
|
111
|
+
size_t totalSize=0;
|
112
|
+
_buf=0;
|
113
|
+
while(true){
|
114
|
+
_blocks++;
|
115
|
+
long rbufSz = BUFSIZE*_blocks+1;
|
116
|
+
if(rbufSz <long(0)){
|
117
|
+
rb_raise(rb_eRuntimeError,"read buffer is full");
|
118
|
+
}
|
119
|
+
REALLOC_N(_buf, char, rbufSz); // +1は最終行に改行がなかった場合の終端'\0'用
|
120
|
+
size_t rsize = ::read(fd, _buf+(BUFSIZE*(_blocks-1)), BUFSIZE);
|
121
|
+
if(rsize==0) break;
|
122
|
+
totalSize+=rsize;
|
123
|
+
}
|
124
|
+
::close(fd);
|
125
|
+
|
126
|
+
// bufferの終端位置
|
127
|
+
char* endPos=_buf+totalSize;
|
128
|
+
|
129
|
+
if(totalSize==0){
|
130
|
+
_fldSize = 0;
|
131
|
+
_recSize = 0;
|
132
|
+
return 0;
|
133
|
+
}
|
134
|
+
if(*(endPos-1)!='\n' && *(endPos-1)!='\r'){
|
135
|
+
*endPos='\n';
|
136
|
+
totalSize++;
|
137
|
+
endPos++;
|
138
|
+
}
|
139
|
+
|
140
|
+
// 項目数のカウント
|
141
|
+
_fldSize = kglib::cntFldToken(_buf, totalSize);
|
142
|
+
|
143
|
+
// 項目名(先頭rec)の取得
|
144
|
+
char* pnt = _buf;
|
145
|
+
|
146
|
+
// 1行目が項目名行の場合, 項目名のtoken分割
|
147
|
+
if(!nfn()){
|
148
|
+
_nameStr_ap.set( new char*[_fldSize] );
|
149
|
+
_nameStr = _nameStr_ap.get();
|
150
|
+
pnt = sepFldToken(_nameStr, _fldSize , pnt , totalSize)+1;
|
151
|
+
for(size_t i=0; i<_fldSize;i++){
|
152
|
+
splitToken(_nameStr[i],'%'); // 項目名 % チェック
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
// 項目値char*へのインデックス
|
157
|
+
_valStr_ap.set( new char*[_fldSize] );
|
158
|
+
char ** valStr = _valStr_ap.get();
|
159
|
+
|
160
|
+
while(pnt < endPos){
|
161
|
+
pnt = sepFldToken(valStr, _fldSize, pnt , endPos-pnt) + 1;
|
162
|
+
_recSize++;
|
163
|
+
for(size_t i=0; i < _fldSize; i++){
|
164
|
+
_cell.push_back( *(valStr+i) );
|
165
|
+
}
|
166
|
+
}
|
167
|
+
return 0;
|
168
|
+
}catch(kgError& err){
|
169
|
+
ostringstream ss;
|
170
|
+
ss << "Error in processing line " << _recSize+1 << "(not including header line)";
|
171
|
+
err.addMessage(ss.str());
|
172
|
+
throw;
|
173
|
+
}catch(...){
|
174
|
+
ostringstream ss;
|
175
|
+
ss << "Internal error in processing line" << _recSize+1 << "(not including header line)";
|
176
|
+
throw kgError(ss.str());
|
177
|
+
}
|
178
|
+
|
179
|
+
// =============================================================================
|
180
|
+
// rMmtable クラス(mtableクラスのrubyラッパ)
|
181
|
+
// 機能: 1) kgEnvとコマンドライン引数のメモリを確保する
|
182
|
+
// 2) 正常終了,エラー終了の統一的メソッドを提供する
|
183
|
+
// =============================================================================
|
184
|
+
class rMtable
|
185
|
+
{
|
186
|
+
public:
|
187
|
+
kgEnv env;
|
188
|
+
string argstr; // rubyの引数をコピーして格納するための変数
|
189
|
+
kgAutoPtr2<char*> argv;
|
190
|
+
mtable* mod; // 一度実行(RUN)されると0となる.
|
191
|
+
VALUE object_; // rMtableオブジェクト(rb_yieldで必要)
|
192
|
+
|
193
|
+
private:
|
194
|
+
void freeMod() try
|
195
|
+
{
|
196
|
+
if(mod!=0){ delete mod; }
|
197
|
+
mod=0;
|
198
|
+
}catch(...){
|
199
|
+
rb_raise(rb_eRuntimeError,"Error at freeMod()");
|
200
|
+
}
|
201
|
+
|
202
|
+
public:
|
203
|
+
|
204
|
+
// エラー終了メソッド
|
205
|
+
void errorEnd(kgError& err) try
|
206
|
+
{
|
207
|
+
mod->errorEnd(err);
|
208
|
+
freeMod();
|
209
|
+
}catch(...){
|
210
|
+
rb_raise(rb_eRuntimeError,"Error at errorEnd()");
|
211
|
+
}
|
212
|
+
|
213
|
+
// 正常終了メソッド
|
214
|
+
void successEnd() try
|
215
|
+
{
|
216
|
+
mod->successEnd();
|
217
|
+
freeMod();
|
218
|
+
}catch(...){
|
219
|
+
rb_raise(rb_eRuntimeError,"Error at successEnd()");
|
220
|
+
}
|
221
|
+
};
|
222
|
+
|
223
|
+
// =============================================================================
|
224
|
+
// 公開メソッド
|
225
|
+
// =============================================================================
|
226
|
+
//
|
227
|
+
// NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW NEW
|
228
|
+
//
|
229
|
+
/*
|
230
|
+
* call-seq:
|
231
|
+
* Mtable.new -> tbl
|
232
|
+
*
|
233
|
+
* <b>説明</b> テーブルクラスのインスタンスを生成する.この段階ではファイルはまだ読み込まれない.runメソッドを実行して初めて読み込まれる.
|
234
|
+
*
|
235
|
+
* <b>書式</b> Mtable.new("i=CSVファイル名 [-nfn]")
|
236
|
+
*
|
237
|
+
* i=:: 読み込むCSVファイル名を指定する.
|
238
|
+
*
|
239
|
+
* -nfn=::1 行目を項目名と見なさない
|
240
|
+
*
|
241
|
+
*/
|
242
|
+
VALUE mtable_init(int argc, VALUE *argv, VALUE self) try
|
243
|
+
{
|
244
|
+
rMtable* rmod;
|
245
|
+
Data_Get_Struct(self,rMtable,rmod);
|
246
|
+
|
247
|
+
try
|
248
|
+
{
|
249
|
+
// 引数セット
|
250
|
+
VALUE options;
|
251
|
+
rb_scan_args(argc, argv,"01",&options);
|
252
|
+
|
253
|
+
// rubyの引数文字列を一旦rmod->argstrに退避させてからtoken分割する。
|
254
|
+
// 退避させないと、ruby変数としての文字列を変更してしまうことになる。
|
255
|
+
if(TYPE(options)==T_NIL){
|
256
|
+
rmod->argstr="";
|
257
|
+
}else if(TYPE(options)==T_STRING){
|
258
|
+
rmod->argstr=RSTRING_PTR(options);
|
259
|
+
}else{
|
260
|
+
rb_raise(rb_eRuntimeError,"1st argument must be String");
|
261
|
+
}
|
262
|
+
vector<char *> opts = splitToken(const_cast<char*>(rmod->argstr.c_str()), ' ',true);
|
263
|
+
|
264
|
+
// 引数文字列へのポインタの領域はここでauto変数に確保する
|
265
|
+
char** vv;
|
266
|
+
try{
|
267
|
+
rmod->argv.set(new char*[opts.size()+1]);
|
268
|
+
vv = rmod->argv.get();
|
269
|
+
}catch(...){
|
270
|
+
rb_raise(rb_eRuntimeError,"memory allocation error");
|
271
|
+
}
|
272
|
+
|
273
|
+
// vv配列0番目はコマンド名
|
274
|
+
vv[0]=const_cast<char*>(rmod->mod->name());
|
275
|
+
|
276
|
+
size_t vvSize;
|
277
|
+
for(vvSize=0; vvSize<opts.size(); vvSize++){
|
278
|
+
vv[vvSize+1] = opts.at(vvSize);
|
279
|
+
}
|
280
|
+
vvSize+=1;
|
281
|
+
|
282
|
+
// modの初期化&引数の存在チェック
|
283
|
+
rmod->mod->init(vvSize, const_cast<const char**>(vv), &rmod->env);
|
284
|
+
rmod->mod->args()->paramcheck("i=,-nfn",false);
|
285
|
+
|
286
|
+
// 各種引数の設定 i=,-nfn
|
287
|
+
rmod->mod->fname(rmod->mod->args()->toString("i=",false));
|
288
|
+
rmod->mod->nfn(rmod->mod->args()->toBool("-nfn"));
|
289
|
+
|
290
|
+
// メモリにローディング
|
291
|
+
rmod->mod->run();
|
292
|
+
|
293
|
+
// ブロック引数があればyield実行
|
294
|
+
if(rb_block_given_p()){
|
295
|
+
rb_yield(rmod->object_);
|
296
|
+
rmod->successEnd();
|
297
|
+
}
|
298
|
+
|
299
|
+
}catch(kgError& err){
|
300
|
+
rmod->errorEnd(err); throw;
|
301
|
+
}
|
302
|
+
return self;
|
303
|
+
|
304
|
+
}catch(...){
|
305
|
+
rb_raise(rb_eRuntimeError,"Error at mtable_init()");
|
306
|
+
}
|
307
|
+
|
308
|
+
// -----------------------------------------------------------------------------
|
309
|
+
// NAMES
|
310
|
+
// -----------------------------------------------------------------------------
|
311
|
+
/*
|
312
|
+
* call-seq:
|
313
|
+
* names -> String Array or nil
|
314
|
+
*
|
315
|
+
* 項目名配列を返す。
|
316
|
+
*
|
317
|
+
* === 引数
|
318
|
+
* なし
|
319
|
+
*
|
320
|
+
*/
|
321
|
+
VALUE mtable_names(VALUE self) try
|
322
|
+
{
|
323
|
+
rMtable* rmod;
|
324
|
+
Data_Get_Struct(self,rMtable,rmod);
|
325
|
+
VALUE rtn;
|
326
|
+
if (rmod->mod->nfn()){
|
327
|
+
rtn = Qnil;
|
328
|
+
}else{
|
329
|
+
rtn = rb_ary_new2(rmod->mod->fldsize());
|
330
|
+
for(size_t i=0 ;i<rmod->mod->fldsize(); i++){
|
331
|
+
rb_ary_store( rtn, i, str2rbstr( rmod->mod->header(i) ) );
|
332
|
+
}
|
333
|
+
}
|
334
|
+
return rtn;
|
335
|
+
|
336
|
+
}catch(...){
|
337
|
+
rb_raise(rb_eRuntimeError,"Error at mtable_names()");
|
338
|
+
}
|
339
|
+
|
340
|
+
// -----------------------------------------------------------------------------
|
341
|
+
// NAME2NUM
|
342
|
+
// -----------------------------------------------------------------------------
|
343
|
+
/*
|
344
|
+
* call-seq:
|
345
|
+
* name2num -> String=>Fixnum Hash or nil
|
346
|
+
*
|
347
|
+
* 項目名をキー、対応する項目番号を値とする Hash を返す。
|
348
|
+
*
|
349
|
+
* === 引数
|
350
|
+
* なし
|
351
|
+
*
|
352
|
+
*/
|
353
|
+
VALUE mtable_name2num(VALUE self) try
|
354
|
+
{
|
355
|
+
rMtable* rmod;
|
356
|
+
Data_Get_Struct(self,rMtable,rmod);
|
357
|
+
VALUE rtn;
|
358
|
+
if (rmod->mod->nfn()){
|
359
|
+
rtn = Qnil;
|
360
|
+
}else{
|
361
|
+
rtn =rb_hash_new();
|
362
|
+
for(size_t i=0 ;i<rmod->mod->fldsize(); i++){
|
363
|
+
rb_hash_aset(rtn, str2rbstr( rmod->mod->header(i) ) , INT2FIX(i));
|
364
|
+
}
|
365
|
+
}
|
366
|
+
return rtn;
|
367
|
+
|
368
|
+
}catch(...){
|
369
|
+
rb_raise(rb_eRuntimeError,"Error at mtable_names()");
|
370
|
+
}
|
371
|
+
|
372
|
+
// -----------------------------------------------------------------------------
|
373
|
+
// SIZE
|
374
|
+
// -----------------------------------------------------------------------------
|
375
|
+
/*
|
376
|
+
* call-seq:
|
377
|
+
* size -> Fixnum
|
378
|
+
*
|
379
|
+
* 行数を返す。
|
380
|
+
*
|
381
|
+
* === 引数
|
382
|
+
* なし
|
383
|
+
*
|
384
|
+
*/
|
385
|
+
VALUE mtable_size(VALUE self) try {
|
386
|
+
rMtable* rmod;
|
387
|
+
Data_Get_Struct(self,rMtable,rmod);
|
388
|
+
return INT2FIX(rmod->mod->recsize());
|
389
|
+
}catch(...){
|
390
|
+
rb_raise(rb_eRuntimeError,"Error at mtable_size()");
|
391
|
+
}
|
392
|
+
|
393
|
+
// -----------------------------------------------------------------------------
|
394
|
+
// CELL
|
395
|
+
// -----------------------------------------------------------------------------
|
396
|
+
/*
|
397
|
+
* call-seq:
|
398
|
+
* cell -> String
|
399
|
+
*
|
400
|
+
* row(行),col(列) に対応するセルの値を返す。
|
401
|
+
* row,col の与え方は、列番号と行番号による。
|
402
|
+
* 列/行番号共に 0 か ら始まる整数 (Mcsvin の列番号は 1 から始まる)。
|
403
|
+
* row,col が範囲外の場合は nil を返す。
|
404
|
+
* row 行番号で、0 以上の整数を用いる。デフォルトは 0。
|
405
|
+
* col 列番号で、0 以上の整数を用いる。項目名は指定できない。デフォルトは 0。
|
406
|
+
* col のみ与えると 0 行目の col 番目の項目の値を返す。
|
407
|
+
* cell(col,0) を指定したのと同等。
|
408
|
+
* また col,row 両方とも与えなければ 0 行目の 0 項目目の値を返す。
|
409
|
+
* cell(0,0) を指定したのと同等。
|
410
|
+
* === 引数
|
411
|
+
* col 列
|
412
|
+
* row 行
|
413
|
+
*/
|
414
|
+
VALUE mtable_cell(int argc, VALUE *argv, VALUE self) try {
|
415
|
+
rMtable* rmod;
|
416
|
+
Data_Get_Struct(self,rMtable,rmod);
|
417
|
+
|
418
|
+
VALUE option;
|
419
|
+
rb_scan_args(argc, argv,"*",&option);
|
420
|
+
|
421
|
+
size_t colNo=0;
|
422
|
+
size_t rowNo=0;
|
423
|
+
|
424
|
+
if(argc==1){
|
425
|
+
// 列番号
|
426
|
+
VALUE v1=RARRAY_PTR(option)[0];
|
427
|
+
if( TYPE(v1) == T_FIXNUM ){
|
428
|
+
colNo = FIX2INT(v1);
|
429
|
+
}else if( TYPE(v1) == T_BIGNUM ){
|
430
|
+
colNo = NUM2INT(v1);
|
431
|
+
}else{
|
432
|
+
rb_raise(rb_eRuntimeError,"argument type error (1st argument must be a number");
|
433
|
+
}
|
434
|
+
|
435
|
+
}else if(argc==2){
|
436
|
+
|
437
|
+
// 列番号
|
438
|
+
VALUE v1=RARRAY_PTR(option)[0];
|
439
|
+
if( TYPE(v1) == T_FIXNUM ){
|
440
|
+
colNo = FIX2INT(v1);
|
441
|
+
}else if( TYPE(v1) == T_BIGNUM ){
|
442
|
+
colNo = NUM2INT(v1);
|
443
|
+
}else{
|
444
|
+
rb_raise(rb_eRuntimeError,"argument type error (1st argument must be a number");
|
445
|
+
}
|
446
|
+
|
447
|
+
// 行番号
|
448
|
+
VALUE v2=RARRAY_PTR(option)[1];
|
449
|
+
if( TYPE(v2) == T_FIXNUM ){
|
450
|
+
rowNo = FIX2INT(v2);
|
451
|
+
}else if( TYPE(v2) == T_BIGNUM ){
|
452
|
+
rowNo = NUM2INT(v2);
|
453
|
+
}else{
|
454
|
+
rb_raise(rb_eRuntimeError,"argument type error (1st argument must be a number");
|
455
|
+
}
|
456
|
+
}
|
457
|
+
|
458
|
+
// 範囲チェック
|
459
|
+
if(colNo>=rmod->mod->fldsize()){
|
460
|
+
rb_raise(rb_eRuntimeError,"col number must be less than %zd",rmod->mod->fldsize());
|
461
|
+
}
|
462
|
+
if(rowNo>=rmod->mod->recsize()){
|
463
|
+
rb_raise(rb_eRuntimeError,"row number must be less than %zd",rmod->mod->recsize());
|
464
|
+
}
|
465
|
+
|
466
|
+
// 値を返す
|
467
|
+
return str2rbstr( rmod->mod->cell(colNo, rowNo) );
|
468
|
+
|
469
|
+
|
470
|
+
}catch(...){
|
471
|
+
rb_raise(rb_eRuntimeError,"Error at mtable_records()");
|
472
|
+
}
|
473
|
+
|
474
|
+
// -----------------------------------------------------------------------------
|
475
|
+
// メモリ解放
|
476
|
+
// kgRubyModの領域開放(GC時にrubyにより実行される)(xxx_alloc()にて登録される)
|
477
|
+
// -----------------------------------------------------------------------------
|
478
|
+
void mtable_free(rMtable* rmod) try
|
479
|
+
{
|
480
|
+
if(rmod!=0){ delete rmod; }
|
481
|
+
|
482
|
+
}catch(...){
|
483
|
+
rb_raise(rb_eRuntimeError,"Error at mtable_free()");
|
484
|
+
}
|
485
|
+
|
486
|
+
// -----------------------------------------------------------------------------
|
487
|
+
// インスタンス化される時のメモリ確保
|
488
|
+
// -----------------------------------------------------------------------------
|
489
|
+
VALUE mtable_alloc(VALUE klass) try
|
490
|
+
{
|
491
|
+
rMtable* rmod=new rMtable;
|
492
|
+
rmod->mod = new mtable;
|
493
|
+
VALUE object=Data_Wrap_Struct(klass,0,mtable_free,rmod);
|
494
|
+
rmod->object_ = object;
|
495
|
+
return object;
|
496
|
+
|
497
|
+
}catch(...){
|
498
|
+
rb_raise(rb_eRuntimeError,"Error at table_alloc()");
|
499
|
+
}
|
500
|
+
|
501
|
+
// -----------------------------------------------------------------------------
|
502
|
+
// ruby Mtable クラス init
|
503
|
+
// -----------------------------------------------------------------------------
|
504
|
+
/*
|
505
|
+
* = 指定した CSV データ全体をメモリに読み込んで処理するクラス以下のような特徴を持つ。
|
506
|
+
* 行と列の指定によりセルをランダムにアクセス可能。
|
507
|
+
* 読み込み専用であり、データの更新や追加は一切できない。
|
508
|
+
* データは全て文字列として読み込むので、その他の方で利用する時は適宜型変換 (ex. to i) が必要。
|
509
|
+
* メモリが空いている限りデータを読み込む。領域がなくなればエラー終了する。
|
510
|
+
* === 利用例1
|
511
|
+
* # dat1.csv
|
512
|
+
* customer,date,amount
|
513
|
+
* A,20081201,10
|
514
|
+
* B,20081002,40
|
515
|
+
*
|
516
|
+
* tbl=Mtable.new("i=dat1.csv")
|
517
|
+
* p tbl.names # -> ["customer", "date", "amount"]
|
518
|
+
* p tbl.name2num # -> {"amount"=>2, "date"=>1, "customer"=>0}
|
519
|
+
* p tbl.size # -> 2
|
520
|
+
* p tbl.cell(0,0) # -> "A"
|
521
|
+
* p tbl.cell(0,1) # -> "B"
|
522
|
+
* p tbl.cell(1,1) # -> "20081202"
|
523
|
+
* p tbl.cell(1) # -> "20081201"
|
524
|
+
* p tbl.cell # -> "A"
|
525
|
+
* === 利用例2
|
526
|
+
* # dat1.csv
|
527
|
+
* customer,date,amount
|
528
|
+
* A,20081201,10
|
529
|
+
* B,20081002,40
|
530
|
+
*
|
531
|
+
* tbl=Mtable.new("i=dat1.csv -nfn") # 一行目もデータと見なす。
|
532
|
+
* p tbl.names # -> nil
|
533
|
+
* p tbl.name2num # -> nil
|
534
|
+
* p tbl.size # -> 3
|
535
|
+
* p tbl.cell(0,0) # -> "customer"
|
536
|
+
* p tbl.cell(0,1) # -> "A"
|
537
|
+
* p tbl.cell(1,1) # -> "20081201"
|
538
|
+
* p tbl.cell(1) # -> "date"
|
539
|
+
* p tbl.cell # -> "customer"
|
540
|
+
*/
|
541
|
+
void Init_mtable(void)
|
542
|
+
{
|
543
|
+
// モジュール定義:MCMD::xxxxの部分
|
544
|
+
VALUE mcmd=rb_define_module("MCMD");
|
545
|
+
|
546
|
+
VALUE mtable;
|
547
|
+
mtable=rb_define_class_under(mcmd,"Mtable",rb_cObject);
|
548
|
+
rb_define_alloc_func(mtable, mtable_alloc);
|
549
|
+
rb_define_method(mtable,"initialize", (VALUE (*)(...))mtable_init , -1);
|
550
|
+
rb_define_method(mtable,"names" , (VALUE (*)(...))mtable_names , 0);
|
551
|
+
rb_define_method(mtable,"name2num" , (VALUE (*)(...))mtable_name2num, 0);
|
552
|
+
rb_define_method(mtable,"cell" , (VALUE (*)(...))mtable_cell , -1);
|
553
|
+
rb_define_method(mtable,"size" , (VALUE (*)(...))mtable_size , 0);
|
554
|
+
}
|
555
|
+
|