Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      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
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 #include "oscl_library_list.h"
     19 #include "oscl_string.h"
     20 #include "oscl_file_io.h"
     21 #include "oscl_file_types.h"
     22 #include "pvlogger.h"
     23 #include "oscl_uuid.h"
     24 
     25 #define HASH '#'
     26 #define NEWLINE '\n'
     27 #define OPEN_PAREN '('
     28 #define CLOSE_PAREN ')'
     29 #define QUOTE '"'
     30 #define COMMA ','
     31 #define OSCL_NUMBER_OF_SHARED_LIBS  16
     32 #define BUFFER_SIZE 256
     33 
     34 
     35 OSCL_EXPORT_REF OsclLibraryList::OsclLibraryList()
     36 {
     37     ipLogger = PVLogger::GetLoggerObject("oscllib");
     38 #if OSCL_LIBRARY_PERF_LOGGING
     39     iDiagnosticsLogger = PVLogger::GetLoggerObject("pvplayerdiagnostics.oscllib.oscllibrarylist");
     40     iLinesRead = 0;
     41     iLibHit = 0;
     42 #endif
     43     int32 err = 0;
     44     OSCL_TRY(err,
     45              iLibList.reserve(OSCL_NUMBER_OF_SHARED_LIBS);
     46             );
     47     if (err)
     48     {
     49         iLibList.clear();
     50         OSCL_LEAVE(err);
     51     }
     52 
     53 }
     54 
     55 OSCL_EXPORT_REF OsclLibraryList::~OsclLibraryList()
     56 {
     57 #if OSCL_LIBRARY_PERF_LOGGING
     58     iDiagnosticsLogger = NULL;
     59 #endif
     60     ipLogger = NULL;
     61     iLibList.clear();
     62 }
     63 
     64 //  This method actually parses through a dll config file, retrieving the paths
     65 // of dlls which implement a specific OsclUuid
     66 OSCL_EXPORT_REF OsclLibStatus OsclLibraryList::Populate(const OsclUuid& aInterfaceId, const OSCL_String& aConfigFile)
     67 {
     68     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipLogger, PVLOGMSG_DEBUG,
     69                     (0, "OsclLibraryList::Populate '%s' IN", aConfigFile.get_cstr()));
     70 
     71     // Open config file
     72     Oscl_FileServer fileserver;
     73     if (0 != fileserver.Connect())
     74     {
     75         // Failed to connect to file server, return failure
     76         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipLogger, PVLOGMSG_ERR,
     77                         (0, "OsclLibraryList::Populate - Unable to connect to fileserver"));
     78         return OsclLibFail;
     79     }
     80     Oscl_File configFile;
     81     if (0 != configFile.Open(aConfigFile.get_cstr(), Oscl_File::MODE_READ, fileserver))
     82     {
     83         // Failed to open config file, return failure
     84         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipLogger, PVLOGMSG_ERR,
     85                         (0, "OsclLibraryList::Populate - Unable to open configFile %s", aConfigFile.get_cstr()));
     86         return OsclLibFail;
     87     }
     88 
     89 #if OSCL_LIBRARY_PERF_LOGGING
     90     // Start collecting stats for current config file
     91     iLinesRead = 0;
     92     iLibHit = 0;
     93     TICK starttime;
     94     SET_TICK(starttime);
     95 #endif
     96 
     97     // Read in a byte at a time
     98     uint8 buf[1];
     99     while (1 == configFile.Read(buf, 1, 1))
    100     {
    101         if (HASH == buf[0])
    102         {
    103 #if OSCL_LIBRARY_PERF_LOGGING
    104             iLinesRead++;
    105 #endif
    106             // Ignore comments - begin with '#'
    107             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipLogger, PVLOGMSG_DEBUG,
    108                             (0, "OsclLibraryList::Populate - Found a comment, skipping"));
    109             // Advance to end of line
    110             while (1 == configFile.Read(buf, 1, 1) && buf[0] != NEWLINE)
    111             {
    112                 // ignore
    113             }
    114         }
    115         else if (OPEN_PAREN == buf[0])
    116         {
    117             // Parse UUID from line - begins with "("
    118             uint8 uuidBuf[BUFFER_SIZE];
    119             int i = 0;
    120             uuidBuf[i++] = buf[0];
    121             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipLogger, PVLOGMSG_DEBUG,
    122                             (0, "OsclLibraryList::Populate - Found a (, reading uuid"));
    123             // Read a character at a time - stop if newline or eof is reached or buffer is filled
    124             while (i < BUFFER_SIZE && 1 == configFile.Read(buf, 1, 1) && buf[0] != NEWLINE)
    125             {
    126                 uuidBuf[i++] = buf[0];
    127                 if (CLOSE_PAREN == buf[0])
    128                 {
    129                     break;
    130                 }
    131             }
    132             uuidBuf[i] = '\0';
    133             if (NEWLINE == buf[0])
    134             {
    135 #if OSCL_LIBRARY_PERF_LOGGING
    136                 iLinesRead++;
    137 #endif
    138                 // Reached the end of line but did not find the closing parentheses
    139                 // Skip this malformed line
    140                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipLogger, PVLOGMSG_WARNING,
    141                                 (0, "OsclLibraryList::Populate - incomplete uuid, skipping line"));
    142             }
    143             else if (BUFFER_SIZE == i && CLOSE_PAREN != buf[0])
    144             {
    145                 // Buffer is filled but did not reach the end of UUID - skip this malformed line
    146                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipLogger, PVLOGMSG_WARNING,
    147                                 (0, "OsclLibraryList::Populate - uuid too long, skipping line"));
    148                 // Advance to end of line
    149                 while (1 == configFile.Read(buf, 1, 1) && buf[0] != NEWLINE)
    150                 {
    151                     // ignore
    152                 }
    153             }
    154             else
    155             {
    156                 // Create an instance of OsclUuid
    157                 OsclUuid tempUuidStr((char*)uuidBuf);
    158                 if (tempUuidStr == aInterfaceId)
    159                 {
    160                     // Parse path from line
    161                     bool commaFound = false;
    162                     bool quoteFound = false;
    163                     while (!(commaFound && quoteFound) && 1 == configFile.Read(buf, 1, 1) && buf[0] != NEWLINE)
    164                     {
    165                         // Advance past ',' and '"'
    166                         if (COMMA == buf[0])
    167                         {
    168                             // If already found a comma, break and skip this malformed line
    169                             if (commaFound) break;
    170                             commaFound = true;
    171                         }
    172                         else if (QUOTE == buf[0])
    173                         {
    174                             // If already found a quote, break and skip this malformed line
    175                             if (quoteFound) break;
    176                             quoteFound = true;
    177                         }
    178                     }
    179                     if (!(commaFound && quoteFound) || NEWLINE == buf[0])
    180                     {
    181 #if OSCL_LIBRARY_PERF_LOGGING
    182                         iLinesRead++;
    183 #endif
    184                         // Did not find both ',' and '"' - Skip this malformed line
    185                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipLogger, PVLOGMSG_WARNING,
    186                                         (0, "OsclLibraryList::Populate - missing ' or \", skipping line"));
    187                     }
    188                     else
    189                     {
    190                         uint8 pathBuf[BUFFER_SIZE];
    191                         i = 0;
    192                         // Read a character at a time - stop if newline is reached, ending quote is reached, or buffer is filled
    193                         // - leave room for terminating null character in buffer
    194                         while (1 == configFile.Read(buf, 1, 1) && buf[0] != QUOTE && buf[0] != NEWLINE && i < (BUFFER_SIZE - 1))
    195                         {
    196                             pathBuf[i++] = buf[0];
    197                         }
    198                         if (NEWLINE == buf[0])
    199                         {
    200 #if OSCL_LIBRARY_PERF_LOGGING
    201                             iLinesRead++;
    202 #endif
    203                             // Reached the end of line but did not find the closing quote
    204                             // Skip this malformed line
    205                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipLogger, PVLOGMSG_WARNING,
    206                                             (0, "OsclLibraryList::Populate - incomplete path, skipping line"));
    207                         }
    208                         else if ((BUFFER_SIZE - 1) == i && QUOTE != buf[0])
    209                         {
    210                             // Buffer is filled but did not reach the end of path - skip this malformed line
    211                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipLogger, PVLOGMSG_WARNING,
    212                                             (0, "OsclLibraryList::Populate - path too long, skipping line"));
    213 #if OSCL_LIBRARY_PERF_LOGGING
    214                             iLinesRead++;
    215 #endif
    216                             // Advance to end of line
    217                             while (1 == configFile.Read(buf, 1, 1) && buf[0] != NEWLINE)
    218                             {
    219                                 // ignore
    220                             }
    221                         }
    222                         else
    223                         {
    224                             // Read in the path, end with terminating character
    225                             pathBuf[i] = NULL_TERM_CHAR;
    226                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipLogger, PVLOGMSG_INFO,
    227                                             (0, "OsclLibraryList::Populate - found a match, adding to list: %s",
    228                                              (char*)pathBuf));
    229                             // Add path to library list
    230                             iLibList.push_back((char*)pathBuf);
    231 #if OSCL_LIBRARY_PERF_LOGGING
    232                             iLibHit++;
    233                             iLinesRead++;
    234 #endif
    235                         }
    236                     }
    237                 }
    238                 else
    239                 {
    240                     // The UUID from this line does not match aInterfaceId - Advance to end of line
    241                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, ipLogger, PVLOGMSG_INFO,
    242                                     (0, "OsclLibraryList::Populate - uuid not a match, skipping line"));
    243 #if OSCL_LIBRARY_PERF_LOGGING
    244                     iLinesRead++;
    245 #endif
    246                     while (1 == configFile.Read(buf, 1, 1) && buf[0] != NEWLINE)
    247                     {
    248                         // ignore
    249                     }
    250                 }
    251             }
    252         }
    253         // else continue on to next byte
    254     };
    255 
    256 #if OSCL_LIBRARY_PERF_LOGGING
    257     // End stats for current config file
    258     uint32 difftime;
    259     DIFF_TICK(starttime, difftime);
    260     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iDiagnosticsLogger, PVLOGMSG_INFO,
    261                     (0, "OsclLibraryList::Populate - Parsing configFile %s ...", aConfigFile.get_cstr()));
    262     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iDiagnosticsLogger, PVLOGMSG_INFO,
    263                     (0, "                                   Time taken = %d ticks", difftime));
    264     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iDiagnosticsLogger, PVLOGMSG_INFO,
    265                     (0, "                                   Lines read = %d", iLinesRead));
    266     PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF, iDiagnosticsLogger, PVLOGMSG_INFO,
    267                     (0, "                                   Libraries found = %d", iLibHit));
    268 #endif
    269 
    270     //If there's atleast one library path name loaded in the vector,
    271     //it means the parsing is successful for at least a particular OsclUuid
    272 
    273     if (iLibList.size() > 0)
    274     {
    275         return OsclLibSuccess;
    276     }
    277     else
    278     {
    279         PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, ipLogger, PVLOGMSG_WARNING,
    280                         (0, "OsclLibraryList::Populate, Didn't find any DLL for the OsclUuid"));
    281         return OsclLibFail;
    282     }
    283 }
    284 
    285 OSCL_EXPORT_REF uint32 OsclLibraryList::Size()
    286 {
    287     return iLibList.size();
    288 }
    289 
    290 OSCL_EXPORT_REF const OSCL_String& OsclLibraryList::GetLibraryPathAt(uint32 n)
    291 {
    292     return iLibList[n];
    293 }
    294 
    295