src/share/classes/org/openjdk/jigsaw/ModuleFile.java

Print this page

        

@@ -216,10 +216,14 @@
 
         public byte[] getHash() {
             return fileHeader.getHash();
         }
 
+        public ModuleArchitecture getArchitecture() {
+            return fileHeader.getArchitecture();
+        }
+
         public List<byte[]> getCalculatedHashes() {
             List<byte[]> hashes = new ArrayList<>();
             hashes.add(parser.getHeaderHash());
             for (Entry<SectionType,byte[]> entry : parser.getHashes().entrySet()) {
                 if (entry.getKey() != SIGNATURE)

@@ -555,33 +559,34 @@
 
     private static byte[] readHash(DataInputStream in) throws IOException {
         return readHashBytes(in, readHashLength(in));
     }
 
-    private static byte[] readFileHash(DigestInputStream dis)
+    private static byte[] readFileHash(InputStream in)
         throws IOException
     {
-        DataInputStream in = new DataInputStream(dis);
+        boolean digestStream = in instanceof DigestInputStream ? true : false;
+        DataInputStream din = new DataInputStream(in);
 
-        final short hashLength = readHashLength(in);
+        final short hashLength = readHashLength(din);
 
         // Turn digest computation off before reading the file hash
-        dis.on(false);
-        byte[] hash = readHashBytes(in, hashLength);
+        if (digestStream)
+            ((DigestInputStream)in).on(false);
+        byte[] hash = readHashBytes(din, hashLength);
         // Turn digest computation on again afterwards.
-        dis.on(true);
+        if (digestStream)
+            ((DigestInputStream)in).on(true);
 
         return hash;
     }
 
     /**
      * <p> A module-file header </p>
      */
     public final static class ModuleFileHeader {
-        public static final int LENGTH_WITHOUT_HASH = 30;
-        public static final int LENGTH =
-            LENGTH_WITHOUT_HASH + HashType.SHA256.length();
+        private static final int LENGTH_WITHOUT_VARIABLE_FIELDS = 34;
 
         // Fields are specified as unsigned. Treat signed values as bugs.
         private final int magic;                // MAGIC
         private final FileConstants.Type type;  // Type.MODULE_FILE
         private final short major;              // ModuleFile.MAJOR_VERSION

@@ -591,11 +596,14 @@
                                                 //   (upper private final ound; need not be exact)
         private final HashType hashType;        // One of ModuleFile.HashType
                                                 //   (applies final o all hashes in this file)
         private final byte[] hash;              // Hash of entire file (except this hash
                                                 // and the Signature section, if present)
+        private final ModuleArchitecture modArch;// os/arch, Java-modified UTF-8 pair
 
+        private final int length;
+
         public HashType getHashType() {
             return hashType;
         }
         
         public byte[] getHash() {

@@ -612,12 +620,20 @@
 
         public long getUSize() {
             return usize;
         }
 
-        public ModuleFileHeader(long csize, long usize,
-                                HashType hashType, byte[] hash) {
+        public ModuleArchitecture getArchitecture() {
+            return modArch;
+        }
+
+        public int getLength() {
+            return length;
+        }
+
+        private ModuleFileHeader(long csize, long usize, HashType hashType,
+                                 byte[] hash, ModuleArchitecture modArch) {
             ensureNonNegativity(csize, "csize");
             ensureNonNegativity(usize, "usize");
 
             magic = FileConstants.MAGIC;
             type = FileConstants.Type.MODULE_FILE;

@@ -626,56 +642,118 @@
 
             this.csize = csize;
             this.usize = usize;
             this.hashType = hashType;
             this.hash = hash.clone();
+            this.modArch = modArch;
+            try {
+                length = LENGTH_WITHOUT_VARIABLE_FIELDS
+                         + hash.length
+                         + modArch.os().getBytes("UTF-8").length
+                         + modArch.arch().getBytes("UTF-8").length;
+            } catch (UnsupportedEncodingException x) {
+                throw new InternalError(x);
         }
+        }
 
+        public static Builder newBuilder() {
+            return new Builder();
+        }
+
+        public static class Builder {
+            private long csize;
+            private long usize;
+            private ModuleArchitecture architecture = ModuleArchitecture.ANY;
+            private HashType hashType;
+            private byte[] hash;
+
+            private Builder() {}
+
+            public Builder setHashType(HashType hashType) {
+                this.hashType = hashType;
+                return this;
+            }
+
+            public Builder setHash(byte[] hash) {
+                this.hash = hash.clone();
+                return this;
+            }
+
+            public Builder setCSize(long csize) {
+                this.csize = csize;
+                return this;
+            }
+
+            public Builder setUSize(long usize) {
+                this.usize = usize;
+                return this;
+            }
+
+            public Builder setArchitecture(ModuleArchitecture architecture) {
+                this.architecture = architecture;
+                return this;
+            }
+
+            public ModuleFileHeader build() {
+                ensureNonNegativity(csize, "csize");
+                ensureNonNegativity(usize, "usize");
+                return new ModuleFileHeader(csize, usize, hashType, hash,
+                                            architecture);
+            }
+        }
+
         public void write(final DataOutput out) throws IOException {
             out.writeInt(magic);
             out.writeShort(type.value());
             out.writeShort(major);
             out.writeShort(minor);
             out.writeLong(csize);
             out.writeLong(usize);
             out.writeShort(hashType.value());
             writeHash(out, hash);
+            out.writeUTF(modArch.os());
+            out.writeUTF(modArch.arch());
         }
 
-        public static ModuleFileHeader read(final DigestInputStream dis)
+        public static ModuleFileHeader read(final InputStream in)
                 throws IOException
         {
-            DataInputStream in = new DataInputStream(dis);
+            DataInputStream din = new DataInputStream(in);
 
-            final int magic = in.readInt();
+            final int magic = din.readInt();
             ensureMatch(magic, FileConstants.MAGIC,
                         "FileConstants.MAGIC");
 
-            final short type = in.readShort();
+            final short type = din.readShort();
             ensureMatch(type, FileConstants.Type.MODULE_FILE.value(),
                        "Type.MODULE_FILE");
 
-            final short major = in.readShort();
+            final short major = din.readShort();
             ensureMatch(major, MAJOR_VERSION,
                         "ModuleFile.MAJOR_VERSION");
 
-            final short minor = in.readShort();
+            final short minor = din.readShort();
             ensureMatch(minor, MINOR_VERSION,
                         "ModuleFile.MINOR_VERSION");
 
-            final long csize = in.readLong();
-            final long usize = in.readLong();
-            final short hashTypeValue = in.readShort();
+            final long csize = din.readLong();
+            final long usize = din.readLong();
+
+            final short hashTypeValue = din.readShort();
             HashType hashType = null;
             try {
                 hashType = HashType.valueOf(hashTypeValue);
             } catch (IllegalArgumentException x) {
                 throw new IOException("Invalid hash type: " + hashTypeValue);
             }
-            final byte[] hash = readFileHash(dis);
+            final byte[] hash = readFileHash(in);
 
-            return new ModuleFileHeader(csize, usize, hashType, hash);
+            final String os = din.readUTF();
+            final String arch = din.readUTF();
+            final ModuleArchitecture architecture = ModuleArchitecture.create(os, arch);
+
+            return new ModuleFileHeader(csize, usize, hashType, hash, architecture);
         }
 
         @Override
         public String toString() {
             return "MODULE{csize=" + csize +