Blame view

node_modules/asn1.js/lib/asn1/base/buffer.js 3.02 KB
aaac7fed   liuqimichale   add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
  var inherits = require('inherits');
  var Reporter = require('../base').Reporter;
  var Buffer = require('buffer').Buffer;
  
  function DecoderBuffer(base, options) {
    Reporter.call(this, options);
    if (!Buffer.isBuffer(base)) {
      this.error('Input not Buffer');
      return;
    }
  
    this.base = base;
    this.offset = 0;
    this.length = base.length;
  }
  inherits(DecoderBuffer, Reporter);
  exports.DecoderBuffer = DecoderBuffer;
  
  DecoderBuffer.prototype.save = function save() {
    return { offset: this.offset, reporter: Reporter.prototype.save.call(this) };
  };
  
  DecoderBuffer.prototype.restore = function restore(save) {
    // Return skipped data
    var res = new DecoderBuffer(this.base);
    res.offset = save.offset;
    res.length = this.offset;
  
    this.offset = save.offset;
    Reporter.prototype.restore.call(this, save.reporter);
  
    return res;
  };
  
  DecoderBuffer.prototype.isEmpty = function isEmpty() {
    return this.offset === this.length;
  };
  
  DecoderBuffer.prototype.readUInt8 = function readUInt8(fail) {
    if (this.offset + 1 <= this.length)
      return this.base.readUInt8(this.offset++, true);
    else
      return this.error(fail || 'DecoderBuffer overrun');
  }
  
  DecoderBuffer.prototype.skip = function skip(bytes, fail) {
    if (!(this.offset + bytes <= this.length))
      return this.error(fail || 'DecoderBuffer overrun');
  
    var res = new DecoderBuffer(this.base);
  
    // Share reporter state
    res._reporterState = this._reporterState;
  
    res.offset = this.offset;
    res.length = this.offset + bytes;
    this.offset += bytes;
    return res;
  }
  
  DecoderBuffer.prototype.raw = function raw(save) {
    return this.base.slice(save ? save.offset : this.offset, this.length);
  }
  
  function EncoderBuffer(value, reporter) {
    if (Array.isArray(value)) {
      this.length = 0;
      this.value = value.map(function(item) {
        if (!(item instanceof EncoderBuffer))
          item = new EncoderBuffer(item, reporter);
        this.length += item.length;
        return item;
      }, this);
    } else if (typeof value === 'number') {
      if (!(0 <= value && value <= 0xff))
        return reporter.error('non-byte EncoderBuffer value');
      this.value = value;
      this.length = 1;
    } else if (typeof value === 'string') {
      this.value = value;
      this.length = Buffer.byteLength(value);
    } else if (Buffer.isBuffer(value)) {
      this.value = value;
      this.length = value.length;
    } else {
      return reporter.error('Unsupported type: ' + typeof value);
    }
  }
  exports.EncoderBuffer = EncoderBuffer;
  
  EncoderBuffer.prototype.join = function join(out, offset) {
    if (!out)
      out = new Buffer(this.length);
    if (!offset)
      offset = 0;
  
    if (this.length === 0)
      return out;
  
    if (Array.isArray(this.value)) {
      this.value.forEach(function(item) {
        item.join(out, offset);
        offset += item.length;
      });
    } else {
      if (typeof this.value === 'number')
        out[offset] = this.value;
      else if (typeof this.value === 'string')
        out.write(this.value, offset);
      else if (Buffer.isBuffer(this.value))
        this.value.copy(out, offset);
      offset += this.length;
    }
  
    return out;
  };