org.bytedeco.javacpp.tools.InfoMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javacpp Show documentation
Show all versions of javacpp Show documentation
The missing bridge between Java and native C++
/*
* Copyright (C) 2014-2018 Samuel Audet
*
* Licensed either under the Apache License, Version 2.0, or (at your option)
* under the terms of the GNU General Public License as published by
* the Free Software Foundation (subject to the "Classpath" exception),
* either version 2, or any later version (collectively, the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.gnu.org/licenses/
* http://www.gnu.org/software/classpath/license.html
*
* or as provided in the LICENSE.txt file that accompanied this code.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.bytedeco.javacpp.tools;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A {@link Map} containing {@link Info} objects consumed by the {@link Parser}.
* Also contains a few utility methods to facilitate its use for both the user
* and the {@link Parser}.
*
* @author Samuel Audet
*/
public class InfoMap extends HashMap> {
public InfoMap() { this.parent = defaults; }
public InfoMap(InfoMap parent) { this.parent = parent; }
InfoMap parent = null;
static final InfoMap defaults = new InfoMap(null)
.put(new Info("basic/containers").cppTypes("std::bitset", "std::deque", "std::list", "std::map", "std::queue", "std::set",
"std::stack", "std::vector", "std::valarray", "std::pair", "std::forward_list",
"std::priority_queue", "std::unordered_map", "std::unordered_set"))
.put(new Info("basic/types").cppTypes("signed", "unsigned", "char", "short", "int", "long", "bool", "float", "double",
"_Bool", "_Complex", "_Imaginary", "complex", "imaginary"))
.put(new Info("noexcept").annotations("@NoException"))
.put(new Info("__COUNTER__").cppText("#define __COUNTER__ 0"))
.put(new Info(" __attribute__", "__declspec", "static_assert").annotations().skip())
.put(new Info("void").valueTypes("void").pointerTypes("Pointer"))
.put(new Info("std::nullptr_t").valueTypes("Pointer").pointerTypes("PointerPointer"))
.put(new Info("FILE", "time_t", "va_list", "std::exception", "std::istream", "std::ostream", "std::iostream",
"std::ifstream", "std::ofstream", "std::fstream").cast().pointerTypes("Pointer"))
.put(new Info("int8_t", "__int8", "jbyte", "signed char")
.valueTypes("byte").pointerTypes("BytePointer", "ByteBuffer", "byte[]"))
.put(new Info("uint8_t", "unsigned __int8", "char", "unsigned char").cast()
.valueTypes("byte").pointerTypes("BytePointer", "ByteBuffer", "byte[]"))
.put(new Info("int16_t", "__int16", "jshort", "short", "signed short", "short int", "signed short int")
.valueTypes("short").pointerTypes("ShortPointer", "ShortBuffer", "short[]"))
.put(new Info("uint16_t", "unsigned __int16", "unsigned short", "unsigned short int").cast()
.valueTypes("short").pointerTypes("ShortPointer", "ShortBuffer", "short[]"))
.put(new Info("int32_t", "__int32", "jint", "int", "signed int", "signed")
.valueTypes("int").pointerTypes("IntPointer", "IntBuffer", "int[]"))
.put(new Info("uint32_t", "unsigned __int32", "unsigned int", "unsigned").cast()
.valueTypes("int").pointerTypes("IntPointer", "IntBuffer", "int[]"))
.put(new Info("jlong", "long long", "signed long long", "long long int", "signed long long int")
.valueTypes("long").pointerTypes("LongPointer", "LongBuffer", "long[]"))
.put(new Info("int64_t", "__int64", "uint64_t", "unsigned __int64", "unsigned long long", "unsigned long long int").cast()
.valueTypes("long").pointerTypes("LongPointer", "LongBuffer", "long[]"))
.put(new Info("long", "signed long", "long int", "signed long int")
.valueTypes("long").pointerTypes("CLongPointer"))
.put(new Info("unsigned long", "unsigned long int").cast()
.valueTypes("long").pointerTypes("CLongPointer"))
.put(new Info("size_t", "ssize_t", "ptrdiff_t", "intptr_t", "uintptr_t", "off_t").cast().valueTypes("long").pointerTypes("SizeTPointer"))
.put(new Info("float", "jfloat").valueTypes("float").pointerTypes("FloatPointer", "FloatBuffer", "float[]"))
.put(new Info("double", "jdouble").valueTypes("double").pointerTypes("DoublePointer", "DoubleBuffer", "double[]"))
.put(new Info("long double").cast().valueTypes("double").pointerTypes("Pointer"))
.put(new Info("std::complex", "float _Complex", "float _Imaginary", "float complex", "float imaginary").cast()
.pointerTypes("FloatPointer", "FloatBuffer", "float[]"))
.put(new Info("std::complex", "double _Complex", "double _Imaginary", "double complex", "double imaginary").cast()
.pointerTypes("DoublePointer", "DoubleBuffer", "double[]"))
.put(new Info("_Bool", "bool", "jboolean").cast().valueTypes("boolean").pointerTypes("BoolPointer", "boolean[]"))
.put(new Info("char16_t").cast().valueTypes("char").pointerTypes("CharPointer", "char[]"))
.put(new Info("char32_t").cast().valueTypes("int").pointerTypes("IntPointer", "int[]"))
.put(new Info("wchar_t", "WCHAR").cast().valueTypes("char", "int").pointerTypes("CharPointer", "IntPointer"))
.put(new Info("const char").valueTypes("byte").pointerTypes("@Cast(\"const char*\") BytePointer", "String"))
.put(new Info("boost::shared_ptr", "std::shared_ptr").annotations("@SharedPtr"))
.put(new Info("boost::movelib::unique_ptr", "std::unique_ptr").annotations("@UniquePtr"))
.put(new Info("std::string").annotations("@StdString").valueTypes("BytePointer", "String").pointerTypes("BytePointer"))
.put(new Info("std::u16string").annotations("@StdString(\"char16_t\")").valueTypes("CharPointer").pointerTypes("CharPointer"))
.put(new Info("std::u32string").annotations("@StdString(\"char32_t\")").valueTypes("IntPointer").pointerTypes("IntPointer"))
.put(new Info("std::wstring").annotations("@StdWString").valueTypes("CharPointer", "IntPointer").pointerTypes("CharPointer", "IntPointer"))
.put(new Info("std::vector").annotations("@StdVector"))
.put(new Info("abstract").javaNames("_abstract"))
.put(new Info("boolean").javaNames("_boolean"))
.put(new Info("byte").javaNames("_byte"))
.put(new Info("extends").javaNames("_extends"))
.put(new Info("finally").javaNames("_finally"))
.put(new Info("implements").javaNames("_implements"))
.put(new Info("import").javaNames("_import"))
.put(new Info("instanceof").javaNames("_instanceof"))
.put(new Info("native").javaNames("_native"))
.put(new Info("package").javaNames("_package"))
.put(new Info("super").javaNames("_super"))
.put(new Info("synchronized").javaNames("_synchronized"))
.put(new Info("transient").javaNames("_transient"))
.put(new Info("operator ->").javaNames("access"))
.put(new Info("operator ()").javaNames("apply"))
.put(new Info("operator []").javaNames("get"))
.put(new Info("operator =").javaNames("put"))
.put(new Info("operator +").javaNames("add"))
.put(new Info("operator -").javaNames("subtract"))
.put(new Info("operator *").javaNames("multiply"))
.put(new Info("operator /").javaNames("divide"))
.put(new Info("operator %").javaNames("mod"))
.put(new Info("operator ++").javaNames("increment"))
.put(new Info("operator --").javaNames("decrement"))
.put(new Info("operator ==").javaNames("equals"))
.put(new Info("operator !=").javaNames("notEquals"))
.put(new Info("operator <").javaNames("lessThan"))
.put(new Info("operator >").javaNames("greaterThan"))
.put(new Info("operator <=").javaNames("lessThanEquals"))
.put(new Info("operator >=").javaNames("greaterThanEquals"))
.put(new Info("operator !").javaNames("not"))
.put(new Info("operator &&").javaNames("and"))
.put(new Info("operator ||").javaNames("or"))
.put(new Info("operator &").javaNames("and"))
.put(new Info("operator |").javaNames("or"))
.put(new Info("operator ^").javaNames("xor"))
.put(new Info("operator ~").javaNames("not"))
.put(new Info("operator <<").javaNames("shiftLeft"))
.put(new Info("operator >>").javaNames("shiftRight"))
.put(new Info("operator +=").javaNames("addPut"))
.put(new Info("operator -=").javaNames("subtractPut"))
.put(new Info("operator *=").javaNames("multiplyPut"))
.put(new Info("operator /=").javaNames("dividePut"))
.put(new Info("operator %=").javaNames("modPut"))
.put(new Info("operator &=").javaNames("andPut"))
.put(new Info("operator |=").javaNames("orPut"))
.put(new Info("operator ^=").javaNames("xorPut"))
.put(new Info("operator <<=").javaNames("shiftLeftPut"))
.put(new Info("operator >>=").javaNames("shiftRightPut"))
.put(new Info("operator new").javaNames("_new"))
.put(new Info("operator delete").javaNames("_delete"))
.put(new Info("getClass").javaNames("_getClass"))
.put(new Info("notify").javaNames("_notify"))
.put(new Info("notifyAll").javaNames("_notifyAll"))
.put(new Info("wait").javaNames("_wait"))
.put(new Info("allocate").javaNames("_allocate"))
.put(new Info("close").javaNames("_close"))
.put(new Info("deallocate").javaNames("_deallocate"))
.put(new Info("free").javaNames("_free"))
.put(new Info("address").javaNames("_address"))
.put(new Info("position").javaNames("_position"))
.put(new Info("limit").javaNames("_limit"))
.put(new Info("capacity").javaNames("_capacity"))
.put(new Info("fill").javaNames("_fill"))
.put(new Info("zero").javaNames("_zero"));
String normalize(String name, boolean unconst, boolean untemplate) {
if (name == null || name.length() == 0 || name.startsWith("basic/")) {
return name;
}
boolean foundConst = false, simpleType = true;
String prefix = null;
Token[] tokens = new Tokenizer(name, null, 0).tokenize();
int n = tokens.length;
Info info = getFirst("basic/types");
String[] basicTypes = info != null ? info.cppTypes : new String[0];
Arrays.sort(basicTypes);
for (int i = 0; i < n; i++) {
if (tokens[i].match(Token.CONST, Token.CONSTEXPR)) {
foundConst = true;
for (int j = i + 1; j < n; j++) {
tokens[j - 1] = tokens[j];
}
i--; n--;
} else if (tokens[i].match(Token.CLASS, Token.STRUCT, Token.UNION)) {
prefix = tokens[i].value;
for (int j = i + 1; j < n; j++) {
tokens[j - 1] = tokens[j];
}
i--; n--;
} else if (Arrays.binarySearch(basicTypes, tokens[i].value) < 0) {
simpleType = false;
break;
}
}
if (simpleType) {
Arrays.sort(tokens, 0, n);
name = (foundConst ? "const " : "") + tokens[0].value;
for (int i = 1; i < n; i++) {
name += " " + tokens[i].value;
}
} else if (untemplate) {
int count = 0, template = -1;
for (int i = 0; i < n; i++) {
if (tokens[i].match('<')) {
if (count == 0) {
template = i;
}
count++;
} else if (tokens[i].match('>')) {
count--;
if (count == 0 && i + 1 != n) {
template = -1;
}
}
}
if (template >= 0) {
name = foundConst ? "const " : "";
for (int i = 0; i < template; i++) {
name += tokens[i].value;
}
}
}
if (unconst && foundConst) {
name = name.substring(name.indexOf("const") + 5);
}
if (prefix != null) {
name = name.substring(name.indexOf(prefix) + prefix.length());
}
return name.trim();
}
@Override public boolean containsKey(Object key) {
return super.containsKey(key) || (parent != null && parent.containsKey(key));
}
public List get(String cppName) {
return get(cppName, true);
}
public List get(String cppName, boolean partial) {
String key = normalize(cppName, false, false);
List infoList = super.get(key);
boolean partialMatch = false;
if (infoList == null) {
key = normalize(cppName, true, false);
infoList = super.get(key);
}
if (infoList == null && partial) {
key = normalize(cppName, true, true);
infoList = super.get(key);
partialMatch = true;
}
if (infoList == null) {
infoList = new ArrayList();
}
if (parent != null) {
List l = parent.get(cppName, partial);
if (l != null && l.size() > 0) {
infoList = new ArrayList(infoList);
// prioritize parent when we only have a partial match
if (partialMatch) {
infoList.addAll(0, l);
} else {
infoList.addAll(l);
}
}
}
return infoList;
}
public Info get(int index, String cppName) {
return get(index, cppName, true);
}
public Info get(int index, String cppName, boolean partial) {
List infoList = get(cppName, partial);
return infoList.size() > 0 ? infoList.get(index) : null;
}
public Info getFirst(String cppName) {
return getFirst(cppName, true);
}
public Info getFirst(String cppName, boolean partial) {
List infoList = get(cppName, partial);
return infoList.size() > 0 ? infoList.get(0) : null;
}
public InfoMap put(int index, Info info) {
for (String cppName : info.cppNames != null ? info.cppNames : new String[] { null }) {
String[] keys = { normalize(cppName, false, false),
normalize(cppName, false, true) };
for (String key : keys) {
List infoList = super.get(key);
if (infoList == null) {
super.put(key, infoList = new ArrayList());
}
if (!infoList.contains(info)) {
switch (index) {
case -1: infoList.add(info); break;
default: infoList.add(index, info); break;
}
}
}
}
return this;
}
public InfoMap put(Info info) {
return put(-1, info);
}
public InfoMap putFirst(Info info) {
return put(0, info);
}
}