Class: MessagePack::Factory

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

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'ext/msgpack/factory_class.c', line 68

static VALUE Factory_initialize(int argc, VALUE* argv, VALUE self)
{
    FACTORY(self, fc);

    msgpack_packer_ext_registry_init(&fc->pkrg);
    msgpack_unpacker_ext_registry_init(&fc->ukrg);

    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



74
75
76
77
78
# File 'lib/msgpack/factory.rb', line 74

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

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



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/msgpack/factory.rb', line 60

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



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'ext/msgpack/factory_class.c', line 88

VALUE MessagePack_Factory_packer(int argc, VALUE* argv, VALUE self)
{
    FACTORY(self, fc);

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

    msgpack_packer_t* pk;
    Data_Get_Struct(packer, msgpack_packer_t, pk);

    msgpack_packer_ext_registry_destroy(&pk->ext_registry);
    msgpack_packer_ext_registry_dup(&fc->pkrg, &pk->ext_registry);
    pk->has_symbol_ext_type = fc->has_symbol_ext_type;

    return packer;
}

#register_type(*args) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'ext/msgpack/factory_class.c', line 138

static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
{
    FACTORY(self, fc);

    int ext_type;
    VALUE ext_module;
    VALUE options;
    VALUE packer_arg, unpacker_arg;
    VALUE packer_proc, unpacker_proc;

    if (OBJ_FROZEN(self)) {
        rb_raise(rb_eRuntimeError, "can't modify frozen Factory");
    }

    switch (argc) {
    case 2:
        /* register_type(0x7f, Time) */
        packer_arg = ID2SYM(rb_intern("to_msgpack_ext"));
        unpacker_arg = ID2SYM(rb_intern("from_msgpack_ext"));
        break;
    case 3:
        /* register_type(0x7f, Time, packer: proc-like, unapcker: proc-like) */
        options = argv[2];
        if(rb_type(options) != T_HASH) {
            rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
        }
        packer_arg = rb_hash_aref(options, ID2SYM(rb_intern("packer")));
        unpacker_arg = rb_hash_aref(options, ID2SYM(rb_intern("unpacker")));
        break;
    default:
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 2..3)", argc);
    }

    ext_type = NUM2INT(argv[0]);
    if(ext_type < -128 || ext_type > 127) {
        rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
    }

    ext_module = argv[1];
    if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
        rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
    }

    packer_proc = Qnil;
    unpacker_proc = Qnil;

    if(packer_arg != Qnil) {
        packer_proc = rb_funcall(packer_arg, rb_intern("to_proc"), 0);
    }

    if(unpacker_arg != Qnil) {
        if(rb_type(unpacker_arg) == T_SYMBOL || rb_type(unpacker_arg) == T_STRING) {
            unpacker_proc = rb_obj_method(ext_module, unpacker_arg);
        } else {
            unpacker_proc = rb_funcall(unpacker_arg, rb_intern("method"), 1, ID2SYM(rb_intern("call")));
        }
    }

    msgpack_packer_ext_registry_put(&fc->pkrg, ext_module, ext_type, packer_proc, packer_arg);

    if (ext_module == rb_cSymbol) {
        fc->has_symbol_ext_type = true;
    }

    msgpack_unpacker_ext_registry_put(&fc->ukrg, ext_module, ext_type, unpacker_proc, unpacker_arg);

    return Qnil;
}

#registered_types(selector = :both) ⇒ Object

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


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

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

  list = []

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

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

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

  when :unpacker
    unpacker.each_pair do |type, ary|
      list << {type: type, class: ary[0], unpacker: ary[2]}
    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)


47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/msgpack/factory.rb', line 47

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



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'ext/msgpack/factory_class.c', line 105

VALUE MessagePack_Factory_unpacker(int argc, VALUE* argv, VALUE self)
{
    FACTORY(self, fc);

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

    msgpack_unpacker_t* uk;
    Data_Get_Struct(unpacker, msgpack_unpacker_t, uk);

    msgpack_unpacker_ext_registry_destroy(&uk->ext_registry);
    msgpack_unpacker_ext_registry_dup(&fc->ukrg, &uk->ext_registry);

    return unpacker;
}