Mercurial > jhg
annotate src/org/tmatesoft/hg/internal/StoragePathHelper.java @ 338:3cfa4d908fc9
Add options to control DataAccessProvider, allow to turn off use of file memory mapping in particular to solve potential sharing violation (os file handle gets released on MappedByteByffer being GC'd, not on FileChannel.close())
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Tue, 15 Nov 2011 04:47:03 +0100 |
parents | a415fe296a50 |
children | 6d2c6b2469fc |
rev | line source |
---|---|
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
1 /* |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
2 * Copyright (c) 2011 TMate Software Ltd |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
3 * |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
4 * This program is free software; you can redistribute it and/or modify |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
6 * the Free Software Foundation; version 2 of the License. |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
7 * |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
8 * This program is distributed in the hope that it will be useful, |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
11 * GNU General Public License for more details. |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
12 * |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
13 * For information on how to redistribute this software under |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
14 * the terms of a license other than GNU General Public License |
102
a3a2e5deb320
Updated contact address to support@hg4j.com
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
83
diff
changeset
|
15 * contact TMate Software at support@hg4j.com |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
16 */ |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
17 package org.tmatesoft.hg.internal; |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
18 |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
19 import java.util.Arrays; |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
20 import java.util.TreeSet; |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
21 |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
22 import org.tmatesoft.hg.util.PathRewrite; |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
23 |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
24 /** |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
25 * @see http://mercurial.selenic.com/wiki/CaseFoldingPlan |
80
4222b04f34ee
Follow history of a file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
74
diff
changeset
|
26 * @see http://mercurial.selenic.com/wiki/fncacheRepoFormat |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
27 * |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
28 * @author Artem Tikhomirov |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
29 * @author TMate Software Ltd. |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
30 */ |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
31 class StoragePathHelper implements PathRewrite { |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
32 |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
33 private final boolean store; |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
34 private final boolean fncache; |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
35 private final boolean dotencode; |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
36 |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
37 public StoragePathHelper(boolean isStore, boolean isFncache, boolean isDotencode) { |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
38 store = isStore; |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
39 fncache = isFncache; |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
40 dotencode = isDotencode; |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
41 } |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
42 |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
43 // FIXME document what path argument is, whether it includes .i or .d, and whether it's 'normalized' (slashes) or not. |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
44 // since .hg/store keeps both .i files and files without extension (e.g. fncache), guees, for data == false |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
45 // we shall assume path has extension |
292
a415fe296a50
Refactor PathRewrite to accept any char sequence, not only string
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
138
diff
changeset
|
46 public CharSequence rewrite(CharSequence p) { |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
47 final String STR_STORE = "store/"; |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
48 final String STR_DATA = "data/"; |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
49 final String STR_DH = "dh/"; |
83
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
50 final String reservedChars = "\\:*?\"<>|"; |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
51 char[] hexByte = new char[2]; |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
52 |
292
a415fe296a50
Refactor PathRewrite to accept any char sequence, not only string
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
138
diff
changeset
|
53 String path = p.toString(); |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
54 path = path.replace(".hg/", ".hg.hg/").replace(".i/", ".i.hg/").replace(".d/", ".d.hg/"); |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
55 StringBuilder sb = new StringBuilder(path.length() << 1); |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
56 if (store || fncache) { |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
57 // encodefilename |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
58 for (int i = 0; i < path.length(); i++) { |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
59 final char ch = path.charAt(i); |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
60 if (ch >= 'a' && ch <= 'z') { |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
61 sb.append(ch); // POIRAE |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
62 } else if (ch >= 'A' && ch <= 'Z') { |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
63 sb.append('_'); |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
64 sb.append(Character.toLowerCase(ch)); // Perhaps, (char) (((int) ch) + 32)? Even better, |= 0x20? |
83
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
65 } else if (reservedChars.indexOf(ch) != -1) { |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
66 sb.append('~'); |
83
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
67 sb.append(toHexByte(ch, hexByte)); |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
68 } else if ((ch >= '~' /*126*/ && ch <= 255) || ch < ' ' /*32*/) { |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
69 sb.append('~'); |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
70 sb.append(toHexByte(ch, hexByte)); |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
71 } else if (ch == '_') { |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
72 sb.append('_'); |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
73 sb.append('_'); |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
74 } else { |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
75 sb.append(ch); |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
76 } |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
77 } |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
78 // auxencode |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
79 if (fncache) { |
83
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
80 encodeWindowsDeviceNames(sb); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
81 } |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
82 } |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
83 final int MAX_PATH_LEN = 120; |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
84 if (fncache && (sb.length() + STR_DATA.length() + ".i".length() > MAX_PATH_LEN)) { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
85 String digest = new DigestHelper().sha1(STR_DATA, path, ".i").asHexString(); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
86 final int DIR_PREFIX_LEN = 8; |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
87 // not sure why (-4) is here. 120 - 40 = up to 80 for path with ext. dh/ + ext(.i) = 3+2 |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
88 final int MAX_DIR_PREFIX = 8 * (DIR_PREFIX_LEN + 1) - 4; |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
89 sb = new StringBuilder(MAX_PATH_LEN); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
90 for (int i = 0; i < path.length(); i++) { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
91 final char ch = path.charAt(i); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
92 if (ch >= 'a' && ch <= 'z') { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
93 sb.append(ch); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
94 } else if (ch >= 'A' && ch <= 'Z') { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
95 sb.append((char) (ch | 0x20)); // lowercase |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
96 } else if (reservedChars.indexOf(ch) != -1) { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
97 sb.append('~'); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
98 sb.append(toHexByte(ch, hexByte)); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
99 } else if ((ch >= '~' /*126*/ && ch <= 255) || ch < ' ' /*32*/) { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
100 sb.append('~'); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
101 sb.append(toHexByte(ch, hexByte)); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
102 } else { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
103 sb.append(ch); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
104 } |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
105 } |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
106 encodeWindowsDeviceNames(sb); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
107 int fnameStart = sb.lastIndexOf("/"); // since we rewrite file names, it never ends with slash (for dirs, I'd pass length-2); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
108 StringBuilder completeHashName = new StringBuilder(MAX_PATH_LEN); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
109 completeHashName.append(STR_STORE); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
110 completeHashName.append(STR_DH); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
111 if (fnameStart == -1) { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
112 // no dirs, just long filename |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
113 sb.setLength(MAX_PATH_LEN - 40 /*digest.length()*/ - STR_DH.length() - ".i".length()); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
114 completeHashName.append(sb); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
115 } else { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
116 StringBuilder sb2 = new StringBuilder(MAX_PATH_LEN); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
117 int x = 0; |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
118 do { |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
119 int i = sb.indexOf("/", x); |
83
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
120 final int sb2Len = sb2.length(); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
121 if (i-x <= DIR_PREFIX_LEN) { // a b c d e f g h / |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
122 sb2.append(sb, x, i + 1); // with slash |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
123 } else { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
124 sb2.append(sb, x, x + DIR_PREFIX_LEN); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
125 // may unexpectedly end with bad character |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
126 final int last = sb2.length()-1; |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
127 char lastChar = sb2.charAt(last); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
128 assert lastChar == sb.charAt(x + DIR_PREFIX_LEN - 1); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
129 if (lastChar == '.' || lastChar == ' ') { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
130 sb2.setCharAt(last, '_'); |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
131 } |
83
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
132 sb2.append('/'); |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
133 } |
83
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
134 if (sb2.length()-1 > MAX_DIR_PREFIX) { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
135 sb2.setLength(sb2Len); // strip off last segment, it's too much |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
136 break; |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
137 } |
83
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
138 x = i+1; |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
139 } while (x < fnameStart); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
140 assert sb2.charAt(sb2.length() - 1) == '/'; |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
141 int left = MAX_PATH_LEN - sb2.length() - 40 /*digest.length()*/ - STR_DH.length() - ".i".length(); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
142 assert left >= 0; |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
143 fnameStart++; // move from / to actual name |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
144 sb2.append(sb, fnameStart, fnameStart + left > sb.length() ? sb.length() : fnameStart+left); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
145 completeHashName.append(sb2); |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
146 } |
83
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
147 completeHashName.append(digest); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
148 sb = completeHashName; |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
149 } else if (store) { |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
150 sb.insert(0, STR_STORE + STR_DATA); |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
151 } |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
152 sb.append(".i"); |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
153 return sb.toString(); |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
154 } |
83
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
155 |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
156 private void encodeWindowsDeviceNames(StringBuilder sb) { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
157 char[] hexByte = new char[2]; |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
158 int x = 0; // last segment start |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
159 final TreeSet<String> windowsReservedFilenames = new TreeSet<String>(); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
160 windowsReservedFilenames.addAll(Arrays.asList("con prn aux nul com1 com2 com3 com4 com5 com6 com7 com8 com9 lpt1 lpt2 lpt3 lpt4 lpt5 lpt6 lpt7 lpt8 lpt9".split(" "))); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
161 do { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
162 int i = sb.indexOf("/", x); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
163 if (i == -1) { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
164 i = sb.length(); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
165 } |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
166 // windows reserved filenames are at least of length 3 |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
167 if (i - x >= 3) { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
168 boolean found = false; |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
169 if (i-x == 3 || i-x == 4) { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
170 found = windowsReservedFilenames.contains(sb.subSequence(x, i)); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
171 } else if (sb.charAt(x+3) == '.') { // implicit i-x > 3 |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
172 found = windowsReservedFilenames.contains(sb.subSequence(x, x+3)); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
173 } else if (i-x > 4 && sb.charAt(x+4) == '.') { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
174 found = windowsReservedFilenames.contains(sb.subSequence(x, x+4)); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
175 } |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
176 if (found) { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
177 sb.insert(x+3, toHexByte(sb.charAt(x+2), hexByte)); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
178 sb.setCharAt(x+2, '~'); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
179 i += 2; |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
180 } |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
181 } |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
182 if (dotencode && (sb.charAt(x) == '.' || sb.charAt(x) == ' ')) { |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
183 sb.insert(x+1, toHexByte(sb.charAt(x), hexByte)); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
184 sb.setCharAt(x, '~'); // setChar *after* charAt/insert to get ~2e, not ~7e for '.' |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
185 i += 2; |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
186 } |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
187 x = i+1; |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
188 } while (x < sb.length()); |
a5275143664c
Complete path hash calculation of fncache requirement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
80
diff
changeset
|
189 } |
74
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
190 |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
191 private static char[] toHexByte(int ch, char[] buf) { |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
192 assert buf.length > 1; |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
193 final String hexDigits = "0123456789abcdef"; |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
194 buf[0] = hexDigits.charAt((ch & 0x00F0) >>> 4); |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
195 buf[1] = hexDigits.charAt(ch & 0x0F); |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
196 return buf; |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
197 } |
6f1b88693d48
Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
198 } |