Class: Rixmap::Binary

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
src/rixmapcore.cxx,
src/rixmapcore.cxx

Overview

バイナリ配列クラス. RubyのArrayと違い、0~255の範囲でしか値を扱えなくしてあります. この範囲を超える場合はオーバーフローします.

上の特徴のため、たとえば #[] で得られる値は常に Fixnum になります.

Instance Method Summary collapse

Constructor Details

#initialize(size = 0, value = 0) (private) #initialize(ary) (private) #initialize(bytes) (private)

バイナリ配列オブジェクトを初期化します

Overloads:

  • #initialize(size = 0, value = 0)

    指定したサイズのバイナリ配列を作成します. 配列内はすべて value で初期化されます.

    Parameters:

    • size (Integer) (defaults to: 0)

      バイナリ配列サイズ

    • value (Integer) (defaults to: 0)

      初期値

  • #initialize(ary)

    指定された配列を複製した、新しいバイナリ配列として初期化します.

    Parameters:

  • #initialize(bytes)

    指定されたバイナリ文字列を元に、バイナリ配列を初期化します.

    Parameters:

    • bytes (String)

      元にする文字列



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'src/rixmapcore.cxx', line 55

static VALUE Binary_initialize(int argc, VALUE* argv, VALUE self) {
    VALUE arg0, arg1;
    rb_scan_args(argc, argv, "02", &arg0, &arg1);

    // 自分ポインタ
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    _this->clear();     // 何も入ってないと思うけど念のため

    // 型別に初期化処理を分岐
    if (!NIL_P(arg0)) {
        // 最初の引数有
        if (RB_TYPE_P(arg0, T_ARRAY) || rb_respond_to(arg0, rb_intern("to_ary"))) {
            // 配列型
            VALUE aryItems = rb_Array(arg0);
            long nitem = RARRAY_LEN(aryItems);
            for (long i = 0; i < nitem; i++) {
                VALUE item = rb_Integer(rb_ary_entry(aryItems, i));
                uint8_t value = static_cast<uint8_t>(NUM2INT(item));
                _this->push_back(value);
            }
        } else if (RB_TYPE_P(arg0, T_STRING) || rb_respond_to(arg0, rb_intern("to_str"))) {
            // 文字列型
            VALUE strItems = rb_String(arg0);
            long nitem = RSTRING_LEN(strItems);
            const char* items = StringValuePtr(strItems);
            _this->insert(_this->end(), &(items[0]), &(items[nitem]));
        } else {
            // サイズ指定っぽい
            size_t size = NUM2ULONG(rb_Integer(arg0));

            // リサイズ
            _this->resize(size);

            // 第二引数ある?
            if (!NIL_P(arg1)) {
                // 初期値
                uint8_t value = static_cast<uint8_t>(NUM2INT(rb_Integer(arg1)));
                for (auto it = _this->begin(); it != _this->end(); it++) {
                    *it = value;
                }
            }
        }
    }

    return self;
}

Instance Method Details

#*(argTimes) ⇒ Rixmap::Binary

バイナリ配列の内容をtimes回繰り返した新しいバイナリ配列を返します.

Parameters:

  • times (Integer)

    繰り返す回数

Returns:

See Also:

  • Array#*


128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'src/rixmapcore.cxx', line 128

static VALUE Binary_operatorMul(VALUE self, VALUE argTimes) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    long times = NUM2LONG(rb_Integer(argTimes));

    if (times < 0) {
        rb_raise(rb_eArgError, "negative repeat times is not supported: %ld", times);
    }

    // 新しいバイナリ配列を確保
    VALUE objResult = rb_class_new_instance(0, NULL, cRixmapBinary);
    Rixmap::BinaryData* _result = rixmap_unwrap<Rixmap::BinaryData>(objResult);

    // 指定回数だけ複製
    for (long i = 0; i < times; i++) {
        _result->insert(_result->end(), _this->begin(), _this->end());
    }

    // 戻る
    return objResult;
}

#+(argOther) ⇒ Rixmap::Binary

バイナリ配列の末尾に別の配列を連結した新しいバイナリ配列を返します.

Parameters:

Returns:

Raises:

  • TypeError other が配列ではなかった場合

See Also:

  • Array#+


157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'src/rixmapcore.cxx', line 157

