• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
OsclLibraryList()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 
~OsclLibraryList()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
Populate(const OsclUuid & aInterfaceId,const OSCL_String & aConfigFile)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 
Size()285 OSCL_EXPORT_REF uint32 OsclLibraryList::Size()
286 {
287     return iLibList.size();
288 }
289 
GetLibraryPathAt(uint32 n)290 OSCL_EXPORT_REF const OSCL_String& OsclLibraryList::GetLibraryPathAt(uint32 n)
291 {
292     return iLibList[n];
293 }
294 
295