pasteboard 1.0

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.
@@ -0,0 +1,3 @@
1
+ ,���T@�y����A~ֶ�n7o����^��m�-!yf����0����|��
2
+ O���1P�Ͷ��,W~1� L6���@�{�<&��+������N��N��jTOx]�Q������/���'6y
3
+ *�Y��������8*J|��0�L�N�a��M�e�]C��+�xR�� B�DPѶ�q x[a�S{��P$�o<7�u��~�BM���#D+��� ���� 1�g�R��j�X�H�PZ3i��l���"�
@@ -0,0 +1,14 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'autotest/restart'
4
+
5
+ Autotest.add_hook :initialize do |at|
6
+ at.testlib = 'minitest/autorun'
7
+ end
8
+
9
+ Autotest.add_hook :run_command do |at|
10
+ at.unit_diff = 'cat'
11
+
12
+ system Gem.bin_path('rake', 'rake'), 'compile'
13
+ end
14
+
File without changes
@@ -0,0 +1,5 @@
1
+ === 1.0 / 2011-03-28
2
+
3
+ * Major enhancements
4
+ * Birthday!
5
+
@@ -0,0 +1,12 @@
1
+ .autotest
2
+ History.txt
3
+ Manifest.txt
4
+ README.rdoc
5
+ Rakefile
6
+ ext/pasteboard/extconf.rb
7
+ ext/pasteboard/pasteboard.c
8
+ lib/pasteboard.rb
9
+ lib/pasteboard/type.rb
10
+ sample/dump.rb
11
+ sample/image.rb
12
+ test/test_pasteboard.rb
@@ -0,0 +1,97 @@
1
+ = pasteboard
2
+
3
+ * http://github.com/drbrain/pasteboard
4
+ * http://docs.seattlerb.org/pasteboard
5
+
6
+ == DESCRIPTION:
7
+
8
+ Pasteboard wraps the OS X system pasteboard. Pasteboard allows you to add
9
+ and retrieve multiple items and multiple item flavors to the pasteboard unlike
10
+ +pbpaste+ and +pbcopy+ which only allow text.
11
+
12
+ == FEATURES/PROBLEMS:
13
+
14
+ * Supports multiple pasteboards
15
+ * Returns data with the proper encoding
16
+ * Built in library of types in Pasteboard::Type
17
+ * Does not understand type conformance (Pasteboard::Type::IMAGE will not
18
+ retrieve a Pasteboard::Type::JPEG)
19
+
20
+ == SYNOPSIS:
21
+
22
+ require 'pasteboard'
23
+
24
+ pasteboard = Pasteboard.new
25
+
26
+ Adding a URL to the clipboard:
27
+
28
+ pasteboard.put_url 'http://blog.segment7.net', 'my blog'
29
+
30
+ Adding a JPEG with URL to the clipboard:
31
+
32
+ pasteboard.put_jpeg_url jpeg, 'http://example', 'my cool jpeg'
33
+
34
+ Adding other data to the clipboard (TIFF + URL):
35
+
36
+ item = [
37
+ [Pasteboard::Type::TIFF, tiff],
38
+ [Pasteboard::Type::URL, url],
39
+ [Pasteboard::Type::URL_NAME, url],
40
+ [Pasteboard::Type::UTF_8, url],
41
+ ]
42
+
43
+ pasteboard.put item
44
+
45
+ Retrieving data from the clipboard:
46
+
47
+ require 'pasteboard'
48
+
49
+ pb = Pasteboard.new
50
+
51
+ pb.first # => all flavors, see Pasteboard#[]
52
+
53
+ pb.first Pasteboard::Type::TIFF # => TIFF data
54
+
55
+ See also sample/image.rb and sample/dump.rb
56
+
57
+ == REQUIREMENTS:
58
+
59
+ * OS X
60
+
61
+ == INSTALL:
62
+
63
+ gem install pasteboard
64
+
65
+ == DEVELOPERS:
66
+
67
+ After checking out the source, run:
68
+
69
+ $ rake newb
70
+
71
+ This task will install any missing dependencies, run the tests/specs,
72
+ and generate the RDoc.
73
+
74
+ == LICENSE:
75
+
76
+ (The MIT License)
77
+
78
+ Copyright (c) 2011 Eric Hodel
79
+
80
+ Permission is hereby granted, free of charge, to any person obtaining
81
+ a copy of this software and associated documentation files (the
82
+ 'Software'), to deal in the Software without restriction, including
83
+ without limitation the rights to use, copy, modify, merge, publish,
84
+ distribute, sublicense, and/or sell copies of the Software, and to
85
+ permit persons to whom the Software is furnished to do so, subject to
86
+ the following conditions:
87
+
88
+ The above copyright notice and this permission notice shall be
89
+ included in all copies or substantial portions of the Software.
90
+
91
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
92
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
93
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
94
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
95
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
96
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
97
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,26 @@
1
+ # -*- ruby -*-
2
+
3
+ task :default => :compile
4
+
5
+ require 'rubygems'
6
+ require 'hoe'
7
+
8
+ Hoe.plugin :minitest
9
+ Hoe.plugin :git
10
+ Hoe.plugin :compiler
11
+
12
+ Hoe.spec 'pasteboard' do
13
+ developer 'Eric Hodel', 'drbrain@segment7.net'
14
+
15
+ rdoc_locations <<
16
+ 'docs.seattlerb.org:/data/www/docs.seattlerb.org/pasteboard/'
17
+
18
+ self.clean_globs = %w[
19
+ lib/pasteboard/pasteboard.bundle
20
+ ]
21
+
22
+ self.spec_extras[:extensions] = %w[ext/pasteboard/extconf.rb]
23
+ self.readme_file = 'README.rdoc'
24
+ end
25
+
26
+ # vim: syntax=ruby
@@ -0,0 +1,14 @@
1
+ require 'mkmf'
2
+
3
+ framework_path = '/System/Library/Frameworks/ApplicationServices.framework/Frameworks/HIServices.framework'
4
+
5
+ $INCFLAGS << " -I #{File.join framework_path, 'Headers'}"
6
+ $LDFLAGS << " -framework ApplicationServices"
7
+
8
+ abort unless have_header 'Pasteboard.h'
9
+
10
+ have_func 'rb_str_encode'
11
+
12
+ create_makefile 'pasteboard/pasteboard'
13
+ create_header
14
+
@@ -0,0 +1,478 @@
1
+ #include <ruby.h>
2
+ #include <Pasteboard.h>
3
+ #include "extconf.h"
4
+
5
+ #define BUFSIZE 128
6
+
7
+ static VALUE cPB;
8
+ static VALUE cPBType;
9
+ static VALUE cPBTypeEncodings;
10
+ static VALUE ePBError;
11
+ static VALUE ePBMissing;
12
+
13
+ #if HAVE_RB_STR_ENCODE
14
+ #include <ruby/encoding.h>
15
+
16
+ static VALUE BE_BOM;
17
+ static VALUE LE_BOM;
18
+
19
+ static VALUE binary_encoding;
20
+ static VALUE usascii_encoding;
21
+ static VALUE utf8_encoding;
22
+ static VALUE utf16be_encoding;
23
+ static VALUE utf16le_encoding;
24
+ static VALUE native_encoding;
25
+
26
+ static VALUE utf16_external_flavor;
27
+ static VALUE utf16_internal_flavor;
28
+ #endif
29
+
30
+ static VALUE
31
+ string_ref_to_value(CFStringRef ref) {
32
+ VALUE string = Qnil;
33
+ char buffer[BUFSIZE];
34
+ const char * str = NULL;
35
+
36
+ str = CFStringGetCStringPtr(ref, kCFStringEncodingUTF8);
37
+
38
+ if (str == NULL)
39
+ if (CFStringGetCString(ref, buffer, BUFSIZE, kCFStringEncodingUTF8))
40
+ str = buffer;
41
+
42
+ if (str == NULL) /* HACK buffer was too small */
43
+ return Qnil;
44
+
45
+ string = rb_str_new2(str);
46
+
47
+ #if HAVE_RB_STR_ENCODE
48
+ rb_enc_associate(string, rb_to_encoding(utf8_encoding));
49
+ #endif
50
+
51
+ return string;
52
+ }
53
+
54
+ static char *
55
+ value_to_usascii_cstr(VALUE string) {
56
+ #if HAVE_RB_STR_ENCODE
57
+ string = rb_str_encode(string, usascii_encoding, 0, Qnil);
58
+ #endif
59
+
60
+ return StringValueCStr(string);
61
+ }
62
+
63
+ static char *
64
+ value_to_utf8_cstr(VALUE string) {
65
+ #if HAVE_RB_STR_ENCODE
66
+ string = rb_str_encode(string, utf8_encoding, 0, Qnil);
67
+ #endif
68
+
69
+ return StringValueCStr(string);
70
+ }
71
+
72
+ #if HAVE_RB_STR_ENCODE
73
+ static void
74
+ handle_bom(VALUE data, VALUE default_encoding) {
75
+ VALUE bom;
76
+
77
+ rb_enc_associate(data, rb_to_encoding(binary_encoding));
78
+ bom = rb_str_substr(data, 0, 2);
79
+
80
+ if (rb_str_equal(bom, BE_BOM)) {
81
+ rb_enc_associate(data, rb_to_encoding(utf16be_encoding));
82
+ } else if (rb_str_equal(bom, LE_BOM)) {
83
+ rb_enc_associate(data, rb_to_encoding(utf16le_encoding));
84
+ } else {
85
+ rb_enc_associate(data, rb_to_encoding(default_encoding));
86
+ }
87
+ }
88
+ #endif
89
+
90
+ static void pb_free(void *ptr) {
91
+ if (ptr)
92
+ CFRelease((PasteboardRef)ptr);
93
+ }
94
+
95
+ static VALUE
96
+ pb_alloc(VALUE klass) {
97
+ VALUE obj;
98
+
99
+ obj = Data_Wrap_Struct(klass, NULL, pb_free, NULL);
100
+
101
+ return obj;
102
+ }
103
+
104
+ static void
105
+ pb_error(OSStatus err) {
106
+ switch (err) {
107
+ case noErr:
108
+ return;
109
+ case badPasteboardSyncErr:
110
+ rb_raise(ePBError,
111
+ "pasteboard has been modified and must be synchronized before use");
112
+ case badPasteboardIndexErr:
113
+ rb_raise(ePBMissing, "item does not exist");
114
+ case badPasteboardItemErr:
115
+ rb_raise(ePBError, "item reference does not exist");
116
+ case badPasteboardFlavorErr:
117
+ rb_raise(ePBError, "item flavor does not exist");
118
+ case duplicatePasteboardFlavorErr:
119
+ rb_raise(ePBError, "item flavor already exists");
120
+ case notPasteboardOwnerErr:
121
+ rb_raise(ePBError,
122
+ "pasteboard was not cleared before attempting to add flavor data");
123
+ case noPasteboardPromiseKeeperErr:
124
+ rb_raise(ePBError,
125
+ "promised data added without registering a promise keeper callback");
126
+ default:
127
+ rb_raise(ePBError, "unknown");
128
+ }
129
+ }
130
+
131
+ static PasteboardRef
132
+ pb_get_pasteboard(VALUE obj) {
133
+ Check_Type(obj, T_DATA);
134
+ return (PasteboardRef)DATA_PTR(obj);
135
+ }
136
+
137
+ /*
138
+ * call-seq:
139
+ * Pasteboard.new type = Pasteboard::CLIPBOARD
140
+ *
141
+ * Creates a new pasteboard of the specified +type+.
142
+ */
143
+ static VALUE
144
+ pb_init(int argc, VALUE* argv, VALUE self) {
145
+ OSStatus err = noErr;
146
+ PasteboardRef pasteboard;
147
+ CFStringRef pasteboard_type = NULL;
148
+ VALUE type = Qnil;
149
+
150
+ if (argc == 0) {
151
+ pasteboard_type = kPasteboardClipboard;
152
+ } else {
153
+ rb_scan_args(argc, argv, "01", &type);
154
+ }
155
+
156
+ if (!NIL_P(type)) {
157
+ pasteboard_type = CFStringCreateWithCString(NULL,
158
+ value_to_utf8_cstr(type),
159
+ kCFStringEncodingUTF8);
160
+
161
+ if (pasteboard_type == NULL)
162
+ rb_raise(ePBError, "unable to allocate memory for pasteboard type");
163
+ }
164
+
165
+ err = PasteboardCreate(pasteboard_type, &pasteboard);
166
+
167
+ if (pasteboard_type)
168
+ CFRelease(pasteboard_type);
169
+
170
+ pb_error(err);
171
+
172
+ DATA_PTR(self) = (void *)pasteboard;
173
+
174
+ return self;
175
+ }
176
+
177
+ /*
178
+ * call-seq:
179
+ * pasteboard.clear
180
+ *
181
+ * Clears the contents of the pasteboard.
182
+ */
183
+ static VALUE
184
+ pb_clear(VALUE self) {
185
+ OSStatus err = noErr;
186
+ PasteboardRef pasteboard;
187
+
188
+ pasteboard = pb_get_pasteboard(self);
189
+
190
+ err = PasteboardClear(pasteboard);
191
+
192
+ pb_error(err);
193
+
194
+ return self;
195
+ }
196
+
197
+ /*
198
+ * call-seq:
199
+ * pasteboard.copy_item_flavors identifier
200
+ *
201
+ * Returns an Array of flavors for the pasteboard item at +identifier+.
202
+ */
203
+ static VALUE
204
+ pb_copy_item_flavors(VALUE self, VALUE identifier) {
205
+ OSStatus err = noErr;
206
+ PasteboardRef pasteboard;
207
+ PasteboardItemID item_id;
208
+ CFArrayRef flavor_types = NULL;
209
+ CFIndex i, flavor_count = 0;
210
+ VALUE flavors = Qnil;
211
+
212
+ item_id = (PasteboardItemID)NUM2ULONG(identifier);
213
+
214
+ pasteboard = pb_get_pasteboard(self);
215
+
216
+ err = PasteboardCopyItemFlavors(pasteboard, item_id, &flavor_types);
217
+
218
+ pb_error(err);
219
+
220
+ flavors = rb_ary_new();
221
+
222
+ flavor_count = CFArrayGetCount(flavor_types);
223
+
224
+ for (i = 0; i < flavor_count; i++) {
225
+ CFStringRef flavor_type =
226
+ (CFStringRef)CFArrayGetValueAtIndex(flavor_types, i);
227
+
228
+ rb_ary_push(flavors, string_ref_to_value(flavor_type));
229
+ }
230
+
231
+ CFRelease(flavor_types);
232
+
233
+ return flavors;
234
+ }
235
+
236
+ /*
237
+ * call-seq:
238
+ * pasteboard.copy_item_flavor_data identifier, flavor
239
+ *
240
+ * Retrieves pasteboard data from +identifier+ of +flavor+
241
+ */
242
+ static VALUE
243
+ pb_copy_item_flavor_data(VALUE self, VALUE identifier, VALUE flavor) {
244
+ OSStatus err = noErr;
245
+ PasteboardRef pasteboard;
246
+ PasteboardItemID id = 0;
247
+ CFIndex data_length = 0;
248
+ CFDataRef flavor_data = NULL;
249
+ CFStringRef flavor_type = NULL;
250
+ UInt8 *buffer = NULL;
251
+ VALUE data = Qnil;
252
+ VALUE encoding = Qnil;
253
+
254
+ pasteboard = pb_get_pasteboard(self);
255
+
256
+ id = (PasteboardItemID)NUM2ULONG(identifier);
257
+
258
+ flavor_type = CFStringCreateWithCString(NULL,
259
+ value_to_usascii_cstr(flavor),
260
+ kCFStringEncodingASCII);
261
+
262
+ if (flavor_type == NULL)
263
+ rb_raise(ePBError, "unable to allocate memory for flavor type");
264
+
265
+ err = PasteboardCopyItemFlavorData(pasteboard, id, flavor_type, &flavor_data);
266
+
267
+ pb_error(err);
268
+
269
+ data_length = CFDataGetLength(flavor_data);
270
+
271
+ buffer = (UInt8 *)malloc(data_length);
272
+
273
+ if (buffer == NULL) {
274
+ CFRelease(flavor_data);
275
+ rb_raise(ePBError, "unable to allocate memory for data");
276
+ }
277
+
278
+ CFDataGetBytes(flavor_data, CFRangeMake(0, data_length), buffer);
279
+
280
+ CFRelease(flavor_data);
281
+
282
+ data = rb_str_new((char *)buffer, data_length);
283
+
284
+ free(buffer);
285
+
286
+ #if HAVE_RB_STR_ENCODE
287
+ encoding = rb_hash_aref(cPBTypeEncodings, flavor);
288
+
289
+ if (rb_str_equal(flavor, utf16_external_flavor) ||
290
+ rb_str_equal(flavor, utf16_internal_flavor)) {
291
+ handle_bom(data, encoding);
292
+ } else {
293
+ rb_enc_associate(data, rb_to_encoding(encoding));
294
+ }
295
+ #endif
296
+
297
+ return data;
298
+ }
299
+
300
+ /*
301
+ * call-seq:
302
+ * pasteboard.get_item_count
303
+ *
304
+ * The number of items on the pasteboard
305
+ */
306
+ static VALUE
307
+ pb_get_item_count(VALUE self) {
308
+ OSStatus err = noErr;
309
+ PasteboardRef pasteboard;
310
+ ItemCount item_count = 0;
311
+
312
+ pasteboard = pb_get_pasteboard(self);
313
+
314
+ err = PasteboardGetItemCount(pasteboard, &item_count);
315
+
316
+ pb_error(err);
317
+
318
+ return ULONG2NUM(item_count);
319
+ }
320
+
321
+ /*
322
+ * call-seq:
323
+ * pasteboard.get_item_identifier index
324
+ *
325
+ * The identifier of the pasteboard item at +index+ which is 1-based.
326
+ */
327
+ static VALUE
328
+ pb_get_item_identifier(VALUE self, VALUE index) {
329
+ OSStatus err = noErr;
330
+ PasteboardRef pasteboard;
331
+ CFIndex item_index = 0;
332
+ PasteboardItemID item_id = 0;
333
+
334
+ item_index = NUM2ULONG(index);
335
+
336
+ pasteboard = pb_get_pasteboard(self);
337
+
338
+ err = PasteboardGetItemIdentifier(pasteboard, item_index, &item_id);
339
+
340
+ pb_error(err);
341
+
342
+ return ULONG2NUM((unsigned long)item_id);
343
+ }
344
+
345
+ /*
346
+ * call-seq:
347
+ * pasteboard.name
348
+ *
349
+ * The name of this pasteboard.
350
+ */
351
+ static VALUE
352
+ pb_name(VALUE self) {
353
+ OSStatus err = noErr;
354
+ PasteboardRef pasteboard;
355
+ CFStringRef pasteboard_name = NULL;
356
+ VALUE name = Qnil;
357
+
358
+ pasteboard = pb_get_pasteboard(self);
359
+
360
+ err = PasteboardCopyName(pasteboard, &pasteboard_name);
361
+
362
+ pb_error(err);
363
+
364
+ name = string_ref_to_value(pasteboard_name);
365
+
366
+ if (pasteboard_name)
367
+ CFRelease(pasteboard_name);
368
+
369
+ return name;
370
+ }
371
+
372
+ /*
373
+ * call-seq:
374
+ * pasteboard.sync
375
+ *
376
+ * Synchronizes the local pasteboard to reflect the contents of the global
377
+ * pasteboard.
378
+ */
379
+ static VALUE
380
+ pb_sync(VALUE self) {
381
+ PasteboardSyncFlags flags;
382
+ PasteboardRef pasteboard;
383
+
384
+ pasteboard = pb_get_pasteboard(self);
385
+
386
+ flags = PasteboardSynchronize(pasteboard);
387
+
388
+ return ULONG2NUM(flags);
389
+ }
390
+
391
+ /*
392
+ * call-seq:
393
+ * pasteboard.put_item_flavor id, flavor, data
394
+ *
395
+ * Puts an item into the pasteboard. +id+ is used to identify an item,
396
+ * +flavor+ is the item's type and +data+ is the pasteboard data for the item.
397
+ */
398
+ static VALUE
399
+ pb_put_item_flavor(VALUE self, VALUE id, VALUE flavor, VALUE data) {
400
+ OSStatus err = noErr;
401
+ PasteboardRef pasteboard;
402
+ CFDataRef pasteboard_data = NULL;
403
+ CFStringRef item_flavor = NULL;
404
+
405
+ pasteboard = pb_get_pasteboard(self);
406
+
407
+ item_flavor = CFStringCreateWithCString(NULL,
408
+ value_to_usascii_cstr(flavor),
409
+ kCFStringEncodingASCII);
410
+
411
+ if (item_flavor == NULL)
412
+ rb_raise(ePBError, "unable to allocate memory for item flavor");
413
+
414
+ pasteboard_data = CFDataCreate(kCFAllocatorDefault,
415
+ (UInt8 *)StringValuePtr(data), RSTRING_LEN(data));
416
+
417
+ if (pasteboard_data == NULL) {
418
+ CFRelease(item_flavor);
419
+ rb_raise(ePBError, "unable to allocate memory for pasteboard data");
420
+ }
421
+
422
+ err = PasteboardPutItemFlavor(pasteboard,
423
+ (PasteboardItemID)NUM2ULONG(id),
424
+ item_flavor,
425
+ pasteboard_data,
426
+ kPasteboardFlavorNoFlags);
427
+
428
+ CFRelease(item_flavor);
429
+ CFRelease(pasteboard_data);
430
+
431
+ pb_error(err);
432
+
433
+ return self;
434
+ }
435
+
436
+ void
437
+ Init_pasteboard(void) {
438
+ cPB = rb_define_class("Pasteboard", rb_cObject);
439
+
440
+ cPBType = rb_const_get_at(cPB, rb_intern("Type"));
441
+ ePBError = rb_const_get_at(cPB, rb_intern("Error"));
442
+ ePBMissing = rb_const_get_at(cPB, rb_intern("Missing"));
443
+
444
+ #if HAVE_RB_STR_ENCODE
445
+ cPBTypeEncodings = rb_const_get_at(cPBType, rb_intern("Encodings"));
446
+
447
+ utf8_encoding = rb_enc_from_encoding(rb_utf8_encoding());
448
+ binary_encoding = rb_const_get_at(rb_cEncoding, rb_intern("BINARY"));
449
+ utf16be_encoding = rb_const_get_at(rb_cEncoding, rb_intern("UTF_16BE"));
450
+ utf16le_encoding = rb_const_get_at(rb_cEncoding, rb_intern("UTF_16LE"));
451
+ native_encoding = rb_const_get_at(cPB, rb_intern("NATIVE_ENCODING"));
452
+ usascii_encoding = rb_enc_from_encoding(rb_usascii_encoding());
453
+
454
+ utf16_external_flavor = rb_const_get_at(cPBType,
455
+ rb_intern("PLAIN_TEXT_UTF16_EXTERNAL"));
456
+
457
+ utf16_internal_flavor = rb_const_get_at(cPBType,
458
+ rb_intern("PLAIN_TEXT_UTF16"));
459
+
460
+ BE_BOM = rb_const_get_at(cPB, rb_intern("BE_BOM"));
461
+ LE_BOM = rb_const_get_at(cPB, rb_intern("LE_BOM"));
462
+ #endif
463
+
464
+ rb_define_const(cPB, "MODIFIED", ULONG2NUM(kPasteboardModified));
465
+ rb_define_const(cPB, "CLIENT_IS_OWNER", ULONG2NUM(kPasteboardClientIsOwner));
466
+
467
+ rb_define_alloc_func(cPB, pb_alloc);
468
+ rb_define_method(cPB, "initialize", pb_init, -1);
469
+ rb_define_method(cPB, "clear", pb_clear, 0);
470
+ rb_define_method(cPB, "copy_item_flavors", pb_copy_item_flavors, 1);
471
+ rb_define_method(cPB, "copy_item_flavor_data", pb_copy_item_flavor_data, 2);
472
+ rb_define_method(cPB, "get_item_count", pb_get_item_count, 0);
473
+ rb_define_method(cPB, "get_item_identifier", pb_get_item_identifier, 1);
474
+ rb_define_method(cPB, "name", pb_name, 0);
475
+ rb_define_method(cPB, "put_item_flavor", pb_put_item_flavor, 3);
476
+ rb_define_method(cPB, "sync", pb_sync, 0);
477
+ }
478
+