static VALUE Binary_operatorAdd(VALUE self, VALUE argOther) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);

    // 返却用オブジェクトを確保
    VALUE objResult = rb_class_new_instance(0, NULL, cRixmapBinary);
    Rixmap::BinaryData* _result = rixmap_unwrap<Rixmap::BinaryData>(objResult);

    // 型を判定
    if (RTEST(rb_obj_is_kind_of(argOther, cRixmapBinary))) {
        Rixmap::BinaryData* _other = rixmap_unwrap<Rixmap::BinaryData>(argOther);
        _result->insert(_result->end(), _this->begin(), _this->end());
        _result->insert(_result->end(), _other->begin(), _other->end());
    } else if (RB_TYPE_P(argOther, T_ARRAY) || rb_respond_to(argOther, rb_intern("to_ary"))) {
        VALUE aryItems = rb_Array(argOther);
        long nitem = RARRAY_LEN(aryItems);
        std::vector<uint8_t> items;
        for (long i = 0; i < nitem; i++) {
            int item = NUM2INT(rb_ary_entry(aryItems, i));
            items.push_back(static_cast<uint8_t>(item));
        }
        _result->insert(_result->end(), _this->begin(), _this->end());
        _result->insert(_result->end(), items.begin(), items.end());
    } else if (RB_TYPE_P(argOther, T_STRING) || rb_respond_to(argOther, rb_intern("to_str"))) {
        VALUE strItems = rb_String(argOther);
        long nitem = RSTRING_LEN(strItems);
        const char* items = StringValuePtr(strItems);

        _result->insert(_result->end(), _this->begin(), _this->end());
        _result->insert(_result->end(), &(items[0]), &(items[nitem]));
    } else {
        rb_raise(rb_eTypeError, "unexpected object type: %s", rb_obj_classname(argOther));
    }

    return objResult;
}

#<<(argValue) ⇒ Rixmap::Binary

バイナリ配列の末尾に整数値を追加します.

Parameters:

  • value (Integer)

    追加する整数値

Returns:

Raises:

  • TypeError value が整数値でない場合

See Also:

  • Array#<<


201
202
203
204
205
206
207
# File 'src/rixmapcore.cxx', line 201

static VALUE Binary_operatorLShift(VALUE self, VALUE argValue) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    VALUE objValue = rb_Integer(argValue);
    uint8_t value = static_cast<uint8_t>(NUM2INT(objValue));
    _this->push_back(value);
    return self;
}

#<=>(argOther) ⇒ Integer

バイナリ配列とほかの配列を比較します.

Parameters:

  • other (Object)

    比較する配列

Returns:

  • (Integer)

    比較結果を数値で返します.

    • 負数の場合 ==> selfotherより小さい
    • 0の場合 ==> selfotherが等しい
    • 正数の場合 ==> selfotherより大きい
    • nilの場合 == > otherが配列でない

See Also:

  • Array#<=>


220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'src/rixmapcore.cxx', line 220

