/*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.oracle.truffle.llvm.parser.metadata;
import com.oracle.truffle.llvm.parser.scanner.BitStream;
import com.oracle.truffle.llvm.parser.scanner.RecordBuffer;
public final class MDString implements MDBaseNode {
private final String s;
@Override
public void accept(MetadataVisitor visitor) {
visitor.visit(this);
}
private MDString(String s) {
this.s = s;
}
public String getString() {
return s;
}
@Override
public void replace(MDBaseNode oldValue, MDBaseNode newValue) {
}
@Override
public String toString() {
return String.format("!\"%s\"", s);
}
public static MDString create(RecordBuffer buffer) {
return new MDString(buffer.readUnicodeString());
}
private static final int STRINGS_ARGINDEX_COUNT = 0;
private static final int STRINGS_ARGINDEX_STROFFSET = 1;
private static final int STRINGS_ARGOFFSET_BLOB = 2;
private static final int STRINGS_SIZE_WIDTH = 6;
public static MDString[] createFromBlob(long[] args) {
// the number of strings in the attached blob
final long count = args[STRINGS_ARGINDEX_COUNT];
final MDString[] strings = new MDString[Math.toIntExact(count)];
final BitStream blob = BitStream.createFromBlob(args, STRINGS_ARGOFFSET_BLOB);
long strOffset = args[STRINGS_ARGINDEX_STROFFSET] * Byte.SIZE;
long lenOffset = 0;
for (int i = 0; i < count; i++) {
long size = blob.readVBR(lenOffset, STRINGS_SIZE_WIDTH);
lenOffset += BitStream.widthVBR(size, STRINGS_SIZE_WIDTH);
final byte[] bytes = new byte[(int) (size)];
int j = 0;
while (size > 0) {
bytes[j++] = (byte) blob.read(strOffset, Byte.SIZE);
size--;
strOffset += Byte.SIZE;
}
strings[i] = new MDString(new String(bytes));
}
return strings;
}
public static String getIfInstance(MDBaseNode strNode) {
if (strNode instanceof MDString) {
return ((MDString) strNode).getString();
} else {
return null;
}
}
}