• 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 
19 #ifndef PVMF_NODE_UTILS_H_INCLUDED
20 #define PVMF_NODE_UTILS_H_INCLUDED
21 
22 #ifndef PVMF_NODE_INTERFACE_H_INCLUDED
23 #include "pvmf_node_interface.h"
24 #endif
25 #ifndef OSCL_STRING_CONTAINERS_H_INCLUDED
26 #include "oscl_string_containers.h"
27 #endif
28 
29 /**
30 //A basic implemention of PVInterface.  Interface implementations
31 //can derive from this.
32 */
33 template<class Alloc>
34 class PVInterfaceImpl
35 {
36     public:
PVInterfaceImpl(const PVUuid & uuid)37         PVInterfaceImpl(const PVUuid& uuid)
38                 : iRefCounter(1)
39                 , iUuid(uuid)
40         {}
~PVInterfaceImpl()41         virtual ~PVInterfaceImpl()
42         {}
removeRef()43         void removeRef()
44         {
45             --iRefCounter;
46             if (iRefCounter <= 0)
47             {
48                 this->~PVInterfaceImpl();
49                 Alloc alloc;
50                 alloc.deallocate(this);
51             }
52         }
addRef()53         void addRef()
54         {
55             iRefCounter++;
56         }
Uuid()57         const PVUuid& Uuid()const
58         {
59             return iUuid;
60         }
61     private:
62         int32 iRefCounter;
63         PVUuid iUuid;
64 };
65 
66 
67 /**
68 //A vector for holding port pointers, with a built-in port iterator.
69 //This vector automatically calls the port destructor when pointers are
70 //removed from the vector.
71 //Node implementations can use this to manage multiple ports.
72 */
73 template<class Port, class Alloc>
74 class PVMFPortVector: public PVMFPortIter
75 {
76     public:
77         typedef Port vec_element_deref;
78         typedef Port* vec_element;
79         typedef vec_element* vec_element_ptr;
80 
~PVMFPortVector()81         virtual ~PVMFPortVector()
82         {
83             while (iVec.size() > 0)
84                 Erase(&front());
85         }
Construct(uint32 nres)86         void Construct(uint32 nres)
87         {//construct the vector
88             iIterIndex = 0;
89             iVec.reserve(nres);
90             iNres = nres;
91         }
Erase(vec_element_ptr elem)92         void Erase(vec_element_ptr elem)
93         {//erase an element
94             if (elem)
95             {   //must explicitly call port destructor, since
96                 //vec elements are pointers.
97                 Oscl_TAlloc<vec_element_deref, Alloc> talloc;
98                 talloc.destruct_and_dealloc(*elem);
99                 iVec.erase(elem);
100             }
101         }
Reconstruct()102         void Reconstruct()
103         {//erase all elements & reconstruct the vector.
104             for (uint32 i = 0; i < iVec.size(); i++)
105                 Erase(&iVec[i]);
106             iVec.clear();
107             iVec.reserve(iNres);
108         }
109 
Allocate()110         OsclAny* Allocate()
111         {//allocate space for a port.
112             Alloc alloc;
113             return alloc.ALLOCATE(sizeof(Port));
114         }
DestructAndDealloc(Port * port)115         void DestructAndDealloc(Port* port)
116         {//Cleanup a port using the allocator.  For use only
117             //on port pointers that aren't yet in the vector.
118             Oscl_TAlloc<Port, Alloc> talloc;
119             talloc.destruct_and_dealloc(port);
120         }
121 
AddL(vec_element & elem)122         void AddL(vec_element &elem)
123         {//add an element to the end.
124             iVec.push_back(elem);
125         }
126 
InsertL(vec_element & elem)127         void InsertL(vec_element &elem)
128         {//add an element to the front
129             iVec.push_front(elem);
130         }
131 
FindByValue(vec_element & elem)132         vec_element_ptr FindByValue(vec_element &elem)
133         {//find an element by its value
134             for (uint32 i = 0; i < iVec.size(); i++)
135                 if (iVec[i] == elem)
136                     return &iVec[i];
137             return NULL;
138         }
139 
140         //From PVMFPortIter
NumPorts()141         uint16 NumPorts()
142         {
143             return (uint16)iVec.size();
144         }
GetNext()145         PVMFPortInterface* GetNext()
146         {
147             if (iVec.size() > iIterIndex)
148                 return iVec[iIterIndex++];
149             return NULL;
150         }
Reset()151         void Reset()
152         {
153             iIterIndex = 0;
154         }
155 
156         //wrappers for methods from Oscl_Vector
157         vec_element& operator[](uint32 n)
158         {
159             return iVec[n];
160         }
161         const vec_element& operator[](uint32 n) const
162         {
163             return iVec[n];
164         }
size()165         uint32 size()const
166         {
167             return iVec.size();
168         }
clear()169         void clear()
170         {
171             iVec.clear();
172         }
front()173         vec_element& front()
174         {
175             return iVec.front();
176         }
empty()177         bool empty()const
178         {
179             return iVec.empty();
180         }
181 
182     private:
183         Oscl_Vector<vec_element, Alloc> iVec;
184         uint32 iNres;
185         uint32 iIterIndex;
186 };
187 
188 /**
189 // Node Command queue utilities.
190 */
191 
192 //IDs for all of the asynchronous node commands.
193 enum TPVMFGenericNodeCommand
194 {
195     PVMF_GENERIC_NODE_QUERYUUID
196     , PVMF_GENERIC_NODE_QUERYINTERFACE
197     , PVMF_GENERIC_NODE_REQUESTPORT
198     , PVMF_GENERIC_NODE_RELEASEPORT
199     , PVMF_GENERIC_NODE_INIT
200     , PVMF_GENERIC_NODE_PREPARE
201     , PVMF_GENERIC_NODE_START
202     , PVMF_GENERIC_NODE_STOP
203     , PVMF_GENERIC_NODE_FLUSH
204     , PVMF_GENERIC_NODE_PAUSE
205     , PVMF_GENERIC_NODE_RESET
206     , PVMF_GENERIC_NODE_CANCELALLCOMMANDS
207     , PVMF_GENERIC_NODE_CANCELCOMMAND
208     , PVMF_GENERIC_NODE_COMMAND_LAST //a placeholder for adding
209     //node-specific commands to this list.
210 };
211 
212 /**
213 //A node command class with constructors and destructors
214 //for all of the generic asynchronous node commands.
215 */
216 template<class Alloc>
217 class PVMFGenericNodeCommand
218 {
219     public:
~PVMFGenericNodeCommand()220         virtual ~PVMFGenericNodeCommand() {}
221 
222         //base construction for all commands.  derived class can override this
223         //to add initialization of other parameters.
BaseConstruct(PVMFSessionId s,int32 aCmd,const OsclAny * aContext)224         virtual void BaseConstruct(PVMFSessionId s, int32 aCmd, const OsclAny* aContext)
225         {
226             iSession = s;
227             iCmd = aCmd;
228             iContext = aContext;
229             iParam1 = NULL;
230             iParam2 = NULL;
231             iParam3 = NULL;
232             iParam4 = NULL;
233             iParam5 = NULL;
234         }
235 
236         //for Init, Start, Stop, Pause and other commands.
Construct(PVMFSessionId s,int32 aCmd,const OsclAny * aContext)237         void Construct(PVMFSessionId s, int32 aCmd, const OsclAny* aContext)
238         {
239             BaseConstruct(s, aCmd, aContext);
240         }
241 
242         //for CancelCommand
Construct(PVMFSessionId s,int32 aCmd,int32 aTag,const OsclAny * aContext)243         void Construct(PVMFSessionId s, int32 aCmd, int32 aTag, const OsclAny* aContext)
244         {
245             BaseConstruct(s, aCmd, aContext);
246             iParam1 = (OsclAny*)aTag;
247         }
Parse(int32 & aTag)248         void Parse(int32&aTag)
249         {
250             aTag = (int32)iParam1;
251         }
252 
253         //for ReleasePort
Construct(PVMFSessionId s,int32 aCmd,PVMFPortInterface & aPort,const OsclAny * aContext)254         void Construct(PVMFSessionId s, int32 aCmd, PVMFPortInterface& aPort, const OsclAny* aContext)
255         {
256             BaseConstruct(s, aCmd, aContext);
257             iParam1 = (OsclAny*) & aPort;
258         }
Parse(PVMFPortInterface * & aPort)259         void Parse(PVMFPortInterface*&aPort)
260         {
261             aPort = (PVMFPortInterface*)iParam1;
262         }
263 
264         //for QueryInterface
Construct(PVMFSessionId s,int32 aCmd,const PVUuid & aUuid,PVInterface * & aInterfacePtr,const OsclAny * aContext)265         void Construct(PVMFSessionId s, int32 aCmd, const PVUuid& aUuid,
266                        PVInterface*& aInterfacePtr,
267                        const OsclAny* aContext)
268         {
269             BaseConstruct(s, aCmd, aContext);
270             //if input cmd id isn't as expected, memory won't get
271             //cleaned up later, so assert here.
272             OSCL_ASSERT(aCmd == PVMF_GENERIC_NODE_QUERYINTERFACE);
273             //allocate a copy of the Uuid.
274             Oscl_TAlloc<PVUuid, Alloc>uuid;
275             iParam1 = uuid.ALLOC_AND_CONSTRUCT(aUuid);
276             iParam2 = (OsclAny*) & aInterfacePtr;
277         }
Parse(PVUuid * & aUuid,PVInterface ** & aInterface)278         void Parse(PVUuid*&aUuid, PVInterface**&aInterface)
279         {
280             aUuid = (PVUuid*)iParam1;
281             aInterface = (PVInterface**)iParam2;
282         }
283 
284         //for QueryUuids
Construct(PVMFSessionId s,int32 aCmd,const PvmfMimeString & aMimeType,Oscl_Vector<PVUuid,OsclMemAllocator> & aUuids,bool aExactUuidsOnly,const OsclAny * aContext)285         void Construct(PVMFSessionId s, int32 aCmd, const PvmfMimeString& aMimeType,
286                        Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
287                        bool aExactUuidsOnly,
288                        const OsclAny* aContext)
289         {
290             BaseConstruct(s, aCmd, aContext);
291             //if input cmd id isn't as expected, memory won't get
292             //cleaned up later, so assert here.
293             OSCL_ASSERT(aCmd == PVMF_GENERIC_NODE_QUERYUUID);
294             //allocate a copy of the mime type string.
295             Oscl_TAlloc<OSCL_HeapString<Alloc>, Alloc> mimetype;
296             iParam1 = mimetype.ALLOC_AND_CONSTRUCT(aMimeType);
297             iParam2 = (OsclAny*) & aUuids;
298             iParam3 = (OsclAny*)aExactUuidsOnly;
299         }
Parse(OSCL_String * & aMimetype,Oscl_Vector<PVUuid,OsclMemAllocator> * & aUuids,bool & aExact)300         void Parse(OSCL_String*&aMimetype, Oscl_Vector<PVUuid, OsclMemAllocator>*&aUuids, bool &aExact)
301         {
302             aMimetype = (OSCL_HeapString<Alloc>*)iParam1;
303             aUuids = (Oscl_Vector<PVUuid, OsclMemAllocator>*)iParam2;
304             aExact = (iParam3) ? true : false;
305         }
306 
307         //for RequestPort
Construct(PVMFSessionId s,int32 aCmd,int32 aPortTag,const PvmfMimeString * aMimeType,const OsclAny * aContext)308         void Construct(PVMFSessionId s, int32 aCmd
309                        , int32 aPortTag
310                        , const PvmfMimeString* aMimeType
311                        , const OsclAny* aContext)
312         {
313             BaseConstruct(s, aCmd, aContext);
314             iParam1 = (OsclAny*)aPortTag;
315             //if input cmd id isn't as expected, memory won't get
316             //cleaned up later, so assert here.
317             OSCL_ASSERT(aCmd == PVMF_GENERIC_NODE_REQUESTPORT);
318             //allocate a copy of the mime type string.
319             if (aMimeType)
320             {
321                 Oscl_TAlloc<OSCL_HeapString<Alloc>, Alloc> mimetype;
322                 iParam2 = mimetype.ALLOC_AND_CONSTRUCT(*aMimeType);
323             }
324         }
Parse(int32 & aPortTag,OSCL_String * & aMimetype)325         void Parse(int32&aPortTag, OSCL_String*&aMimetype)
326         {
327             aPortTag = (int32)iParam1;
328             aMimetype = (OSCL_HeapString<Alloc>*)iParam2;
329         }
330 
331         //cleanup routine.  Derived class can override this to cleanup additional
332         //allocated memory.
Destroy()333         virtual void Destroy()
334         {
335             switch (iCmd)
336             {
337                 case PVMF_GENERIC_NODE_QUERYUUID:
338                 {//destroy the allocated mimetype string
339                     Oscl_TAlloc<OSCL_HeapString<Alloc>, Alloc> mimetype;
340                     mimetype.destruct_and_dealloc(iParam1);
341                 }
342                 break;
343                 case PVMF_GENERIC_NODE_REQUESTPORT:
344                 {//destroy the allocated mimetype string
345                     if (iParam2)
346                     {
347                         Oscl_TAlloc<OSCL_HeapString<Alloc>, Alloc> mimetype;
348                         mimetype.destruct_and_dealloc(iParam2);
349                     }
350                 }
351                 break;
352                 case PVMF_GENERIC_NODE_QUERYINTERFACE:
353                 {//destroy the allocated uuid
354                     Oscl_TAlloc<PVUuid, Alloc>uuid;
355                     uuid.destruct_and_dealloc(iParam1);
356                 }
357                 break;
358                 default:
359                     break;
360             }
361         }
362 
363         //command copy.  derived class can override this to allocate
364         //any additional parameters.
Copy(const PVMFGenericNodeCommand<Alloc> & aCmd)365         virtual void Copy(const PVMFGenericNodeCommand<Alloc>& aCmd)
366         {
367             iId = aCmd.iId;
368             iSession = aCmd.iSession;
369             iContext = aCmd.iContext;
370             iParam1 = aCmd.iParam1;
371             iParam2 = aCmd.iParam2;
372             iParam3 = aCmd.iParam3;
373             iParam4 = aCmd.iParam4;
374             iParam5 = aCmd.iParam5;
375             iCmd = aCmd.iCmd;
376             switch (aCmd.iCmd)
377             {
378                 case PVMF_GENERIC_NODE_QUERYUUID:
379                 {//copy the allocated mimetype string
380                     OSCL_HeapString<Alloc>* aMimetype = (OSCL_HeapString<Alloc>*)aCmd.iParam1;
381                     Oscl_TAlloc<OSCL_HeapString<Alloc>, Alloc> mimetype;
382                     iParam1 = mimetype.ALLOC_AND_CONSTRUCT(*aMimetype);
383                 }
384                 break;
385                 case PVMF_GENERIC_NODE_REQUESTPORT:
386                 {//copy the allocated mimetype string
387                     OSCL_HeapString<Alloc>* aMimetype = (OSCL_HeapString<Alloc>*)aCmd.iParam2;
388                     if (aMimetype)
389                     {
390                         Oscl_TAlloc<OSCL_HeapString<Alloc>, Alloc> mimetype;
391                         iParam2 = mimetype.ALLOC_AND_CONSTRUCT(*aMimetype);
392                     }
393                 }
394                 break;
395                 case PVMF_GENERIC_NODE_QUERYINTERFACE:
396                 {//copy the allocated uuid
397                     PVUuid* aUuid = (PVUuid*)aCmd.iParam1;
398                     Oscl_TAlloc<PVUuid, Alloc>uuid;
399                     iParam1 = uuid.ALLOC_AND_CONSTRUCT(*aUuid);
400                 }
401                 break;
402                 default:
403                     break;
404             }
405         }
406 
407         //this routine identifies commands that need to
408         //go at the front of the queue.  derived command
409         //classes can override it if needed.
hipri()410         virtual bool hipri()
411         {
412             return (iCmd == PVMF_GENERIC_NODE_CANCELALLCOMMANDS
413                     || iCmd == PVMF_GENERIC_NODE_CANCELCOMMAND);
414         }
415 
416         //allocate space for a command using the class allocator.
Allocate()417         static OsclAny* Allocate()
418         {
419             Alloc alloc;
420             return alloc.ALLOCATE(sizeof(PVMFGenericNodeCommand));
421         }
422 
423         //command parameters.
424         PVMFCommandId iId;
425         PVMFSessionId iSession;
426         const OsclAny *iContext;
427         OsclAny* iParam1;
428         OsclAny* iParam2;
429         OsclAny* iParam3;
430         OsclAny* iParam4;
431         OsclAny* iParam5;
432         int32 iCmd;
433 };
434 
435 /**
436 //A command queue with a built-in command ID generator.
437 */
438 template<class Command, class Alloc>
439 class PVMFNodeCommandQueue
440 {
441     public:
442         typedef Command vec_element;
443         typedef vec_element* vec_element_ptr;
444 
PVMFNodeCommandQueue()445         PVMFNodeCommandQueue()
446         {
447             iCommandCounter = 0;
448         }
449 
450         //note: usage of the class requires calling the Construct function
Construct(int32 init,uint32 nres)451         void Construct(int32 init, uint32 nres)
452         {//construct the vector
453             iCommandCounter = init;
454             iVec.reserve(nres);
455         }
456 
~PVMFNodeCommandQueue()457         ~PVMFNodeCommandQueue()
458         {
459             while (!empty())
460             {//must explicitly destroy all elements.
461                 Erase(&iVec[0]);
462             }
463         }
464 
Erase(vec_element_ptr elem)465         void Erase(vec_element_ptr elem)
466         {//erase an element
467             elem->Destroy();
468             iVec.erase(elem);
469         }
470 
AddL(vec_element & elem)471         int32 AddL(vec_element &elem)
472         {//add an element with a new ID
473             elem.iId = iCommandCounter++;
474             if (elem.hipri())
475                 iVec.push_front(elem);
476             else
477                 iVec.push_back(elem);
478             return elem.iId;
479         }
480 
StoreL(vec_element & elem)481         vec_element_ptr StoreL(vec_element &elem)
482         {//store a copy of an element
483             vec_element newelem;
484             newelem.Copy(elem);
485             if (newelem.hipri())
486             {
487                 iVec.push_front(newelem);
488                 return &iVec[0];
489             }
490             else
491             {
492                 iVec.push_back(newelem);
493                 return &iVec[iVec.size()-1];
494             }
495         }
496 
497         vec_element_ptr FindById(PVMFCommandId aId, uint32 aOffset = 0)
498         {//find an element by its command id
499             for (uint32 i = aOffset; i < iVec.size(); i++)
500                 if (iVec[i].iId == aId)
501                     return &iVec[i];
502             return NULL;
503         }
504 
505         //Wrappers for methods from Oscl_Vector
506         vec_element& operator[](uint32 n)
507         {
508             return iVec[n];
509         }
510         const vec_element& operator[](uint32 n) const
511         {
512             return iVec[n];
513         }
size()514         uint32 size()const
515         {
516             return iVec.size();
517         }
clear()518         void clear()
519         {
520             iVec.clear();
521         }
front()522         vec_element& front()
523         {
524             return iVec.front();
525         }
empty()526         bool empty()const
527         {
528             return iVec.empty();
529         }
530 
531     private:
532         Oscl_Vector<vec_element, Alloc> iVec;
533         int32 iCommandCounter;
534 };
535 
536 
537 
538 
539 #endif
540 
541 
542