static VALUE Binary_operatorCompare(VALUE self, VALUE argOther) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);

    // 型を判定
    if (RTEST(rb_obj_is_kind_of(argOther, cRixmapBinary))) {
        Rixmap::BinaryData* _other = rixmap_unwrap<Rixmap::BinaryData>(argOther);
        size_t thisSize = _this->size();
        size_t otherSize = _other->size();
        size_t i = 0, j = 0;
        for (; i < thisSize && j < otherSize; i++, j++) {
            uint8_t lvalue = _this->at(i);
            uint8_t rvalue = _other->at(i);
            if (!(lvalue == rvalue)) {
                return INT2FIX(static_cast<int>(lvalue) - static_cast<int>(rvalue));
            }
        }
        if (i == thisSize && j == otherSize) {
            return INT2FIX(0);
        } else {
            if (thisSize > otherSize) {
                return INT2FIX(1);
            } else {
                return INT2FIX(-1);
            }
        }
    } else if (RB_TYPE_P(argOther, T_ARRAY) || rb_respond_to(argOther, rb_intern("to_ary"))) {
        VALUE aryItems = rb_Array(argOther);
        size_t thisSize = _this->size();
        size_t otherSize = RARRAY_LEN(aryItems);
        size_t i = 0, j = 0;
        for (; i < thisSize && j < otherSize; i++, j++) {
            uint8_t lvalue = _this->at(i);
            uint8_t rvalue = static_cast<uint8_t>(NUM2INT(rb_Integer(rb_ary_entry(aryItems, j))));
            if (!(lvalue == rvalue)) {
                return INT2FIX(static_cast<int>(lvalue) - static_cast<int>(rvalue));
            }
        }
        if (i == thisSize && j == otherSize) {
            return INT2FIX(0);
        } else {
            if (thisSize > otherSize) {
                return INT2FIX(1);
            } else {
                return INT2FIX(-1);
            }
        }
    } else if (RB_TYPE_P(argOther, T_STRING) || rb_respond_to(argOther, rb_intern("to_str"))) {
        VALUE strItems = rb_String(argOther);
        size_t thisSize = _this->size();
        size_t otherSize = RSTRING_LEN(strItems);
        const char* items = StringValuePtr(strItems);

        size_t i = 0, j = 0;
        for (; i < thisSize && j < otherSize; i++, j++) {
            uint8_t lvalue = _this->at(i);
            uint8_t rvalue = static_cast<uint8_t>(items[j]);
            if (!(lvalue == rvalue)) {
                return INT2FIX(static_cast<int>(lvalue) - static_cast<int>(rvalue));
            }
        }
        if (i == thisSize && j == otherSize) {
            return INT2FIX(0);
        } else {
            if (thisSize > otherSize) {
                return INT2FIX(1);
            } else {
                return INT2FIX(-1);
            }
        }
    } else {
        return Qnil;
    }
}

#==(argOther) ⇒ Object

バイナリ配列とほかのオブジェクトとを比較し、同じバイナリ配列か銅貨を返します.

Parameters:



299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'src/rixmapcore.cxx', line 299

static VALUE Binary_operatorEquals(VALUE self, VALUE argOther) {
    if (!RTEST(rb_obj_is_kind_of(argOther, cRixmapBinary))) {
        return Qfalse;
    }

    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    Rixmap::BinaryData* _that = rixmap_unwrap<Rixmap::BinaryData>(argOther);

    if (*_this == *_that) {
        return Qtrue;
    } else {
        return Qfalse;
    }
}

#[](offset) ⇒ Integer? #[](offset, length) ⇒ Rixmap::Binary? #[](range) ⇒ Rixmap::Binary

Overloads:

  • #[](offset) ⇒ Integer?

    指定オフセットのバイトデータを取得します.

    オフセットが負数の場合は末尾からの逆向き指定と解釈します. オフセットが範囲外の場合はnilを返します.

    Parameters:

    • offset (Integer)

      取得オフセット

    Returns:

    • (Integer, nil)

      バイトデータ

  • #[](offset, length) ⇒ Rixmap::Binary?

    offsetから最大でlength個の要素を持った部分バイナリ配列を取得します.

    オフセットが負数の場合は末尾からの逆向き指定と解釈します. 戻り値については以下のルールになっています.

    • lengthが負数の場合はnil
    • offsetが範囲外の場合はnil
    • ただし、offsetが #length と同じだった場合は空配列

    Parameters:

    • offset (Integer)

      取得開始位置

    • length (Integer)

      取得する最大要素数

    Returns:

    • (Rixmap::Binary, nil)

      指定範囲のデータを含む部分配列

  • #[](range) ⇒ Rixmap::Binary

    指定された範囲オブジェクトの範囲内の要素からなる部分バイナリ配列を返します.

    戻り値は以下のようになります.

    • Range#first が配列の範囲外の場合はnil
    • Range#first が Raneg#end より後ろの場合は空の配列

    Parameters:

    • range (Range)

      取得する範囲

    Returns:

See Also:

  • Array#[]


351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
# File 'src/rixmapcore.cxx', line 351

