Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
fa7b30b0
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
fa7b30b0
编写于
11月 17, 2010
作者:
M
michaelm
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
ef144a90
98076d07
变更
24
隐藏空白更改
内联
并排
Showing
24 changed file
with
1379 addition
and
801 deletion
+1379
-801
make/mkdemo/nio/zipfs/Makefile
make/mkdemo/nio/zipfs/Makefile
+7
-0
src/share/classes/java/lang/Readable.java
src/share/classes/java/lang/Readable.java
+2
-2
src/share/classes/java/util/concurrent/LinkedBlockingDeque.java
...are/classes/java/util/concurrent/LinkedBlockingDeque.java
+61
-33
src/share/classes/java/util/jar/JarInputStream.java
src/share/classes/java/util/jar/JarInputStream.java
+23
-10
src/share/classes/sun/security/pkcs11/P11Cipher.java
src/share/classes/sun/security/pkcs11/P11Cipher.java
+5
-4
src/share/demo/nio/zipfs/Demo.java
src/share/demo/nio/zipfs/Demo.java
+59
-6
src/share/demo/nio/zipfs/README.txt
src/share/demo/nio/zipfs/README.txt
+3
-3
src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java
...mo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java
+17
-0
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java
+20
-30
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java
.../demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java
+1
-2
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java
...emo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java
+4
-1
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java
...e/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java
+9
-10
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java
...share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java
+694
-584
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java
...mo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java
+19
-6
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java
+156
-65
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java
+8
-11
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java
+25
-3
src/share/lib/security/sunpkcs11-solaris.cfg
src/share/lib/security/sunpkcs11-solaris.cfg
+4
-0
test/demo/zipfs/ZipFSTester.java
test/demo/zipfs/ZipFSTester.java
+2
-9
test/java/nio/channels/AsynchronousSocketChannel/Leaky.java
test/java/nio/channels/AsynchronousSocketChannel/Leaky.java
+34
-5
test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java
.../concurrent/ConcurrentQueues/IteratorWeakConsistency.java
+37
-17
test/java/util/jar/JarInputStream/BadSignedJar.jar
test/java/util/jar/JarInputStream/BadSignedJar.jar
+0
-0
test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java
...il/jar/JarInputStream/TestIndexedJarWithBadSignature.java
+57
-0
test/sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java
test/sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java
+132
-0
未找到文件。
make/mkdemo/nio/zipfs/Makefile
浏览文件 @
fa7b30b0
...
...
@@ -42,3 +42,10 @@ DEMO_DESTDIR = $(DEMODIR)/nio/$(DEMONAME)
#
include
$(BUILDDIR)/common/Demo.gmk
#EXTJAR = $(EXTDIR)/$(DEMONAME).jar
#
#all : build $(EXTJAR)
#
#$(EXTJAR) : $(DEMO_JAR)
# $(prep-target)
# $(CP) $(DEMO_JAR) $(EXTJAR)
src/share/classes/java/lang/Readable.java
浏览文件 @
fa7b30b0
...
...
@@ -44,11 +44,11 @@ public interface Readable {
* rewinding of the buffer is performed.
*
* @param cb the buffer to read characters into
* @return
@return The number of <tt>char</tt>
values added to the buffer,
* @return
The number of {@code char}
values added to the buffer,
* or -1 if this source of characters is at its end
* @throws IOException if an I/O error occurs
* @throws NullPointerException if cb is null
* @throws ReadOnlyBufferException if cb is a read only buffer
* @throws
java.nio.
ReadOnlyBufferException if cb is a read only buffer
*/
public
int
read
(
java
.
nio
.
CharBuffer
cb
)
throws
IOException
;
...
...
src/share/classes/java/util/concurrent/LinkedBlockingDeque.java
浏览文件 @
fa7b30b0
...
...
@@ -126,10 +126,8 @@ public class LinkedBlockingDeque<E>
*/
Node
<
E
>
next
;
Node
(
E
x
,
Node
<
E
>
p
,
Node
<
E
>
n
)
{
Node
(
E
x
)
{
item
=
x
;
prev
=
p
;
next
=
n
;
}
}
...
...
@@ -199,7 +197,7 @@ public class LinkedBlockingDeque<E>
for
(
E
e
:
c
)
{
if
(
e
==
null
)
throw
new
NullPointerException
();
if
(!
linkLast
(
e
))
if
(!
linkLast
(
new
Node
<
E
>(
e
)
))
throw
new
IllegalStateException
(
"Deque full"
);
}
}
finally
{
...
...
@@ -211,38 +209,38 @@ public class LinkedBlockingDeque<E>
// Basic linking and unlinking operations, called only while holding lock
/**
* Links e as first element, or returns false if full.
* Links
nod
e as first element, or returns false if full.
*/
private
boolean
linkFirst
(
E
e
)
{
private
boolean
linkFirst
(
Node
<
E
>
nod
e
)
{
// assert lock.isHeldByCurrentThread();
if
(
count
>=
capacity
)
return
false
;
Node
<
E
>
f
=
first
;
Node
<
E
>
x
=
new
Node
<
E
>(
e
,
null
,
f
)
;
first
=
x
;
node
.
next
=
f
;
first
=
node
;
if
(
last
==
null
)
last
=
x
;
last
=
node
;
else
f
.
prev
=
x
;
f
.
prev
=
node
;
++
count
;
notEmpty
.
signal
();
return
true
;
}
/**
* Links e as last element, or returns false if full.
* Links
nod
e as last element, or returns false if full.
*/
private
boolean
linkLast
(
E
e
)
{
private
boolean
linkLast
(
Node
<
E
>
nod
e
)
{
// assert lock.isHeldByCurrentThread();
if
(
count
>=
capacity
)
return
false
;
Node
<
E
>
l
=
last
;
Node
<
E
>
x
=
new
Node
<
E
>(
e
,
l
,
null
)
;
last
=
x
;
node
.
prev
=
l
;
last
=
node
;
if
(
first
==
null
)
first
=
x
;
first
=
node
;
else
l
.
next
=
x
;
l
.
next
=
node
;
++
count
;
notEmpty
.
signal
();
return
true
;
...
...
@@ -339,10 +337,11 @@ public class LinkedBlockingDeque<E>
*/
public
boolean
offerFirst
(
E
e
)
{
if
(
e
==
null
)
throw
new
NullPointerException
();
Node
<
E
>
node
=
new
Node
<
E
>(
e
);
final
ReentrantLock
lock
=
this
.
lock
;
lock
.
lock
();
try
{
return
linkFirst
(
e
);
return
linkFirst
(
nod
e
);
}
finally
{
lock
.
unlock
();
}
...
...
@@ -353,10 +352,11 @@ public class LinkedBlockingDeque<E>
*/
public
boolean
offerLast
(
E
e
)
{
if
(
e
==
null
)
throw
new
NullPointerException
();
Node
<
E
>
node
=
new
Node
<
E
>(
e
);
final
ReentrantLock
lock
=
this
.
lock
;
lock
.
lock
();
try
{
return
linkLast
(
e
);
return
linkLast
(
nod
e
);
}
finally
{
lock
.
unlock
();
}
...
...
@@ -368,10 +368,11 @@ public class LinkedBlockingDeque<E>
*/
public
void
putFirst
(
E
e
)
throws
InterruptedException
{
if
(
e
==
null
)
throw
new
NullPointerException
();
Node
<
E
>
node
=
new
Node
<
E
>(
e
);
final
ReentrantLock
lock
=
this
.
lock
;
lock
.
lock
();
try
{
while
(!
linkFirst
(
e
))
while
(!
linkFirst
(
nod
e
))
notFull
.
await
();
}
finally
{
lock
.
unlock
();
...
...
@@ -384,10 +385,11 @@ public class LinkedBlockingDeque<E>
*/
public
void
putLast
(
E
e
)
throws
InterruptedException
{
if
(
e
==
null
)
throw
new
NullPointerException
();
Node
<
E
>
node
=
new
Node
<
E
>(
e
);
final
ReentrantLock
lock
=
this
.
lock
;
lock
.
lock
();
try
{
while
(!
linkLast
(
e
))
while
(!
linkLast
(
nod
e
))
notFull
.
await
();
}
finally
{
lock
.
unlock
();
...
...
@@ -401,11 +403,12 @@ public class LinkedBlockingDeque<E>
public
boolean
offerFirst
(
E
e
,
long
timeout
,
TimeUnit
unit
)
throws
InterruptedException
{
if
(
e
==
null
)
throw
new
NullPointerException
();
Node
<
E
>
node
=
new
Node
<
E
>(
e
);
long
nanos
=
unit
.
toNanos
(
timeout
);
final
ReentrantLock
lock
=
this
.
lock
;
lock
.
lockInterruptibly
();
try
{
while
(!
linkFirst
(
e
))
{
while
(!
linkFirst
(
nod
e
))
{
if
(
nanos
<=
0
)
return
false
;
nanos
=
notFull
.
awaitNanos
(
nanos
);
...
...
@@ -423,11 +426,12 @@ public class LinkedBlockingDeque<E>
public
boolean
offerLast
(
E
e
,
long
timeout
,
TimeUnit
unit
)
throws
InterruptedException
{
if
(
e
==
null
)
throw
new
NullPointerException
();
Node
<
E
>
node
=
new
Node
<
E
>(
e
);
long
nanos
=
unit
.
toNanos
(
timeout
);
final
ReentrantLock
lock
=
this
.
lock
;
lock
.
lockInterruptibly
();
try
{
while
(!
linkLast
(
e
))
{
while
(!
linkLast
(
nod
e
))
{
if
(
nanos
<=
0
)
return
false
;
nanos
=
notFull
.
awaitNanos
(
nanos
);
...
...
@@ -955,7 +959,20 @@ public class LinkedBlockingDeque<E>
final
ReentrantLock
lock
=
this
.
lock
;
lock
.
lock
();
try
{
return
super
.
toString
();
Node
<
E
>
p
=
first
;
if
(
p
==
null
)
return
"[]"
;
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
'['
);
for
(;;)
{
E
e
=
p
.
item
;
sb
.
append
(
e
==
this
?
"(this Collection)"
:
e
);
p
=
p
.
next
;
if
(
p
==
null
)
return
sb
.
append
(
']'
).
toString
();
sb
.
append
(
','
).
append
(
' '
);
}
}
finally
{
lock
.
unlock
();
}
...
...
@@ -1053,6 +1070,26 @@ public class LinkedBlockingDeque<E>
}
}
/**
* Returns the successor node of the given non-null, but
* possibly previously deleted, node.
*/
private
Node
<
E
>
succ
(
Node
<
E
>
n
)
{
// Chains of deleted nodes ending in null or self-links
// are possible if multiple interior nodes are removed.
for
(;;)
{
Node
<
E
>
s
=
nextNode
(
n
);
if
(
s
==
null
)
return
null
;
else
if
(
s
.
item
!=
null
)
return
s
;
else
if
(
s
==
n
)
return
firstNode
();
else
n
=
s
;
}
}
/**
* Advances next.
*/
...
...
@@ -1061,16 +1098,7 @@ public class LinkedBlockingDeque<E>
lock
.
lock
();
try
{
// assert next != null;
Node
<
E
>
s
=
nextNode
(
next
);
if
(
s
==
next
)
{
next
=
firstNode
();
}
else
{
// Skip over removed nodes.
// May be necessary if multiple interior Nodes are removed.
while
(
s
!=
null
&&
s
.
item
==
null
)
s
=
nextNode
(
s
);
next
=
s
;
}
next
=
succ
(
next
);
nextItem
=
(
next
==
null
)
?
null
:
next
.
item
;
}
finally
{
lock
.
unlock
();
...
...
src/share/classes/java/util/jar/JarInputStream.java
浏览文件 @
fa7b30b0
...
...
@@ -28,6 +28,7 @@ package java.util.jar;
import
java.util.zip.*
;
import
java.io.*
;
import
sun.security.util.ManifestEntryVerifier
;
import
sun.misc.JarIndex
;
/**
* The <code>JarInputStream</code> class is used to read the contents of
...
...
@@ -47,7 +48,8 @@ class JarInputStream extends ZipInputStream {
private
JarEntry
first
;
private
JarVerifier
jv
;
private
ManifestEntryVerifier
mev
;
private
final
boolean
doVerify
;
private
boolean
tryManifest
;
/**
* Creates a new <code>JarInputStream</code> and reads the optional
...
...
@@ -72,25 +74,33 @@ class JarInputStream extends ZipInputStream {
*/
public
JarInputStream
(
InputStream
in
,
boolean
verify
)
throws
IOException
{
super
(
in
);
JarEntry
e
=
(
JarEntry
)
super
.
getNextEntry
()
;
this
.
doVerify
=
verify
;
// This implementation assumes the META-INF/MANIFEST.MF entry
// should be either the first or the second entry (when preceded
// by the dir META-INF/). It skips the META-INF/ and then
// "consumes" the MANIFEST.MF to initialize the Manifest object.
JarEntry
e
=
(
JarEntry
)
super
.
getNextEntry
();
if
(
e
!=
null
&&
e
.
getName
().
equalsIgnoreCase
(
"META-INF/"
))
e
=
(
JarEntry
)
super
.
getNextEntry
();
first
=
checkManifest
(
e
);
}
private
JarEntry
checkManifest
(
JarEntry
e
)
throws
IOException
{
if
(
e
!=
null
&&
JarFile
.
MANIFEST_NAME
.
equalsIgnoreCase
(
e
.
getName
()))
{
man
=
new
Manifest
();
byte
bytes
[]
=
getBytes
(
new
BufferedInputStream
(
this
));
man
.
read
(
new
ByteArrayInputStream
(
bytes
));
//man.read(new BufferedInputStream(this));
closeEntry
();
if
(
v
erify
)
{
if
(
doV
erify
)
{
jv
=
new
JarVerifier
(
bytes
);
mev
=
new
ManifestEntryVerifier
(
man
);
}
first
=
getNextJarEntry
();
}
else
{
first
=
e
;
return
(
JarEntry
)
super
.
getNextEntry
();
}
return
e
;
}
private
byte
[]
getBytes
(
InputStream
is
)
...
...
@@ -98,10 +108,7 @@ class JarInputStream extends ZipInputStream {
{
byte
[]
buffer
=
new
byte
[
8192
];
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
(
2048
);
int
n
;
baos
.
reset
();
while
((
n
=
is
.
read
(
buffer
,
0
,
buffer
.
length
))
!=
-
1
)
{
baos
.
write
(
buffer
,
0
,
n
);
}
...
...
@@ -133,8 +140,14 @@ class JarInputStream extends ZipInputStream {
JarEntry
e
;
if
(
first
==
null
)
{
e
=
(
JarEntry
)
super
.
getNextEntry
();
if
(
tryManifest
)
{
e
=
checkManifest
(
e
);
tryManifest
=
false
;
}
}
else
{
e
=
first
;
if
(
first
.
getName
().
equalsIgnoreCase
(
JarIndex
.
INDEX_NAME
))
tryManifest
=
true
;
first
=
null
;
}
if
(
jv
!=
null
&&
e
!=
null
)
{
...
...
src/share/classes/sun/security/pkcs11/P11Cipher.java
浏览文件 @
fa7b30b0
...
...
@@ -74,7 +74,7 @@ final class P11Cipher extends CipherSpi {
// DEC: return the length of trailing padding bytes given the specified
// padded data
int
unpad
(
byte
[]
paddedData
,
int
len
)
throws
BadPaddingException
;
throws
BadPaddingException
,
IllegalBlockSizeException
;
}
private
static
class
PKCS5Padding
implements
Padding
{
...
...
@@ -96,9 +96,10 @@ final class P11Cipher extends CipherSpi {
}
public
int
unpad
(
byte
[]
paddedData
,
int
len
)
throws
BadPaddingException
{
if
(
len
<
1
||
len
>
paddedData
.
length
)
{
throw
new
BadPaddingException
(
"Invalid pad array length!"
);
throws
BadPaddingException
,
IllegalBlockSizeException
{
if
((
len
<
1
)
||
(
len
%
blockSize
!=
0
))
{
throw
new
IllegalBlockSizeException
(
"Input length must be multiples of "
+
blockSize
);
}
byte
padValue
=
paddedData
[
len
-
1
];
if
(
padValue
<
1
||
padValue
>
blockSize
)
{
...
...
src/share/demo/nio/zipfs/Demo.java
浏览文件 @
fa7b30b0
...
...
@@ -75,9 +75,15 @@ public class Demo {
// copy an external src file into zipfile
// as entry dst
copyin_attrs
,
// <java Demo copyin_attrs zipfile src dst>
// copy an external src file into zipfile
// as entry dst, with attributes (timestamp)
copyout
,
// <java Demo copyout zipfile src dst>
// copy zipfile entry src" out to file dst
copyout_attrs
,
// <java Demo copyout_attrs zipfile src dst>
zzmove
,
// <java Demo zzmove zfsrc zfdst path>
// move entry path/dir from zfsrc to zfdst
...
...
@@ -94,6 +100,9 @@ public class Demo {
setmtime
,
// <java Demo setmtime zipfile "MM/dd/yy-HH:mm:ss" path...>
// set the lastModifiedTime of entry path
setatime
,
// <java Demo setatime zipfile "MM/dd/yy-HH:mm:ss" path...>
setctime
,
// <java Demo setctime zipfile "MM/dd/yy-HH:mm:ss" path...>
lsdir
,
// <java Demo lsdir zipfile dir>
// list dir's direct child files/dirs
...
...
@@ -135,12 +144,14 @@ public class Demo {
attrs2
,
// <java Demo attrs2 zipfile file [...]>
// test different ways to print attrs
prof
,
}
public
static
void
main
(
String
[]
args
)
throws
Throwable
{
Action
action
=
Action
.
valueOf
(
args
[
0
]);
;
Map
<
String
,
Object
>
env
=
env
=
new
HashMap
<
String
,
Object
>();
Action
action
=
Action
.
valueOf
(
args
[
0
]);
Map
<
String
,
Object
>
env
=
env
=
new
HashMap
<>();
if
(
action
==
Action
.
create
)
env
.
put
(
"createNew"
,
true
);
if
(
action
==
Action
.
tlist
||
action
==
Action
.
twalk
)
...
...
@@ -185,6 +196,16 @@ public class Demo {
dst
=
fs
.
getPath
(
args
[
3
]);
src
.
copyTo
(
dst
);
break
;
case
copyin_attrs:
src
=
Paths
.
get
(
args
[
2
]);
dst
=
fs
.
getPath
(
args
[
3
]);
src
.
copyTo
(
dst
,
COPY_ATTRIBUTES
);
break
;
case
copyout_attrs:
src
=
fs
.
getPath
(
args
[
2
]);
dst
=
Paths
.
get
(
args
[
3
]);
src
.
copyTo
(
dst
,
COPY_ATTRIBUTES
);
break
;
case
zzmove:
fs2
=
FileSystems
.
newFileSystem
(
URI
.
create
(
"zip"
+
Paths
.
get
(
args
[
2
]).
toUri
().
toString
().
substring
(
4
)),
...
...
@@ -206,6 +227,7 @@ public class Demo {
case
attrs:
for
(
int
i
=
2
;
i
<
args
.
length
;
i
++)
{
path
=
fs
.
getPath
(
args
[
i
]);
System
.
out
.
println
(
path
);
System
.
out
.
println
(
Attributes
.
readBasicFileAttributes
(
path
).
toString
());
}
...
...
@@ -221,6 +243,28 @@ public class Demo {
Attributes
.
readBasicFileAttributes
(
path
).
toString
());
}
break
;
case
setctime:
df
=
new
SimpleDateFormat
(
"MM/dd/yyyy-HH:mm:ss"
);
newDatetime
=
df
.
parse
(
args
[
2
]);
for
(
int
i
=
3
;
i
<
args
.
length
;
i
++)
{
path
=
fs
.
getPath
(
args
[
i
]);
path
.
setAttribute
(
"creationTime"
,
FileTime
.
fromMillis
(
newDatetime
.
getTime
()));
System
.
out
.
println
(
Attributes
.
readBasicFileAttributes
(
path
).
toString
());
}
break
;
case
setatime:
df
=
new
SimpleDateFormat
(
"MM/dd/yyyy-HH:mm:ss"
);
newDatetime
=
df
.
parse
(
args
[
2
]);
for
(
int
i
=
3
;
i
<
args
.
length
;
i
++)
{
path
=
fs
.
getPath
(
args
[
i
]);
path
.
setAttribute
(
"lastAccessTime"
,
FileTime
.
fromMillis
(
newDatetime
.
getTime
()));
System
.
out
.
println
(
Attributes
.
readBasicFileAttributes
(
path
).
toString
());
}
break
;
case
attrsspace:
path
=
fs
.
getPath
(
"/"
);
FileStore
fstore
=
path
.
getFileStore
();
...
...
@@ -293,6 +337,7 @@ public class Demo {
case
attrs2:
for
(
int
i
=
2
;
i
<
args
.
length
;
i
++)
{
path
=
fs
.
getPath
(
args
[
i
]);
System
.
out
.
printf
(
"%n%s%n"
,
path
);
System
.
out
.
println
(
"-------(1)---------"
);
System
.
out
.
println
(
Attributes
.
readBasicFileAttributes
(
path
).
toString
());
...
...
@@ -308,6 +353,13 @@ public class Demo {
}
}
break
;
case
prof:
list
(
fs
.
getPath
(
"/"
),
false
);
while
(
true
)
{
Thread
.
sleep
(
10000
);
//list(fs.getPath("/"), true);
System
.
out
.
println
(
"sleeping..."
);
}
}
}
catch
(
Exception
x
)
{
x
.
printStackTrace
();
...
...
@@ -501,10 +553,11 @@ public class Demo {
}
private
static
void
list
(
Path
path
,
boolean
verbose
)
throws
IOException
{
if
(
verbose
)
System
.
out
.
println
(
Attributes
.
readBasicFileAttributes
(
path
).
toString
());
else
System
.
out
.
printf
(
" %s%n"
,
path
.
toString
());
if
(!
"/"
.
equals
(
path
.
toString
()))
{
System
.
out
.
printf
(
" %s%n"
,
path
.
toString
());
if
(
verbose
)
System
.
out
.
println
(
Attributes
.
readBasicFileAttributes
(
path
).
toString
());
}
if
(
path
.
notExists
())
return
;
if
(
Attributes
.
readBasicFileAttributes
(
path
).
isDirectory
())
{
...
...
src/share/demo/nio/zipfs/README.txt
浏览文件 @
fa7b30b0
...
...
@@ -2,7 +2,7 @@ ZipFileSystem is a file system provider that treats the contents of a zip or
JAR file as a java.nio.file.FileSystem.
To deploy the provider you must copy zipfs.jar into your extensions
directory or else add <JDK_HOME>/demo/nio/
ZipFileSystem
/zipfs.jar
directory or else add <JDK_HOME>/demo/nio/
zipfs
/zipfs.jar
to your class path.
The factory methods defined by the java.nio.file.FileSystems class can be
...
...
@@ -10,8 +10,8 @@ used to create a FileSystem, eg:
// use file type detection
Map<String,?> env = Collections.emptyMap();
Path jarfile = Path.get("foo.jar");
FileSystem fs = FileSystems.newFileSystem(jarfile, env);
Path jarfile = Path
s
.get("foo.jar");
FileSystem fs = FileSystems.newFileSystem(jarfile, env
, null
);
-or
...
...
src/share/demo/nio/zipfs/com/sun/nio/zipfs/JarFileSystemProvider.java
浏览文件 @
fa7b30b0
...
...
@@ -68,4 +68,21 @@ public class JarFileSystemProvider extends ZipFileSystemProvider
throw
new
AssertionError
(
e
);
//never thrown
}
}
@Override
public
Path
getPath
(
URI
uri
)
{
FileSystem
fs
=
getFileSystem
(
uri
);
String
path
=
uri
.
getFragment
();
if
(
path
==
null
)
{
String
uristr
=
uri
.
toString
();
int
off
=
uristr
.
indexOf
(
"!/"
);
if
(
off
!=
-
1
)
path
=
uristr
.
substring
(
off
+
2
);
}
if
(
path
!=
null
)
return
fs
.
getPath
(
path
);
throw
new
IllegalArgumentException
(
"URI: "
+
uri
+
" does not contain path fragment ex. jar:///c:/foo.zip!/BAR"
);
}
}
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipConstants.java
浏览文件 @
fa7b30b0
...
...
@@ -31,7 +31,6 @@
package
com.sun.nio.zipfs
;
import
java.nio.ByteBuffer
;
/**
*
...
...
@@ -48,6 +47,7 @@ class ZipConstants {
static
final
int
METHOD_BZIP2
=
12
;
static
final
int
METHOD_LZMA
=
14
;
static
final
int
METHOD_LZ77
=
19
;
static
final
int
METHOD_AES
=
99
;
/*
* General purpose big flag
...
...
@@ -168,7 +168,8 @@ class ZipConstants {
static
final
int
EXTID_ZIP64
=
0x0001
;
// ZIP64
static
final
int
EXTID_NTFS
=
0x000a
;
// NTFS
static
final
int
EXTID_UNIX
=
0x000d
;
// UNIX
static
final
int
EXTID_EFS
=
0x0017
;
// Strong Encryption
static
final
int
EXTID_EXTT
=
0x5455
;
// Info-ZIP Extended Timestamp
/*
* fields access methods
...
...
@@ -226,34 +227,23 @@ class ZipConstants {
static
final
long
ZIP64_ENDOFF
(
byte
[]
b
)
{
return
LL
(
b
,
48
);}
// central directory offset
static
final
long
ZIP64_LOCOFF
(
byte
[]
b
)
{
return
LL
(
b
,
8
);}
// zip64 end offset
//////////////////////////////////////////
static
final
int
CH
(
ByteBuffer
b
,
int
pos
)
{
return
b
.
get
(
pos
)
&
0xff
;
}
static
final
int
SH
(
ByteBuffer
b
,
int
pos
)
{
return
b
.
getShort
(
pos
)
&
0xffff
;
}
static
final
long
LG
(
ByteBuffer
b
,
int
pos
)
{
return
b
.
getInt
(
pos
)
&
0xffffffff
L
;
}
// central directory header (END) fields
static
final
long
CENSIG
(
ByteBuffer
b
,
int
pos
)
{
return
LG
(
b
,
pos
+
0
);
}
static
final
int
CENVEM
(
ByteBuffer
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
4
);
}
static
final
int
CENVER
(
ByteBuffer
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
6
);
}
static
final
int
CENFLG
(
ByteBuffer
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
8
);
}
static
final
int
CENHOW
(
ByteBuffer
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
10
);}
static
final
long
CENTIM
(
ByteBuffer
b
,
int
pos
)
{
return
LG
(
b
,
pos
+
12
);}
static
final
long
CENCRC
(
ByteBuffer
b
,
int
pos
)
{
return
LG
(
b
,
pos
+
16
);}
static
final
long
CENSIZ
(
ByteBuffer
b
,
int
pos
)
{
return
LG
(
b
,
pos
+
20
);}
static
final
long
CENLEN
(
ByteBuffer
b
,
int
pos
)
{
return
LG
(
b
,
pos
+
24
);}
static
final
int
CENNAM
(
ByteBuffer
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
28
);}
static
final
int
CENEXT
(
ByteBuffer
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
30
);}
static
final
int
CENCOM
(
ByteBuffer
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
32
);}
static
final
int
CENDSK
(
ByteBuffer
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
34
);}
static
final
int
CENATT
(
ByteBuffer
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
36
);}
static
final
long
CENATX
(
ByteBuffer
b
,
int
pos
)
{
return
LG
(
b
,
pos
+
38
);}
static
final
long
CENOFF
(
ByteBuffer
b
,
int
pos
)
{
return
LG
(
b
,
pos
+
42
);}
// central directory header (CEN) fields
static
final
long
CENSIG
(
byte
[]
b
,
int
pos
)
{
return
LG
(
b
,
pos
+
0
);
}
static
final
int
CENVEM
(
byte
[]
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
4
);
}
static
final
int
CENVER
(
byte
[]
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
6
);
}
static
final
int
CENFLG
(
byte
[]
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
8
);
}
static
final
int
CENHOW
(
byte
[]
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
10
);}
static
final
long
CENTIM
(
byte
[]
b
,
int
pos
)
{
return
LG
(
b
,
pos
+
12
);}
static
final
long
CENCRC
(
byte
[]
b
,
int
pos
)
{
return
LG
(
b
,
pos
+
16
);}
static
final
long
CENSIZ
(
byte
[]
b
,
int
pos
)
{
return
LG
(
b
,
pos
+
20
);}
static
final
long
CENLEN
(
byte
[]
b
,
int
pos
)
{
return
LG
(
b
,
pos
+
24
);}
static
final
int
CENNAM
(
byte
[]
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
28
);}
static
final
int
CENEXT
(
byte
[]
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
30
);}
static
final
int
CENCOM
(
byte
[]
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
32
);}
static
final
int
CENDSK
(
byte
[]
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
34
);}
static
final
int
CENATT
(
byte
[]
b
,
int
pos
)
{
return
SH
(
b
,
pos
+
36
);}
static
final
long
CENATX
(
byte
[]
b
,
int
pos
)
{
return
LG
(
b
,
pos
+
38
);}
static
final
long
CENOFF
(
byte
[]
b
,
int
pos
)
{
return
LG
(
b
,
pos
+
42
);}
/* The END header is followed by a variable length comment of size < 64k. */
static
final
long
END_MAXLEN
=
0xFFFF
+
ENDHDR
;
...
...
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipDirectoryStream.java
浏览文件 @
fa7b30b0
...
...
@@ -38,7 +38,6 @@ import java.nio.file.Path;
import
java.util.Iterator
;
import
java.util.NoSuchElementException
;
import
java.io.IOException
;
import
static
com
.
sun
.
nio
.
zipfs
.
ZipUtils
.*;
/**
*
...
...
@@ -77,7 +76,7 @@ public class ZipDirectoryStream implements DirectoryStream<Path> {
}
catch
(
IOException
e
)
{
throw
new
IllegalStateException
(
e
);
}
return
new
Iterator
<
Path
>()
{
return
new
Iterator
<>()
{
private
Path
next
;
@Override
public
boolean
hasNext
()
{
...
...
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributeView.java
浏览文件 @
fa7b30b0
...
...
@@ -32,7 +32,6 @@
package
com.sun.nio.zipfs
;
import
java.nio.file.ReadOnlyFileSystemException
;
import
java.nio.file.attribute.BasicFileAttributeView
;
import
java.nio.file.attribute.FileAttributeView
;
import
java.nio.file.attribute.FileTime
;
...
...
@@ -113,6 +112,10 @@ public class ZipFileAttributeView implements BasicFileAttributeView
try
{
if
(
AttrID
.
valueOf
(
attribute
)
==
AttrID
.
lastModifiedTime
)
setTimes
((
FileTime
)
value
,
null
,
null
);
if
(
AttrID
.
valueOf
(
attribute
)
==
AttrID
.
lastAccessTime
)
setTimes
(
null
,
(
FileTime
)
value
,
null
);
if
(
AttrID
.
valueOf
(
attribute
)
==
AttrID
.
creationTime
)
setTimes
(
null
,
null
,
(
FileTime
)
value
);
return
;
}
catch
(
IllegalArgumentException
x
)
{}
throw
new
UnsupportedOperationException
(
"'"
+
attribute
+
...
...
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileAttributes.java
浏览文件 @
fa7b30b0
...
...
@@ -56,7 +56,7 @@ public class ZipFileAttributes implements BasicFileAttributes
@Override
public
FileTime
creationTime
()
{
if
(
e
.
ctime
!=
-
1
)
return
FileTime
.
fromMillis
(
dosToJavaTime
(
e
.
ctime
)
);
return
FileTime
.
fromMillis
(
e
.
ctime
);
return
null
;
}
...
...
@@ -78,13 +78,13 @@ public class ZipFileAttributes implements BasicFileAttributes
@Override
public
FileTime
lastAccessTime
()
{
if
(
e
.
atime
!=
-
1
)
return
FileTime
.
fromMillis
(
dosToJavaTime
(
e
.
atime
)
);
return
FileTime
.
fromMillis
(
e
.
atime
);
return
null
;
}
@Override
public
FileTime
lastModifiedTime
()
{
return
FileTime
.
fromMillis
(
dosToJavaTime
(
e
.
mtime
)
);
return
FileTime
.
fromMillis
(
e
.
mtime
);
}
@Override
...
...
@@ -103,10 +103,6 @@ public class ZipFileAttributes implements BasicFileAttributes
}
///////// zip entry attributes ///////////
public
byte
[]
name
()
{
return
Arrays
.
copyOf
(
e
.
name
,
e
.
name
.
length
);
}
public
long
compressedSize
()
{
return
e
.
csize
;
}
...
...
@@ -132,10 +128,13 @@ public class ZipFileAttributes implements BasicFileAttributes
}
public
String
toString
()
{
StringBuilder
sb
=
new
StringBuilder
();
StringBuilder
sb
=
new
StringBuilder
(
1024
);
Formatter
fm
=
new
Formatter
(
sb
);
fm
.
format
(
"[/%s]%n"
,
new
String
(
e
.
name
));
// TBD encoding
fm
.
format
(
" creationTime : %s%n"
,
creationTime
());
if
(
creationTime
()
!=
null
)
fm
.
format
(
" creationTime : %tc%n"
,
creationTime
().
toMillis
());
else
fm
.
format
(
" creationTime : null%n"
);
if
(
lastAccessTime
()
!=
null
)
fm
.
format
(
" lastAccessTime : %tc%n"
,
lastAccessTime
().
toMillis
());
else
...
...
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystem.java
浏览文件 @
fa7b30b0
...
...
@@ -35,19 +35,18 @@ import java.io.ByteArrayInputStream;
import
java.io.ByteArrayOutputStream
;
import
java.io.EOFException
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteOrder
;
import
java.nio.MappedByteBuffer
;
import
java.nio.channels.*
;
import
java.nio.file.*
;
import
java.nio.file.attribute.*
;
import
java.nio.file.spi.*
;
import
java.net.URI
;
import
java.util.*
;
import
java.util.concurrent.locks.ReadWriteLock
;
import
java.util.concurrent.locks.ReentrantReadWriteLock
;
import
java.util.regex.Pattern
;
import
java.util.zip.CRC32
;
import
java.util.zip.Inflater
;
...
...
@@ -76,8 +75,6 @@ public class ZipFileSystem extends FileSystem {
private
final
Path
zfpath
;
private
final
ZipCoder
zc
;
private
final
Object
lock
=
new
Object
();
// configurable by env map
private
final
String
defaultDir
;
// default dir for the file system
private
final
String
nameEncoding
;
// default encoding for name/comment
...
...
@@ -85,6 +82,8 @@ public class ZipFileSystem extends FileSystem {
private
final
boolean
useTempFile
;
// use a temp file for newOS, default
// is to use BAOS for better performance
private
final
boolean
createNew
;
// create a new zip if not exists
private
static
final
boolean
isWindows
=
System
.
getProperty
(
"os.name"
).
startsWith
(
"Windows"
);
ZipFileSystem
(
ZipFileSystemProvider
provider
,
Path
zfpath
,
...
...
@@ -92,13 +91,13 @@ public class ZipFileSystem extends FileSystem {
throws
IOException
{
// configurable env setup
this
.
buildDirTree
=
TRUE
.
equals
(
env
.
get
(
"buildDirTree"
));
this
.
useTempFile
=
TRUE
.
equals
(
env
.
get
(
"useTempFile"
));
this
.
createNew
=
TRUE
.
equals
(
env
.
get
(
"createNew"
));
this
.
buildDirTree
=
TRUE
.
equals
(
env
.
get
(
"buildDirTree
a
"
));
this
.
useTempFile
=
TRUE
.
equals
(
env
.
get
(
"useTempFile"
));
this
.
createNew
=
TRUE
.
equals
(
env
.
get
(
"createNew"
));
this
.
nameEncoding
=
env
.
containsKey
(
"nameEncoding"
)
?
(
String
)
env
.
get
(
"nameEncoding"
)
:
"UTF-8"
;
this
.
defaultDir
=
env
.
containsKey
(
"default.dir"
)
?
(
String
)
env
.
get
(
"default.dir"
)
:
"/"
;
this
.
defaultDir
=
env
.
containsKey
(
"default.dir"
)
?
(
String
)
env
.
get
(
"default.dir"
)
:
"/"
;
if
(
this
.
defaultDir
.
charAt
(
0
)
!=
'/'
)
throw
new
IllegalArgumentException
(
"default dir should be absolute"
);
...
...
@@ -121,7 +120,8 @@ public class ZipFileSystem extends FileSystem {
}
this
.
zc
=
ZipCoder
.
get
(
nameEncoding
);
this
.
defaultdir
=
new
ZipPath
(
this
,
getBytes
(
defaultDir
));
initZipFile
();
this
.
ch
=
zfpath
.
newByteChannel
(
READ
);
this
.
cen
=
initCEN
();
}
@Override
...
...
@@ -183,7 +183,7 @@ public class ZipFileSystem extends FileSystem {
@Override
public
Iterable
<
FileStore
>
getFileStores
()
{
ArrayList
<
FileStore
>
list
=
new
ArrayList
<
FileStore
>(
1
);
ArrayList
<
FileStore
>
list
=
new
ArrayList
<>(
1
);
list
.
add
(
new
ZipFileStore
(
new
ZipPath
(
this
,
new
byte
[]{
'/'
})));
return
list
;
}
...
...
@@ -240,19 +240,27 @@ public class ZipFileSystem extends FileSystem {
@Override
public
void
close
()
throws
IOException
{
synchronized
(
lock
)
{
beginWrite
();
try
{
if
(!
isOpen
)
return
;
isOpen
=
false
;
if
(!
streams
.
isEmpty
())
{
synchronized
(
streams
)
{
for
(
InputStream
is:
streams
)
is
.
close
();
}
}
isOpen
=
false
;
// set closed
}
finally
{
endWrite
();
}
if
(!
streams
.
isEmpty
())
{
// unlock and close all remaining streams
Set
<
InputStream
>
copy
=
new
HashSet
<>(
streams
);
for
(
InputStream
is:
copy
)
is
.
close
();
}
beginWrite
();
// lock and sync
try
{
sync
();
ch
.
close
();
ch
.
close
();
// close the ch just in case no update
}
finally
{
// and sync dose not close the ch
endWrite
();
}
synchronized
(
inflaters
)
{
for
(
Inflater
inf
:
inflaters
)
inf
.
end
();
...
...
@@ -261,97 +269,101 @@ public class ZipFileSystem extends FileSystem {
for
(
Deflater
def
:
deflaters
)
def
.
end
();
}
for
(
Path
p:
tmppaths
)
{
try
{
p
.
deleteIfExists
();
}
catch
(
IOException
x
)
{
x
.
printStackTrace
();
synchronized
(
tmppaths
)
{
for
(
Path
p:
tmppaths
)
{
try
{
p
.
deleteIfExists
();
}
catch
(
IOException
x
)
{
x
.
printStackTrace
();
}
}
}
provider
.
removeFileSystem
(
zfpath
);
}
ZipFileAttributes
[]
getAllAttributes
()
throws
IOException
{
ensureOpen
();
int
n
=
inodes
.
size
();
ZipFileAttributes
[]
zes
=
new
ZipFileAttributes
[
n
];
Iterator
<
IndexNode
>
itr
=
inodes
.
values
().
iterator
();
int
i
=
0
;
while
(
itr
.
hasNext
())
{
zes
[
i
++]
=
new
ZipFileAttributes
(
Entry
.
readCEN
(
cen
,
itr
.
next
().
pos
));
}
return
zes
;
}
EntryName
[]
getEntryNames
()
throws
IOException
{
ensureOpen
();
return
inodes
.
keySet
().
toArray
(
new
EntryName
[
0
]);
}
ZipFileAttributes
getFileAttributes
(
byte
[]
path
)
throws
IOException
{
synchronized
(
lock
)
{
Entry
e
=
getEntry0
(
path
);
if
(
e
==
null
)
{
if
(
path
.
length
==
0
)
{
e
=
new
Entry
(
new
byte
[
0
]);
// root
}
else
if
(
buildDirTree
)
{
IndexNode
inode
=
getDirs
().
get
(
new
EntryName
(
path
));
if
(
inode
==
null
)
return
null
;
e
=
new
Entry
(
inode
.
name
);
}
else
{
Entry
e
;
beginRead
();
try
{
ensureOpen
();
e
=
getEntry0
(
path
);
}
finally
{
endRead
();
}
if
(
e
==
null
)
{
if
(
path
.
length
==
0
)
{
e
=
new
Entry
(
new
byte
[
0
]);
// root
}
else
if
(
buildDirTree
)
{
IndexNode
inode
=
getDirs
().
get
(
IndexNode
.
keyOf
(
path
));
if
(
inode
==
null
)
return
null
;
}
e
.
method
=
METHOD_STORED
;
// STORED for dir
BasicFileAttributes
bfas
=
Attributes
.
readBasicFileAttributes
(
zfpath
);
if
(
bfas
.
lastModifiedTime
()
!=
null
)
e
.
mtime
=
javaToDosTime
(
bfas
.
lastModifiedTime
().
toMillis
());
if
(
bfas
.
lastAccessTime
()
!=
null
)
e
.
atime
=
javaToDosTime
(
bfas
.
lastAccessTime
().
toMillis
());
if
(
bfas
.
creationTime
()
!=
null
)
e
.
ctime
=
javaToDosTime
(
bfas
.
creationTime
().
toMillis
());
e
=
new
Entry
(
inode
.
name
);
}
else
{
return
null
;
}
return
new
ZipFileAttributes
(
e
);
e
.
method
=
METHOD_STORED
;
// STORED for dir
BasicFileAttributes
bfas
=
Attributes
.
readBasicFileAttributes
(
zfpath
);
if
(
bfas
.
lastModifiedTime
()
!=
null
)
e
.
mtime
=
bfas
.
lastModifiedTime
().
toMillis
();
if
(
bfas
.
lastAccessTime
()
!=
null
)
e
.
atime
=
bfas
.
lastAccessTime
().
toMillis
();
if
(
bfas
.
creationTime
()
!=
null
)
e
.
ctime
=
bfas
.
creationTime
().
toMillis
();
}
return
new
ZipFileAttributes
(
e
);
}
void
setTimes
(
byte
[]
path
,
FileTime
mtime
,
FileTime
atime
,
FileTime
ctime
)
throws
IOException
{
checkWritable
();
synchronized
(
lock
)
{
beginWrite
();
try
{
ensureOpen
();
Entry
e
=
getEntry0
(
path
);
// ensureOpen checked
if
(
e
==
null
)
throw
new
NoSuchFileException
(
getString
(
path
));
if
(
e
.
type
==
Entry
.
CEN
)
e
.
type
=
Entry
.
COPY
;
// copy e
if
(
mtime
!=
null
)
e
.
mtime
=
javaToDosTime
(
mtime
.
toMillis
()
);
e
.
mtime
=
mtime
.
toMillis
(
);
if
(
atime
!=
null
)
e
.
atime
=
javaToDosTime
(
atime
.
toMillis
()
);
e
.
atime
=
atime
.
toMillis
(
);
if
(
ctime
!=
null
)
e
.
ctime
=
javaToDosTime
(
ctime
.
toMillis
()
);
e
.
ctime
=
ctime
.
toMillis
(
);
update
(
e
);
}
finally
{
endWrite
();
}
}
boolean
exists
(
byte
[]
path
)
throws
IOException
{
return
getEntry0
(
path
)
!=
null
;
beginRead
();
try
{
ensureOpen
();
return
getEntry0
(
path
)
!=
null
;
}
finally
{
endRead
();
}
}
boolean
isDirectory
(
byte
[]
path
)
throws
IOException
{
synchronized
(
lock
)
{
if
(
buildDirTree
)
{
return
getDirs
().
containsKey
(
new
EntryName
(
path
));
}
if
(
buildDirTree
)
return
getDirs
().
containsKey
(
IndexNode
.
keyOf
(
path
));
beginRead
();
try
{
Entry
e
=
getEntry0
(
path
);
return
(
e
!=
null
&&
e
.
isDir
())
||
path
.
length
==
0
;
}
finally
{
endRead
();
}
}
...
...
@@ -368,12 +380,14 @@ public class ZipFileSystem extends FileSystem {
DirectoryStream
.
Filter
<?
super
Path
>
filter
)
throws
IOException
{
synchronized
(
lock
)
{
beginWrite
();
// iteration of inodes needs exclusive lock
try
{
ensureOpen
();
if
(
buildDirTree
)
{
IndexNode
inode
=
getDirs
().
get
(
new
EntryName
(
path
));
IndexNode
inode
=
getDirs
().
get
(
IndexNode
.
keyOf
(
path
));
if
(
inode
==
null
)
throw
new
NotDirectoryException
(
getString
(
path
));
List
<
Path
>
list
=
new
ArrayList
<
Path
>();
List
<
Path
>
list
=
new
ArrayList
<>();
IndexNode
child
=
inode
.
child
;
while
(
child
!=
null
)
{
ZipPath
zp
=
toZipPath
(
child
.
name
);
...
...
@@ -386,25 +400,26 @@ public class ZipFileSystem extends FileSystem {
if
(!
isDirectory
(
path
))
throw
new
NotDirectoryException
(
getString
(
path
));
List
<
Path
>
list
=
new
ArrayList
<
Path
>();
EntryName
[]
entries
=
getEntryNames
();
List
<
Path
>
list
=
new
ArrayList
<>();
path
=
toDirectoryPath
(
path
);
for
(
EntryName
en
:
entries
)
{
if
(!
isParentOf
(
path
,
en
.
name
))
// is "path" the parent of "name"
for
(
IndexNode
key
:
inodes
.
keySet
()
)
{
if
(!
isParentOf
(
path
,
key
.
name
))
// is "path" the parent of "name"
continue
;
int
off
=
path
.
length
;
while
(
off
<
en
.
name
.
length
)
{
if
(
en
.
name
[
off
]
==
'/'
)
while
(
off
<
key
.
name
.
length
)
{
if
(
key
.
name
[
off
]
==
'/'
)
break
;
off
++;
}
if
(
off
<
(
en
.
name
.
length
-
1
))
if
(
off
<
(
key
.
name
.
length
-
1
))
continue
;
ZipPath
zp
=
toZipPath
(
en
.
name
);
ZipPath
zp
=
toZipPath
(
key
.
name
);
if
(
filter
==
null
||
filter
.
accept
(
zp
))
list
.
add
(
zp
);
}
return
list
.
iterator
();
}
finally
{
endWrite
();
}
}
...
...
@@ -413,16 +428,18 @@ public class ZipFileSystem extends FileSystem {
{
checkWritable
();
dir
=
toDirectoryPath
(
dir
);
synchronized
(
lock
)
{
beginWrite
();
try
{
ensureOpen
();
// pseudo root dir, or exiting dir
if
(
dir
.
length
==
0
||
exists
(
dir
))
if
(
dir
.
length
==
0
||
exists
(
dir
))
// root dir, or exiting dir
throw
new
FileAlreadyExistsException
(
getString
(
dir
));
checkParents
(
dir
);
checkParents
(
dir
);
Entry
e
=
new
Entry
(
dir
,
Entry
.
NEW
);
e
.
method
=
METHOD_STORED
;
// STORED for dir
e
.
method
=
METHOD_STORED
;
// STORED for dir
update
(
e
);
}
finally
{
endWrite
();
}
}
...
...
@@ -432,7 +449,10 @@ public class ZipFileSystem extends FileSystem {
checkWritable
();
if
(
Arrays
.
equals
(
src
,
dst
))
return
;
// do nothing, src and dst are the same
synchronized
(
lock
)
{
beginWrite
();
try
{
ensureOpen
();
Entry
eSrc
=
getEntry0
(
src
);
// ensureOpen checked
if
(
eSrc
==
null
)
throw
new
NoSuchFileException
(
getString
(
src
));
...
...
@@ -457,11 +477,6 @@ public class ZipFileSystem extends FileSystem {
}
Entry
u
=
new
Entry
(
eSrc
,
Entry
.
COPY
);
// copy eSrc entry
u
.
name
=
dst
;
// change name
// don't touch the "nlen and elen" here. writeLOC() always
// re-calculate from "name" and "extra" for the correct length,
// copyLOCEntry however needs the original lengths to skip the
// loc header.
// u.nlen = dst.length;
if
(
eSrc
.
type
==
Entry
.
NEW
||
eSrc
.
type
==
Entry
.
FILECH
)
{
u
.
type
=
eSrc
.
type
;
// make it the same type
...
...
@@ -475,10 +490,12 @@ public class ZipFileSystem extends FileSystem {
}
}
if
(!
hasCopyAttrs
)
u
.
mtime
=
u
.
atime
=
u
.
ctime
=
javaToDosTime
(
System
.
currentTimeMillis
()
);
u
.
mtime
=
u
.
atime
=
u
.
ctime
=
System
.
currentTimeMillis
(
);
update
(
u
);
if
(
deletesrc
)
updateDelete
(
eSrc
);
}
finally
{
endWrite
();
}
}
...
...
@@ -501,7 +518,9 @@ public class ZipFileSystem extends FileSystem {
if
(
opt
==
APPEND
)
hasAppend
=
true
;
}
synchronized
(
lock
)
{
beginRead
();
// only need a readlock, the "update()" will
try
{
// try to obtain a writelock when the os is
ensureOpen
();
// being closed.
Entry
e
=
getEntry0
(
path
);
if
(
e
!=
null
)
{
if
(
e
.
isDir
()
||
hasCreateNew
)
...
...
@@ -512,27 +531,33 @@ public class ZipFileSystem extends FileSystem {
copyStream
(
is
,
os
);
is
.
close
();
return
os
;
}
return
getOutputStream
(
new
Entry
(
e
,
Entry
.
NEW
));
}
return
getOutputStream
(
new
Entry
(
e
,
Entry
.
NEW
));
}
else
{
if
(!
hasCreate
&&
!
hasCreateNew
)
throw
new
NoSuchFileException
(
getString
(
path
));
checkParents
(
path
);
return
getOutputStream
(
new
Entry
(
path
,
Entry
.
NEW
));
}
}
finally
{
endRead
();
}
}
// Returns an input stream for reading the contents of the specified
// file entry.
InputStream
newInputStream
(
byte
[]
path
)
throws
IOException
{
synchronized
(
lock
)
{
beginRead
();
try
{
ensureOpen
();
Entry
e
=
getEntry0
(
path
);
if
(
e
==
null
)
throw
new
NoSuchFileException
(
getString
(
path
));
if
(
e
.
isDir
())
throw
new
FileSystemException
(
getString
(
path
),
"is a directory"
,
null
);
return
getInputStream
(
e
);
}
finally
{
endRead
();
}
}
...
...
@@ -559,78 +584,111 @@ public class ZipFileSystem extends FileSystem {
if
(
options
.
contains
(
StandardOpenOption
.
WRITE
)
||
options
.
contains
(
StandardOpenOption
.
APPEND
))
{
checkWritable
();
final
WritableByteChannel
wbc
=
Channels
.
newChannel
(
newOutputStream
(
path
,
options
.
toArray
(
new
OpenOption
[
0
])));
long
leftover
=
0
;;
if
(
options
.
contains
(
StandardOpenOption
.
APPEND
))
{
Entry
e
=
getEntry0
(
path
);
if
(
e
!=
null
&&
e
.
size
>=
0
)
leftover
=
e
.
size
;
}
final
long
offset
=
leftover
;
return
new
SeekableByteChannel
()
{
long
written
=
offset
;
public
boolean
isOpen
()
{
return
wbc
.
isOpen
();
}
public
long
position
()
throws
IOException
{
return
written
;
}
public
SeekableByteChannel
position
(
long
pos
)
throws
IOException
{
throw
new
UnsupportedOperationException
();
}
public
int
read
(
ByteBuffer
dst
)
throws
IOException
{
throw
new
UnsupportedOperationException
();
}
public
SeekableByteChannel
truncate
(
long
size
)
throws
IOException
{
throw
new
UnsupportedOperationException
();
}
public
int
write
(
ByteBuffer
src
)
throws
IOException
{
int
n
=
wbc
.
write
(
src
);
written
+=
n
;
return
n
;
}
public
long
size
()
throws
IOException
{
return
written
;
}
public
void
close
()
throws
IOException
{
wbc
.
close
();
beginRead
();
try
{
final
WritableByteChannel
wbc
=
Channels
.
newChannel
(
newOutputStream
(
path
,
options
.
toArray
(
new
OpenOption
[
0
])));
long
leftover
=
0
;
if
(
options
.
contains
(
StandardOpenOption
.
APPEND
))
{
Entry
e
=
getEntry0
(
path
);
if
(
e
!=
null
&&
e
.
size
>=
0
)
leftover
=
e
.
size
;
}
};
final
long
offset
=
leftover
;
return
new
SeekableByteChannel
()
{
long
written
=
offset
;
public
boolean
isOpen
()
{
return
wbc
.
isOpen
();
}
public
long
position
()
throws
IOException
{
return
written
;
}
public
SeekableByteChannel
position
(
long
pos
)
throws
IOException
{
throw
new
UnsupportedOperationException
();
}
public
int
read
(
ByteBuffer
dst
)
throws
IOException
{
throw
new
UnsupportedOperationException
();
}
public
SeekableByteChannel
truncate
(
long
size
)
throws
IOException
{
throw
new
UnsupportedOperationException
();
}
public
int
write
(
ByteBuffer
src
)
throws
IOException
{
int
n
=
wbc
.
write
(
src
);
written
+=
n
;
return
n
;
}
public
long
size
()
throws
IOException
{
return
written
;
}
public
void
close
()
throws
IOException
{
wbc
.
close
();
}
};
}
finally
{
endRead
();
}
}
else
{
Entry
e
=
getEntry0
(
path
);
if
(
e
==
null
||
e
.
isDir
())
throw
new
NoSuchFileException
(
getString
(
path
));
final
ReadableByteChannel
rbc
=
Channels
.
newChannel
(
getInputStream
(
e
));
final
long
size
=
e
.
size
;
return
new
SeekableByteChannel
()
{
long
read
=
0
;
public
boolean
isOpen
()
{
return
rbc
.
isOpen
();
}
public
long
position
()
throws
IOException
{
return
read
;
}
public
SeekableByteChannel
position
(
long
pos
)
throws
IOException
{
throw
new
UnsupportedOperationException
();
}
public
int
read
(
ByteBuffer
dst
)
throws
IOException
{
return
rbc
.
read
(
dst
);
}
public
SeekableByteChannel
truncate
(
long
size
)
throws
IOException
{
throw
new
NonWritableChannelException
();
}
public
int
write
(
ByteBuffer
src
)
throws
IOException
{
throw
new
NonWritableChannelException
();
}
public
long
size
()
throws
IOException
{
return
size
;
}
public
void
close
()
throws
IOException
{
rbc
.
close
();
}
};
beginRead
();
try
{
ensureOpen
();
Entry
e
=
getEntry0
(
path
);
if
(
e
==
null
||
e
.
isDir
())
throw
new
NoSuchFileException
(
getString
(
path
));
final
ReadableByteChannel
rbc
=
Channels
.
newChannel
(
getInputStream
(
e
));
final
long
size
=
e
.
size
;
return
new
SeekableByteChannel
()
{
long
read
=
0
;
public
boolean
isOpen
()
{
return
rbc
.
isOpen
();
}
public
long
position
()
throws
IOException
{
return
read
;
}
public
SeekableByteChannel
position
(
long
pos
)
throws
IOException
{
throw
new
UnsupportedOperationException
();
}
public
int
read
(
ByteBuffer
dst
)
throws
IOException
{
return
rbc
.
read
(
dst
);
}
public
SeekableByteChannel
truncate
(
long
size
)
throws
IOException
{
throw
new
NonWritableChannelException
();
}
public
int
write
(
ByteBuffer
src
)
throws
IOException
{
throw
new
NonWritableChannelException
();
}
public
long
size
()
throws
IOException
{
return
size
;
}
public
void
close
()
throws
IOException
{
rbc
.
close
();
}
};
}
finally
{
endRead
();
}
}
}
...
...
@@ -647,125 +705,131 @@ public class ZipFileSystem extends FileSystem {
checkOptions
(
options
);
final
boolean
forWrite
=
(
options
.
contains
(
StandardOpenOption
.
WRITE
)
||
options
.
contains
(
StandardOpenOption
.
APPEND
));
Entry
e
=
getEntry0
(
path
);
if
(
forWrite
)
{
checkWritable
();
if
(
e
==
null
)
{
beginRead
();
try
{
ensureOpen
();
Entry
e
=
getEntry0
(
path
);
if
(
forWrite
)
{
checkWritable
();
if
(
e
==
null
)
{
if
(!
options
.
contains
(
StandardOpenOption
.
CREATE_NEW
))
throw
new
NoSuchFileException
(
getString
(
path
));
}
else
{
if
(
options
.
contains
(
StandardOpenOption
.
CREATE_NEW
))
throw
new
FileAlreadyExistsException
(
getString
(
path
));
if
(
e
.
isDir
())
throw
new
FileAlreadyExistsException
(
"directory <"
+
getString
(
path
)
+
"> exists"
);
}
options
.
remove
(
StandardOpenOption
.
CREATE_NEW
);
// for tmpfile
}
else
if
(
e
==
null
||
e
.
isDir
())
{
throw
new
NoSuchFileException
(
getString
(
path
));
}
final
boolean
isFCH
=
(
e
!=
null
&&
e
.
type
==
Entry
.
FILECH
);
final
Path
tmpfile
=
isFCH
?
e
.
file
:
getTempPathForEntry
(
path
);
final
FileChannel
fch
=
tmpfile
.
getFileSystem
()
.
provider
()
.
newFileChannel
(
tmpfile
,
options
,
attrs
);
final
Entry
u
=
isFCH
?
e
:
new
Entry
(
path
,
tmpfile
,
Entry
.
FILECH
);
if
(
forWrite
)
{
u
.
flag
=
FLAG_DATADESCR
;
u
.
method
=
METHOD_DEFLATED
;
}
// is there a better way to hook into the FileChannel's close method?
return
new
FileChannel
()
{
public
int
write
(
ByteBuffer
src
)
throws
IOException
{
return
fch
.
write
(
src
);
}
public
long
write
(
ByteBuffer
[]
srcs
,
int
offset
,
int
length
)
throws
IOException
{
return
fch
.
write
(
srcs
,
offset
,
length
);
}
public
long
position
()
throws
IOException
{
return
fch
.
position
();
}
public
FileChannel
position
(
long
newPosition
)
throws
IOException
{
fch
.
position
(
newPosition
);
return
this
;
}
public
long
size
()
throws
IOException
{
return
fch
.
size
();
}
public
FileChannel
truncate
(
long
size
)
throws
IOException
{
fch
.
truncate
(
size
);
return
this
;
}
public
void
force
(
boolean
metaData
)
throws
IOException
{
fch
.
force
(
metaData
);
}
public
long
transferTo
(
long
position
,
long
count
,
WritableByteChannel
target
)
throws
IOException
{
return
fch
.
transferTo
(
position
,
count
,
target
);
}
public
long
transferFrom
(
ReadableByteChannel
src
,
long
position
,
long
count
)
throws
IOException
{
return
fch
.
transferFrom
(
src
,
position
,
count
);
}
public
int
read
(
ByteBuffer
dst
)
throws
IOException
{
return
fch
.
read
(
dst
);
}
public
int
read
(
ByteBuffer
dst
,
long
position
)
throws
IOException
{
return
fch
.
read
(
dst
,
position
);
}
public
long
read
(
ByteBuffer
[]
dsts
,
int
offset
,
int
length
)
throws
IOException
{
return
fch
.
read
(
dsts
,
offset
,
length
);
}
public
int
write
(
ByteBuffer
src
,
long
position
)
throws
IOException
{
return
fch
.
write
(
src
,
position
);
}
public
MappedByteBuffer
map
(
MapMode
mode
,
long
position
,
long
size
)
throws
IOException
{
throw
new
UnsupportedOperationException
();
}
public
FileLock
lock
(
long
position
,
long
size
,
boolean
shared
)
throws
IOException
{
return
fch
.
lock
(
position
,
size
,
shared
);
}
public
FileLock
tryLock
(
long
position
,
long
size
,
boolean
shared
)
throws
IOException
{
return
fch
.
tryLock
(
position
,
size
,
shared
);
}
protected
void
implCloseChannel
()
throws
IOException
{
fch
.
close
();
if
(
forWrite
)
{
u
.
mtime
=
javaToDosTime
(
System
.
currentTimeMillis
());
u
.
size
=
Attributes
.
readBasicFileAttributes
(
u
.
file
).
size
();
update
(
u
);
}
else
{
if
(!
isFCH
)
// if this is a new fch for reading
removeTempPathForEntry
(
tmpfile
);
if
(
options
.
contains
(
StandardOpenOption
.
CREATE_NEW
))
throw
new
FileAlreadyExistsException
(
getString
(
path
));
if
(
e
.
isDir
())
throw
new
FileAlreadyExistsException
(
"directory <"
+
getString
(
path
)
+
"> exists"
);
}
options
.
remove
(
StandardOpenOption
.
CREATE_NEW
);
// for tmpfile
}
else
if
(
e
==
null
||
e
.
isDir
())
{
throw
new
NoSuchFileException
(
getString
(
path
));
}
};
final
boolean
isFCH
=
(
e
!=
null
&&
e
.
type
==
Entry
.
FILECH
);
final
Path
tmpfile
=
isFCH
?
e
.
file
:
getTempPathForEntry
(
path
);
final
FileChannel
fch
=
tmpfile
.
getFileSystem
()
.
provider
()
.
newFileChannel
(
tmpfile
,
options
,
attrs
);
final
Entry
u
=
isFCH
?
e
:
new
Entry
(
path
,
tmpfile
,
Entry
.
FILECH
);
if
(
forWrite
)
{
u
.
flag
=
FLAG_DATADESCR
;
u
.
method
=
METHOD_DEFLATED
;
}
// is there a better way to hook into the FileChannel's close method?
return
new
FileChannel
()
{
public
int
write
(
ByteBuffer
src
)
throws
IOException
{
return
fch
.
write
(
src
);
}
public
long
write
(
ByteBuffer
[]
srcs
,
int
offset
,
int
length
)
throws
IOException
{
return
fch
.
write
(
srcs
,
offset
,
length
);
}
public
long
position
()
throws
IOException
{
return
fch
.
position
();
}
public
FileChannel
position
(
long
newPosition
)
throws
IOException
{
fch
.
position
(
newPosition
);
return
this
;
}
public
long
size
()
throws
IOException
{
return
fch
.
size
();
}
public
FileChannel
truncate
(
long
size
)
throws
IOException
{
fch
.
truncate
(
size
);
return
this
;
}
public
void
force
(
boolean
metaData
)
throws
IOException
{
fch
.
force
(
metaData
);
}
public
long
transferTo
(
long
position
,
long
count
,
WritableByteChannel
target
)
throws
IOException
{
return
fch
.
transferTo
(
position
,
count
,
target
);
}
public
long
transferFrom
(
ReadableByteChannel
src
,
long
position
,
long
count
)
throws
IOException
{
return
fch
.
transferFrom
(
src
,
position
,
count
);
}
public
int
read
(
ByteBuffer
dst
)
throws
IOException
{
return
fch
.
read
(
dst
);
}
public
int
read
(
ByteBuffer
dst
,
long
position
)
throws
IOException
{
return
fch
.
read
(
dst
,
position
);
}
public
long
read
(
ByteBuffer
[]
dsts
,
int
offset
,
int
length
)
throws
IOException
{
return
fch
.
read
(
dsts
,
offset
,
length
);
}
public
int
write
(
ByteBuffer
src
,
long
position
)
throws
IOException
{
return
fch
.
write
(
src
,
position
);
}
public
MappedByteBuffer
map
(
MapMode
mode
,
long
position
,
long
size
)
throws
IOException
{
throw
new
UnsupportedOperationException
();
}
public
FileLock
lock
(
long
position
,
long
size
,
boolean
shared
)
throws
IOException
{
return
fch
.
lock
(
position
,
size
,
shared
);
}
public
FileLock
tryLock
(
long
position
,
long
size
,
boolean
shared
)
throws
IOException
{
return
fch
.
tryLock
(
position
,
size
,
shared
);
}
protected
void
implCloseChannel
()
throws
IOException
{
fch
.
close
();
if
(
forWrite
)
{
u
.
mtime
=
System
.
currentTimeMillis
();
u
.
size
=
Attributes
.
readBasicFileAttributes
(
u
.
file
).
size
();
update
(
u
);
}
else
{
if
(!
isFCH
)
// if this is a new fch for reading
removeTempPathForEntry
(
tmpfile
);
}
}
};
}
finally
{
endRead
();
}
}
// the outstanding input streams that need to be closed
...
...
@@ -776,11 +840,9 @@ public class ZipFileSystem extends FileSystem {
// input streams are all closed by the obtainers.
private
Set
<
ExChannelCloser
>
exChClosers
=
new
HashSet
<>();
private
Set
<
Path
>
tmppaths
=
new
HashSet
<>(
);
private
Set
<
Path
>
tmppaths
=
Collections
.
synchronizedSet
(
new
HashSet
<
Path
>()
);
private
Path
getTempPathForEntry
(
byte
[]
path
)
throws
IOException
{
Path
tmpPath
=
createTempFileInSameDirectoryAs
(
zfpath
);
tmppaths
.
add
(
tmpPath
);
if
(
path
!=
null
)
{
Entry
e
=
getEntry0
(
path
);
if
(
e
!=
null
)
{
...
...
@@ -805,9 +867,14 @@ public class ZipFileSystem extends FileSystem {
// check if all parents really exit. ZIP spec does not require
// the existence of any "parent directory".
private
void
checkParents
(
byte
[]
path
)
throws
IOException
{
while
((
path
=
getParent
(
path
))
!=
null
)
{
if
(!
inodes
.
containsKey
(
new
EntryName
(
path
)))
throw
new
NoSuchFileException
(
getString
(
path
));
beginRead
();
try
{
while
((
path
=
getParent
(
path
))
!=
null
)
{
if
(!
inodes
.
containsKey
(
IndexNode
.
keyOf
(
path
)))
throw
new
NoSuchFileException
(
getString
(
path
));
}
}
finally
{
endRead
();
}
}
...
...
@@ -839,25 +906,40 @@ public class ZipFileSystem extends FileSystem {
return
true
;
}
///////////////////////////////////////////////////////////////////
private
void
initZipFile
()
throws
IOException
{
ch
=
zfpath
.
newByteChannel
(
READ
);
initCEN
();
private
final
void
beginWrite
()
{
rwlock
.
writeLock
().
lock
();
}
private
final
void
endWrite
()
{
rwlock
.
writeLock
().
unlock
();
}
private
final
void
beginRead
()
{
rwlock
.
readLock
().
lock
();
}
private
final
void
endRead
()
{
rwlock
.
readLock
().
unlock
();
}
///////////////////////////////////////////////////////////////////
private
volatile
boolean
isOpen
=
true
;
private
SeekableByteChannel
ch
;
// channel to the zipfile
ByteBuffer
cen
;
// CEN & ENDHDR
private
final
SeekableByteChannel
ch
;
// channel to the zipfile
final
byte
[]
cen
;
// CEN & ENDHDR
private
END
end
;
private
long
locpos
;
// position of first LOC header (usually 0)
// name -> pos (in cen), package private for ZipInfo
LinkedHashMap
<
EntryName
,
IndexNode
>
inodes
;
private
final
ReadWriteLock
rwlock
=
new
ReentrantReadWriteLock
();
// name -> pos (in cen), IndexNode itself can be used as a "key"
private
LinkedHashMap
<
IndexNode
,
IndexNode
>
inodes
;
byte
[]
getBytes
(
String
name
)
{
final
byte
[]
getBytes
(
String
name
)
{
return
zc
.
getBytes
(
name
);
}
String
getString
(
byte
[]
name
)
{
final
String
getString
(
byte
[]
name
)
{
return
zc
.
toString
(
name
);
}
...
...
@@ -881,7 +963,7 @@ public class ZipFileSystem extends FileSystem {
// Reads len bytes of data from the specified offset into buf.
// Returns the total number of bytes read.
// Each/every byte read from here (except the cen, which is mapped).
private
long
readFullyAt
(
byte
[]
buf
,
int
off
,
long
len
,
long
pos
)
final
long
readFullyAt
(
byte
[]
buf
,
int
off
,
long
len
,
long
pos
)
throws
IOException
{
ByteBuffer
bb
=
ByteBuffer
.
wrap
(
buf
);
...
...
@@ -890,7 +972,7 @@ public class ZipFileSystem extends FileSystem {
return
readFullyAt
(
bb
,
pos
);
}
private
long
readFullyAt
(
ByteBuffer
bb
,
long
pos
)
private
final
long
readFullyAt
(
ByteBuffer
bb
,
long
pos
)
throws
IOException
{
synchronized
(
ch
)
{
...
...
@@ -971,12 +1053,12 @@ public class ZipFileSystem extends FileSystem {
// CEN header, otherwise returns -1 if an error occured. If zip->msg != NULL
// then the error was a zip format error and zip->msg has the error text.
// Always pass in -1 for knownTotal; it's used for a recursive call.
private
long
initCEN
()
throws
IOException
{
private
byte
[]
initCEN
()
throws
IOException
{
end
=
findEND
();
if
(
end
.
endpos
==
0
)
{
inodes
=
new
LinkedHashMap
<
EntryName
,
IndexNode
>(
10
);
inodes
=
new
LinkedHashMap
<>(
10
);
locpos
=
0
;
return
0
;
// only END header present
return
null
;
// only END header present
}
if
(
end
.
cenlen
>
end
.
endpos
)
zerror
(
"invalid END header (bad central directory size)"
);
...
...
@@ -989,18 +1071,14 @@ public class ZipFileSystem extends FileSystem {
zerror
(
"invalid END header (bad central directory offset)"
);
// read in the CEN and END
cen
=
ByteBuffer
.
allocate
((
int
)(
end
.
cenlen
+
ENDHDR
))
;
if
(
readFullyAt
(
cen
,
cenpos
)
!=
end
.
cenlen
+
ENDHDR
)
{
byte
[]
cen
=
new
byte
[(
int
)(
end
.
cenlen
+
ENDHDR
)]
;
if
(
readFullyAt
(
cen
,
0
,
cen
.
length
,
cenpos
)
!=
end
.
cenlen
+
ENDHDR
)
{
zerror
(
"read CEN tables failed"
);
}
cen
.
order
(
ByteOrder
.
LITTLE_ENDIAN
).
flip
();
// Iterate through the entries in the central directory
inodes
=
new
LinkedHashMap
<
EntryName
,
IndexNode
>(
end
.
centot
+
1
);
inodes
=
new
LinkedHashMap
<>(
end
.
centot
+
1
);
int
pos
=
0
;
int
limit
=
cen
.
remaining
()
-
ENDHDR
;
int
i
=
0
;
byte
[]
bBuf
=
new
byte
[
1024
];
int
limit
=
cen
.
length
-
ENDHDR
;
while
(
pos
<
limit
)
{
if
(
CENSIG
(
cen
,
pos
)
!=
CENSIG
)
zerror
(
"invalid CEN header (bad signature)"
);
...
...
@@ -1011,24 +1089,19 @@ public class ZipFileSystem extends FileSystem {
if
((
CENFLG
(
cen
,
pos
)
&
1
)
!=
0
)
zerror
(
"invalid CEN header (encrypted entry)"
);
if
(
method
!=
METHOD_STORED
&&
method
!=
METHOD_DEFLATED
)
zerror
(
"invalid CEN header (
ba
d compression method: "
+
method
+
")"
);
zerror
(
"invalid CEN header (
unsupporte
d compression method: "
+
method
+
")"
);
if
(
pos
+
CENHDR
+
nlen
>
limit
)
zerror
(
"invalid CEN header (bad header size)"
);
if
(
bBuf
.
length
<
nlen
)
bBuf
=
new
byte
[
nlen
];
cen
.
position
(
pos
+
CENHDR
);
byte
[]
name
=
new
byte
[
nlen
];
cen
.
get
(
name
);
inodes
.
put
(
new
EntryName
(
name
),
new
IndexNode
(
name
,
pos
));
byte
[]
name
=
Arrays
.
copyOfRange
(
cen
,
pos
+
CENHDR
,
pos
+
CENHDR
+
nlen
);
IndexNode
inode
=
new
IndexNode
(
name
,
pos
);
inodes
.
put
(
inode
,
inode
);
// skip ext and comment
cen
.
position
(
pos
+=
(
CENHDR
+
nlen
+
elen
+
clen
));
i
++;
pos
+=
(
CENHDR
+
nlen
+
elen
+
clen
);
}
if
(
cen
.
remaining
()
!=
ENDHDR
)
{
if
(
pos
+
ENDHDR
!=
cen
.
length
)
{
zerror
(
"invalid CEN header (bad header size)"
);
}
dirs
=
null
;
// clear the dir map
return
cenpos
;
return
cen
;
}
private
void
ensureOpen
()
throws
IOException
{
...
...
@@ -1038,27 +1111,40 @@ public class ZipFileSystem extends FileSystem {
// Creates a new empty temporary file in the same directory as the
// specified file. A variant of File.createTempFile.
private
static
Path
createTempFileInSameDirectoryAs
(
Path
path
)
private
Path
createTempFileInSameDirectoryAs
(
Path
path
)
throws
IOException
{
Path
parent
=
path
.
toAbsolutePath
().
getParent
();
String
dir
=
(
parent
==
null
)?
"."
:
parent
.
toString
();
return
File
.
createTempFile
(
"zipfstmp"
,
null
,
new
File
(
dir
)).
toPath
();
Path
tmpPath
=
File
.
createTempFile
(
"zipfstmp"
,
null
,
new
File
(
dir
)).
toPath
();
tmppaths
.
add
(
tmpPath
);
return
tmpPath
;
}
////////////////////update & sync //////////////////////////////////////
private
boolean
hasUpdate
=
false
;
private
void
updateDelete
(
Entry
e
)
{
EntryName
en
=
new
EntryName
(
e
.
name
);
inodes
.
remove
(
en
);
hasUpdate
=
true
;
beginWrite
();
try
{
inodes
.
remove
(
IndexNode
.
keyOf
(
e
.
name
));
//inodes.remove(e.name);
hasUpdate
=
true
;
dirs
=
null
;
}
finally
{
endWrite
();
}
}
private
void
update
(
Entry
e
)
{
EntryName
en
=
new
EntryName
(
e
.
name
);
inodes
.
put
(
en
,
e
);
hasUpdate
=
true
;
beginWrite
();
try
{
inodes
.
put
(
IndexNode
.
keyOf
(
e
.
name
),
e
);
//inodes.put(e, e);
hasUpdate
=
true
;
dirs
=
null
;
}
finally
{
endWrite
();
}
}
// copy over the whole LOC entry (header if necessary, data and ext) from
...
...
@@ -1080,13 +1166,18 @@ public class ZipFileSystem extends FileSystem {
else
size
=
16
;
}
if
(
updateHeader
)
{
// if we need update the loc header
locoff
+=
LOCHDR
+
e
.
nlen
+
e
.
elen
;
// skip header
// read loc, use the original loc.elen/nlen
if
(
readFullyAt
(
buf
,
0
,
LOCHDR
,
locoff
)
!=
LOCHDR
)
throw
new
ZipException
(
"loc: reading failed"
);
if
(
updateHeader
)
{
locoff
+=
LOCHDR
+
LOCNAM
(
buf
)
+
LOCEXT
(
buf
);
// skip header
size
+=
e
.
csize
;
written
=
e
.
writeLOC
(
os
)
+
size
;
}
else
{
size
+=
LOCHDR
+
e
.
nlen
+
e
.
elen
+
e
.
csize
;
written
=
size
;
os
.
write
(
buf
,
0
,
LOCHDR
);
// write out the loc header
locoff
+=
LOCHDR
;
size
+=
LOCNAM
(
buf
)
+
LOCEXT
(
buf
)
+
LOCSIZ
(
buf
);
written
=
LOCHDR
+
size
;
}
int
n
;
while
(
size
>
0
&&
...
...
@@ -1103,7 +1194,7 @@ public class ZipFileSystem extends FileSystem {
// sync the zip file system, if there is any udpate
private
void
sync
()
throws
IOException
{
assert
Thread
.
holdsLock
(
this
);
//System.out.printf("->sync(%s) starting....!%n", toString()
);
// check ex-closer
if
(!
exChClosers
.
isEmpty
())
{
...
...
@@ -1117,7 +1208,6 @@ public class ZipFileSystem extends FileSystem {
}
if
(!
hasUpdate
)
return
;
Path
tmpFile
=
createTempFileInSameDirectoryAs
(
zfpath
);
OutputStream
os
=
tmpFile
.
newOutputStream
(
WRITE
);
ArrayList
<
Entry
>
elist
=
new
ArrayList
<>(
inodes
.
size
());
...
...
@@ -1174,7 +1264,7 @@ public class ZipFileSystem extends FileSystem {
x
.
printStackTrace
();
// skip any in-accurate entry
}
}
else
{
// unchanged inode
e
=
Entry
.
readCEN
(
cen
,
inode
.
pos
);
e
=
Entry
.
readCEN
(
this
,
inode
.
pos
);
try
{
written
+=
copyLOCEntry
(
e
,
false
,
os
,
written
,
buf
);
elist
.
add
(
e
);
...
...
@@ -1195,6 +1285,11 @@ public class ZipFileSystem extends FileSystem {
os
.
close
();
if
(!
streams
.
isEmpty
())
{
//
// TBD: ExChannelCloser should not be necessary if we only
// sync when being closed, all streams should have been
// closed already. Keep the logic here for now.
//
// There are outstanding input streams open on existing "ch",
// so, don't close the "cha" and delete the "file for now, let
// the "ex-channel-closer" to handle them
...
...
@@ -1209,45 +1304,41 @@ public class ZipFileSystem extends FileSystem {
ch
.
close
();
zfpath
.
delete
();
}
tmpFile
.
moveTo
(
zfpath
,
REPLACE_EXISTING
);
hasUpdate
=
false
;
// clear
/*
if (isOpen) {
ch = zfpath.newByteChannel(READ); // re-fresh "ch" and "cen"
initCEN
();
cen =
initCEN();
}
//System.out.println("->sync() done!");
*/
//System.out.printf("->sync(%s) done!%n", toString());
}
private
Entry
getEntry0
(
byte
[]
path
)
throws
IOException
{
assert
Thread
.
holdsLock
(
this
);
if
(
path
==
null
)
throw
new
NullPointerException
(
"path"
);
if
(
path
.
length
==
0
)
return
null
;
EntryName
en
=
new
EntryName
(
path
);
IndexNode
inode
=
null
;
synchronized
(
lock
)
{
ensureOpen
();
if
((
inode
=
inodes
.
get
(
en
))
==
null
)
{
if
(
path
[
path
.
length
-
1
]
==
'/'
)
// already has a slash
return
null
;
path
=
Arrays
.
copyOf
(
path
,
path
.
length
+
1
);
path
[
path
.
length
-
1
]
=
'/'
;
en
.
name
(
path
);
if
((
inode
=
inodes
.
get
(
en
))
==
null
)
return
null
;
}
if
(
inode
instanceof
Entry
)
return
(
Entry
)
inode
;
return
Entry
.
readCEN
(
cen
,
inode
.
pos
);
IndexNode
key
=
IndexNode
.
keyOf
(
path
);
if
((
inode
=
inodes
.
get
(
key
))
==
null
)
{
if
(
path
[
path
.
length
-
1
]
==
'/'
)
// already has a slash
return
null
;
path
=
Arrays
.
copyOf
(
path
,
path
.
length
+
1
);
path
[
path
.
length
-
1
]
=
'/'
;
if
((
inode
=
inodes
.
get
(
key
.
as
(
path
)))
==
null
)
return
null
;
}
if
(
inode
instanceof
Entry
)
return
(
Entry
)
inode
;
return
Entry
.
readCEN
(
this
,
inode
.
pos
);
}
// Test if the "name" a parent directory of any entry (dir empty)
boolean
isAncestor
(
byte
[]
name
)
{
for
(
Map
.
Entry
<
EntryNam
e
,
IndexNode
>
entry
:
inodes
.
entrySet
())
{
for
(
Map
.
Entry
<
IndexNod
e
,
IndexNode
>
entry
:
inodes
.
entrySet
())
{
byte
[]
ename
=
entry
.
getKey
().
name
;
if
(
isParentOf
(
name
,
ename
))
return
true
;
...
...
@@ -1259,18 +1350,16 @@ public class ZipFileSystem extends FileSystem {
throws
IOException
{
checkWritable
();
synchronized
(
lock
)
{
Entry
e
=
getEntry0
(
path
);
if
(
e
==
null
)
{
if
(
path
!=
null
&&
path
.
length
==
0
)
throw
new
ZipException
(
"root directory </> can't not be delete"
);
if
(
failIfNotExists
)
throw
new
NoSuchFileException
(
getString
(
path
));
}
else
{
if
(
e
.
isDir
()
&&
isAncestor
(
path
))
throw
new
DirectoryNotEmptyException
(
getString
(
path
));
updateDelete
(
e
);
}
Entry
e
=
getEntry0
(
path
);
if
(
e
==
null
)
{
if
(
path
!=
null
&&
path
.
length
==
0
)
throw
new
ZipException
(
"root directory </> can't not be delete"
);
if
(
failIfNotExists
)
throw
new
NoSuchFileException
(
getString
(
path
));
}
else
{
if
(
e
.
isDir
()
&&
isAncestor
(
path
))
throw
new
DirectoryNotEmptyException
(
getString
(
path
));
updateDelete
(
e
);
}
}
...
...
@@ -1289,9 +1378,8 @@ public class ZipFileSystem extends FileSystem {
// (2) updating/replacing the contents of the specified existing entry.
private
OutputStream
getOutputStream
(
Entry
e
)
throws
IOException
{
ensureOpen
();
if
(
e
.
mtime
==
-
1
)
e
.
mtime
=
javaToDosTime
(
System
.
currentTimeMillis
()
);
e
.
mtime
=
System
.
currentTimeMillis
(
);
if
(
e
.
method
==
-
1
)
e
.
method
=
METHOD_DEFLATED
;
// TBD: use default method
// store size, compressed size, and crc-32 in LOC header
...
...
@@ -1334,7 +1422,7 @@ public class ZipFileSystem extends FileSystem {
long
bufSize
=
e
.
size
+
2
;
// Inflater likes a bit of slack
if
(
bufSize
>
65536
)
bufSize
=
8192
;
final
long
size
=
e
.
size
;
;
final
long
size
=
e
.
size
;
eis
=
new
InflaterInputStream
(
eis
,
getInflater
(),
(
int
)
bufSize
)
{
private
boolean
isClosed
=
false
;
...
...
@@ -1343,6 +1431,7 @@ public class ZipFileSystem extends FileSystem {
releaseInflater
(
inf
);
this
.
in
.
close
();
isClosed
=
true
;
streams
.
remove
(
this
);
}
}
// Override fill() method to provide an extra "dummy" byte
...
...
@@ -1372,7 +1461,9 @@ public class ZipFileSystem extends FileSystem {
Integer
.
MAX_VALUE
:
(
int
)
avail
;
}
};
}
else
if
(
e
.
method
!=
METHOD_STORED
)
{
}
else
if
(
e
.
method
==
METHOD_STORED
)
{
// TBD: wrap/ it does not seem necessary
}
else
{
throw
new
ZipException
(
"invalid compression method"
);
}
streams
.
add
(
eis
);
...
...
@@ -1382,11 +1473,11 @@ public class ZipFileSystem extends FileSystem {
// Inner class implementing the input stream used to read
// a (possibly compressed) zip file entry.
private
class
EntryInputStream
extends
InputStream
{
private
SeekableByteChannel
zfch
;
// local ref to zipfs's "ch". zipfs.ch might
private
final
SeekableByteChannel
zfch
;
// local ref to zipfs's "ch". zipfs.ch might
// point to a new channel after sync()
private
long
pos
;
// current position within entry data
protected
long
rem
;
// number of remaining bytes within entry
protected
long
size
;
// uncompressed size of this entry
protected
final
long
size
;
// uncompressed size of this entry
EntryInputStream
(
Entry
e
,
SeekableByteChannel
zfch
)
throws
IOException
...
...
@@ -1527,14 +1618,14 @@ public class ZipFileSystem extends FileSystem {
}
}
private
static
void
zerror
(
String
msg
)
{
static
void
zerror
(
String
msg
)
{
throw
new
ZipError
(
msg
);
}
// Maxmum number of de/inflater we cache
private
final
int
MAX_FLATER
=
20
;
// List of available Inflater objects for decompression
private
List
<
Inflater
>
inflaters
=
new
ArrayList
<>();
private
final
List
<
Inflater
>
inflaters
=
new
ArrayList
<>();
// Gets an inflater from the list of available inflaters or allocates
// a new one.
...
...
@@ -1563,7 +1654,7 @@ public class ZipFileSystem extends FileSystem {
}
// List of available Deflater objects for compression
private
List
<
Deflater
>
deflaters
=
new
ArrayList
<>();
private
final
List
<
Deflater
>
deflaters
=
new
ArrayList
<>();
// Gets an deflater from the list of available deflaters or allocates
// a new one.
...
...
@@ -1660,44 +1751,40 @@ public class ZipFileSystem extends FileSystem {
}
}
// wrapper for the byte[] name
static
class
EntryName
{
// Internal node that links a "name" to its pos in cen table.
// The node itself can be used as a "key" to lookup itself in
// the HashMap inodes.
static
class
IndexNode
{
byte
[]
name
;
int
hashcode
;
// node is hashable/hashed by its name
int
hashcode
;
// node is hashable/hashed by its name
int
pos
=
-
1
;
// postion in cen table, -1 menas the
// entry does not exists in zip file
IndexNode
(
byte
[]
name
,
int
pos
)
{
as
(
name
);
this
.
pos
=
pos
;
}
public
EntryName
(
byte
[]
name
)
{
name
(
name
);
final
static
IndexNode
keyOf
(
byte
[]
name
)
{
// get a lookup key;
return
new
IndexNode
(
name
,
-
1
);
}
void
name
(
byte
[]
name
)
{
this
.
name
=
name
;
final
IndexNode
as
(
byte
[]
name
)
{
// reuse the node, mostly
this
.
name
=
name
;
// as a lookup "key"
this
.
hashcode
=
Arrays
.
hashCode
(
name
);
return
this
;
}
public
boolean
equals
(
Object
other
)
{
if
(!(
other
instanceof
EntryNam
e
))
if
(!(
other
instanceof
IndexNod
e
))
return
false
;
return
Arrays
.
equals
(
name
,
((
EntryNam
e
)
other
).
name
);
return
Arrays
.
equals
(
name
,
((
IndexNod
e
)
other
).
name
);
}
public
int
hashCode
()
{
return
hashcode
;
}
}
// can simply use Integer instead, if we don't use it to
// build a internal node tree.
static
class
IndexNode
{
byte
[]
name
;
int
pos
=
-
1
;
// postion in cen table, -1 menas the
// entry does not exists in zip file
IndexNode
(
byte
[]
name
,
int
pos
)
{
this
.
name
=
name
;
this
.
pos
=
pos
;
}
IndexNode
()
{}
IndexNode
sibling
;
IndexNode
child
;
// 1st child
}
...
...
@@ -1723,37 +1810,25 @@ public class ZipFileSystem extends FileSystem {
long
crc
=
-
1
;
// crc-32 of entry data
long
csize
=
-
1
;
// compressed size of entry data
long
size
=
-
1
;
// uncompressed size of entry data
int
nlen
;
int
elen
;
byte
[]
extra
;
// loc
long
startPos
;
long
endPos
;
// exclusive
// cen
int
versionMade
;
int
disk
;
int
attrs
;
long
attrsEx
;
long
locoff
;
int
clen
;
byte
[]
comment
;
// ZIP64 flag
boolean
hasZip64
;
Entry
()
{}
Entry
(
byte
[]
name
)
{
this
.
name
=
name
;
//this.nlen = name.length;
this
.
mtime
=
javaToDosTime
(
System
.
currentTimeMillis
());
this
.
crc
=
0
;
this
.
size
=
0
;
this
.
csize
=
0
;
this
.
method
=
METHOD_DEFLATED
;
this
.
name
=
name
;
this
.
mtime
=
System
.
currentTimeMillis
();
this
.
crc
=
0
;
this
.
size
=
0
;
this
.
csize
=
0
;
this
.
method
=
METHOD_DEFLATED
;
}
Entry
(
byte
[]
name
,
int
type
)
{
...
...
@@ -1761,16 +1836,9 @@ public class ZipFileSystem extends FileSystem {
this
.
type
=
type
;
}
Entry
(
byte
[]
name
,
Path
file
,
int
type
)
{
this
(
name
,
type
);
this
.
file
=
file
;
this
.
method
=
METHOD_STORED
;
}
Entry
(
Entry
e
)
{
Entry
(
Entry
e
,
int
type
)
{
this
.
version
=
e
.
version
;
this
.
name
=
e
.
name
;
// copyOf?
this
.
nlen
=
e
.
nlen
;
this
.
name
=
e
.
name
;
this
.
ctime
=
e
.
ctime
;
this
.
atime
=
e
.
atime
;
this
.
mtime
=
e
.
mtime
;
...
...
@@ -1778,25 +1846,21 @@ public class ZipFileSystem extends FileSystem {
this
.
size
=
e
.
size
;
this
.
csize
=
e
.
csize
;
this
.
method
=
e
.
method
;
this
.
extra
=
(
e
.
extra
==
null
)?
null
:
Arrays
.
copyOf
(
e
.
extra
,
e
.
extra
.
length
);
this
.
elen
=
e
.
elen
;
this
.
extra
=
e
.
extra
;
this
.
versionMade
=
e
.
versionMade
;
this
.
disk
=
e
.
disk
;
this
.
attrs
=
e
.
attrs
;
this
.
attrsEx
=
e
.
attrsEx
;
this
.
locoff
=
e
.
locoff
;
this
.
clen
=
e
.
clen
;
this
.
comment
=
(
e
.
comment
==
null
)?
null
:
Arrays
.
copyOf
(
e
.
comment
,
e
.
comment
.
length
);
this
.
startPos
=
e
.
startPos
;
this
.
endPos
=
e
.
endPos
;
this
.
hasZip64
=
e
.
hasZip64
;;
this
.
comment
=
e
.
comment
;
this
.
type
=
type
;
}
Entry
(
Entry
e
,
int
type
)
{
this
(
e
);
this
.
type
=
type
;
Entry
(
byte
[]
name
,
Path
file
,
int
type
)
{
this
(
name
,
type
);
this
.
file
=
file
;
this
.
method
=
METHOD_STORED
;
}
boolean
isDir
()
{
...
...
@@ -1814,77 +1878,45 @@ public class ZipFileSystem extends FileSystem {
}
///////////////////// CEN //////////////////////
static
Entry
readCEN
(
ByteBuffer
cen
,
int
pos
)
throws
IOException
static
Entry
readCEN
(
ZipFileSystem
zipfs
,
int
pos
)
throws
IOException
{
return
new
Entry
().
cen
(
cen
,
pos
);
return
new
Entry
().
cen
(
zipfs
,
pos
);
}
private
Entry
cen
(
ByteBuffer
cen
,
int
pos
)
throws
IOException
private
Entry
cen
(
ZipFileSystem
zipfs
,
int
pos
)
throws
IOException
{
byte
[]
cen
=
zipfs
.
cen
;
if
(
CENSIG
(
cen
,
pos
)
!=
CENSIG
)
zerror
(
"invalid CEN header (bad signature)"
);
versionMade
=
CENVEM
(
cen
,
pos
);
version
=
CENVER
(
cen
,
pos
);
flag
=
CENFLG
(
cen
,
pos
);
method
=
CENHOW
(
cen
,
pos
);
mtime
=
CENTIM
(
cen
,
pos
);
mtime
=
dosToJavaTime
(
CENTIM
(
cen
,
pos
)
);
crc
=
CENCRC
(
cen
,
pos
);
csize
=
CENSIZ
(
cen
,
pos
);
size
=
CENLEN
(
cen
,
pos
);
nlen
=
CENNAM
(
cen
,
pos
);
elen
=
CENEXT
(
cen
,
pos
);
clen
=
CENCOM
(
cen
,
pos
);
int
nlen
=
CENNAM
(
cen
,
pos
);
int
elen
=
CENEXT
(
cen
,
pos
);
int
clen
=
CENCOM
(
cen
,
pos
);
disk
=
CENDSK
(
cen
,
pos
);
attrs
=
CENATT
(
cen
,
pos
);
attrsEx
=
CENATX
(
cen
,
pos
);
locoff
=
CENOFF
(
cen
,
pos
);
cen
.
position
(
pos
+
CENHDR
);
name
=
new
byte
[
nlen
];
cen
.
get
(
name
);
pos
+=
CENHDR
;
name
=
Arrays
.
copyOfRange
(
cen
,
pos
,
pos
+
nlen
);
pos
+=
nlen
;
if
(
elen
>
0
)
{
extra
=
new
byte
[
elen
];
cen
.
get
(
extra
);
if
(
csize
==
ZIP64_MINVAL
||
size
==
ZIP64_MINVAL
||
locoff
==
ZIP64_MINVAL
)
{
int
off
=
0
;
while
(
off
+
4
<
elen
)
{
// extra spec: HeaderID+DataSize+Data
int
sz
=
SH
(
extra
,
off
+
2
);
if
(
SH
(
extra
,
off
)
==
EXTID_ZIP64
)
{
off
+=
4
;
if
(
size
==
ZIP64_MINVAL
)
{
// if invalid zip64 extra fields, just skip
if
(
sz
<
8
||
(
off
+
8
)
>
elen
)
break
;
size
=
LL
(
extra
,
off
);
sz
-=
8
;
off
+=
8
;
}
if
(
csize
==
ZIP64_MINVAL
)
{
if
(
sz
<
8
||
(
off
+
8
)
>
elen
)
break
;
csize
=
LL
(
extra
,
off
);
sz
-=
8
;
off
+=
8
;
}
if
(
locoff
==
ZIP64_MINVAL
)
{
if
(
sz
<
8
||
(
off
+
8
)
>
elen
)
break
;
locoff
=
LL
(
extra
,
off
);
sz
-=
8
;
off
+=
8
;
}
break
;
}
off
+=
(
sz
+
4
);
}
}
extra
=
Arrays
.
copyOfRange
(
cen
,
pos
,
pos
+
elen
);
pos
+=
elen
;
readExtra
(
zipfs
);
}
if
(
clen
>
0
)
{
comment
=
new
byte
[
clen
];
cen
.
get
(
comment
);
comment
=
Arrays
.
copyOfRange
(
cen
,
pos
,
pos
+
clen
);
}
return
this
;
}
...
...
@@ -1897,31 +1929,37 @@ public class ZipFileSystem extends FileSystem {
long
csize0
=
csize
;
long
size0
=
size
;
long
locoff0
=
locoff
;
int
e64len
=
0
;
int
elen64
=
0
;
// extra for ZIP64
int
elenNTFS
=
0
;
// extra for NTFS (a/c/mtime)
int
elenEXTT
=
0
;
// extra for Extended Timestamp
// confirm size/length
nlen
=
(
name
!=
null
)
?
name
.
length
:
0
;
elen
=
(
extra
!=
null
)
?
extra
.
length
:
0
;
clen
=
(
comment
!=
null
)
?
comment
.
length
:
0
;
boolean
hasZip64
=
false
;
int
nlen
=
(
name
!=
null
)
?
name
.
length
:
0
;
int
elen
=
(
extra
!=
null
)
?
extra
.
length
:
0
;
int
clen
=
(
comment
!=
null
)
?
comment
.
length
:
0
;
if
(
csize
>=
ZIP64_MINVAL
)
{
csize0
=
ZIP64_MINVAL
;
e64len
+=
8
;
// csize(8)
hasZip64
=
true
;
elen64
+=
8
;
// csize(8)
}
if
(
size
>=
ZIP64_MINVAL
)
{
size0
=
ZIP64_MINVAL
;
// size(8)
e64len
+=
8
;
hasZip64
=
true
;
elen64
+=
8
;
}
if
(
locoff
>=
ZIP64_MINVAL
)
{
locoff0
=
ZIP64_MINVAL
;
e64len
+=
8
;
// offset(8)
hasZip64
=
true
;
elen64
+=
8
;
// offset(8)
}
if
(
elen64
!=
0
)
elen64
+=
4
;
// header and data sz 4 bytes
if
(
atime
!=
-
1
)
{
if
(
isWindows
)
// use NTFS
elenNTFS
=
36
;
// total 36 bytes
else
// Extended Timestamp otherwise
elenEXTT
=
9
;
// only mtime in cen
}
writeInt
(
os
,
CENSIG
);
// CEN header signature
if
(
hasZip64
)
{
if
(
elen64
!=
0
)
{
writeShort
(
os
,
45
);
// ver 4.5 for zip64
writeShort
(
os
,
45
);
}
else
{
...
...
@@ -1930,18 +1968,14 @@ public class ZipFileSystem extends FileSystem {
}
writeShort
(
os
,
flag
);
// general purpose bit flag
writeShort
(
os
,
method
);
// compression method
writeInt
(
os
,
mtime
);
// last modification time
// last modification time
writeInt
(
os
,
(
int
)
javaToDosTime
(
mtime
));
writeInt
(
os
,
crc
);
// crc-32
writeInt
(
os
,
csize0
);
// compressed size
writeInt
(
os
,
size0
);
// uncompressed size
writeShort
(
os
,
name
.
length
);
writeShort
(
os
,
elen
+
elen64
+
elenNTFS
+
elenEXTT
);
if
(
hasZip64
)
{
// + headid(2) + datasize(2)
writeShort
(
os
,
e64len
+
4
+
elen
);
}
else
{
writeShort
(
os
,
elen
);
}
if
(
comment
!=
null
)
{
writeShort
(
os
,
Math
.
min
(
clen
,
0xffff
));
}
else
{
...
...
@@ -1952,9 +1986,9 @@ public class ZipFileSystem extends FileSystem {
writeInt
(
os
,
0
);
// external file attributes (unused)
writeInt
(
os
,
locoff0
);
// relative offset of local header
writeBytes
(
os
,
name
);
if
(
hasZip64
)
{
if
(
elen64
!=
0
)
{
writeShort
(
os
,
EXTID_ZIP64
);
// Zip64 extra
writeShort
(
os
,
e
64len
);
writeShort
(
os
,
e
len64
);
// size of "this" extra block
if
(
size0
==
ZIP64_MINVAL
)
writeLong
(
os
,
size
);
if
(
csize0
==
ZIP64_MINVAL
)
...
...
@@ -1962,58 +1996,73 @@ public class ZipFileSystem extends FileSystem {
if
(
locoff0
==
ZIP64_MINVAL
)
writeLong
(
os
,
locoff
);
}
if
(
extra
!=
null
)
{
writeBytes
(
os
,
extra
);
if
(
elenNTFS
!=
0
)
{
// System.out.println("writing NTFS:" + elenNTFS);
writeShort
(
os
,
EXTID_NTFS
);
writeShort
(
os
,
elenNTFS
-
4
);
writeInt
(
os
,
0
);
// reserved
writeShort
(
os
,
0x0001
);
// NTFS attr tag
writeShort
(
os
,
24
);
writeLong
(
os
,
javaToWinTime
(
mtime
));
writeLong
(
os
,
javaToWinTime
(
atime
));
writeLong
(
os
,
javaToWinTime
(
ctime
));
}
if
(
elenEXTT
!=
0
)
{
writeShort
(
os
,
EXTID_EXTT
);
writeShort
(
os
,
elenEXTT
-
4
);
if
(
ctime
==
-
1
)
os
.
write
(
0x3
);
// mtime and atime
else
os
.
write
(
0x7
);
// mtime, atime and ctime
writeInt
(
os
,
javaToUnixTime
(
mtime
));
}
if
(
comment
!=
null
)
{
//TBD: 0, Math.min(commentBytes.length, 0xffff));
if
(
extra
!=
null
)
// whatever not recognized
writeBytes
(
os
,
extra
);
if
(
comment
!=
null
)
//TBD: 0, Math.min(commentBytes.length, 0xffff));
writeBytes
(
os
,
comment
);
}
return
CENHDR
+
nlen
+
elen
+
clen
+
(
hasZip64
?(
e64len
+
4
):
0
);
return
CENHDR
+
nlen
+
elen
+
clen
+
elen64
+
elenNTFS
+
elenEXTT
;
}
///////////////////// LOC //////////////////////
static
Entry
readLOC
(
ZipFileSystem
z
f
,
long
pos
)
static
Entry
readLOC
(
ZipFileSystem
z
ipfs
,
long
pos
)
throws
IOException
{
return
readLOC
(
z
f
,
pos
,
new
byte
[
1024
]);
return
readLOC
(
z
ipfs
,
pos
,
new
byte
[
1024
]);
}
static
Entry
readLOC
(
ZipFileSystem
z
f
,
long
pos
,
byte
[]
buf
)
static
Entry
readLOC
(
ZipFileSystem
z
ipfs
,
long
pos
,
byte
[]
buf
)
throws
IOException
{
return
new
Entry
().
loc
(
z
f
,
pos
,
buf
);
return
new
Entry
().
loc
(
z
ipfs
,
pos
,
buf
);
}
Entry
loc
(
ZipFileSystem
z
f
,
long
pos
,
byte
[]
buf
)
Entry
loc
(
ZipFileSystem
z
ipfs
,
long
pos
,
byte
[]
buf
)
throws
IOException
{
assert
(
buf
.
length
>=
LOCHDR
);
if
(
z
f
.
readFullyAt
(
buf
,
0
,
LOCHDR
,
pos
)
!=
LOCHDR
)
{
if
(
z
ipfs
.
readFullyAt
(
buf
,
0
,
LOCHDR
,
pos
)
!=
LOCHDR
)
throw
new
ZipException
(
"loc: reading failed"
);
}
if
(
LOCSIG
(
buf
)
!=
LOCSIG
)
{
if
(
LOCSIG
(
buf
)
!=
LOCSIG
)
throw
new
ZipException
(
"loc: wrong sig ->"
+
Long
.
toString
(
LOCSIG
(
buf
),
16
));
}
startPos
=
pos
;
//startPos = pos;
version
=
LOCVER
(
buf
);
flag
=
LOCFLG
(
buf
);
method
=
LOCHOW
(
buf
);
mtime
=
LOCTIM
(
buf
);
mtime
=
dosToJavaTime
(
LOCTIM
(
buf
)
);
crc
=
LOCCRC
(
buf
);
csize
=
LOCSIZ
(
buf
);
size
=
LOCLEN
(
buf
);
nlen
=
LOCNAM
(
buf
);
elen
=
LOCEXT
(
buf
);
int
nlen
=
LOCNAM
(
buf
);
int
elen
=
LOCEXT
(
buf
);
name
=
new
byte
[
nlen
];
if
(
z
f
.
readFullyAt
(
name
,
0
,
nlen
,
pos
+
LOCHDR
)
!=
nlen
)
{
if
(
z
ipfs
.
readFullyAt
(
name
,
0
,
nlen
,
pos
+
LOCHDR
)
!=
nlen
)
{
throw
new
ZipException
(
"loc: name reading failed"
);
}
if
(
elen
>
0
)
{
extra
=
new
byte
[
elen
];
if
(
z
f
.
readFullyAt
(
extra
,
0
,
elen
,
pos
+
LOCHDR
+
nlen
)
if
(
z
ipfs
.
readFullyAt
(
extra
,
0
,
elen
,
pos
+
LOCHDR
+
nlen
)
!=
elen
)
{
throw
new
ZipException
(
"loc: ext reading failed"
);
}
...
...
@@ -2021,7 +2070,7 @@ public class ZipFileSystem extends FileSystem {
pos
+=
(
LOCHDR
+
nlen
+
elen
);
if
((
flag
&
FLAG_DATADESCR
)
!=
0
)
{
// Data Descriptor
Entry
e
=
z
f
.
getEntry0
(
name
);
// get the size/csize from cen
Entry
e
=
z
ipfs
.
getEntry0
(
name
);
// get the size/csize from cen
if
(
e
==
null
)
throw
new
ZipException
(
"loc: name not found in cen"
);
size
=
e
.
size
;
...
...
@@ -2032,7 +2081,6 @@ public class ZipFileSystem extends FileSystem {
else
pos
+=
16
;
}
else
{
boolean
hasZip64
=
false
;
if
(
extra
!=
null
&&
(
size
==
ZIP64_MINVAL
||
csize
==
ZIP64_MINVAL
))
{
// zip64 ext: must include both size and csize
...
...
@@ -2042,7 +2090,6 @@ public class ZipFileSystem extends FileSystem {
if
(
SH
(
extra
,
off
)
==
EXTID_ZIP64
&&
sz
==
16
)
{
size
=
LL
(
extra
,
off
+
4
);
csize
=
LL
(
extra
,
off
+
12
);
hasZip64
=
true
;
break
;
}
off
+=
(
sz
+
4
);
...
...
@@ -2050,7 +2097,6 @@ public class ZipFileSystem extends FileSystem {
}
pos
+=
(
method
==
METHOD_STORED
?
size
:
csize
);
}
endPos
=
pos
;
return
this
;
}
...
...
@@ -2058,14 +2104,18 @@ public class ZipFileSystem extends FileSystem {
throws
IOException
{
writeInt
(
os
,
LOCSIG
);
// LOC header signature
int
version
=
version
();
int
nlen
=
(
name
!=
null
)
?
name
.
length
:
0
;
int
elen
=
(
extra
!=
null
)
?
extra
.
length
:
0
;
int
elen64
=
0
;
int
elenEXTT
=
0
;
if
((
flag
&
FLAG_DATADESCR
)
!=
0
)
{
writeShort
(
os
,
version
());
// version needed to extract
writeShort
(
os
,
flag
);
// general purpose bit flag
writeShort
(
os
,
method
);
// compression method
writeInt
(
os
,
mtime
);
// last modification time
// last modification time
writeInt
(
os
,
(
int
)
javaToDosTime
(
mtime
));
// store size, uncompressed size, and crc-32 in data descriptor
// immediately following compressed entry data
writeInt
(
os
,
0
);
...
...
@@ -2073,7 +2123,7 @@ public class ZipFileSystem extends FileSystem {
writeInt
(
os
,
0
);
}
else
{
if
(
csize
>=
ZIP64_MINVAL
||
size
>=
ZIP64_MINVAL
)
{
hasZip64
=
true
;
elen64
=
20
;
//headid(2) + size(2) + size(8) + csize(8)
writeShort
(
os
,
45
);
// ver 4.5 for zip64
}
else
{
writeShort
(
os
,
version
());
// version needed to extract
...
...
@@ -2082,29 +2132,45 @@ public class ZipFileSystem extends FileSystem {
writeShort
(
os
,
method
);
// compression method
writeInt
(
os
,
mtime
);
// last modification time
writeInt
(
os
,
crc
);
// crc-32
if
(
hasZip64
)
{
if
(
elen64
!=
0
)
{
writeInt
(
os
,
ZIP64_MINVAL
);
writeInt
(
os
,
ZIP64_MINVAL
);
//TBD: e.elen += 20; //headid(2) + size(2) + size(8) + csize(8)
}
else
{
writeInt
(
os
,
csize
);
// compressed size
writeInt
(
os
,
size
);
// uncompressed size
}
}
if
(
atime
!=
-
1
&&
!
isWindows
)
{
// on unix use "ext time"
if
(
ctime
==
-
1
)
elenEXTT
=
13
;
else
elenEXTT
=
17
;
}
writeShort
(
os
,
name
.
length
);
writeShort
(
os
,
elen
+
(
hasZip64
?
20
:
0
)
);
writeShort
(
os
,
elen
+
elen64
+
elenEXTT
);
writeBytes
(
os
,
name
);
if
(
hasZip64
)
{
// TBD: should we update extra directory?
if
(
elen64
!=
0
)
{
writeShort
(
os
,
EXTID_ZIP64
);
writeShort
(
os
,
16
);
writeLong
(
os
,
size
);
writeLong
(
os
,
csize
);
}
if
(
elenEXTT
!=
0
)
{
writeShort
(
os
,
EXTID_EXTT
);
writeShort
(
os
,
elenEXTT
-
4
);
// size for the folowing data block
if
(
ctime
==
-
1
)
os
.
write
(
0x3
);
// mtime and atime
else
os
.
write
(
0x7
);
// mtime, atime and ctime
writeInt
(
os
,
javaToUnixTime
(
mtime
));
writeInt
(
os
,
javaToUnixTime
(
atime
));
if
(
ctime
!=
-
1
)
writeInt
(
os
,
javaToUnixTime
(
ctime
));
}
if
(
extra
!=
null
)
{
writeBytes
(
os
,
extra
);
}
return
LOCHDR
+
name
.
length
+
elen
+
(
hasZip64
?
20
:
0
)
;
return
LOCHDR
+
name
.
length
+
elen
+
elen64
+
elenEXTT
;
}
// Data Descriptior
...
...
@@ -2125,17 +2191,18 @@ public class ZipFileSystem extends FileSystem {
}
// read NTFS, UNIX and ZIP64 data from cen.extra
void
readExtra
(
)
{
void
readExtra
(
ZipFileSystem
zipfs
)
throws
IOException
{
if
(
extra
==
null
)
return
;
int
elen
=
extra
.
length
;
int
off
=
0
;
int
newOff
=
0
;
while
(
off
+
4
<
elen
)
{
// extra spec: HeaderID+DataSize+Data
int
sz
=
SH
(
extra
,
off
+
2
);
int
tag
=
SH
(
extra
,
off
);
off
+=
4
;
int
pos
=
off
;
int
tag
=
SH
(
extra
,
pos
);
int
sz
=
SH
(
extra
,
pos
+
2
);
pos
+=
4
;
if
(
pos
+
sz
>
elen
)
// invalid data
break
;
switch
(
tag
)
{
...
...
@@ -2165,18 +2232,66 @@ public class ZipFileSystem extends FileSystem {
break
;
if
(
SH
(
extra
,
pos
+
2
)
!=
24
)
break
;
mtime
=
LL
(
extra
,
pos
+
4
);
atime
=
LL
(
extra
,
pos
+
12
);
ctime
=
LL
(
extra
,
pos
+
20
);
// override the loc field, datatime here is
// more "accurate"
mtime
=
winToJavaTime
(
LL
(
extra
,
pos
+
4
));
atime
=
winToJavaTime
(
LL
(
extra
,
pos
+
12
));
ctime
=
winToJavaTime
(
LL
(
extra
,
pos
+
20
));
break
;
case
EXTID_UNIX:
atime
=
LG
(
extra
,
pos
);
mtime
=
LG
(
extra
,
pos
+
4
);
case
EXTID_EXTT:
// spec says the Extened timestamp in cen only has mtime
// need to read the loc to get the extra a/ctime
byte
[]
buf
=
new
byte
[
LOCHDR
];
if
(
zipfs
.
readFullyAt
(
buf
,
0
,
buf
.
length
,
locoff
)
!=
buf
.
length
)
throw
new
ZipException
(
"loc: reading failed"
);
if
(
LOCSIG
(
buf
)
!=
LOCSIG
)
throw
new
ZipException
(
"loc: wrong sig ->"
+
Long
.
toString
(
LOCSIG
(
buf
),
16
));
int
locElen
=
LOCEXT
(
buf
);
if
(
locElen
<
9
)
// EXTT is at lease 9 bytes
break
;
int
locNlen
=
LOCNAM
(
buf
);
buf
=
new
byte
[
locElen
];
if
(
zipfs
.
readFullyAt
(
buf
,
0
,
buf
.
length
,
locoff
+
LOCHDR
+
locNlen
)
!=
buf
.
length
)
throw
new
ZipException
(
"loc extra: reading failed"
);
int
locPos
=
0
;
while
(
locPos
+
4
<
buf
.
length
)
{
int
locTag
=
SH
(
buf
,
locPos
);
int
locSZ
=
SH
(
buf
,
locPos
+
2
);
locPos
+=
4
;
if
(
locTag
!=
EXTID_EXTT
)
{
locPos
+=
locSZ
;
continue
;
}
int
flag
=
CH
(
buf
,
locPos
++);
if
((
flag
&
0x1
)
!=
0
)
{
mtime
=
unixToJavaTime
(
LG
(
buf
,
locPos
));
locPos
+=
4
;
}
if
((
flag
&
0x2
)
!=
0
)
{
atime
=
unixToJavaTime
(
LG
(
buf
,
locPos
));
locPos
+=
4
;
}
if
((
flag
&
0x4
)
!=
0
)
{
ctime
=
unixToJavaTime
(
LG
(
buf
,
locPos
));
locPos
+=
4
;
}
break
;
}
break
;
default
:
// unknow
default
:
// unknown tag
System
.
arraycopy
(
extra
,
off
,
extra
,
newOff
,
sz
+
4
);
newOff
+=
(
sz
+
4
);
}
off
+=
sz
;
off
+=
(
sz
+
4
)
;
}
if
(
newOff
!=
0
&&
newOff
!=
extra
.
length
)
extra
=
Arrays
.
copyOf
(
extra
,
newOff
);
else
extra
=
null
;
}
}
...
...
@@ -2201,9 +2316,9 @@ public class ZipFileSystem extends FileSystem {
// structure.
// A possible solution is to build the node tree ourself as
// implemented below.
private
HashMap
<
EntryNam
e
,
IndexNode
>
dirs
;
private
HashMap
<
IndexNod
e
,
IndexNode
>
dirs
;
private
IndexNode
root
;
private
IndexNode
addToDir
(
EntryNam
e
child
)
{
private
IndexNode
addToDir
(
IndexNod
e
child
)
{
IndexNode
cinode
=
dirs
.
get
(
child
);
if
(
cinode
!=
null
)
return
cinode
;
...
...
@@ -2213,7 +2328,7 @@ public class ZipFileSystem extends FileSystem {
IndexNode
pinode
;
if
(
pname
!=
null
)
pinode
=
addToDir
(
new
EntryName
(
pname
));
pinode
=
addToDir
(
IndexNode
.
keyOf
(
pname
));
else
pinode
=
root
;
cinode
=
inodes
.
get
(
child
);
...
...
@@ -2222,8 +2337,8 @@ public class ZipFileSystem extends FileSystem {
pinode
.
child
=
cinode
;
return
null
;
}
cinode
=
dirs
.
get
(
child
);
if
(
cinode
==
null
)
// pseudo directry entry
//
cinode = dirs.get(child);
if
(
cinode
==
null
)
// pseudo directry entry
cinode
=
new
IndexNode
(
cname
,
-
1
);
cinode
.
sibling
=
pinode
.
child
;
pinode
.
child
=
cinode
;
...
...
@@ -2232,26 +2347,21 @@ public class ZipFileSystem extends FileSystem {
return
cinode
;
}
private
HashMap
<
EntryNam
e
,
IndexNode
>
getDirs
()
private
HashMap
<
IndexNod
e
,
IndexNode
>
getDirs
()
throws
IOException
{
if
(
hasUpdate
)
sync
();
if
(
dirs
!=
null
)
beginWrite
();
try
{
if
(
dirs
!=
null
)
return
dirs
;
dirs
=
new
HashMap
<>();
root
=
new
IndexNode
(
new
byte
[
0
],
-
1
);
dirs
.
put
(
root
,
root
);
for
(
IndexNode
node
:
inodes
.
keySet
())
addToDir
(
node
);
return
dirs
;
dirs
=
new
HashMap
<
EntryName
,
IndexNode
>();
byte
[]
empty
=
new
byte
[
0
];
root
=
new
IndexNode
(
empty
,
-
1
);
dirs
.
put
(
new
EntryName
(
empty
),
root
);
EntryName
[]
names
=
inodes
.
keySet
().
toArray
(
new
EntryName
[
0
]);
int
i
=
names
.
length
;
while
(--
i
>=
0
)
{
addToDir
(
names
[
i
]);
}
// for (int i EntryName en : inodes.keySet()) {
// addToDir(en);
// }
return
dirs
;
}
finally
{
endWrite
();
}
}
}
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipFileSystemProvider.java
浏览文件 @
fa7b30b0
...
...
@@ -55,6 +55,8 @@ import java.util.Set;
*/
public
class
ZipFileSystemProvider
extends
FileSystemProvider
{
private
final
Map
<
Path
,
ZipFileSystem
>
filesystems
=
new
HashMap
<>();
public
ZipFileSystemProvider
()
{}
...
...
@@ -101,10 +103,16 @@ public class ZipFileSystemProvider extends FileSystemProvider {
throws
IOException
{
synchronized
(
filesystems
)
{
if
(
filesystems
.
containsKey
(
path
))
throw
new
FileSystemAlreadyExistsException
();
Path
realPath
=
null
;
if
(
path
.
exists
())
{
realPath
=
path
.
toRealPath
(
true
);
if
(
filesystems
.
containsKey
(
realPath
))
throw
new
FileSystemAlreadyExistsException
();
}
ZipFileSystem
zipfs
=
new
ZipFileSystem
(
this
,
path
,
env
);
filesystems
.
put
(
path
,
zipfs
);
if
(
realPath
==
null
)
realPath
=
path
.
toRealPath
(
true
);
filesystems
.
put
(
realPath
,
zipfs
);
return
zipfs
;
}
}
...
...
@@ -137,16 +145,21 @@ public class ZipFileSystemProvider extends FileSystemProvider {
@Override
public
FileSystem
getFileSystem
(
URI
uri
)
{
synchronized
(
filesystems
)
{
ZipFileSystem
zipfs
=
filesystems
.
get
(
uriToPath
(
uri
));
ZipFileSystem
zipfs
=
null
;
try
{
zipfs
=
filesystems
.
get
(
uriToPath
(
uri
).
toRealPath
(
true
));
}
catch
(
IOException
x
)
{
// ignore the ioe from toRealPath(), return FSNFE
}
if
(
zipfs
==
null
)
throw
new
FileSystemNotFoundException
();
return
zipfs
;
}
}
void
removeFileSystem
(
Path
zfpath
)
{
void
removeFileSystem
(
Path
zfpath
)
throws
IOException
{
synchronized
(
filesystems
)
{
filesystems
.
remove
(
zfpath
);
filesystems
.
remove
(
zfpath
.
toRealPath
(
true
)
);
}
}
}
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipInfo.java
浏览文件 @
fa7b30b0
...
...
@@ -31,7 +31,6 @@
package
com.sun.nio.zipfs
;
import
java.io.PrintStream
;
import
java.nio.file.Paths
;
import
java.util.Collections
;
import
java.util.Iterator
;
...
...
@@ -41,7 +40,7 @@ import static com.sun.nio.zipfs.ZipConstants.*;
import
static
com
.
sun
.
nio
.
zipfs
.
ZipUtils
.*;
/**
* Print
the loc and cen table
s of the ZIP file
* Print
all loc and cen header
s of the ZIP file
*
* @author Xueming Shen
*/
...
...
@@ -49,34 +48,38 @@ import static com.sun.nio.zipfs.ZipUtils.*;
public
class
ZipInfo
{
public
static
void
main
(
String
[]
args
)
throws
Throwable
{
if
(
args
.
length
<
2
)
{
print
(
"Usage: java ZipInfo
[cen|loc]
zfname"
);
if
(
args
.
length
<
1
)
{
print
(
"Usage: java ZipInfo zfname"
);
}
else
{
Map
<
String
,
?>
env
=
Collections
.
emptyMap
();
ZipFileSystem
zfs
=
(
ZipFileSystem
)(
new
ZipFileSystemProvider
()
.
newFileSystem
(
Paths
.
get
(
args
[
1
]),
env
));
long
pos
=
0
;
.
newFileSystem
(
Paths
.
get
(
args
[
0
]),
env
));
byte
[]
cen
=
zfs
.
cen
;
if
(
cen
==
null
)
{
print
(
"zip file is empty%n"
);
return
;
}
int
pos
=
0
;
byte
[]
buf
=
new
byte
[
1024
];
int
no
=
1
;
while
(
pos
+
CENHDR
<
cen
.
length
)
{
print
(
"----------------#%d--------------------%n"
,
no
++);
printCEN
(
cen
,
pos
);
if
(
"loc"
.
equals
(
args
[
0
]))
{
print
(
"[Local File Header]%n"
);
byte
[]
buf
=
new
byte
[
1024
];
for
(
int
i
=
0
;
i
<
zfs
.
getEntryNames
().
length
;
i
++)
{
Entry
loc
=
Entry
.
readLOC
(
zfs
,
pos
,
buf
);
print
(
"--------loc[%x]--------%n"
,
pos
);
printLOC
(
loc
);
pos
=
loc
.
endPos
;
}
}
if
(
"cen"
.
equals
(
args
[
0
]))
{
int
i
=
0
;
Iterator
<
ZipFileSystem
.
IndexNode
>
itr
=
zfs
.
inodes
.
values
().
iterator
();
print
(
"[Central Directory Header]%n"
);
while
(
itr
.
hasNext
())
{
Entry
cen
=
Entry
.
readCEN
(
zfs
.
cen
,
itr
.
next
().
pos
);
print
(
"--------cen[%d]--------%n"
,
i
);
printCEN
(
cen
);
i
++;
// use size CENHDR as the extra bytes to read, just in case the
// loc.extra is bigger than the cen.extra, try to avoid to read
// twice
long
len
=
LOCHDR
+
CENNAM
(
cen
,
pos
)
+
CENEXT
(
cen
,
pos
)
+
CENHDR
;
if
(
zfs
.
readFullyAt
(
buf
,
0
,
len
,
locoff
(
cen
,
pos
))
!=
len
)
zfs
.
zerror
(
"read loc header failed"
);
if
(
LOCEXT
(
buf
)
>
CENEXT
(
cen
,
pos
)
+
CENHDR
)
{
// have to read the second time;
len
=
LOCHDR
+
LOCNAM
(
buf
)
+
LOCEXT
(
buf
);
if
(
zfs
.
readFullyAt
(
buf
,
0
,
len
,
locoff
(
cen
,
pos
))
!=
len
)
zfs
.
zerror
(
"read loc header failed"
);
}
printLOC
(
buf
);
pos
+=
CENHDR
+
CENNAM
(
cen
,
pos
)
+
CENEXT
(
cen
,
pos
)
+
CENCOM
(
cen
,
pos
);
}
zfs
.
close
();
}
...
...
@@ -86,47 +89,135 @@ public class ZipInfo {
System
.
out
.
printf
(
fmt
,
objs
);
}
static
void
printLOC
(
Entry
loc
)
{
print
(
" [%x, %x]%n"
,
loc
.
startPos
,
loc
.
endPos
);
print
(
" Signature : %8x%n"
,
LOCSIG
);
print
(
" Version : %4x [%d.%d]%n"
,
loc
.
version
,
loc
.
version
/
10
,
loc
.
version
%
10
);
print
(
" Flag : %4x%n"
,
loc
.
flag
);
print
(
" Method : %4x%n"
,
loc
.
method
);
print
(
" LastMTime : %8x [%tc]%n"
,
loc
.
mtime
,
dosToJavaTime
(
loc
.
mtime
));
print
(
" CRC : %8x%n"
,
loc
.
crc
);
print
(
" CSize : %8x%n"
,
loc
.
csize
);
print
(
" Size : %8x%n"
,
loc
.
size
);
print
(
" NameLength : %4x [%s]%n"
,
loc
.
nlen
,
new
String
(
loc
.
name
));
print
(
" ExtraLength : %4x%n"
,
loc
.
elen
);
if
(
loc
.
hasZip64
)
print
(
" *ZIP64*%n"
);
static
void
printLOC
(
byte
[]
loc
)
{
print
(
"%n"
);
print
(
"[Local File Header]%n"
);
print
(
" Signature : %#010x%n"
,
LOCSIG
(
loc
));
if
(
LOCSIG
(
loc
)
!=
LOCSIG
)
{
print
(
" Wrong signature!"
);
return
;
}
print
(
" Version : %#6x [%d.%d]%n"
,
LOCVER
(
loc
),
LOCVER
(
loc
)
/
10
,
LOCVER
(
loc
)
%
10
);
print
(
" Flag : %#6x%n"
,
LOCFLG
(
loc
));
print
(
" Method : %#6x%n"
,
LOCHOW
(
loc
));
print
(
" LastMTime : %#10x [%tc]%n"
,
LOCTIM
(
loc
),
dosToJavaTime
(
LOCTIM
(
loc
)));
print
(
" CRC : %#10x%n"
,
LOCCRC
(
loc
));
print
(
" CSize : %#10x%n"
,
LOCSIZ
(
loc
));
print
(
" Size : %#10x%n"
,
LOCLEN
(
loc
));
print
(
" NameLength : %#6x [%s]%n"
,
LOCNAM
(
loc
),
new
String
(
loc
,
LOCHDR
,
LOCNAM
(
loc
)));
print
(
" ExtraLength : %#6x%n"
,
LOCEXT
(
loc
));
if
(
LOCEXT
(
loc
)
!=
0
)
printExtra
(
loc
,
LOCHDR
+
LOCNAM
(
loc
),
LOCEXT
(
loc
));
}
static
void
printCEN
(
byte
[]
cen
,
int
off
)
{
print
(
"[Central Directory Header]%n"
);
print
(
" Signature : %#010x%n"
,
CENSIG
(
cen
,
off
));
if
(
CENSIG
(
cen
,
off
)
!=
CENSIG
)
{
print
(
" Wrong signature!"
);
return
;
}
print
(
" VerMadeby : %#6x [%d, %d.%d]%n"
,
CENVEM
(
cen
,
off
),
(
CENVEM
(
cen
,
off
)
>>
8
),
(
CENVEM
(
cen
,
off
)
&
0xff
)
/
10
,
(
CENVEM
(
cen
,
off
)
&
0xff
)
%
10
);
print
(
" VerExtract : %#6x [%d.%d]%n"
,
CENVER
(
cen
,
off
),
CENVER
(
cen
,
off
)
/
10
,
CENVER
(
cen
,
off
)
%
10
);
print
(
" Flag : %#6x%n"
,
CENFLG
(
cen
,
off
));
print
(
" Method : %#6x%n"
,
CENHOW
(
cen
,
off
));
print
(
" LastMTime : %#10x [%tc]%n"
,
CENTIM
(
cen
,
off
),
dosToJavaTime
(
CENTIM
(
cen
,
off
)));
print
(
" CRC : %#10x%n"
,
CENCRC
(
cen
,
off
));
print
(
" CSize : %#10x%n"
,
CENSIZ
(
cen
,
off
));
print
(
" Size : %#10x%n"
,
CENLEN
(
cen
,
off
));
print
(
" NameLen : %#6x [%s]%n"
,
CENNAM
(
cen
,
off
),
new
String
(
cen
,
off
+
CENHDR
,
CENNAM
(
cen
,
off
)));
print
(
" ExtraLen : %#6x%n"
,
CENEXT
(
cen
,
off
));
if
(
CENEXT
(
cen
,
off
)
!=
0
)
printExtra
(
cen
,
off
+
CENHDR
+
CENNAM
(
cen
,
off
),
CENEXT
(
cen
,
off
));
print
(
" CommentLen : %#6x%n"
,
CENCOM
(
cen
,
off
));
print
(
" DiskStart : %#6x%n"
,
CENDSK
(
cen
,
off
));
print
(
" Attrs : %#6x%n"
,
CENATT
(
cen
,
off
));
print
(
" AttrsEx : %#10x%n"
,
CENATX
(
cen
,
off
));
print
(
" LocOff : %#10x%n"
,
CENOFF
(
cen
,
off
));
}
static
long
locoff
(
byte
[]
cen
,
int
pos
)
{
long
locoff
=
CENOFF
(
cen
,
pos
);
if
(
locoff
==
ZIP64_MINVAL
)
{
//ZIP64
int
off
=
pos
+
CENHDR
+
CENNAM
(
cen
,
pos
);
int
end
=
off
+
CENEXT
(
cen
,
pos
);
while
(
off
+
4
<
end
)
{
int
tag
=
SH
(
cen
,
off
);
int
sz
=
SH
(
cen
,
off
+
2
);
if
(
tag
!=
EXTID_ZIP64
)
{
off
+=
4
+
sz
;
continue
;
}
off
+=
4
;
if
(
CENLEN
(
cen
,
pos
)
==
ZIP64_MINVAL
)
off
+=
8
;
if
(
CENSIZ
(
cen
,
pos
)
==
ZIP64_MINVAL
)
off
+=
8
;
return
LL
(
cen
,
off
);
}
// should never be here
}
return
locoff
;
}
static
void
printCEN
(
Entry
cen
)
{
print
(
" Signature : %08x%n"
,
CENSIG
);
print
(
" VerMadeby : %4x [%d.%d]%n"
,
cen
.
versionMade
,
cen
.
versionMade
/
10
,
cen
.
versionMade
%
10
);
print
(
" VerExtract : %4x [%d.%d]%n"
,
cen
.
version
,
cen
.
version
/
10
,
cen
.
version
%
10
);
print
(
" Flag : %4x%n"
,
cen
.
flag
);
print
(
" Method : %4x%n"
,
cen
.
method
);
print
(
" LastMTime : %8x [%tc]%n"
,
cen
.
mtime
,
dosToJavaTime
(
cen
.
mtime
));
print
(
" CRC : %8x%n"
,
cen
.
crc
);
print
(
" CSize : %8x%n"
,
cen
.
csize
);
print
(
" Size : %8x%n"
,
cen
.
size
);
print
(
" NameLen : %4x [%s]%n"
,
cen
.
nlen
,
new
String
(
cen
.
name
));
print
(
" ExtraLen : %4x%n"
,
cen
.
elen
);
print
(
" CommentLen : %4x%n"
,
cen
.
clen
);
print
(
" DiskStart : %4x%n"
,
cen
.
disk
);
print
(
" Attrs : %4x%n"
,
cen
.
attrs
);
print
(
" AttrsEx : %8x%n"
,
cen
.
attrsEx
);
print
(
" LocOff : %8x%n"
,
cen
.
locoff
);
if
(
cen
.
hasZip64
)
print
(
" *ZIP64*%n"
);
static
void
printExtra
(
byte
[]
extra
,
int
off
,
int
len
)
{
int
end
=
off
+
len
;
while
(
off
+
4
<
end
)
{
int
tag
=
SH
(
extra
,
off
);
int
sz
=
SH
(
extra
,
off
+
2
);
print
(
" [tag=0x%04x, sz=%d, data= "
,
tag
,
sz
);
if
(
off
+
sz
>
end
)
{
print
(
" Error: Invalid extra data, beyond extra length"
);
break
;
}
off
+=
4
;
for
(
int
i
=
0
;
i
<
sz
;
i
++)
print
(
"%02x "
,
extra
[
off
+
i
]);
print
(
"]%n"
);
switch
(
tag
)
{
case
EXTID_ZIP64
:
print
(
" ->ZIP64: "
);
int
pos
=
off
;
while
(
pos
+
8
<=
off
+
sz
)
{
print
(
" *0x%x "
,
LL
(
extra
,
pos
));
pos
+=
8
;
}
print
(
"%n"
);
break
;
case
EXTID_NTFS:
print
(
" ->PKWare NTFS%n"
);
// 4 bytes reserved
if
(
SH
(
extra
,
off
+
4
)
!=
0x0001
||
SH
(
extra
,
off
+
6
)
!=
24
)
print
(
" Error: Invalid NTFS sub-tag or subsz"
);
print
(
" mtime:%tc%n"
,
winToJavaTime
(
LL
(
extra
,
off
+
8
)));
print
(
" atime:%tc%n"
,
winToJavaTime
(
LL
(
extra
,
off
+
16
)));
print
(
" ctime:%tc%n"
,
winToJavaTime
(
LL
(
extra
,
off
+
24
)));
break
;
case
EXTID_EXTT:
print
(
" ->Inof-ZIP Extended Timestamp: flag=%x%n"
,
extra
[
off
]);
pos
=
off
+
1
;
while
(
pos
+
4
<=
off
+
sz
)
{
print
(
" *%tc%n"
,
unixToJavaTime
(
LG
(
extra
,
pos
)));
pos
+=
4
;
}
break
;
default
:
}
off
+=
sz
;
}
}
}
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipPath.java
浏览文件 @
fa7b30b0
...
...
@@ -32,24 +32,19 @@
package
com.sun.nio.zipfs
;
import
java.io.File
;
import
java.io.FilterInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.net.URI
;
import
java.nio.ByteBuffer
;
import
java.nio.channels.FileChannel
;
import
java.nio.channels.SeekableByteChannel
;
import
java.nio.file.*
;
import
java.nio.file.DirectoryStream.Filter
;
import
java.nio.file.spi.FileSystemProvider
;
import
java.nio.file.attribute.BasicFileAttributeView
;
import
java.nio.file.attribute.FileAttribute
;
import
java.nio.file.attribute.FileAttributeView
;
import
java.nio.file.attribute.FileTime
;
import
java.util.*
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
import
static
java
.
nio
.
file
.
StandardOpenOption
.*;
import
static
java
.
nio
.
file
.
StandardCopyOption
.*;
...
...
@@ -599,7 +594,7 @@ public class ZipPath extends Path {
}
private
static
final
DirectoryStream
.
Filter
<
Path
>
acceptAllFilter
=
new
DirectoryStream
.
Filter
<
Path
>()
{
new
DirectoryStream
.
Filter
<>()
{
@Override
public
boolean
accept
(
Path
entry
)
{
return
true
;
}
};
...
...
@@ -625,7 +620,7 @@ public class ZipPath extends Path {
// create a matcher and return a filter that uses it.
final
PathMatcher
matcher
=
getFileSystem
().
getPathMatcher
(
"glob:"
+
glob
);
DirectoryStream
.
Filter
<
Path
>
filter
=
new
DirectoryStream
.
Filter
<
Path
>()
{
DirectoryStream
.
Filter
<
Path
>
filter
=
new
DirectoryStream
.
Filter
<>()
{
@Override
public
boolean
accept
(
Path
entry
)
{
return
matcher
.
matches
(
entry
.
getName
());
...
...
@@ -758,7 +753,7 @@ public class ZipPath extends Path {
@Override
public
Iterator
<
Path
>
iterator
()
{
return
new
Iterator
<
Path
>()
{
return
new
Iterator
<>()
{
private
int
i
=
0
;
@Override
...
...
@@ -803,7 +798,7 @@ public class ZipPath extends Path {
@Override
public
SeekableByteChannel
newByteChannel
(
OpenOption
...
options
)
throws
IOException
{
Set
<
OpenOption
>
set
=
new
HashSet
<
OpenOption
>(
options
.
length
);
Set
<
OpenOption
>
set
=
new
HashSet
<>(
options
.
length
);
Collections
.
addAll
(
set
,
options
);
return
newByteChannel
(
set
);
}
...
...
@@ -908,7 +903,7 @@ public class ZipPath extends Path {
if
(
opt
==
REPLACE_EXISTING
)
replaceExisting
=
true
;
else
if
(
opt
==
COPY_ATTRIBUTES
)
copyAttrs
=
fals
e
;
copyAttrs
=
tru
e
;
}
// attributes of source file
ZipFileAttributes
zfas
=
getAttributes
();
...
...
@@ -951,7 +946,9 @@ public class ZipPath extends Path {
BasicFileAttributeView
view
=
target
.
getFileAttributeView
(
BasicFileAttributeView
.
class
);
try
{
view
.
setTimes
(
zfas
.
lastModifiedTime
(),
null
,
null
);
view
.
setTimes
(
zfas
.
lastModifiedTime
(),
zfas
.
lastAccessTime
(),
zfas
.
creationTime
());
}
catch
(
IOException
x
)
{
// rollback?
try
{
...
...
src/share/demo/nio/zipfs/com/sun/nio/zipfs/ZipUtils.java
浏览文件 @
fa7b30b0
...
...
@@ -36,6 +36,7 @@ import java.io.OutputStream;
import
java.util.Arrays
;
import
java.util.Date
;
import
java.util.regex.PatternSyntaxException
;
import
java.util.concurrent.TimeUnit
;
/**
*
...
...
@@ -48,7 +49,7 @@ class ZipUtils {
* Writes a 16-bit short to the output stream in little-endian byte order.
*/
public
static
void
writeShort
(
OutputStream
os
,
int
v
)
throws
IOException
{
os
.
write
(
(
v
>>>
0
)
&
0xff
);
os
.
write
(
v
&
0xff
);
os
.
write
((
v
>>>
8
)
&
0xff
);
}
...
...
@@ -56,7 +57,7 @@ class ZipUtils {
* Writes a 32-bit int to the output stream in little-endian byte order.
*/
public
static
void
writeInt
(
OutputStream
os
,
long
v
)
throws
IOException
{
os
.
write
((
int
)(
(
v
>>>
0
)
&
0xff
));
os
.
write
((
int
)(
v
&
0xff
));
os
.
write
((
int
)((
v
>>>
8
)
&
0xff
));
os
.
write
((
int
)((
v
>>>
16
)
&
0xff
));
os
.
write
((
int
)((
v
>>>
24
)
&
0xff
));
...
...
@@ -66,7 +67,7 @@ class ZipUtils {
* Writes a 64-bit int to the output stream in little-endian byte order.
*/
public
static
void
writeLong
(
OutputStream
os
,
long
v
)
throws
IOException
{
os
.
write
((
int
)(
(
v
>>>
0
)
&
0xff
));
os
.
write
((
int
)(
v
&
0xff
));
os
.
write
((
int
)((
v
>>>
8
)
&
0xff
));
os
.
write
((
int
)((
v
>>>
16
)
&
0xff
));
os
.
write
((
int
)((
v
>>>
24
)
&
0xff
));
...
...
@@ -132,6 +133,27 @@ class ZipUtils {
d
.
getSeconds
()
>>
1
;
}
// used to adjust values between Windows and java epoch
private
static
final
long
WINDOWS_EPOCH_IN_MICROSECONDS
=
-
11644473600000000L
;
public
static
final
long
winToJavaTime
(
long
wtime
)
{
return
TimeUnit
.
MILLISECONDS
.
convert
(
wtime
/
10
+
WINDOWS_EPOCH_IN_MICROSECONDS
,
TimeUnit
.
MICROSECONDS
);
}
public
static
final
long
javaToWinTime
(
long
time
)
{
return
(
TimeUnit
.
MICROSECONDS
.
convert
(
time
,
TimeUnit
.
MILLISECONDS
)
-
WINDOWS_EPOCH_IN_MICROSECONDS
)
*
10
;
}
public
static
final
long
unixToJavaTime
(
long
utime
)
{
return
TimeUnit
.
MILLISECONDS
.
convert
(
utime
,
TimeUnit
.
SECONDS
);
}
public
static
final
long
javaToUnixTime
(
long
time
)
{
return
TimeUnit
.
SECONDS
.
convert
(
time
,
TimeUnit
.
MILLISECONDS
);
}
private
static
final
String
regexMetaChars
=
".^$+{[]|()"
;
private
static
final
String
globMetaChars
=
"\\*?[{"
;
private
static
boolean
isRegexMeta
(
char
c
)
{
...
...
src/share/lib/security/sunpkcs11-solaris.cfg
浏览文件 @
fa7b30b0
...
...
@@ -31,5 +31,9 @@ disabledMechanisms = {
CKM_SHA256_RSA_PKCS
CKM_SHA384_RSA_PKCS
CKM_SHA512_RSA_PKCS
# the following mechanisms are disabled to ensure backward compatibility (Solaris bug 6545046)
CKM_DES_CBC_PAD
CKM_DES3_CBC_PAD
CKM_AES_CBC_PAD
}
test/demo/zipfs/ZipFSTester.java
浏览文件 @
fa7b30b0
...
...
@@ -64,7 +64,6 @@ public class ZipFSTester {
fs0
.
close
();
// sync to file
fs
=
newZipFileSystem
(
tmpfsPath
,
new
HashMap
<
String
,
Object
>());
try
{
// prepare a src
Path
src
=
getTempPath
();
...
...
@@ -146,13 +145,6 @@ public class ZipFSTester {
Path
fs2Path
=
getTempPath
();
Path
fs3Path
=
getTempPath
();
if
(
fs1Path
.
exists
())
fs1Path
.
delete
();
if
(
fs2Path
.
exists
())
fs2Path
.
delete
();
if
(
fs3Path
.
exists
())
fs3Path
.
delete
();
// create a new filesystem, copy everything from fs
Map
<
String
,
Object
>
env
=
new
HashMap
<
String
,
Object
>();
env
.
put
(
"createNew"
,
true
);
...
...
@@ -280,7 +272,6 @@ public class ZipFSTester {
walk
(
fs4
.
getPath
(
"/"
));
System
.
out
.
println
(
"closing: fs4"
);
fs4
.
close
();
System
.
out
.
printf
(
"failed=%d%n"
,
failed
);
fs1Path
.
delete
();
...
...
@@ -426,6 +417,8 @@ public class ZipFSTester {
}
private
static
void
mkdirs
(
Path
path
)
throws
IOException
{
if
(
path
.
exists
())
return
;
path
=
path
.
toAbsolutePath
();
Path
parent
=
path
.
getParent
();
if
(
parent
!=
null
)
{
...
...
test/java/nio/channels/AsynchronousSocketChannel/Leaky.java
浏览文件 @
fa7b30b0
...
...
@@ -22,15 +22,19 @@
*/
/* @test
* @bug 4607272
* @bug 4607272
6999915
* @summary Unit test for AsynchronousSocketChannel
* @run main/othervm -XX:+DisableExplicitGC -
mx
64m Leaky
* @run main/othervm -XX:+DisableExplicitGC -
XX:MaxDirectMemorySize=
64m Leaky
*/
import
java.nio.ByteBuffer
;
import
java.nio.BufferPoolMXBean
;
import
java.nio.channels.*
;
import
java.net.*
;
import
java.util.List
;
import
java.util.concurrent.Future
;
import
java.util.concurrent.ThreadFactory
;
import
java.lang.management.ManagementFactory
;
/**
* Heap buffers must be substituted with direct buffers when doing I/O. This
...
...
@@ -49,13 +53,13 @@ public class Leaky {
private
final
ByteBuffer
dst
;
private
Future
<
Integer
>
readResult
;
Connection
()
throws
Exception
{
Connection
(
AsynchronousChannelGroup
group
)
throws
Exception
{
ServerSocketChannel
ssc
=
ServerSocketChannel
.
open
().
bind
(
new
InetSocketAddress
(
0
));
InetAddress
lh
=
InetAddress
.
getLocalHost
();
int
port
=
((
InetSocketAddress
)(
ssc
.
getLocalAddress
())).
getPort
();
SocketAddress
remote
=
new
InetSocketAddress
(
lh
,
port
);
client
=
AsynchronousSocketChannel
.
open
();
client
=
AsynchronousSocketChannel
.
open
(
group
);
client
.
connect
(
remote
).
get
();
peer
=
ssc
.
accept
();
ssc
.
close
();
...
...
@@ -77,11 +81,21 @@ public class Leaky {
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
ThreadFactory
threadFactory
=
new
ThreadFactory
()
{
@Override
public
Thread
newThread
(
Runnable
r
)
{
Thread
t
=
new
Thread
(
r
);
t
.
setDaemon
(
true
);
return
t
;
}
};
AsynchronousChannelGroup
group
=
AsynchronousChannelGroup
.
withFixedThreadPool
(
4
,
threadFactory
);
final
int
CONNECTION_COUNT
=
10
;
Connection
[]
connections
=
new
Connection
[
CONNECTION_COUNT
];
for
(
int
i
=
0
;
i
<
CONNECTION_COUNT
;
i
++)
{
connections
[
i
]
=
new
Connection
();
connections
[
i
]
=
new
Connection
(
group
);
}
for
(
int
i
=
0
;
i
<
1024
;
i
++)
{
...
...
@@ -100,5 +114,20 @@ public class Leaky {
conn
.
finishRead
();
}
}
// print summary of buffer pool usage
List
<
BufferPoolMXBean
>
pools
=
ManagementFactory
.
getPlatformMXBeans
(
BufferPoolMXBean
.
class
);
for
(
BufferPoolMXBean
pool:
pools
)
System
.
out
.
format
(
" %8s "
,
pool
.
getName
());
System
.
out
.
println
();
for
(
int
i
=
0
;
i
<
pools
.
size
();
i
++)
System
.
out
.
format
(
"%6s %10s %10s "
,
"Count"
,
"Capacity"
,
"Memory"
);
System
.
out
.
println
();
for
(
BufferPoolMXBean
pool:
pools
)
{
System
.
out
.
format
(
"%6d %10d %10d "
,
pool
.
getCount
(),
pool
.
getTotalCapacity
(),
pool
.
getMemoryUsed
());
}
System
.
out
.
println
();
}
}
test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java
浏览文件 @
fa7b30b0
...
...
@@ -56,23 +56,44 @@ public class IteratorWeakConsistency {
// test(new ArrayBlockingQueue(20));
}
void
test
(
Queue
q
)
throws
Throwable
{
void
test
(
Queue
q
)
{
// TODO: make this more general
for
(
int
i
=
0
;
i
<
10
;
i
++)
q
.
add
(
i
);
Iterator
it
=
q
.
iterator
();
q
.
poll
();
q
.
poll
();
q
.
poll
();
q
.
remove
(
7
);
List
list
=
new
ArrayList
();
while
(
it
.
hasNext
())
list
.
add
(
it
.
next
());
equal
(
list
,
Arrays
.
asList
(
0
,
3
,
4
,
5
,
6
,
8
,
9
));
check
(!
list
.
contains
(
null
));
System
.
out
.
printf
(
"%s: %s%n"
,
q
.
getClass
().
getSimpleName
(),
list
);
try
{
for
(
int
i
=
0
;
i
<
10
;
i
++)
q
.
add
(
i
);
Iterator
it
=
q
.
iterator
();
q
.
poll
();
q
.
poll
();
q
.
poll
();
q
.
remove
(
7
);
List
list
=
new
ArrayList
();
while
(
it
.
hasNext
())
list
.
add
(
it
.
next
());
equal
(
list
,
Arrays
.
asList
(
0
,
3
,
4
,
5
,
6
,
8
,
9
));
check
(!
list
.
contains
(
null
));
System
.
out
.
printf
(
"%s: %s%n"
,
q
.
getClass
().
getSimpleName
(),
list
);
}
catch
(
Throwable
t
)
{
unexpected
(
t
);
}
try
{
q
.
clear
();
q
.
add
(
1
);
q
.
add
(
2
);
q
.
add
(
3
);
q
.
add
(
4
);
Iterator
it
=
q
.
iterator
();
it
.
next
();
q
.
remove
(
2
);
q
.
remove
(
1
);
q
.
remove
(
3
);
boolean
found4
=
false
;
while
(
it
.
hasNext
())
{
found4
|=
it
.
next
().
equals
(
4
);
}
check
(
found4
);
}
catch
(
Throwable
t
)
{
unexpected
(
t
);
}
}
//--------------------- Infrastructure ---------------------------
...
...
@@ -85,7 +106,6 @@ public class IteratorWeakConsistency {
void
equal
(
Object
x
,
Object
y
)
{
if
(
x
==
null
?
y
==
null
:
x
.
equals
(
y
))
pass
();
else
fail
(
x
+
" not equal to "
+
y
);}
static
Class
<?>
thisClass
=
new
Object
(){}.
getClass
().
getEnclosingClass
();
public
static
void
main
(
String
[]
args
)
throws
Throwable
{
new
IteratorWeakConsistency
().
instanceMain
(
args
);}
public
void
instanceMain
(
String
[]
args
)
throws
Throwable
{
...
...
test/java/util/jar/JarInputStream/BadSignedJar.jar
0 → 100644
浏览文件 @
fa7b30b0
文件已添加
test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java
0 → 100644
浏览文件 @
fa7b30b0
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6544278
* @summary Confirm the JarInputStream throws the SecurityException when
* verifying an indexed jar file with corrupted signature
*/
import
java.io.IOException
;
import
java.io.FileInputStream
;
import
java.util.jar.JarEntry
;
import
java.util.jar.JarInputStream
;
public
class
TestIndexedJarWithBadSignature
{
public
static
void
main
(
String
...
args
)
throws
Throwable
{
try
(
JarInputStream
jis
=
new
JarInputStream
(
new
FileInputStream
(
System
.
getProperty
(
"tst.src"
,
"."
)
+
System
.
getProperty
(
"file.separator"
)
+
"BadSignedJar.jar"
)))
{
JarEntry
je1
=
jis
.
getNextJarEntry
();
while
(
je1
!=
null
){
System
.
out
.
println
(
"Jar Entry1==>"
+
je1
.
getName
());
je1
=
jis
.
getNextJarEntry
();
// This should throw Security Exception
}
throw
new
RuntimeException
(
"Test Failed:Security Exception not being thrown"
);
}
catch
(
IOException
ie
){
ie
.
printStackTrace
();
}
catch
(
SecurityException
e
)
{
System
.
out
.
println
(
"Test passed: Security Exception thrown as expected"
);
}
}
}
test/sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java
0 → 100644
浏览文件 @
fa7b30b0
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 6687725
* @summary Test internal PKCS5Padding impl with various error conditions.
* @author Valerie Peng
* @library ..
*/
import
java.io.*
;
import
java.nio.*
;
import
java.util.*
;
import
java.security.*
;
import
java.security.spec.AlgorithmParameterSpec
;
import
javax.crypto.*
;
import
javax.crypto.spec.IvParameterSpec
;
public
class
TestPKCS5PaddingError
extends
PKCS11Test
{
private
static
class
CI
{
// class for holding Cipher Information
String
transformation
;
String
keyAlgo
;
CI
(
String
transformation
,
String
keyAlgo
)
{
this
.
transformation
=
transformation
;
this
.
keyAlgo
=
keyAlgo
;
}
}
private
static
final
CI
[]
TEST_LIST
=
{
// algorithms which use the native padding impl
new
CI
(
"DES/CBC/PKCS5Padding"
,
"DES"
),
new
CI
(
"DESede/CBC/PKCS5Padding"
,
"DESede"
),
new
CI
(
"AES/CBC/PKCS5Padding"
,
"AES"
),
// algorithms which use SunPKCS11's own padding impl
new
CI
(
"DES/ECB/PKCS5Padding"
,
"DES"
),
new
CI
(
"DESede/ECB/PKCS5Padding"
,
"DESede"
),
new
CI
(
"AES/ECB/PKCS5Padding"
,
"AES"
),
};
private
static
StringBuffer
debugBuf
=
new
StringBuffer
();
public
void
main
(
Provider
p
)
throws
Exception
{
boolean
status
=
true
;
Random
random
=
new
Random
();
try
{
byte
[]
plainText
=
new
byte
[
200
];
for
(
int
i
=
0
;
i
<
TEST_LIST
.
length
;
i
++)
{
CI
currTest
=
TEST_LIST
[
i
];
System
.
out
.
println
(
"==="
+
currTest
.
transformation
+
"==="
);
try
{
KeyGenerator
kg
=
KeyGenerator
.
getInstance
(
currTest
.
keyAlgo
,
p
);
SecretKey
key
=
kg
.
generateKey
();
Cipher
c1
=
Cipher
.
getInstance
(
currTest
.
transformation
,
"SunJCE"
);
c1
.
init
(
Cipher
.
ENCRYPT_MODE
,
key
);
byte
[]
cipherText
=
c1
.
doFinal
(
plainText
);
AlgorithmParameters
params
=
c1
.
getParameters
();
Cipher
c2
=
Cipher
.
getInstance
(
currTest
.
transformation
,
p
);
c2
.
init
(
Cipher
.
DECRYPT_MODE
,
key
,
params
);
// 1st test: wrong output length
// NOTE: Skip NSS since it reports CKR_DEVICE_ERROR when
// the data passed to its EncryptUpdate/DecryptUpdate is
// not multiple of blocks
if
(!
p
.
getName
().
equals
(
"SunPKCS11-NSS"
))
{
try
{
System
.
out
.
println
(
"Testing with wrong cipherText length"
);
c2
.
doFinal
(
cipherText
,
0
,
cipherText
.
length
-
2
);
}
catch
(
IllegalBlockSizeException
ibe
)
{
// expected
}
catch
(
Exception
ex
)
{
System
.
out
.
println
(
"Error: Unexpected Ex "
+
ex
);
ex
.
printStackTrace
();
}
}
// 2nd test: wrong padding value
try
{
System
.
out
.
println
(
"Testing with wrong padding bytes"
);
cipherText
[
cipherText
.
length
-
1
]++;
c2
.
doFinal
(
cipherText
);
}
catch
(
BadPaddingException
bpe
)
{
// expected
}
catch
(
Exception
ex
)
{
System
.
out
.
println
(
"Error: Unexpected Ex "
+
ex
);
ex
.
printStackTrace
();
}
System
.
out
.
println
(
"DONE"
);
}
catch
(
NoSuchAlgorithmException
nsae
)
{
System
.
out
.
println
(
"Skipping unsupported algorithm: "
+
nsae
);
}
}
}
catch
(
Exception
ex
)
{
// print out debug info when exception is encountered
if
(
debugBuf
!=
null
)
{
System
.
out
.
println
(
debugBuf
.
toString
());
debugBuf
=
new
StringBuffer
();
}
throw
ex
;
}
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
main
(
new
TestPKCS5PaddingError
());
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录