Class: MessagePack::Factory

Inherits:
Object
  • Object
show all
Defined in:
lib/msgpack/factory.rb,
ext/msgpack/factory_class.c

Defined Under Namespace

Classes: Pool

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'ext/msgpack/factory_class.c', line 97

static VALUE Factory_initialize(int argc, VALUE* argv, VALUE self)
{
    msgpack_factory_t *fc = Factory_get(self);

    msgpack_packer_ext_registry_init(self, &fc->pkrg);
    // fc->ukrg is lazily initialized

    fc->has_symbol_ext_type = false;

    switch (argc) {
    case 0:
        break;
    default:
        // TODO options is not supported yet
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
    }

    return Qnil;
}

Instance Method Details

#dump(v, *rest) ⇒ Object Also known as: pack



113
114
115
116
117
# File 'lib/msgpack/factory.rb', line 113

def dump(v, *rest)
  packer = packer(*rest)
  packer.write(v)
  packer.full_pack
end

#dupObject



117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'ext/msgpack/factory_class.c', line 117

static VALUE Factory_dup(VALUE self)
{
    VALUE clone = Factory_alloc(rb_obj_class(self));

    msgpack_factory_t *fc = Factory_get(self);
    msgpack_factory_t *cloned_fc = Factory_get(clone);

    cloned_fc->has_symbol_ext_type = fc->has_symbol_ext_type;
    cloned_fc->pkrg = fc->pkrg;
    msgpack_unpacker_ext_registry_borrow(fc->ukrg, &cloned_fc->ukrg);
    msgpack_packer_ext_registry_dup(clone, &fc->pkrg, &cloned_fc->pkrg);

    return clone;
}

#freezeObject



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'ext/msgpack/factory_class.c', line 132

static VALUE Factory_freeze(VALUE self) {
    if(!rb_obj_frozen_p(self)) {
        msgpack_factory_t *fc = Factory_get(self);

        if (RTEST(fc->pkrg.hash)) {
            rb_hash_freeze(fc->pkrg.hash);
            if (!RTEST(fc->pkrg.cache)) {
                // If the factory is frozen, we can safely share the packer cache between
                // all packers. So we eagerly create it now so it's available when #packer
                // is called.
                RB_OBJ_WRITE(self, &fc->pkrg.cache, rb_hash_new());
            }
        }

        rb_obj_freeze(self);
    }

    return self;
}

#load(src, param = nil) ⇒ Object Also known as: unpack



99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/msgpack/factory.rb', line 99

def load(src, param = nil)
  unpacker = nil

  if src.is_a? String
    unpacker = unpacker(param)
    unpacker.feed(src)
  else
    unpacker = unpacker(src, param)
  end

  unpacker.full_unpack
end

#packer(*args) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'ext/msgpack/factory_class.c', line 152

VALUE MessagePack_Factory_packer(int argc, VALUE* argv, VALUE self)
{
    msgpack_factory_t *fc = Factory_get(self);

    VALUE packer = MessagePack_Packer_alloc(cMessagePack_Packer);
    MessagePack_Packer_initialize(argc, argv, packer);

    msgpack_packer_t* pk = MessagePack_Packer_get(packer);
    msgpack_packer_ext_registry_destroy(&pk->ext_registry);
    msgpack_packer_ext_registry_borrow(packer, &fc->pkrg, &pk->ext_registry);
    pk->has_bigint_ext_type = fc->has_bigint_ext_type;
    pk->has_symbol_ext_type = fc->has_symbol_ext_type;

    return packer;
}

#pool(size = 1, **options) ⇒ Object



120
121
122
123
124
125
126
# File 'lib/msgpack/factory.rb', line 120

def pool(size = 1, **options)
  Pool.new(
    frozen? ? self : dup.freeze,
    size,
    options.empty? ? nil : options,
  )
end

#register_type(type, klass, options = { packer: :to_msgpack_ext, unpacker: :from_msgpack_ext }) ⇒ Object