static VALUE Binary_offsetGet(int argc, VALUE* argv, VALUE self) {
    // 引数
    VALUE argOffset, argLength;
    rb_scan_args(argc, argv, "11", &argOffset, &argLength);

    // 自分
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);

    // 長さを long として取得しておく
    // FIXME 危険('A`)
    long dataLength = static_cast<long>(_this->size());

    // 型別に処理
    if (RTEST(rb_obj_is_kind_of(argOffset, rb_cRange))) {
        // 範囲オブジェクトなので、まず先頭と末尾を取得する
        VALUE objFirst, objLast;
        int excludeLast = 0;
        rb_range_values(argOffset, &objFirst, &objLast, &excludeLast);

        // 整数値へ
        long first = NUM2LONG(objFirst);
        long last  = NUM2LONG(objLast);

        // 負数の場合は、後ろからのオフセットへ変換
        if (first < 0) {
            first += dataLength;
        }
        if (last < 0) {
            last += dataLength;
        }

        // 終端を含まない場合は縮める
        if (excludeLast) {
            last--;
        }

        // 範囲チェック
        if (first < 0 || first > dataLength) {
            // 先頭が範囲外
            return Qnil;
        } else {
            VALUE objResult = rb_class_new_instance(0, NULL, cRixmapBinary);
            Rixmap::BinaryData* _result = rixmap_unwrap<Rixmap::BinaryData>(objResult);
            for (long i = first; i < last && i < dataLength; i++) {
                _result->push_back(_this->at(i));
            }
            return objResult;
        }
    } else {
        // 整数値 (にする)
        VALUE numOffset = rb_Integer(argOffset);
        long offset = NUM2LONG(numOffset);

        // 負数の場合は後ろからのオフセットとしてずらす
        if (offset < 0) {
            offset += dataLength;
        }

        // 範囲外かどうか (1)
        if (offset < 0) {
            return Qnil;
        }

        if (NIL_P(argLength)) {
            // オフセットのみ
            if (offset < dataLength) {  // 範囲外チェック (2.1)
                return INT2FIX(_this->at(offset));
            } else {
                return Qnil;
            }
        } else {
            // 長さある

            // 範囲外チェック (2.2)
            if (offset > dataLength) {
                // NOTE Arrayと挙動合わせたらこんなことになった
                return Qnil;
            }

            VALUE numLength = rb_Integer(argLength);
            long length = NUM2LONG(numLength);

            // 戻り値用
            VALUE objResult = rb_class_new_instance(0, NULL, cRixmapBinary);
            Rixmap::BinaryData* _result = rixmap_unwrap<Rixmap::BinaryData>(objResult);

            // 追加
            for (long i = 0, j = offset; i < length && j < dataLength; i++, j++) {
                _result->push_back(_this->at(j));
            }

            return objResult;
        }
    }
}

#[]=(offset, value) #[]=(offset, length, values) #[]=(range, values)

Overloads:

  • #[]=(offset, value)

    This method returns an undefined value.

    指定位置のバイトデータを value に設定します.

    offset が #length より後ろだった場合は配列自体を拡張します.

    Parameters:

    • offset (Integer)

      設定位置

    • value (Integer)

      設定するバイトデータ

  • #[]=(offset, length, values)

    This method returns an undefined value.

    offsetからlength個の要素をvaluesで置き換えます.

    valuesは配列または配列に変換できる値であり、それ以外は要素数が1の配列として扱われます. また、lengthが0の場合はoffsetの前にvaluesを挿入します.

    Parameters:

    • offset (Integer)

      開始オフセット

    • length (Integer)

      置き換える長さ

    • values (Array, Rixmap::Binary)

      置き換える値

  • #[]=(range, values)

    This method returns an undefined value.

    指定範囲をvaluesで置き換えます.

    Parameters:

    • range (Range)

      置き換える範囲

    • values (Array, Rixmap::Binary)

      置き換える値

See Also:

  • Array#[]=


477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
# File 'src/rixmapcore.cxx', line 477

