Home | History | Annotate | Download | only in format
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.ide.eclipse.gltrace.format;
     18 
     19 import java.io.BufferedReader;
     20 import java.io.IOException;
     21 import java.io.InputStream;
     22 import java.io.InputStreamReader;
     23 import java.util.ArrayList;
     24 import java.util.Arrays;
     25 import java.util.HashMap;
     26 import java.util.List;
     27 import java.util.Map;
     28 
     29 /**
     30  * Model a single GL API function call's specification.
     31  */
     32 public class GLAPISpec {
     33     private static final String GL_SPECS_FILE = "/entries.in"; //$NON-NLS-1$
     34     private static final String GLES2_ENTRIES_HEADER_V1 =
     35             "# com.android.ide.eclipse.gltrace.glentries, v1"; //$NON-NLS-1$
     36     private static Map<String, GLAPISpec> sApiSpecs;
     37 
     38     private final String mGLFunction;
     39     private final GLDataTypeSpec mReturnType;
     40     private final List<GLDataTypeSpec> mArgs;
     41 
     42     private GLAPISpec(String glFunction, GLDataTypeSpec returnType, List<GLDataTypeSpec> args) {
     43         mGLFunction = glFunction;
     44         mReturnType = returnType;
     45         mArgs = args;
     46     }
     47 
     48     public String getFunction() {
     49         return mGLFunction;
     50     }
     51 
     52     public GLDataTypeSpec getReturnValue() {
     53         return mReturnType;
     54     }
     55 
     56     public List<GLDataTypeSpec> getArgs() {
     57         return mArgs;
     58     }
     59 
     60     public static Map<String, GLAPISpec> getSpecs() {
     61         if (sApiSpecs == null) {
     62             sApiSpecs = parseApiSpecs(GLAPISpec.class.getResourceAsStream(GL_SPECS_FILE));
     63         }
     64 
     65         return sApiSpecs;
     66     }
     67 
     68     private static Map<String, GLAPISpec> parseApiSpecs(InputStream specFile) {
     69         BufferedReader reader = new BufferedReader(new InputStreamReader(specFile));
     70         Map<String, GLAPISpec> specs = new HashMap<String, GLAPISpec>(400);
     71 
     72         try{
     73             String header = reader.readLine().trim();
     74             assert header.equals(GLES2_ENTRIES_HEADER_V1);
     75 
     76             String line;
     77             while ((line = reader.readLine()) != null) {
     78                 // strip away the comments
     79                 int commentPos = line.indexOf('#');
     80                 if (commentPos != -1) {
     81                     line = line.substring(0, commentPos);
     82                 }
     83                 line = line.trim();
     84 
     85                 // parse non empty lines
     86                 if (line.length() > 0) {
     87                     GLAPISpec spec = parseLine(line);
     88                     specs.put(spec.getFunction(), spec);
     89                 }
     90             }
     91 
     92             specFile.close();
     93         } catch (IOException e) {
     94             // this is unlikely to happen as the file is present within this .jar file.
     95             // Even if it does happen, we just return whatever we've read till now. The net
     96             // impact will be that the function calls will not be parsed fully and will just
     97             // display the function name.
     98         }
     99 
    100         return specs;
    101     }
    102 
    103     /**
    104      * Parse a GL API Specification entry from "/entries.in". Each line is of the format:
    105      * {@code returnType, funcName, arg*}. This method is package private for testing.
    106      */
    107     static GLAPISpec parseLine(String line) {
    108         List<String> words = Arrays.asList(line.split(","));
    109 
    110         String retType = words.get(0).trim();
    111         String func = words.get(1).trim();
    112         List<String> argDefinitions = words.subList(2, words.size());
    113 
    114         List<GLDataTypeSpec> glArgs = new ArrayList<GLDataTypeSpec>(argDefinitions.size()/2);
    115         for (String argDefn: argDefinitions) {
    116             // an argDefn is something like: "const GLvoid* data"
    117             argDefn = argDefn.trim();
    118             int lastSeparator = argDefn.lastIndexOf(' ');
    119             if (lastSeparator == -1) {
    120                 // no space => a void type with no argument name
    121                 glArgs.add(new GLDataTypeSpec(argDefn, null));
    122             } else {
    123                 // everything upto the last space is the type
    124                 String type = argDefn.substring(0, lastSeparator);
    125 
    126                 // and the last word is the variable name
    127                 String name = argDefn.substring(lastSeparator + 1);
    128                 glArgs.add(new GLDataTypeSpec(type, name));
    129             }
    130         }
    131 
    132         return new GLAPISpec(func, new GLDataTypeSpec(retType, null), glArgs);
    133     }
    134 }
    135