rdavila-rugged 0.24.0b13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +619 -0
  4. data/ext/rugged/extconf.rb +105 -0
  5. data/ext/rugged/rugged.c +527 -0
  6. data/ext/rugged/rugged.h +185 -0
  7. data/ext/rugged/rugged_backend.c +34 -0
  8. data/ext/rugged/rugged_blame.c +292 -0
  9. data/ext/rugged/rugged_blob.c +638 -0
  10. data/ext/rugged/rugged_branch.c +195 -0
  11. data/ext/rugged/rugged_branch_collection.c +408 -0
  12. data/ext/rugged/rugged_commit.c +691 -0
  13. data/ext/rugged/rugged_config.c +404 -0
  14. data/ext/rugged/rugged_cred.c +148 -0
  15. data/ext/rugged/rugged_diff.c +686 -0
  16. data/ext/rugged/rugged_diff_delta.c +105 -0
  17. data/ext/rugged/rugged_diff_hunk.c +103 -0
  18. data/ext/rugged/rugged_diff_line.c +83 -0
  19. data/ext/rugged/rugged_index.c +1255 -0
  20. data/ext/rugged/rugged_note.c +376 -0
  21. data/ext/rugged/rugged_object.c +383 -0
  22. data/ext/rugged/rugged_patch.c +245 -0
  23. data/ext/rugged/rugged_reference.c +396 -0
  24. data/ext/rugged/rugged_reference_collection.c +446 -0
  25. data/ext/rugged/rugged_remote.c +691 -0
  26. data/ext/rugged/rugged_remote_collection.c +457 -0
  27. data/ext/rugged/rugged_repo.c +2669 -0
  28. data/ext/rugged/rugged_revwalk.c +495 -0
  29. data/ext/rugged/rugged_settings.c +155 -0
  30. data/ext/rugged/rugged_signature.c +106 -0
  31. data/ext/rugged/rugged_submodule.c +852 -0
  32. data/ext/rugged/rugged_submodule_collection.c +384 -0
  33. data/ext/rugged/rugged_tag.c +251 -0
  34. data/ext/rugged/rugged_tag_collection.c +347 -0
  35. data/ext/rugged/rugged_tree.c +919 -0
  36. data/lib/rugged.rb +23 -0
  37. data/lib/rugged/attributes.rb +41 -0
  38. data/lib/rugged/blob.rb +28 -0
  39. data/lib/rugged/branch.rb +19 -0
  40. data/lib/rugged/commit.rb +54 -0
  41. data/lib/rugged/console.rb +9 -0
  42. data/lib/rugged/credentials.rb +43 -0
  43. data/lib/rugged/diff.rb +20 -0
  44. data/lib/rugged/diff/delta.rb +53 -0
  45. data/lib/rugged/diff/hunk.rb +18 -0
  46. data/lib/rugged/diff/line.rb +47 -0
  47. data/lib/rugged/index.rb +13 -0
  48. data/lib/rugged/object.rb +7 -0
  49. data/lib/rugged/patch.rb +36 -0
  50. data/lib/rugged/reference.rb +7 -0
  51. data/lib/rugged/remote.rb +4 -0
  52. data/lib/rugged/repository.rb +227 -0
  53. data/lib/rugged/submodule_collection.rb +48 -0
  54. data/lib/rugged/tag.rb +50 -0
  55. data/lib/rugged/tree.rb +38 -0
  56. data/lib/rugged/version.rb +3 -0
  57. data/lib/rugged/walker.rb +5 -0
  58. metadata +146 -0