static VALUE Binary_offsetSet(int argc, VALUE* argv, VALUE self) {
    // 引数取得
    VALUE arg0, arg1, arg2; // arg1 or arg2 が設定する値
    rb_scan_args(argc, argv, "21", &arg0, &arg1, &arg2);

    // 自分情報
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    long dataLength = static_cast<long>(_this->size());

    // 更新情報
    long start = -1;
    long count = -1;
    VALUE objValues = Qnil;

    // 型チェック (Rangeかそれ以外か)
    if (RTEST(rb_obj_is_kind_of(arg0, rb_cRange))) {
        // Range (arg1が値)
        objValues = arg1;

        // 範囲オブジェクトを展開
        VALUE objFirst = Qnil, objLast = Qnil;
        int excludeLast = 0;
        rb_range_values(arg0, &objFirst, &objLast, &excludeLast);

        // Ruby Obj -> C Type
        long first = NUM2LONG(objFirst);
        long last  = NUM2LONG(objLast);
        if (first < 0) {
            first += dataLength;

            // 範囲外チェック
            if (first < 0) {
                // NOTE Arrayと挙動合わせた
                VALUE strRange = rb_inspect(arg0);
                rb_raise(rb_eRangeError, "%s is out of range", StringValueCStr(strRange));
            }
        }
        if (last < 0) {
            last += dataLength;
        }
        if (excludeLast) {
            last--;
        }

        // 範囲
        start = first;
        count = (last - start) + 1;
    } else {
        // それ以外
        VALUE objOffset = rb_Integer(arg0);
        long offset = NUM2LONG(objOffset);
        if (offset < 0) {
            // 範囲外チェック
            // NOTE Arrayと挙動合わせた
            if ((offset + dataLength) < 0) {
                rb_raise(rb_eIndexError, "index %ld too small for array; minimum: -%ld", offset, dataLength);
            }
            offset += dataLength;
        }
        start = offset;

        // 第2引数と第3引数の関係を処理
        if (NIL_P(arg2)) {
            // 第3引数なし => arg1がvalue
            objValues = arg1;
            count     = 1;      // 長さ1
        } else {
            // 第3引数あり => arg2がvalue
            objValues = arg2;
            count     = NUM2LONG(rb_Integer(arg1));
        }
    }

    // 値チェック
    if (NIL_P(objValues)) {
        rb_raise(rb_eArgError, "unexpected value type: %s", rb_obj_classname(objValues));
    }

    /* 以下変更処理 */
    // 値をC配列へ
    std::deque<uint8_t> input;
    if (RTEST(rb_obj_is_kind_of(objValues, cRixmapBinary))) {
        // Rixmap::Binary
        Rixmap::BinaryData* values = rixmap_unwrap<Rixmap::BinaryData>(objValues);
        input.insert(input.end(), values->begin(), values->end());
    } else if (RB_TYPE_P(objValues, T_ARRAY) || rb_respond_to(objValues, rb_intern("to_ary"))) {
        // Ruby配列
        VALUE aryValues = rb_Array(objValues);
        long aryLength = RARRAY_LEN(aryValues);
        for (long i = 0; i < aryLength; i++) {
            VALUE aryItem = rb_Integer(rb_ary_entry(aryValues, i));
            input.push_back(static_cast<uint8_t>(NUM2INT(aryItem)));
        }
    } else if (RB_TYPE_P(objValues, T_STRING) || rb_respond_to(objValues, rb_intern("to_str"))) {
        // Ruby文字列
        VALUE strValues = rb_String(objValues);
        long strLength = RSTRING_LEN(strValues);
        const char* strData = StringValuePtr(strValues);
        input.insert(input.end(), &(strData[0]), &(strData[strLength]));
    } else {
        // その他. 数値変換を試す
        int value = NUM2INT(rb_Integer(objValues));
        input.push_back(static_cast<uint8_t>(value));
    }

    // 始点分だけ伸ばす
    if (start >= dataLength) {
        // 伸ばす
        _this->resize(start + 1);
        dataLength = static_cast<long>(_this->size());
    }

    // 変更長から挿入位置を分けるよー
    // NOTE Arrayに合わせた
    if (count <= 0) {
        // 前に挿入
        auto iter = _this->begin() + start;
        _this->insert(iter, input.begin(), input.end());
    } else {
        // 挿入位置を基準に前と後ろの分割点を探す
        auto firstEndIter    = _this->begin() + start;  // 一応startに関しては↑で伸ばしてあるので平気
        auto secondStartIter = _this->begin();

        if ((start + count) < dataLength) {
            // 終端まで収まってる
            secondStartIter = _this->begin() + (start + count);
        } else {
            // 収まってない
            secondStartIter = _this->end();
        }

        // バッファへ入れて入れ替える
        std::deque<uint8_t> buffer;
        buffer.insert(buffer.end(), _this->begin(), firstEndIter);
        buffer.insert(buffer.end(), input.begin(), input.end());
        buffer.insert(buffer.end(), secondStartIter, _this->end());
        _this->swap(buffer);
    }

    // 戻る
    return objValues;
}

#at(argOffset) ⇒ Integer?

指定位置のバイトデータを取得します.

これは #[offset] と同じです.

Parameters:

  • offset (Integer)

    配列位置

