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 /* @} */