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    }