see ext for other methods

Raises:

  • (FrozenError)


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
# File 'lib/msgpack/factory.rb', line 5

def register_type(type, klass, options = { packer: :to_msgpack_ext, unpacker: :from_msgpack_ext })
  raise FrozenError, "can't modify frozen MessagePack::Factory" if frozen?

  if options
    options = options.dup
    case packer = options[:packer]
    when nil, Proc
      # all good
    when String, Symbol
      options[:packer] = packer.to_sym.to_proc
    when Method
      options[:packer] = packer.to_proc
    when packer.respond_to?(:call)
      options[:packer] = packer.method(:call).to_proc
    else
      raise ::TypeError, "expected :packer argument to be a callable object, got: #{packer.inspect}"
    end

    case unpacker = options[:unpacker]
    when nil, Proc
      # all good
    when String, Symbol
      options[:unpacker] = klass.method(unpacker).to_proc
    when Method
      options[:unpacker] = unpacker.to_proc
    when packer.respond_to?(:call)
      options[:unpacker] = unpacker.method(:call).to_proc
    else
      raise ::TypeError, "expected :unpacker argument to be a callable object, got: #{unpacker.inspect}"
    end
  end

  register_type_internal(type, klass, options)
end

#registered_types(selector = :both) ⇒ Object

id, class: Class(or nil), packer: arg, unpacker: arg, …


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
# File 'lib/msgpack/factory.rb', line 41

def registered_types(selector=:both)
  packer, unpacker = registered_types_internal
  # packer: Class -> [tid, proc, _flags]
  # unpacker: tid -> [klass, proc, _flags]

  list = []

  case selector
  when :both
    packer.each_pair do |klass, ary|
      type = ary[0]
      packer_proc = ary[1]
      unpacker_proc = nil
      if unpacker.has_key?(type)
        unpacker_proc = unpacker.delete(type)[1]
      end
      list << {type: type, class: klass, packer: packer_proc, unpacker: unpacker_proc}
    end

    # unpacker definition only
    unpacker.each_pair do |type, ary|
      list << {type: type, class: ary[0], packer: nil, unpacker: ary[1]}
    end

  when :packer
    packer.each_pair do |klass, ary|
      if ary[1]
        list << {type: ary[0], class: klass, packer: ary[1]}
      end
    end

  when :unpacker
    unpacker.each_pair do |type, ary|
      if ary[1]
        list << {type: type, class: ary[0], unpacker: ary[1]}
      end
    end

  else
    raise ArgumentError, "invalid selector #{selector}"
  end

  list.sort{|a, b| a[:type] <=> b[:type] }
end

#type_registered?(klass_or_type, selector = :both) ⇒ Boolean

Returns:

  • (Boolean)


86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/msgpack/factory.rb', line 86

def type_registered?(klass_or_type, selector=:both)
  case klass_or_type
  when Class
    klass = klass_or_type
    registered_types(selector).any?{|entry| klass <= entry[:class] }
  when Integer
    type = klass_or_type
    registered_types(selector).any?{|entry| type == entry[:type] }
  else
    raise ArgumentError, "class or type id"
  end
end

#unpacker(*args) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'ext/msgpack/factory_class.c', line 168

VALUE MessagePack_Factory_unpacker(int argc, VALUE* argv, VALUE self)
{
    msgpack_factory_t *fc = Factory_get(self);

    VALUE unpacker = MessagePack_Unpacker_alloc(cMessagePack_Unpacker);
    MessagePack_Unpacker_initialize(argc, argv, unpacker);

    msgpack_unpacker_t* uk = MessagePack_Unpacker_get(unpacker);
    msgpack_unpacker_ext_registry_borrow(fc->ukrg, &uk->ext_registry);
    uk->optimized_symbol_ext_type = fc->optimized_symbol_ext_type;
    uk->symbol_ext_type = fc->symbol_ext_type;

    return unpacker;
}