001 /*
002 Copyright (c) 2009 Olivier Chafik, All Rights Reserved
003
004 This file is part of JNAerator (http://jnaerator.googlecode.com/).
005
006 JNAerator is free software: you can redistribute it and/or modify
007 it under the terms of the GNU General Public License as published by
008 the Free Software Foundation, either version 3 of the License, or
009 (at your option) any later version.
010
011 JNAerator is distributed in the hope that it will be useful,
012 but WITHOUT ANY WARRANTY; without even the implied warranty of
013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 GNU General Public License for more details.
015
016 You should have received a copy of the GNU General Public License
017 along with JNAerator. If not, see <http://www.gnu.org/licenses/>.
018 */
019 package com.ochafik.lang.jnaerator.runtime;
020
021 import java.lang.reflect.Method;
022 import java.util.ArrayList;
023 import java.util.Arrays;
024 import java.util.Collections;
025 import java.util.HashMap;
026 import java.util.List;
027 import java.util.Map;
028
029 import com.sun.jna.FunctionMapper;
030 import com.sun.jna.Library;
031 import com.sun.jna.NativeLibrary;
032 import com.sun.jna.win32.StdCallFunctionMapper;
033 import com.sun.jna.win32.W32APIFunctionMapper;
034
035 public class MangledFunctionMapper implements FunctionMapper {
036 public static final Map<Object, Object> DEFAULT_OPTIONS;
037 static {
038 Map<Object, Object> m = new HashMap<Object, Object>();
039 m.put(Library.OPTION_FUNCTION_MAPPER, new MangledFunctionMapper(
040 new StdCallFunctionMapper()
041 ));
042
043 DEFAULT_OPTIONS = Collections.unmodifiableMap(m);
044 }
045 public List<FunctionMapper> linked = new ArrayList<FunctionMapper>();
046 public MangledFunctionMapper(FunctionMapper... linked ) {
047 this.linked.addAll(Arrays.asList(linked));
048 }
049 public String getFunctionName(NativeLibrary library, Method method) {
050 Mangling name = method.getAnnotation(Mangling.class);
051 if (name != null) {
052 for (String n : name.value()) {
053 try {
054 if (library.getGlobalVariableAddress(n) != null)
055 return n;
056 if (n.startsWith("_")) {
057 n = n.substring(1);
058 if (library.getGlobalVariableAddress(n) != null)
059 return n;
060 }
061 } catch (Throwable ex) {
062 ex = null;
063 }
064 }
065 }
066 if (linked != null)
067 for (FunctionMapper fm : linked) {
068 String n = fm.getFunctionName(library, method);
069 if (n != null && library.getGlobalVariableAddress(n) != null)
070 return n;
071 }
072 return method.getName();
073 }
074
075 }