All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bytedeco.javacpp.tools.InfoMap Maven / Gradle / Ivy

There is a newer version: 1.5.11
Show newest version
/*
 * 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);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy