1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
3  *
4  * This file is part of libgit2, distributed under the GNU GPL v2 with
5  * a Linking Exception. For full terms see the included COPYING file.
6  */
7 /**
8  * License: GPL-2.0(Linking Exception)
9  */
10 module libgit2.oid;
11 
12 
13 private import libgit2.common: GIT_EXTERN;
14 
15 /*
16  * @file git2/oid.h
17  * @brief Git object id routines
18  * @defgroup git_oid Git object id routines
19  * @ingroup Git
20  * @{
21  */
22 extern (C):
23 nothrow @nogc:
24 public:
25 
26 version (GIT_EXPERIMENTAL_SHA256) {
27 	/**
28 	 * The type of object id.
29 	 */
30 	enum git_oid_t
31 	{
32 		/**
33 		 * SHA1
34 		 */
35 		GIT_OID_SHA1 = 1,
36 
37 		/**
38 		 * SHA256
39 		 */
40 		GIT_OID_SHA256 = 2,
41 	}
42 
43 	//Declaration name in C language
44 	enum
45 	{
46 		GIT_OID_SHA1 = .git_oid_t.GIT_OID_SHA1,
47 		GIT_OID_SHA256 = .git_oid_t.GIT_OID_SHA256,
48 	}
49 } else {
50 	/**
51 	 * The type of object id.
52 	 */
53 	enum git_oid_t
54 	{
55 		/**
56 		 * SHA1
57 		 */
58 		GIT_OID_SHA1 = 1,
59 	}
60 
61 	//Declaration name in C language
62 	enum
63 	{
64 		GIT_OID_SHA1 = .git_oid_t.GIT_OID_SHA1,
65 	}
66 }
67 
68 /*
69  * SHA1 is currently the only supported object ID type.
70  */
71 
72 /**
73  * SHA1 is currently libgit2's default oid type.
74  */
75 enum GIT_OID_DEFAULT = .git_oid_t.GIT_OID_SHA1;
76 
77 /**
78  * Size (in bytes) of a raw/binary sha1 oid
79  */
80 enum GIT_OID_SHA1_SIZE = 20;
81 
82 /**
83  * Size (in bytes) of a hex formatted sha1 oid
84  */
85 enum GIT_OID_SHA1_HEXSIZE = .GIT_OID_SHA1_SIZE * 2;
86 
87 /*
88  * The binary representation of the null sha1 object ID.
89  */
90 /+
91 #ifndef GIT_EXPERIMENTAL_SHA256
92 	#define GIT_OID_SHA1_ZERO   { { 0 } }
93 #else
94 	#define GIT_OID_SHA1_ZERO   { .git_oid_t.GIT_OID_SHA1, { 0 } }
95 #endif
96 +/
97 
98 /**
99  * The string representation of the null sha1 object ID.
100  */
101 enum GIT_OID_SHA1_HEXZERO = "0000000000000000000000000000000000000000";
102 
103 /*
104  * Experimental SHA256 support is a breaking change to the API.
105  * This exists for application compatibility testing.
106  */
107 
108 version (GIT_EXPERIMENTAL_SHA256) {
109 	/**
110 	 * Size (in bytes) of a raw/binary sha256 oid
111 	 */
112 	enum GIT_OID_SHA256_SIZE = 32;
113 
114 	/**
115 	 * Size (in bytes) of a hex formatted sha256 oid
116 	 */
117 	enum GIT_OID_SHA256_HEXSIZE = GIT_OID_SHA256_SIZE * 2;
118 
119 	/*
120 	 * The binary representation of the null sha256 object ID.
121 	 */
122 	/+
123 	#define GIT_OID_SHA256_ZERO { GIT_OID_SHA256, { 0 } }
124 	+/
125 
126 	/**
127 	 * The string representation of the null sha256 object ID.
128 	 */
129 	enum GIT_OID_SHA256_HEXZERO = "0000000000000000000000000000000000000000000000000000000000000000";
130 }
131 
132 /* Maximum possible object ID size in raw / hex string format. */
133 version (GIT_EXPERIMENTAL_SHA256) {
134 	enum GIT_OID_MAX_SIZE = .GIT_OID_SHA256_SIZE;
135 	enum GIT_OID_MAX_HEXSIZE = .GIT_OID_SHA256_HEXSIZE;
136 } else {
137 	enum GIT_OID_MAX_SIZE = .GIT_OID_SHA1_SIZE;
138 	enum GIT_OID_MAX_HEXSIZE = .GIT_OID_SHA1_HEXSIZE;
139 }
140 
141 /**
142  * Unique identity of any object (commit, tree, blob, tag).
143  */
144 struct git_oid
145 {
146 	version (GIT_EXPERIMENTAL_SHA256) {
147 		/**
148 		 * type of object id
149 		 */
150 		ubyte type;
151 	}
152 
153 	/**
154 	 * raw binary formatted id
155 	 */
156 	ubyte[.GIT_OID_MAX_SIZE] id;
157 }
158 
159 version (GIT_EXPERIMENTAL_SHA256) {
160 	/**
161 	 * Parse a hex formatted object id into a git_oid.
162 	 *
163 	 * The appropriate number of bytes for the given object ID type will
164 	 * be read from the string - 40 bytes for SHA1, 64 bytes for SHA256.
165 	 * The given string need not be null terminated.
166 	 *
167 	 * Params:
168 	 *      out_ = oid structure the result is written into.
169 	 *      str = input hex string; must be pointing at the start of the hex sequence and have at least the number of bytes needed for an oid encoded in hex (40 bytes for sha1, 256 bytes for sha256).
170 	 *      type = the type of object id
171 	 *
172 	 * Returns: 0 or an error code
173 	 */
174 	@GIT_EXTERN
175 	int git_oid_fromstr(.git_oid* out_, const (char)* str, .git_oid_t type);
176 } else {
177 	/**
178 	 * Parse a hex formatted object id into a git_oid.
179 	 *
180 	 * The appropriate number of bytes for the given object ID type will
181 	 * be read from the string - 40 bytes for SHA1, 64 bytes for SHA256.
182 	 * The given string need not be null terminated.
183 	 *
184 	 * Params:
185 	 *      out_ = oid structure the result is written into.
186 	 *      str = input hex string; must be pointing at the start of the hex sequence and have at least the number of bytes needed for an oid encoded in hex (40 bytes for sha1, 256 bytes for sha256).
187 	 *
188 	 * Returns: 0 or an error code
189 	 */
190 	@GIT_EXTERN
191 	int git_oid_fromstr(.git_oid* out_, const (char)* str);
192 }
193 
194 version (GIT_EXPERIMENTAL_SHA256) {
195 	/**
196 	 * Parse a hex formatted null-terminated string into a git_oid.
197 	 *
198 	 * Params:
199 	 *      out_ = oid structure the result is written into.
200 	 *      str = input hex string; must be null-terminated.
201 	 *      type = the type of object id
202 	 *
203 	 * Returns: 0 or an error code
204 	 */
205 	@GIT_EXTERN
206 	int git_oid_fromstrp(.git_oid* out_, const (char)* str, .git_oid_t type);
207 } else {
208 	/**
209 	 * Parse a hex formatted null-terminated string into a git_oid.
210 	 *
211 	 * Params:
212 	 *      out_ = oid structure the result is written into.
213 	 *      str = input hex string; must be null-terminated.
214 	 *
215 	 * Returns: 0 or an error code
216 	 */
217 	@GIT_EXTERN
218 	int git_oid_fromstrp(.git_oid* out_, const (char)* str);
219 }
220 
221 version (GIT_EXPERIMENTAL_SHA256) {
222 	/**
223 	 * Parse N characters of a hex formatted object id into a git_oid.
224 	 *
225 	 * If N is odd, the last byte's high nibble will be read in and the
226 	 * low nibble set to zero.
227 	 *
228 	 * Params:
229 	 *      out_ = oid structure the result is written into.
230 	 *      str = input hex string of at least size `length`
231 	 *      length = length of the input string
232 	 *      type = the type of object id
233 	 *
234 	 * Returns: 0 or an error code
235 	 */
236 	@GIT_EXTERN
237 	int git_oid_fromstrn(.git_oid* out_, const (char)* str, size_t length, .git_oid_t type);
238 } else {
239 	/**
240 	 * Parse N characters of a hex formatted object id into a git_oid.
241 	 *
242 	 * If N is odd, the last byte's high nibble will be read in and the
243 	 * low nibble set to zero.
244 	 *
245 	 * Params:
246 	 *      out_ = oid structure the result is written into.
247 	 *      str = input hex string of at least size `length`
248 	 *      length = length of the input string
249 	 *
250 	 * Returns: 0 or an error code
251 	 */
252 	@GIT_EXTERN
253 	int git_oid_fromstrn(.git_oid* out_, const (char)* str, size_t length);
254 }
255 
256 version (GIT_EXPERIMENTAL_SHA256) {
257 	/**
258 	 * Copy an already raw oid into a git_oid structure.
259 	 *
260 	 * Params:
261 	 *      out_ = oid structure the result is written into.
262 	 *      raw = the raw input bytes to be copied.
263 	 *      type = ?
264 	 *
265 	 * Returns: 0 on success or error code
266 	 */
267 	@GIT_EXTERN
268 	int git_oid_fromraw(.git_oid* out_, const (ubyte)* raw, .git_oid_t type);
269 } else {
270 	/**
271 	 * Copy an already raw oid into a git_oid structure.
272 	 *
273 	 * Params:
274 	 *      out_ = oid structure the result is written into.
275 	 *      raw = the raw input bytes to be copied.
276 	 *
277 	 * Returns: 0 on success or error code
278 	 */
279 	@GIT_EXTERN
280 	int git_oid_fromraw(.git_oid* out_, const (ubyte)* raw);
281 }
282 
283 /**
284  * Format a git_oid into a hex string.
285  *
286  * Params:
287  *      out_ = output hex string; must be pointing at the start of the hex sequence and have at least the number of bytes needed for an oid encoded in hex (40 bytes for SHA1, 64 bytes for SHA256). Only the oid digits are written; a '\\0' terminator must be added by the caller if it is required.
288  *      id = oid structure to format.
289  *
290  * Returns: 0 on success or error code
291  */
292 @GIT_EXTERN
293 int git_oid_fmt(char* out_, const (.git_oid)* id);
294 
295 /**
296  * Format a git_oid into a partial hex string.
297  *
298  * Params:
299  *      out_ = output hex string; you say how many bytes to write. If the number of bytes is > GIT_OID_SHA1_HEXSIZE, extra bytes will be zeroed; if not, a '\0' terminator is NOT added.
300  *      n = number of characters to write into out string
301  *      id = oid structure to format.
302  *
303  * Returns: 0 on success or error code
304  */
305 @GIT_EXTERN
306 int git_oid_nfmt(char* out_, size_t n, const (.git_oid)* id);
307 
308 /**
309  * Format a git_oid into a loose-object path string.
310  *
311  * The resulting string is "aa/...", where "aa" is the first two
312  * hex digits of the oid and "..." is the remaining 38 digits.
313  *
314  * Params:
315  *      out_ = output hex string; must be pointing at the start of the hex sequence and have at least the number of bytes needed for an oid encoded in hex (41 bytes for SHA1, 65 bytes for SHA256). Only the oid digits are written; a '\\0' terminator must be added by the caller if it is required.
316  *      id = oid structure to format.
317  *
318  * Returns: 0 on success, non-zero callback return value, or error code
319  */
320 @GIT_EXTERN
321 int git_oid_pathfmt(char* out_, const (.git_oid)* id);
322 
323 /**
324  * Format a git_oid into a statically allocated c-string.
325  *
326  * The c-string is owned by the library and should not be freed
327  * by the user. If libgit2 is built with thread support, the string
328  * will be stored in TLS (i.e. one buffer per thread) to allow for
329  * concurrent calls of the function.
330  *
331  * Params:
332  *      oid = The oid structure to format
333  *
334  * Returns: the c-string
335  */
336 @GIT_EXTERN
337 char* git_oid_tostr_s(const (.git_oid)* oid);
338 
339 /**
340  * Format a git_oid into a buffer as a hex format c-string.
341  *
342  * If the buffer is smaller than the size of a hex-formatted oid string
343  * plus an additional byte (GIT_OID_SHA_HEXSIZE + 1 for SHA1 or
344  * GIT_OID_SHA256_HEXSIZE + 1 for SHA256), then the resulting
345  * oid c-string will be truncated to n-1 characters (but will still be
346  * null-byte terminated).
347  *
348  * If there are any input parameter errors (out == null, n == 0, oid ==
349  * null), then a pointer to an empty string is returned, so that the
350  * return value can always be printed.
351  *
352  * Params:
353  *      out_ = the buffer into which the oid string is output.
354  *      n = the size of the out buffer.
355  *      id = the oid structure to format.
356  *
357  * Returns: the out buffer pointer, assuming no input parameter errors, otherwise a pointer to an empty string.
358  */
359 @GIT_EXTERN
360 char* git_oid_tostr(char* out_, size_t n, const (.git_oid)* id);
361 
362 /**
363  * Copy an oid from one structure to another.
364  *
365  * Params:
366  *      out_ = oid structure the result is written into.
367  *      src = oid structure to copy from.
368  *
369  * Returns: 0 on success or error code
370  */
371 @GIT_EXTERN
372 int git_oid_cpy(.git_oid* out_, const (.git_oid)* src);
373 
374 /**
375  * Compare two oid structures.
376  *
377  * Params:
378  *      a = first oid structure.
379  *      b = second oid structure.
380  *
381  * Returns: <0, 0, >0 if a < b, a == b, a > b.
382  */
383 @GIT_EXTERN
384 int git_oid_cmp(const (.git_oid)* a, const (.git_oid)* b);
385 
386 /**
387  * Compare two oid structures for equality
388  *
389  * Params:
390  *      a = first oid structure.
391  *      b = second oid structure.
392  *
393  * Returns: true if equal, false otherwise
394  */
395 @GIT_EXTERN
396 int git_oid_equal(const (.git_oid)* a, const (.git_oid)* b);
397 
398 /**
399  * Compare the first 'len' hexadecimal characters (packets of 4 bits)
400  * of two oid structures.
401  *
402  * Params:
403  *      a = first oid structure.
404  *      b = second oid structure.
405  *      len = the number of hex chars to compare
406  *
407  * Returns: 0 in case of a match
408  */
409 @GIT_EXTERN
410 int git_oid_ncmp(const (.git_oid)* a, const (.git_oid)* b, size_t len);
411 
412 /**
413  * Check if an oid equals an hex formatted object id.
414  *
415  * Params:
416  *      id = oid structure.
417  *      str = input hex string of an object id.
418  *
419  * Returns: 0 in case of a match, -1 otherwise.
420  */
421 @GIT_EXTERN
422 int git_oid_streq(const (.git_oid)* id, const (char)* str);
423 
424 /**
425  * Compare an oid to an hex formatted object id.
426  *
427  * Params:
428  *      id = oid structure.
429  *      str = input hex string of an object id.
430  *
431  * Returns: -1 if str is not valid, <0 if id sorts before str, 0 if id matches str, >0 if id sorts after str.
432  */
433 @GIT_EXTERN
434 int git_oid_strcmp(const (.git_oid)* id, const (char)* str);
435 
436 /**
437  * Check is an oid is all zeros.
438  *
439  * Returns: 1 if all zeros, 0 otherwise.
440  */
441 @GIT_EXTERN
442 int git_oid_is_zero(const (.git_oid)* id);
443 
444 /**
445  * OID Shortener object
446  */
447 struct git_oid_shorten;
448 
449 /**
450  * Create a new OID shortener.
451  *
452  * The OID shortener is used to process a list of OIDs
453  * in text form and return the shortest length that would
454  * uniquely identify all of them.
455  *
456  * E.g. look at the result of `git log --abbrev`.
457  *
458  * Params:
459  *      min_length = The minimal length for all identifiers, which will be used even if shorter OIDs would still be unique.
460  *
461  * Returns: a `git_oid_shorten` instance, null if OOM
462  */
463 @GIT_EXTERN
464 .git_oid_shorten* git_oid_shorten_new(size_t min_length);
465 
466 /**
467  * Add a new OID to set of shortened OIDs and calculate
468  * the minimal length to uniquely identify all the OIDs in
469  * the set.
470  *
471  * The OID is expected to be a 40-char hexadecimal string.
472  * The OID is owned by the user and will not be modified
473  * or freed.
474  *
475  * For performance reasons, there is a hard-limit of how many
476  * OIDs can be added to a single set (around ~32000, assuming
477  * a mostly randomized distribution), which should be enough
478  * for any kind of program, and keeps the algorithm fast and
479  * memory-efficient.
480  *
481  * Attempting to add more than those OIDs will result in a
482  * git_error_t.GIT_ERROR_INVALID error
483  *
484  * Params:
485  *      os = a `git_oid_shorten` instance
486  *      text_id = an OID in text form
487  *
488  * Returns: the minimal length to uniquely identify all OIDs added so far to the set; or an error code (<0) if an error occurs.
489  */
490 @GIT_EXTERN
491 int git_oid_shorten_add(.git_oid_shorten* os, const (char)* text_id);
492 
493 /**
494  * Free an OID shortener instance
495  *
496  * Params:
497  *      os = a `git_oid_shorten` instance
498  */
499 @GIT_EXTERN
500 void git_oid_shorten_free(.git_oid_shorten* os);
501 
502 /* @} */