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 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 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 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 158 MemAppender() 159 { 160 _cache.len = 0; 161 _cache.ptr = 0; 162 stringbuf = NULL; 163 _memOverFlow = 0; 164 } 165 166 private: 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