pasteboard 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+