1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24 */
  25 
  26 package jdk.internal.jimage;
  27 
  28 import java.nio.ByteOrder;
  29 import java.nio.IntBuffer;
  30 
  31 public final class ImageHeader {
  32     public static final int MAGIC = 0xCAFEDADA;
  33     public static final int BADMAGIC = 0xDADAFECA;
  34     public static final short MAJOR_VERSION = 0;
  35     public static final short MINOR_VERSION = 1;
  36 
  37     private final int magic;
  38     private final short majorVersion;
  39     private final short minorVersion;
  40     private final int locationCount;
  41     private final int locationsSize;
  42     private final int stringsSize;
  43 
  44     ImageHeader(int locationCount, int locationsSize, int stringsSize) {
  45         this(MAGIC, MAJOR_VERSION, MINOR_VERSION, locationCount, locationsSize, stringsSize);
  46     }
  47 
  48     ImageHeader(int magic, short majorVersion, short minorVersion, int locationCount,
  49                 int locationsSize, int stringsSize)
  50     {
  51         this.magic = magic;
  52         this.majorVersion = majorVersion;
  53         this.minorVersion = minorVersion;
  54         this.locationCount = locationCount;
  55         this.locationsSize = locationsSize;
  56         this.stringsSize = stringsSize;
  57     }
  58 
  59     static int getHeaderSize() {
  60        return 4 +
  61               2 + 2 +
  62               4 +
  63               4 +
  64               4;
  65     }
  66 
  67     static ImageHeader readFrom(ByteOrder byteOrder, IntBuffer buffer) {
  68         int magic = buffer.get(0);
  69         int version = buffer.get(1);
  70         short majorVersion = (short)(byteOrder == ByteOrder.BIG_ENDIAN ?
  71             version >>> 16 : (version & 0xFFFF));
  72         short minorVersion = (short)(byteOrder == ByteOrder.BIG_ENDIAN ?
  73             (version & 0xFFFF) : version >>> 16);
  74         int locationCount = buffer.get(2);
  75         int locationsSize = buffer.get(3);
  76         int stringsSize = buffer.get(4);
  77 
  78         return new ImageHeader(magic, majorVersion, minorVersion, locationCount,
  79                                locationsSize, stringsSize);
  80     }
  81 
  82     void writeTo(ImageStream stream) {
  83         stream.putInt(magic);
  84         stream.putShort(majorVersion);
  85         stream.putShort(minorVersion);
  86         stream.putInt(locationCount);
  87         stream.putInt(locationsSize);
  88         stream.putInt(stringsSize);
  89     }
  90 
  91     public int getMagic() {
  92         return magic;
  93     }
  94 
  95     public int getMajorVersion() {
  96         return majorVersion;
  97     }
  98 
  99     public int getMinorVersion() {
 100         return minorVersion;
 101     }
 102 
 103     public int getLocationCount() {
 104         return locationCount;
 105     }
 106 
 107     public int getRedirectSize() {
 108         return locationCount* 4;
 109     }
 110 
 111     public int getOffsetsSize() {
 112         return locationCount* 4;
 113     }
 114 
 115     public int getLocationsSize() {
 116         return locationsSize;
 117     }
 118 
 119     public int getStringsSize() {
 120         return stringsSize;
 121     }
 122 
 123     public int getIndexSize() {
 124         return getHeaderSize() +
 125                getRedirectSize() +
 126                getOffsetsSize() +
 127                getLocationsSize() +
 128                getStringsSize();
 129     }
 130 
 131     int getRedirectOffset() {
 132         return getHeaderSize();
 133     }
 134 
 135     int getOffsetsOffset() {
 136         return getRedirectOffset() +
 137                getRedirectSize();
 138     }
 139 
 140     int getLocationsOffset() {
 141         return getOffsetsOffset() +
 142                getOffsetsSize();
 143     }
 144 
 145     int getStringsOffset() {
 146         return getLocationsOffset() +
 147                getLocationsSize();
 148     }
 149 }