35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
-
-
-
-
-
+
-
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
|
const unsigned char *fileContents;
const char **dirChildren;
} data;
};
<?
package require xvfs
set ::xvfs::hashNameThreshold 3
if {[info exists ::env(XVFS_CREATE_HASH_NAME_THRESHOLD)]} {
set ::xvfs::hashNameThreshold $::env(XVFS_CREATE_HASH_NAME_THRESHOLD)
}
xvfs::main $argv
proc emitFilenameVerification {indentLevel outputFileNameLen outputFileIndexes} {
set indent [string repeat "\t" $indentLevel]
foreach outputFileIndex $outputFileIndexes {
?><?= $indent ?>if (memcmp(path, xvfs_<?= $::xvfs::fsName ?>_data[<?= $outputFileIndex ?>].name, <?= $outputFileNameLen ?>) == 0) {
<?= $indent ?> return(<?= $outputFileIndex ?>);
<?= $indent ?>}
<?
}
}
?>
static long xvfs_<?= $::xvfs::fsName ?>_nameToIndex(const char *path) {
<?
for {set index 0} {$index < [llength $::xvfs::outputFiles]} {incr index} {
set outputFileName [lindex $::xvfs::outputFiles $index]
set outputFileNameLen [string length $outputFileName]
set outputFileNameHash [zlib adler32 $outputFileName 0]
lappend outputFileNameHashToIndex([list $outputFileNameLen $outputFileNameHash]) $index
lappend outputFileNameLenToIndex($outputFileNameLen) $index
}
set needZlib false
foreach {outputFileNameLen outputFileIndexes} [lsort -stride 2 -dictionary [array get outputFileNameLenToIndex]] {
if {[llength $outputFileIndexes] > $::xvfs::hashNameThreshold} {
set needZlib true
break;
}
}
?><?
if {$needZlib} {
unsigned int pathHash;
size_t pathLen;
?> unsigned int pathHash;
<? } ?> size_t pathLen;
if (path == NULL) {
return(XVFS_NAME_LOOKUP_ERROR);
}
pathLen = strlen(path);
pathHash = Tcl_ZlibAdler32(0, (const unsigned char *) path, pathLen);
switch (pathHash) {
switch (pathLen) {
<?
for {set index 0} {$index < [llength $::xvfs::outputFiles]} {incr index} {
set outputFile [lindex $::xvfs::outputFiles $index]
set outputFileHash [zlib adler32 $outputFile 0]
lappend outputFileHashToIndex($outputFileHash) $index
}
foreach {outputFileHash outputFileIndexes} [lsort -stride 2 -dictionary [array get outputFileHashToIndex]] {
?> case <?= $outputFileHash ?>:
foreach {outputFileNameLen outputFileIndexes} [lsort -stride 2 -dictionary [array get outputFileNameLenToIndex]] {
?> case <?= $outputFileNameLen ?>:
<?
foreach outputFileIndex $outputFileIndexes {
set outputFileName [lindex $::xvfs::outputFiles $outputFileIndex]
set outputFileNameLen [string length $outputFileName]
?> if (pathLen == <?= $outputFileNameLen ?> && memcmp(path, xvfs_<?= $::xvfs::fsName ?>_data[<?= $outputFileIndex ?>].name, pathLen) == 0) {
return(<?= $outputFileIndex ?>);
}
if {[llength $outputFileIndexes] > $::xvfs::hashNameThreshold} {
?> pathHash = Tcl_ZlibAdler32(0, (const unsigned char *) path, <?= $outputFileNameLen ?>);
switch (pathHash) {
<?
foreach {key outputFileIndexes} [lsort -stride 2 -dictionary [array get outputFileNameHashToIndex [list $outputFileNameLen *]]] {
set outputFileNameHash [lindex $key 1]
?> case <?= $outputFileNameHash ?>:
<?
emitFilenameVerification 5 $outputFileNameLen $outputFileIndexes
?> break;
<?
}
?> }
<?
} else {
emitFilenameVerification 3 $outputFileNameLen $outputFileIndexes
}
?> break;
<? } ?>
<? } ?> }
}
return(XVFS_NAME_LOOKUP_ERROR);
}
static const char **xvfs_<?= $::xvfs::fsName ?>_getChildren(const char *path, Tcl_WideInt *count) {
struct xvfs_file_data *fileInfo;
long inode;
|