Returns:

  • (Integer, nil)

    バイトデータ

See Also:



706
707
708
709
710
711
712
713
714
715
716
717
718
# File 'src/rixmapcore.cxx', line 706

static VALUE Binary_at(VALUE self, VALUE argOffset) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    long size   = static_cast<long>(_this->size());
    long offset = NUM2LONG(rb_Integer(argOffset));
    if (offset < 0) {
        offset += size;
    }
    if (0 <= offset && offset < size) {
        return INT2FIX(_this->at(offset));
    } else {
        return Qnil;
    }
}

#eachEnumerator #each {|byte| ... }

Overloads:

  • #eachEnumerator

    全てのバイトデータを走査するEnumeratorを返します.

    Returns:

    • (Enumerator)

      バイトデータを走査するイテレータ

  • #each {|byte| ... }

    This method returns an undefined value.

    全てのバイトデータを順に引数としてブロックを呼び出します.

    Yields:

    • (byte)

      バイトデータを引数としてブロックを呼び出します.

    Yield Parameters:

    • byte (Integer)

      バイトデータ

See Also:

  • Array#each


862
863
864
865
866
867
868
869
870
871
872
873
874
# File 'src/rixmapcore.cxx', line 862

static VALUE Binary_each(VALUE self) {
    if (rb_block_given_p()) {
        Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
        for (auto it = _this->begin(); it != _this->end(); it++) {
            VALUE item = INT2FIX(*it);
            rb_yield_values(1, item);
        }
        return self;
    } else {
        // TODO サイズ計算関数の追加
        return rb_enumeratorize(self, ID2SYM(rb_frame_this_func()), 0, NULL);
    }
}

#initialize_copy(argObject) (private)

This method returns an undefined value.

バイナリ配列の複製を初期化します.

Parameters:

  • obj (Object)

    複製元

See Also:

  • Object#clone
  • Object#dup


110
111
112
113
114
115
116
117
118
119
# File 'src/rixmapcore.cxx', line 110

static VALUE Binary_initializeCopy(VALUE self, VALUE argObject) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    Rixmap::BinaryData* _that = rixmap_unwrap<Rixmap::BinaryData>(argObject);

    // 自分を消去して追加
    _this->clear();
    _this->insert(_this->end(), _that->begin(), _that->end());

    return self;
}

#inspectString

バイナリ配列オブジェクトの、オブジェクトとしての文字列表現を返します.

Returns:

  • (String)

    オブジェクト文字列表現



687
688
689
690
691
692
693
694
695
# File 'src/rixmapcore.cxx', line 687

static VALUE Binary_inspect(VALUE self) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    VALUE text = rb_funcall(self, rb_intern("to_s"), 0);
    return rb_enc_sprintf(
            rb_usascii_encoding(),
            "#<%s:%p size=%d, data=%s>",
            rb_obj_classname(self), reinterpret_cast<void*>(self),
            _this->size(), StringValueCStr(text));
}

#lengthInteger

バイナリ配列の長さを取得します.

Returns:

  • (Integer)

    配列長.



625
626
627
628
# File 'src/rixmapcore.cxx', line 625

static VALUE Binary_getLength(VALUE self) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    return ULONG2NUM(_this->size());
}

#map {|byte| ... } ⇒ Rixmap::Binary

バイナリ要素の各バイトについてブロックを呼び出し、その戻り値で構成される新しいバイナリ配列を返します.

Returns ブロックを呼び出し結果からなる新しいバイナリ配列を返します.

Yields:

  • (byte)

    バイトごとにブロックを呼び出します.

Yield Parameters:

  • byte (Integer)

    バイトデータ

Returns:

  • (Rixmap::Binary)

    ブロックを呼び出し結果からなる新しいバイナリ配列を返します.



933
934
935
936
# File 'src/rixmapcore.cxx', line 933

static VALUE Binary_map(VALUE self) {
    VALUE binary = rb_obj_clone(self);
    return rb_funcall_passing_block(binary, rb_intern("map!"), 0, NULL);
}

#map! {|byte| ... } ⇒ Rixmap::Binary

バイナリ要素の各バイトについてブロックを呼び出し、その戻り値で要素を置き換えます.

Returns selfを返します.

Yields:

  • (byte)

    バイトごとにブロックを呼び出します.

