• 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 #ifndef PVLOGGER_MEM_APPENDER_H_INCLUDED
19 #define PVLOGGER_MEM_APPENDER_H_INCLUDED
20 
21 #ifndef OSCL_MEM_AUTO_PTR_H_INCLUDED
22 #include "oscl_mem_auto_ptr.h"
23 #endif
24 #ifndef OSCL_FILE_IO_H_INCLUDED
25 #include "oscl_file_io.h"
26 #endif
27 #ifndef PVLOGGERACCESSORIES_H_INCLUDED
28 #include "pvlogger_accessories.h"
29 #endif
30 
31 #define DEFAULT_MEM_SIZE 0x500000 // 2MB
32 
33 template < class Layout, int32 LayoutBufferSize, class Lock = OsclNullLock >
34 class MemAppender : public PVLoggerAppender
35 {
36     public:
37         typedef PVLoggerAppender::message_id_type message_id_type;
38 
39         static MemAppender<Layout, LayoutBufferSize, Lock>* CreateAppender(OSCL_TCHAR * filename, uint32 cacheSize = 0)
40         {
41 
42             MemAppender<Layout, LayoutBufferSize, Lock> * appender = new MemAppender<Layout, LayoutBufferSize, Lock>();
43             if (NULL == appender) return NULL;
44 
45 #ifdef T_ARM
46 // Seems like ADS 1.2 compiler crashes if template argument is used as part of another template argument so explicitly declare it.
47             OSCLMemAutoPtr<MemAppender<Layout, LayoutBufferSize, Lock>, Oscl_TAlloc<MemAppender<Layout, LayoutBufferSize, Lock>, OsclMemAllocator> > holdAppender(appender);
48 #else
49             OSCLMemAutoPtr<MemAppender<Layout, LayoutBufferSize, Lock> > holdAppender(appender);
50 #endif
51 
52             if (0 != appender->_fs.Connect()) return NULL;
53 
54             if (0 != appender->_logFile.Open(filename,
55                                              Oscl_File::MODE_READWRITE | Oscl_File::MODE_TEXT,
56                                              appender->_fs))
57             {
58                 return NULL;
59             }
60 
61             if (!cacheSize)
62             {
63                 cacheSize = DEFAULT_MEM_SIZE;
64             }
65 
66             appender->_base.ptr = OSCL_DEFAULT_MALLOC(cacheSize);
67             appender->_cache.len = 0;
68             appender->_cacheSize = cacheSize;
69             appender->_cache.ptr = OSCL_STATIC_CAST(uint8*, appender->_base.ptr);
70             appender->_memOverFlow = 0;
71 
72             return holdAppender.release();
73         }
74 
~MemAppender()75         virtual ~MemAppender()
76         {
77 
78             uint32 length;
79             length = OSCL_STATIC_CAST(uint32, (OSCL_STATIC_CAST(uint8*, _cache.ptr) - OSCL_STATIC_CAST(uint8*, _base.ptr)));
80 
81             if (_memOverFlow)
82             {
83                 _logFile.Write(_cache.ptr, sizeof(char), (_cacheSize - length));
84             }
85             _logFile.Write(_base.ptr, sizeof(char), length);
86 
87             OSCL_DEFAULT_FREE(_base.ptr);
88 
89             _logFile.Close();
90             _fs.Close();
91             if (stringbuf)
92                 OSCL_DEFAULT_FREE((OsclAny*)stringbuf);
93         }
94 
AppendString(message_id_type msgID,const char * fmt,va_list va)95         void AppendString(message_id_type msgID, const char *fmt, va_list va)
96         {
97             _lock.Lock();
98 
99             if (!stringbuf)
100                 stringbuf = (char*)OSCL_DEFAULT_MALLOC(LayoutBufferSize);
101             if (!stringbuf)
102                 return;//out of memory!
103             int32 size;
104             char newline[2];
105             newline[0] = 0x0D;
106             newline[1] = 0x0A;
107 
108             size = _layout.FormatString(stringbuf, LayoutBufferSize, msgID, fmt, va);
109             if (_cache.len + size + 2 >= _cacheSize)
110             {
111                 _cache.ptr = _base.ptr;
112                 _cache.len = 0;
113                 _memOverFlow = 1;
114             }
115             uint32 temp = OSCL_STATIC_CAST(uint32, _cache.ptr);
116 
117             oscl_memcpy(OSCL_STATIC_CAST(uint8*, _cache.ptr), stringbuf, size);
118             temp += size;
119 
120             oscl_memcpy(OSCL_STATIC_CAST(uint8*, _cache.ptr) + size, newline, 2);
121             temp += 2;
122 
123             _cache.ptr = OSCL_STATIC_CAST(uint8*, temp);
124             _cache.len += (size + 2);
125 
126             _lock.Unlock();
127         }
128 
AppendBuffers(message_id_type msgID,int32 numPairs,va_list va)129         void AppendBuffers(message_id_type msgID, int32 numPairs, va_list va)
130         {
131             OSCL_UNUSED_ARG(msgID);
132 
133             for (int32 i = 0; i < numPairs; i++)
134             {
135                 int32 length = va_arg(va, int32);
136                 uint8* buffer = va_arg(va, uint8*);
137 
138                 int32 jj;
139                 for (jj = 10; jj < length; jj += 10)
140                 {
141                     AppendStringA(0, "  %x %x %x %x %x %x %x %x %x %x", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9]);
142                     buffer += 10;
143                 }
144 
145                 uint8 remainderbuf[10];
146                 uint32 remainder = length - (jj - 10);
147                 if (remainder > 0 && remainder <= 10)
148                 {
149                     oscl_memcpy(remainderbuf, buffer, remainder);
150                     oscl_memset(remainderbuf + remainder, 0, 10 - remainder);
151                     buffer = remainderbuf;
152                     AppendStringA(0, "  %x %x %x %x %x %x %x %x %x %x", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9]);
153                 }
154             }
155             va_end(va);
156         }
157 
MemAppender()158         MemAppender()
159         {
160             _cache.len = 0;
161             _cache.ptr = 0;
162             stringbuf = NULL;
163             _memOverFlow = 0;
164         }
165 
166     private:
AppendStringA(message_id_type msgID,const char * fmt,...)167         void AppendStringA(message_id_type msgID, const char *fmt, ...)
168         {
169             va_list arguments;
170             va_start(arguments, fmt);
171             AppendString(msgID, fmt, arguments);
172             va_end(arguments);
173         }
174 
175         Layout _layout;
176 
177 #ifdef T_ARM
178 //ADS 1.2 compiler doesn't interpret this correctly.
179     public:
180 #else
181     private:
182 #endif
183         Oscl_FileServer _fs;
184         Oscl_File _logFile;
185         OsclMemoryFragment _cache;
186         uint32 _cacheSize;
187         bool _memOverFlow;
188         OsclMemoryFragment _base;
189 
190     private:
191         Lock _lock;
192         char* stringbuf;
193 
194 
195 };
196 
197 #endif // PVLOGGER_MEM_APPENDER_H_INCLUDED
198 
199 
200