@@ -0,0 +1,638 @@
1
+ /*
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2014 GitHub, Inc
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ * THE SOFTWARE.
23
+ */
24
+
25
+ #include "rugged.h"
26
+ #include <ctype.h>
27
+ #include <git2/sys/hashsig.h>
28
+
29
+ extern VALUE rb_mRugged;
30
+ extern VALUE rb_cRuggedObject;
31
+ extern VALUE rb_cRuggedRepo;
32
+ static ID id_read;
33
+
34
+ VALUE rb_cRuggedBlob;
35
+ VALUE rb_cRuggedBlobSig;
36
+
37
+ /*
38
+ * call-seq:
39
+ * blob.text(max_lines = -1, encoding = Encoding.default_external) -> string
40
+ *
41
+ * Return up to +max_lines+ of text from a blob as a +String+.
42
+ * If +max_lines+ is less than 0, the full string is returned.
43
+ *
44
+ * The string is created with the given +encoding+, defaulting to
45
+ * Encoding.default_external.
46
+ *
47
+ * When limiting the size of the text with +max_lines+, the string is
48
+ * expected to have an ASCII-compatible encoding, and is checked
49
+ * for the newline +\n+ character.
50
+ */
51
+ static VALUE rb_git_blob_text_GET(int argc, VALUE *argv, VALUE self)
52
+ {
53
+ git_blob *blob;
54
+ size_t size;
55
+ const char *content;
56
+ VALUE rb_max_lines, rb_encoding;
57
+
58
+ Data_Get_Struct(self, git_blob, blob);
59
+ rb_scan_args(argc, argv, "02", &rb_max_lines, &rb_encoding);
60
+
61
+ content = git_blob_rawcontent(blob);
62
+ size = git_blob_rawsize(blob);
63
+
64
+ if (!NIL_P(rb_max_lines)) {
65
+ size_t i = 0;
66
+ int lines = 0, maxlines;
67
+
68
+ Check_Type(rb_max_lines, T_FIXNUM);
69
+ maxlines = FIX2INT(rb_max_lines);
70
+
71
+ if (maxlines >= 0) {
72
+ while (i < size && lines < maxlines) {
73
+ if (content[i++] == '\n')
74
+ lines++;
75
+ }
76
+ size = (size_t)i;
77
+ }
78
+
79
+ }
80
+
81
+ if (!NIL_P(rb_encoding)) {
82
+ return rb_enc_str_new(content, size, rb_to_encoding(rb_encoding));
83
+ }
84
+
85
+ return rb_external_str_new(content, size);
86
+ }
87
+
88
+ /*
89
+ * call-seq:
90
+ * blob.content(max_bytes=-1) -> string
91
+ *
92
+ * Return up to +max_bytes+ from the contents of a blob as bytes +String+.
93
+ * If +max_bytes+ is less than 0, the full string is returned.
94
+ *
95
+ * This string is tagged with the ASCII-8BIT encoding: the bytes are
96
+ * returned as-is, since Git is encoding agnostic.
97
+ */
98
+ static VALUE rb_git_blob_content_GET(int argc, VALUE *argv, VALUE self)
99
+ {
100
+ git_blob *blob;
101
+ size_t size;
102
+ const char *content;
103
+ VALUE rb_max_bytes;
104
+
105
+ Data_Get_Struct(self, git_blob, blob);
106
+ rb_scan_args(argc, argv, "01", &rb_max_bytes);
107
+
108
+ content = git_blob_rawcontent(blob);
109
+ size = git_blob_rawsize(blob);
110
+
111
+ if (!NIL_P(rb_max_bytes)) {
112
+ int maxbytes;
113
+
114
+ Check_Type(rb_max_bytes, T_FIXNUM);
115
+ maxbytes = FIX2INT(rb_max_bytes);
116
+
117
+ if (maxbytes >= 0 && (size_t)maxbytes < size)
118
+ size = (size_t)maxbytes;
119
+ }
120
+
121
+ /*
122
+ * since we don't really ever know the encoding of a blob
123
+ * lets default to the binary encoding (ascii-8bit)
124
+ */
125
+ return rb_str_new(content, size);
126
+ }
127
+
128
+ /*
129
+ * call-seq:
130
+ * blob.rawsize -> int
131
+ *
132
+ * Return the size in bytes of the blob. This is the real,
133
+ * uncompressed size and the length of +blob.content+, not
134
+ * the compressed size.
135
+ */
136
+ static VALUE rb_git_blob_rawsize(VALUE self)
137
+ {
138
+ git_blob *blob;
139
+ Data_Get_Struct(self, git_blob, blob);
140
+
141
+ return INT2FIX(git_blob_rawsize(blob));
142
+ }
143
+
144
+ /*
145
+ * call-seq:
146
+ * Blob.from_buffer(repository, buffer) -> oid
147
+ *
148
+ * Write a blob to +repository+ with the contents specified
149
+ * in +buffer+, where +buffer+ is a +String+.
150
+ * The encoding of +buffer+ is ignored and bytes are copied as-is.
151
+ */
152
+ static VALUE rb_git_blob_from_buffer(VALUE self, VALUE rb_repo, VALUE rb_buffer)
153
+ {
154
+ int error;
155
+ git_oid oid;
156
+ git_repository *repo;
157
+
158
+ Check_Type(rb_buffer, T_STRING);
159
+ rugged_check_repo(rb_repo);
160
+
161
+ Data_Get_Struct(rb_repo, git_repository, repo);
162
+
163
+ error = git_blob_create_frombuffer(&oid, repo, RSTRING_PTR(rb_buffer), RSTRING_LEN(rb_buffer));
164
+ rugged_exception_check(error);
165
+
166
+ return rugged_create_oid(&oid);
167
+ }
168
+
169
+ /*
170
+ * call-seq:
171
+ * Blob.from_workdir(repository, file_path) -> oid
172
+ *
173
+ * Write the file specified in +file_path+ to a blob in +repository+.
174
+ * +file_path+ must be relative to the repository's working folder.
175
+ * The repository cannot be bare.
176
+ *
177
+ * Blob.from_workdir(repo, 'src/blob.h') #=> '9d09060c850defbc7711d08b57def0d14e742f4e'
178
+ */
179
+ static VALUE rb_git_blob_from_workdir(VALUE self, VALUE rb_repo, VALUE rb_path)
180
+ {
181
+ int error;
182
+ git_oid oid;
183
+ git_repository *repo;
184
+
185
+ Check_Type(rb_path, T_STRING);
186
+ rugged_check_repo(rb_repo);
187
+
188
+ Data_Get_Struct(rb_repo, git_repository, repo);
189
+
190
+ error = git_blob_create_fromworkdir(&oid, repo, StringValueCStr(rb_path));
191
+ rugged_exception_check(error);
192
+
193
+ return rugged_create_oid(&oid);
194
+ }
195
+
196
+ /*
197
+ * call-seq:
198
+ * Blob.from_disk(repository, file_path) -> oid
199
+ *
200
+ * Write the file specified in +file_path+ to a blob in +repository+.
201
+ * The repository can be bare or not.
202
+ *
203
+ * Example:
204
+ *
205
+ * Blob.from_disk(repo, '/var/repos/blob.h') #=> '5b5b025afb0b4c913b4c338a42934a3863bf3643'
206
+ */
207
+ static VALUE rb_git_blob_from_disk(VALUE self, VALUE rb_repo, VALUE rb_path)
208
+ {
209
+ int error;
210
+ git_oid oid;
211
+ git_repository *repo;
212
+
213
+ Check_Type(rb_path, T_STRING);
214
+ rugged_check_repo(rb_repo);
215
+
216
+ Data_Get_Struct(rb_repo, git_repository, repo);
217
+
218
+ error = git_blob_create_fromdisk(&oid, repo, StringValueCStr(rb_path));
219
+ rugged_exception_check(error);
220
+
221
+ return rugged_create_oid(&oid);
222
+ }
223
+
224
+ static VALUE rb_read_check(VALUE pointer) {
225
+ VALUE *args = (VALUE *)pointer;
226
+ VALUE rb_buffer = rb_funcall(args[0], id_read, 1, args[1]);
227
+
228
+ if (!NIL_P(rb_buffer))
229
+ Check_Type(rb_buffer, T_STRING);
230
+
231
+ return rb_buffer;
232
+ }
233
+
234
+ static int cb_blob__get__chunk(char *content, size_t max_length, void *data)
235
+ {
236
+ VALUE rb_buffer, rb_args[2];
237
+ size_t str_len, safe_len;
238
+ struct rugged_cb_payload *payload = data;
239
+
240
+ rb_args[0] = payload->rb_data;
241
+ rb_args[1] = INT2FIX(max_length);
242
+
243
+ rb_buffer = rb_protect(rb_read_check, (VALUE)rb_args, &payload->exception);
244
+
245
+ if (payload->exception)
246
+ return GIT_ERROR;
247
+
248
+ if (NIL_P(rb_buffer))
249
+ return 0;
250
+
251
+ str_len = (size_t)RSTRING_LEN(rb_buffer);
252
+ safe_len = str_len > max_length ? max_length : str_len;
253
+ memcpy(content, StringValuePtr(rb_buffer), safe_len);
254
+
255
+ return (int)safe_len;
256
+ }
257
+
258
+ /*
259
+ * call-seq:
260
+ * Blob.from_io(repository, io [, hint_path]) -> oid
261
+ *
262
+ * Write a loose blob to the +repository+ from an +IO+ provider
263
+ * of data.
264
+ *
265
+ * The repository can be bare or not.
266
+ *
267
+ * The data provider +io+ should respond to a <code>read(size)</code>
268
+ * method. Generally any instance of a class based on Ruby's +IO+ class
269
+ * should work(ex. +File+). On each +read+ call it should
270
+ * return a +String+ with maximum size of +size+.
271
+ *
272
+ * *NOTE:* If an exception is raised in the +io+ object's
273
+ * +read+ method, no blob will be created.
274
+ *
275
+ * Provided the +hint_path+ parameter is given, its value
276
+ * will help to determine what git filters should be applied
277
+ * to the object before it can be placed to the object database.
278
+ *
279
+ * File.open('/path/to/file') do |file|
280
+ * Blob.from_io(repo, file, 'hint/blob.h') #=> '42cab3c0cde61e2b5a2392e1eadbeffa20ffa171'
281
+ * end
282
+ */
283
+ static VALUE rb_git_blob_from_io(int argc, VALUE *argv, VALUE klass)
284
+ {
285
+ VALUE rb_repo, rb_io, rb_hint_path;
286
+ struct rugged_cb_payload payload;
287
+ const char * hint_path = NULL;
288
+
289
+ int error;
290
+ git_oid oid;
291
+ git_repository *repo;
292
+
293
+ rb_scan_args(argc, argv, "21", &rb_repo, &rb_io, &rb_hint_path);
294
+
295
+ rugged_check_repo(rb_repo);
296
+ Data_Get_Struct(rb_repo, git_repository, repo);
297
+
298
+ if (!NIL_P(rb_hint_path)) {
299
+ Check_Type(rb_hint_path, T_STRING);
300
+ hint_path = StringValueCStr(rb_hint_path);
301
+ }
302
+
303
+ payload.exception = 0;
304
+ payload.rb_data = rb_io;
305
+
306
+ error = git_blob_create_fromchunks(
307
+ &oid,
308
+ repo,
309
+ hint_path,
310
+ cb_blob__get__chunk,
311
+ (void *)&payload);
312
+
313
+ if (payload.exception)
314
+ rb_jump_tag(payload.exception);
315
+ rugged_exception_check(error);
316
+
317
+ return rugged_create_oid(&oid);
318
+ }
319
+
320
+ /*
321
+ * call-seq:
322
+ * blob.loc -> int
323
+ *
324
+ * Return the number of lines for this blob,
325
+ * assuming the blob is plaintext (i.e. not binary)
326
+ */
327
+ static VALUE rb_git_blob_loc(VALUE self)
328
+ {
329
+ git_blob *blob;
330
+ const char *data, *data_end;
331
+ size_t loc = 0;
332
+
333
+ Data_Get_Struct(self, git_blob, blob);
334
+
335
+ data = git_blob_rawcontent(blob);
336
+ data_end = data + git_blob_rawsize(blob);
337
+
338
+ if (data == data_end)
339
+ return INT2FIX(0);
340
+
341
+ for (; data < data_end; ++data) {
342
+ if (data[0] == '\n') {
343
+ loc++;
344
+ }
345
+ else if (data[0] == '\r') {
346
+ if (data + 1 < data_end && data[1] == '\n')
347
+ data++;
348
+ loc++;
349
+ }
350
+ }
351
+
352
+ if (data[-1] != '\n' && data[-1] != '\r')
353
+ loc++;
354
+
355
+ return INT2FIX(loc);
356
+ }
357
+
358
+
359
+ /*
360
+ * call-seq:
361
+ * blob.sloc -> int
362
+ *
363
+ * Return the number of non-empty code lines for the blob,
364
+ * assuming the blob is plaintext (i.e. not binary)
365
+ */
366
+ static VALUE rb_git_blob_sloc(VALUE self)
367
+ {
368
+ git_blob *blob;
369
+ const char *data, *data_end;
370
+ size_t sloc = 0;
371
+
372
+ Data_Get_Struct(self, git_blob, blob);
373
+
374
+ data = git_blob_rawcontent(blob);
375
+ data_end = data + git_blob_rawsize(blob);
376
+
377
+ if (data == data_end)
378
+ return INT2FIX(0);
379
+
380
+ /* go through the whole blob, counting lines
381
+ * that are not empty */
382
+ while (data < data_end) {
383
+ if (*data++ == '\n') {
384
+ while (data < data_end && isspace(*data))
385
+ data++;
386
+
387
+ sloc++;
388
+ }
389
+ }
390
+
391
+ /* last line without trailing '\n'? */
392
+ if (data[-1] != '\n')
393
+ sloc++;
394
+
395
+ return INT2FIX(sloc);
396
+ }
397
+
398
+ /*
399
+ * call-seq:
400
+ * blob.binary? -> true or false
401
+ *
402
+ * Determine if the blob content is most certainly binary or not.
403
+ *
404
+ * The heuristic used to guess if a file is binary is taken from core git:
405
+ * Searching for NUL bytes and looking for a reasonable ratio of printable
406
+ * to non-printable characters among the first 4000 bytes.
407
+ *
408
+ */
409
+ static VALUE rb_git_blob_is_binary(VALUE self)
410
+ {
411
+ git_blob *blob;
412
+ Data_Get_Struct(self, git_blob, blob);
413
+ return git_blob_is_binary(blob) ? Qtrue : Qfalse;
414
+ }
415
+
416
+ /*
417
+ * call-seq:
418
+ * blob.diff(other, options = {}) -> patch
419
+ *
420
+ * Directly generate a Rugged::Patch from the difference between +blob+ and +other+.
421
+ *
422
+ * +other+ can either be another Rugged::Blob instance, a string,
423
+ * or nil (treated as an empty blob).
424
+ *
425
+ * The following options can be passed in the +options+ Hash:
426
+ *
427
+ * :max_size ::
428
+ * An integer specifying the maximum byte size of a blob before a it will
429
+ * be treated as binary. The default value is 512MB.
430
+ *
431
+ * :context_lines ::
432
+ * The number of unchanged lines that define the boundary of a hunk (and
433
+ * to display before and after the actual changes). The default is 3.
434
+ *
435
+ * :interhunk_lines ::
436
+ * The maximum number of unchanged lines between hunk boundaries before the hunks
437
+ * will be merged into a one. The default is 0.
438
+ *
439
+ * :reverse ::
440
+ * If true, the sides of the diff will be reversed.
441
+ *
442
+ * :force_text ::
443
+ * If true, all files will be treated as text, disabling binary attributes & detection.
444
+ *
445
+ * :ignore_whitespace ::
446
+ * If true, all whitespace will be ignored.
447
+ *
448
+ * :ignore_whitespace_change ::
449
+ * If true, changes in amount of whitespace will be ignored.
450
+ *
451
+ * :ignore_whitespace_eol ::
452
+ * If true, whitespace at end of line will be ignored.
453
+ *
454
+ * :patience ::
455
+ * If true, the "patience diff" algorithm will be used (currently unimplemented).
456
+ *
457
+ * :skip_binary_check ::
458
+ * If true, diff deltas will be generated without spending time on binary
459
+ * detection. This is useful to improve performance in cases where the actual
460
+ * file content difference is not needed.
461
+ *
462
+ * :old_path ::
463
+ * An optional string to treat +blob+ as if it had this filename.
464
+ *
465
+ * :new_path ::
466
+ * An optional string to treat +other+ as if it had this filename.
467
+ */
468
+ static VALUE rb_git_blob_diff(int argc, VALUE *argv, VALUE self)
469
+ {
470
+ git_blob *blob;
471
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
472
+ git_patch *patch;
473
+ const char *old_path = NULL, *new_path = NULL;
474
+ VALUE rb_other, rb_options;
475
+ int error;
476
+
477
+ rb_scan_args(argc, argv, "10:", &rb_other, &rb_options);
478
+ if (!NIL_P(rb_options)) {
479
+ VALUE rb_value;
480
+
481
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("old_path"));
482
+ if (!NIL_P(rb_value)) {
483
+ Check_Type(rb_value, T_STRING);
484
+ old_path = StringValueCStr(rb_value);
485
+ }
486
+
487
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("new_path"));
488
+ if (!NIL_P(rb_value)) {
489
+ Check_Type(rb_value, T_STRING);
490
+ new_path = StringValueCStr(rb_value);
491
+ }
492
+
493
+ rugged_parse_diff_options(&opts, rb_options);
494
+ }
495
+
496
+ Data_Get_Struct(self, git_blob, blob);
497
+
498
+ if (NIL_P(rb_other)) {
499
+ error = git_patch_from_blobs(&patch, blob, old_path, NULL, new_path, &opts);
500
+ } else if (rb_obj_is_kind_of(rb_other, rb_cRuggedBlob)) {
501
+ git_blob *other_blob;
502
+
503
+ Data_Get_Struct(rb_other, git_blob, other_blob);
504
+
505
+ error = git_patch_from_blobs(&patch, blob, old_path, other_blob, new_path, &opts);
506
+ } else if (TYPE(rb_other) == T_STRING) {
507
+ const char * buffer = StringValueCStr(rb_other);
508
+
509
+ error = git_patch_from_blob_and_buffer(&patch, blob, old_path, buffer, RSTRING_LEN(rb_other), new_path, &opts);
510
+ } else {
511
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Rugged::Blob, String, or nil)",
512
+ rb_obj_classname(rb_other));
513
+ }
514
+
515
+ rugged_exception_check(error);
516
+
517
+ return rugged_patch_new(self, patch);
518
+ }
519
+
520
+ static VALUE rb_git_blob_to_buffer(int argc, VALUE *argv, VALUE self)
521
+ {
522
+ VALUE rb_repo, rb_sha1, rb_max_bytes;
523
+ VALUE rb_ret;
524
+
525
+ git_repository *repo = NULL;
526
+ git_blob *blob = NULL;
527
+
528
+ size_t size;
529
+ const char *content;
530
+
531
+ rb_scan_args(argc, argv, "21", &rb_repo, &rb_sha1, &rb_max_bytes);
532
+
533
+ rugged_check_repo(rb_repo);
534
+ Data_Get_Struct(rb_repo, git_repository, repo);
535
+
536
+ blob = (git_blob *)rugged_object_get(repo, rb_sha1, GIT_OBJ_BLOB);
537
+
538
+ content = git_blob_rawcontent(blob);
539
+ size = git_blob_rawsize(blob);
540
+
541
+ if (!NIL_P(rb_max_bytes)) {
542
+ int maxbytes;
543
+
544
+ Check_Type(rb_max_bytes, T_FIXNUM);
545
+ maxbytes = FIX2INT(rb_max_bytes);
546
+
547
+ if (maxbytes >= 0 && (size_t)maxbytes < size)
548
+ size = (size_t)maxbytes;
549
+ }
550
+
551
+ rb_ret = rb_ary_new();
552
+
553
+ rb_ary_push(rb_ret, rb_str_new(content, size));
554
+ rb_ary_push(rb_ret, INT2FIX(git_blob_rawsize(blob)));
555
+
556
+ git_object_free((git_object*)blob);
557
+
558
+ /* TODO: LOC */
559
+
560
+ return rb_ret;
561
+ }
562
+
563
+ static VALUE rb_git_blob_sig_new(int argc, VALUE *argv, VALUE klass)
564
+ {
565
+ int error, opts = 0;
566
+ git_hashsig *sig;
567
+ VALUE rb_blob, rb_options;
568
+
569
+ if (rb_scan_args(argc, argv, "11", &rb_blob, &rb_options) == 2) {
570
+ Check_Type(rb_options, T_FIXNUM);
571
+ opts = FIX2INT(rb_options);
572
+ }
573
+
574
+ if (rb_obj_is_kind_of(rb_blob, rb_cRuggedBlob)) {
575
+ git_blob *blob;
576
+ Data_Get_Struct(rb_blob, git_blob, blob);
577
+
578
+ error = git_hashsig_create(&sig,
579
+ git_blob_rawcontent(blob),
580
+ git_blob_rawsize(blob),
581
+ opts);
582
+ } else {
583
+ Check_Type(rb_blob, T_STRING);
584
+ error = git_hashsig_create(&sig, RSTRING_PTR(rb_blob), RSTRING_LEN(rb_blob), opts);
585
+ }
586
+
587
+ rugged_exception_check(error);
588
+
589
+ return Data_Wrap_Struct(klass, NULL, &git_hashsig_free, sig);
590
+ }
591
+
592
+ static VALUE rb_git_blob_sig_compare(VALUE self, VALUE rb_sig_a, VALUE rb_sig_b)
593
+ {
594
+ git_hashsig *sig_a;
595
+ git_hashsig *sig_b;
596
+ int result;
597
+
598
+ if (!rb_obj_is_kind_of(rb_sig_a, rb_cRuggedBlobSig) ||
599
+ !rb_obj_is_kind_of(rb_sig_b, rb_cRuggedBlobSig)) {
600
+ rb_raise(rb_eTypeError, "Expected Rugged::Blob::HashSignature");
601
+ }
602
+
603
+ Data_Get_Struct(rb_sig_a, git_hashsig, sig_a);
604
+ Data_Get_Struct(rb_sig_b, git_hashsig, sig_b);
605
+
606
+ result = git_hashsig_compare(sig_a, sig_b);
607
+
608
+ if (result < 0)
609
+ rugged_exception_check(result);
610
+
611
+ return INT2FIX(result);
612
+ }
613
+
614
+ void Init_rugged_blob(void)
615
+ {
616
+ id_read = rb_intern("read");
617
+
618
+ rb_cRuggedBlob = rb_define_class_under(rb_mRugged, "Blob", rb_cRuggedObject);
619
+
620
+ rb_define_method(rb_cRuggedBlob, "size", rb_git_blob_rawsize, 0);
621
+ rb_define_method(rb_cRuggedBlob, "content", rb_git_blob_content_GET, -1);
622
+ rb_define_method(rb_cRuggedBlob, "text", rb_git_blob_text_GET, -1);
623
+ rb_define_method(rb_cRuggedBlob, "sloc", rb_git_blob_sloc, 0);
624
+ rb_define_method(rb_cRuggedBlob, "loc", rb_git_blob_loc, 0);
625
+ rb_define_method(rb_cRuggedBlob, "binary?", rb_git_blob_is_binary, 0);
626
+ rb_define_method(rb_cRuggedBlob, "diff", rb_git_blob_diff, -1);
627
+
628
+ rb_define_singleton_method(rb_cRuggedBlob, "from_buffer", rb_git_blob_from_buffer, 2);
629
+ rb_define_singleton_method(rb_cRuggedBlob, "from_workdir", rb_git_blob_from_workdir, 2);
630
+ rb_define_singleton_method(rb_cRuggedBlob, "from_disk", rb_git_blob_from_disk, 2);
631
+ rb_define_singleton_method(rb_cRuggedBlob, "from_io", rb_git_blob_from_io, -1);
632
+
633
+ rb_define_singleton_method(rb_cRuggedBlob, "to_buffer", rb_git_blob_to_buffer, -1);
634
+
635
+ rb_cRuggedBlobSig = rb_define_class_under(rb_cRuggedBlob, "HashSignature", rb_cObject);
636
+ rb_define_singleton_method(rb_cRuggedBlobSig, "new", rb_git_blob_sig_new, -1);
637
+ rb_define_singleton_method(rb_cRuggedBlobSig, "compare", rb_git_blob_sig_compare, 2);
638
+ }