Yield Parameters:

  • byte (Integer)

    バイトデータ

Returns:



910
911
912
913
914
915
916
917
918
919
920
921
922
923
# File 'src/rixmapcore.cxx', line 910

static VALUE Binary_mapSelf(VALUE self) {
    if (!rb_block_given_p()) {
        rb_raise(rb_eRuntimeError, "block parameter are required.");
    }

    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    size_t size = _this->size();
    for (size_t i = 0; i < size; i++) {
        VALUE byte = INT2FIX(_this->at(i));
        VALUE resp = rb_yield_values(1, byte);
        rb_funcall(self, rb_intern("[]="), 2, ULONG2NUM(i), resp);
    }
    return self;
}

#popInteger? #pop(num) ⇒ Rixmap::Binary

Overloads:

  • #popInteger?

    末尾から要素を取り除き、取り除かれた要素を返します.

    Returns:

    • (Integer, nil)

      取り除かれたバイトデータ. 配列が空だった場合はnil.

  • #pop(num) ⇒ Rixmap::Binary

    末尾から指定された数だけ要素を取り除き、取り除かれた要素を配列で返します.

    Parameters:

    • num (Integer)

      取り除く要素数

    Returns:

    • (Rixmap::Binary)

      取り除かれたバイトデータの配列. 空配列だった場合は空配列が返されます.

See Also:

  • Array#pop


755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
# File 'src/rixmapcore.cxx', line 755

static VALUE Binary_pop(int argc, VALUE* argv, VALUE self) {
    // 引数
    VALUE argCount = Qnil;
    rb_scan_args(argc, argv, "01", &argCount);

    // 自分
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);

    // 引数の有無で挙動を変える
    if (NIL_P(argCount)) {
        if (_this->empty()) {
            return Qnil;
        } else {
            uint8_t value = _this->back();
            _this->pop_back();
            return INT2FIX(value);
        }
    } else {
        long num = NUM2LONG(rb_Integer(argCount));
        VALUE objResult = rb_class_new_instance(0, NULL, cRixmapBinary);
        Rixmap::BinaryData* result = rixmap_unwrap<Rixmap::BinaryData>(objResult);
        for (long i = 0; i < num && !_this->empty(); i++) {
            result->push_front(_this->back());
            _this->pop_back();
        }
        return objResult;
    }
}

#push(*items) ⇒ Rixmap::Binary

末尾に値を追加します.

Returns selfを返します.

Parameters:

  • *items (*Integer)

    追加する値

Returns:

See Also:

  • Array#push


729
730
731
732
733
734
735
736
737
# File 'src/rixmapcore.cxx', line 729

static VALUE Binary_push(int argc, VALUE* argv, VALUE self) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    for (int i = 0; i < argc; i++) {
        VALUE arg = argv[i];
        long value = NUM2LONG(rb_Integer(arg));
        _this->push_back(static_cast<uint8_t>(value));
    }
    return self;
}

#reverseRixmap::Binary

逆順に並べられたバイナリ配列の複製を返します.

Returns:

See Also:

  • Array#reverse


894
895
896
897
898
899
900
# File 'src/rixmapcore.cxx', line 894

static VALUE Binary_reverse(VALUE self) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    VALUE objResult = rb_class_new_instance(0, NULL, cRixmapBinary);
    Rixmap::BinaryData* result = rixmap_unwrap<Rixmap::BinaryData>(objResult);
    result->insert(result->begin(), _this->rbegin(), _this->rend());
    return objResult;
}

#reverse!Rixmap::Binary

バイナリ配列を破壊的に逆順に並べなおします.

Returns:

See Also:

  • Array#reverse!


882
883
884
885
886
# File 'src/rixmapcore.cxx', line 882

static VALUE Binary_reverseSelf(VALUE self) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    std::reverse(_this->begin(), _this->end());
    return self;
}

#shiftInteger? #shift(num) ⇒ Rixmap::Binary

Overloads:

  • #shiftInteger?

    先頭の要素を取り除き、取り除かれたバイトデータを返します.

    Returns:

    • (Integer, nil)

      取り除かれたバイトデータ. selfが空配列だった場合はnil.

  • #shift(num) ⇒ Rixmap::Binary

    先頭の要素を指定された数だけ取り除き、取り除かれたバイトデータを配列で返します.

    Parameters:

    • num (Integer)

      取り除く要素数

    Returns:

    • (Rixmap::Binary)

      取り除かれたバイトデータの配列. selfが空配列だった場合は空配列になります.

