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.tools.jlink.internal; 27 28 import jdk.internal.jimage.ImageLocation; 29 import jdk.internal.jimage.ImageStream; 30 import jdk.internal.jimage.ImageStringsReader; 31 32 public final class ImageLocationWriter extends ImageLocation { 33 private int locationOffset; 34 35 private ImageLocationWriter(ImageStringsWriter strings) { 36 super(new long[ATTRIBUTE_COUNT], strings); 37 } 38 39 void writeTo(ImageStream stream) { 40 byte[] bytes = ImageLocation.compress(attributes); 41 locationOffset = stream.getPosition(); 42 stream.put(bytes, 0, bytes.length); 43 } 44 45 private ImageLocationWriter addAttribute(int kind, long value) { 46 assert ATTRIBUTE_END < kind && 47 kind < ATTRIBUTE_COUNT : "Invalid attribute kind"; 48 attributes[kind] = value; 49 return this; 50 } 51 52 private ImageLocationWriter addAttribute(int kind, String value) { 53 return addAttribute(kind, strings.add(value)); 54 } 55 56 static ImageLocationWriter newLocation(String fullName, 57 ImageStringsWriter strings, 58 long contentOffset, long compressedSize, long uncompressedSize) { 59 String moduleName = ""; 60 String parentName = ""; 61 String baseName; 62 String extensionName = ""; 63 64 if (fullName.startsWith("/modules/")) { 65 moduleName = "modules"; 66 baseName = fullName.substring("/modules/".length()); 67 } else if ( fullName.startsWith("/packages/")) { 68 moduleName = "packages"; 69 baseName = fullName.substring("/packages/".length()); 70 } else { 71 int offset = fullName.indexOf('/', 1); 72 if (fullName.length() >= 2 && fullName.charAt(0) == '/' && offset != -1) { 73 moduleName = fullName.substring(1, offset); 74 fullName = fullName.substring(offset + 1); 75 } 76 77 offset = fullName.lastIndexOf('/'); 78 if (1 < offset) { 79 parentName = fullName.substring(0, offset); 80 fullName = fullName.substring(offset + 1); 81 } 82 83 offset = fullName.lastIndexOf('.'); 84 if (offset != -1) { 85 baseName = fullName.substring(0, offset); 86 extensionName = fullName.substring(offset + 1); 87 } else { 88 baseName = fullName; 89 } 90 } 91 92 return new ImageLocationWriter(strings) 93 .addAttribute(ATTRIBUTE_MODULE, moduleName) 94 .addAttribute(ATTRIBUTE_PARENT, parentName) 95 .addAttribute(ATTRIBUTE_BASE, baseName) 96 .addAttribute(ATTRIBUTE_EXTENSION, extensionName) 97 .addAttribute(ATTRIBUTE_OFFSET, contentOffset) 98 .addAttribute(ATTRIBUTE_COMPRESSED, compressedSize) 99 .addAttribute(ATTRIBUTE_UNCOMPRESSED, uncompressedSize); 100 } 101 102 @Override 103 public int hashCode() { 104 return hashCode(ImageStringsReader.HASH_MULTIPLIER); 105 } 106 107 int hashCode(int seed) { 108 int hash = seed; 109 110 if (getModuleOffset() != 0) { 111 hash = ImageStringsReader.unmaskedHashCode("/", hash); 112 hash = ImageStringsReader.unmaskedHashCode(getModule(), hash); 113 hash = ImageStringsReader.unmaskedHashCode("/", hash); 114 } 115 116 if (getParentOffset() != 0) { 117 hash = ImageStringsReader.unmaskedHashCode(getParent(), hash); 118 hash = ImageStringsReader.unmaskedHashCode("/", hash); 119 } 120 121 hash = ImageStringsReader.unmaskedHashCode(getBase(), hash); 122 123 if (getExtensionOffset() != 0) { 124 hash = ImageStringsReader.unmaskedHashCode(".", hash); 125 hash = ImageStringsReader.unmaskedHashCode(getExtension(), hash); 126 } 127 128 return hash & ImageStringsReader.POSITIVE_MASK; 129 } 130 131 @Override 132 public boolean equals(Object obj) { 133 if (this == obj) { 134 return true; 135 } 136 137 if (!(obj instanceof ImageLocationWriter)) { 138 return false; 139 } 140 141 ImageLocationWriter other = (ImageLocationWriter) obj; 142 143 return getModuleOffset() == other.getModuleOffset() && 144 getParentOffset() == other.getParentOffset() && 145 getBaseOffset() == other.getBaseOffset() && 146 getExtensionOffset() == other.getExtensionOffset(); 147 } 148 149 int getLocationOffset() { 150 return locationOffset; 151 } 152 }