You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

FileMode.java 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /*
  2. * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
  3. * Copyright (C) 2006-2008, Shawn O. Pearce <spearce@spearce.org> and others
  4. *
  5. * This program and the accompanying materials are made available under the
  6. * terms of the Eclipse Distribution License v. 1.0 which is available at
  7. * https://www.eclipse.org/org/documents/edl-v10.php.
  8. *
  9. * SPDX-License-Identifier: BSD-3-Clause
  10. */
  11. package org.eclipse.jgit.lib;
  12. import java.io.IOException;
  13. import java.io.OutputStream;
  14. /**
  15. * Constants describing various file modes recognized by GIT.
  16. * <p>
  17. * GIT uses a subset of the available UNIX file permission bits. The
  18. * <code>FileMode</code> class provides access to constants defining the modes
  19. * actually used by GIT.
  20. * </p>
  21. */
  22. public abstract class FileMode {
  23. /**
  24. * Mask to apply to a file mode to obtain its type bits.
  25. *
  26. * @see #TYPE_TREE
  27. * @see #TYPE_SYMLINK
  28. * @see #TYPE_FILE
  29. * @see #TYPE_GITLINK
  30. * @see #TYPE_MISSING
  31. */
  32. public static final int TYPE_MASK = 0170000;
  33. /** Bit pattern for {@link #TYPE_MASK} matching {@link #TREE}. */
  34. public static final int TYPE_TREE = 0040000;
  35. /** Bit pattern for {@link #TYPE_MASK} matching {@link #SYMLINK}. */
  36. public static final int TYPE_SYMLINK = 0120000;
  37. /** Bit pattern for {@link #TYPE_MASK} matching {@link #REGULAR_FILE}. */
  38. public static final int TYPE_FILE = 0100000;
  39. /** Bit pattern for {@link #TYPE_MASK} matching {@link #GITLINK}. */
  40. public static final int TYPE_GITLINK = 0160000;
  41. /** Bit pattern for {@link #TYPE_MASK} matching {@link #MISSING}. */
  42. public static final int TYPE_MISSING = 0000000;
  43. /**
  44. * Mode indicating an entry is a tree (aka directory).
  45. */
  46. public static final FileMode TREE = new FileMode(TYPE_TREE,
  47. Constants.OBJ_TREE) {
  48. @Override
  49. @SuppressWarnings("NonOverridingEquals")
  50. public boolean equals(int modeBits) {
  51. return (modeBits & TYPE_MASK) == TYPE_TREE;
  52. }
  53. };
  54. /** Mode indicating an entry is a symbolic link. */
  55. public static final FileMode SYMLINK = new FileMode(TYPE_SYMLINK,
  56. Constants.OBJ_BLOB) {
  57. @Override
  58. @SuppressWarnings("NonOverridingEquals")
  59. public boolean equals(int modeBits) {
  60. return (modeBits & TYPE_MASK) == TYPE_SYMLINK;
  61. }
  62. };
  63. /** Mode indicating an entry is a non-executable file. */
  64. public static final FileMode REGULAR_FILE = new FileMode(0100644,
  65. Constants.OBJ_BLOB) {
  66. @Override
  67. @SuppressWarnings("NonOverridingEquals")
  68. public boolean equals(int modeBits) {
  69. return (modeBits & TYPE_MASK) == TYPE_FILE && (modeBits & 0111) == 0;
  70. }
  71. };
  72. /** Mode indicating an entry is an executable file. */
  73. public static final FileMode EXECUTABLE_FILE = new FileMode(0100755,
  74. Constants.OBJ_BLOB) {
  75. @Override
  76. @SuppressWarnings("NonOverridingEquals")
  77. public boolean equals(int modeBits) {
  78. return (modeBits & TYPE_MASK) == TYPE_FILE && (modeBits & 0111) != 0;
  79. }
  80. };
  81. /** Mode indicating an entry is a submodule commit in another repository. */
  82. public static final FileMode GITLINK = new FileMode(TYPE_GITLINK,
  83. Constants.OBJ_COMMIT) {
  84. @Override
  85. @SuppressWarnings("NonOverridingEquals")
  86. public boolean equals(int modeBits) {
  87. return (modeBits & TYPE_MASK) == TYPE_GITLINK;
  88. }
  89. };
  90. /** Mode indicating an entry is missing during parallel walks. */
  91. public static final FileMode MISSING = new FileMode(TYPE_MISSING,
  92. Constants.OBJ_BAD) {
  93. @Override
  94. @SuppressWarnings("NonOverridingEquals")
  95. public boolean equals(int modeBits) {
  96. return modeBits == 0;
  97. }
  98. };
  99. /**
  100. * Convert a set of mode bits into a FileMode enumerated value.
  101. *
  102. * @param bits
  103. * the mode bits the caller has somehow obtained.
  104. * @return the FileMode instance that represents the given bits.
  105. */
  106. public static final FileMode fromBits(int bits) {
  107. switch (bits & TYPE_MASK) {
  108. case TYPE_MISSING:
  109. if (bits == 0)
  110. return MISSING;
  111. break;
  112. case TYPE_TREE:
  113. return TREE;
  114. case TYPE_FILE:
  115. if ((bits & 0111) != 0)
  116. return EXECUTABLE_FILE;
  117. return REGULAR_FILE;
  118. case TYPE_SYMLINK:
  119. return SYMLINK;
  120. case TYPE_GITLINK:
  121. return GITLINK;
  122. }
  123. return new FileMode(bits, Constants.OBJ_BAD) {
  124. @Override
  125. @SuppressWarnings("NonOverridingEquals")
  126. public boolean equals(int a) {
  127. return bits == a;
  128. }
  129. };
  130. }
  131. private final byte[] octalBytes;
  132. private final int modeBits;
  133. private final int objectType;
  134. private FileMode(int mode, int expType) {
  135. modeBits = mode;
  136. objectType = expType;
  137. if (mode != 0) {
  138. final byte[] tmp = new byte[10];
  139. int p = tmp.length;
  140. while (mode != 0) {
  141. tmp[--p] = (byte) ('0' + (mode & 07));
  142. mode >>= 3;
  143. }
  144. octalBytes = new byte[tmp.length - p];
  145. for (int k = 0; k < octalBytes.length; k++) {
  146. octalBytes[k] = tmp[p + k];
  147. }
  148. } else {
  149. octalBytes = new byte[] { '0' };
  150. }
  151. }
  152. /**
  153. * Test a file mode for equality with this
  154. * {@link org.eclipse.jgit.lib.FileMode} object.
  155. *
  156. * @param modebits
  157. * a int.
  158. * @return true if the mode bits represent the same mode as this object
  159. */
  160. @SuppressWarnings("NonOverridingEquals")
  161. public abstract boolean equals(int modebits);
  162. /**
  163. * Copy this mode as a sequence of octal US-ASCII bytes.
  164. * <p>
  165. * The mode is copied as a sequence of octal digits using the US-ASCII
  166. * character encoding. The sequence does not use a leading '0' prefix to
  167. * indicate octal notation. This method is suitable for generation of a mode
  168. * string within a GIT tree object.
  169. * </p>
  170. *
  171. * @param os
  172. * stream to copy the mode to.
  173. * @throws java.io.IOException
  174. * the stream encountered an error during the copy.
  175. */
  176. public void copyTo(OutputStream os) throws IOException {
  177. os.write(octalBytes);
  178. }
  179. /**
  180. * Copy this mode as a sequence of octal US-ASCII bytes.
  181. *
  182. * The mode is copied as a sequence of octal digits using the US-ASCII
  183. * character encoding. The sequence does not use a leading '0' prefix to
  184. * indicate octal notation. This method is suitable for generation of a mode
  185. * string within a GIT tree object.
  186. *
  187. * @param buf
  188. * buffer to copy the mode to.
  189. * @param ptr
  190. * position within {@code buf} for first digit.
  191. */
  192. public void copyTo(byte[] buf, int ptr) {
  193. System.arraycopy(octalBytes, 0, buf, ptr, octalBytes.length);
  194. }
  195. /**
  196. * Copy the number of bytes written by {@link #copyTo(OutputStream)}.
  197. *
  198. * @return the number of bytes written by {@link #copyTo(OutputStream)}.
  199. */
  200. public int copyToLength() {
  201. return octalBytes.length;
  202. }
  203. /**
  204. * Get the object type that should appear for this type of mode.
  205. * <p>
  206. * See the object type constants in {@link org.eclipse.jgit.lib.Constants}.
  207. *
  208. * @return one of the well known object type constants.
  209. */
  210. public int getObjectType() {
  211. return objectType;
  212. }
  213. /**
  214. * {@inheritDoc}
  215. * <p>
  216. * Format this mode as an octal string (for debugging only).
  217. */
  218. @Override
  219. public String toString() {
  220. return Integer.toOctalString(modeBits);
  221. }
  222. /**
  223. * Get the mode bits as an integer.
  224. *
  225. * @return The mode bits as an integer.
  226. */
  227. public int getBits() {
  228. return modeBits;
  229. }
  230. }