See Also:

  • Array#shift


800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
# File 'src/rixmapcore.cxx', line 800

static VALUE Binary_shift(int argc, VALUE* argv, VALUE self) {
    // 引数
    VALUE argCount = Qnil;
    rb_scan_args(argc, argv, "01", &argCount);

    // 自分
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);

    // 引数の有無で挙動を変える
    if (NIL_P(argCount)) {
        if (_this->empty()) {
            return Qnil;
        } else {
            uint8_t value = _this->front();
            _this->pop_front();
            return INT2FIX(value);
        }
    } else {
        long num = NUM2LONG(rb_Integer(argCount));
        VALUE objResult = rb_class_new_instance(0, NULL, cRixmapBinary);
        Rixmap::BinaryData* result = rixmap_unwrap<Rixmap::BinaryData>(objResult);
        for (long i = 0; i < num && !_this->empty(); i++) {
            result->push_back(_this->front());
            _this->pop_front();
        }
        return objResult;
    }
}

#to_aArray<Integer>

バイナリ配列をRuby配列へ変換します.

Returns:

  • (Array<Integer>)

    バイナリデータが格納された整数値配列



635
636
637
638
639
640
641
642
643
644
645
# File 'src/rixmapcore.cxx', line 635

static VALUE Binary_toArray(VALUE self) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    VALUE ary = rb_ary_new2(_this->size());

    // Rubyオブジェクトへ変換しつつ格納
    for (size_t i = 0; i < _this->size(); i++) {
        rb_ary_store(ary, i, INT2FIX(_this->at(i)));
    }

    return ary;
}

#to_aryArray<Integer>

バイナリ配列をRuby配列へ変換します.

Returns:

  • (Array<Integer>)

    バイナリデータが格納された整数値配列



635
636
637
638
639
640
641
642
643
644
645
# File 'src/rixmapcore.cxx', line 635

static VALUE Binary_toArray(VALUE self) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    VALUE ary = rb_ary_new2(_this->size());

    // Rubyオブジェクトへ変換しつつ格納
    for (size_t i = 0; i < _this->size(); i++) {
        rb_ary_store(ary, i, INT2FIX(_this->at(i)));
    }

    return ary;
}

#to_sString

バイナリ配列を配列形式の文字列として返します.

Returns:

  • (String)

    配列形式文字列

See Also:

  • Array#to_s


665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
# File 'src/rixmapcore.cxx', line 665

static VALUE Binary_toTextString(VALUE self) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    std::ostringstream buffer;

    buffer << "[";
    for (auto it = _this->begin(); it != _this->end(); it++) {
        if (it != _this->begin()) {
            buffer << ", ";
        }
        buffer << static_cast<unsigned int>(*it);
    }
    buffer << "]";
    std::string text = buffer.str();

    return rb_enc_str_new(text.data(), text.size(), rb_ascii8bit_encoding());
}

#to_strString

バイナリ配列をバイト文字列へ変換します.

Returns:

  • (String)

    バイナリ配列のデータによる文字列



652
653
654
655
656
657
# File 'src/rixmapcore.cxx', line 652

static VALUE Binary_toString(VALUE self) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    std::string str;
    str.insert(str.end(), _this->begin(), _this->end());
    return rb_enc_str_new(str.data(), str.size(), rb_ascii8bit_encoding());
}

#unshift(*items) ⇒ Rixmap::Binary

先頭に指定された要素をすべて追加します.

Parameters:

  • *items (*Integer)

    追加するバイトデータ

Returns:

See Also:

  • Array#unshift


838
839
840
841
842
843
844
845
846
847
# File 'src/rixmapcore.cxx', line 838

static VALUE Binary_unshift(int argc, VALUE* argv, VALUE self) {
    Rixmap::BinaryData* _this = rixmap_unwrap<Rixmap::BinaryData>(self);
    std::deque<uint8_t> buffer;
    for (int i = 0; i < argc; i++) {
        VALUE item = argv[i];
        buffer.push_back(static_cast<uint8_t>(NUM2INT(rb_Integer(item))));
    }
    _this->insert(_this->begin(), buffer.begin(), buffer.end());
    return self;
}