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