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_FILE_APPENDER_H_INCLUDED 19 #define PVLOGGER_FILE_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 template < class Layout, int32 LayoutBufferSize, class Lock = OsclNullLock > 32 class TextFileAppender : public PVLoggerAppender 33 { 34 public: 35 typedef PVLoggerAppender::message_id_type message_id_type; 36 37 static TextFileAppender<Layout, LayoutBufferSize, Lock>* CreateAppender(const OSCL_TCHAR * filename, uint32 cacheSize = 0) 38 { 39 40 TextFileAppender<Layout, LayoutBufferSize, Lock> * appender = new TextFileAppender<Layout, LayoutBufferSize, Lock>(); 41 if (NULL == appender) return NULL; 42 43 #ifdef T_ARM 44 // Seems like ADS 1.2 compiler crashes if template argument is used as part of another template argument so explicitly declare it. 45 OSCLMemAutoPtr<TextFileAppender<Layout, LayoutBufferSize, Lock>, Oscl_TAlloc<TextFileAppender<Layout, LayoutBufferSize, Lock>, OsclMemAllocator> > holdAppender(appender); 46 #else 47 OSCLMemAutoPtr<TextFileAppender<Layout, LayoutBufferSize, Lock> > holdAppender(appender); 48 #endif 49 50 if (0 != appender->_fs.Connect()) return NULL; 51 52 //set log file object options 53 //this has its own cache so there's no reason to use pv cache. 54 appender->_logFile.SetPVCacheSize(0); 55 //make sure there's no logging on this file or we get infinite loop! 56 appender->_logFile.SetLoggingEnable(false); 57 appender->_logFile.SetSummaryStatsLoggingEnable(false); 58 //end of log file object options. 59 60 if (0 != appender->_logFile.Open(filename, 61 Oscl_File::MODE_READWRITE | Oscl_File::MODE_TEXT, 62 appender->_fs)) 63 { 64 return NULL; 65 } 66 67 if (cacheSize) 68 { 69 appender->_cache.ptr = OSCL_DEFAULT_MALLOC(cacheSize); 70 appender->_cache.len = 0; 71 } 72 appender->_cacheSize = cacheSize; 73 74 return holdAppender.release(); 75 } 76 ~TextFileAppender()77 virtual ~TextFileAppender() 78 { 79 if (_cache.ptr) 80 { 81 _logFile.Write(_cache.ptr, sizeof(char), _cache.len); 82 OSCL_DEFAULT_FREE(_cache.ptr); 83 } 84 _logFile.Close(); 85 _fs.Close(); 86 if (stringbuf) 87 OSCL_DEFAULT_FREE((OsclAny*)stringbuf); 88 } 89 AppendString(message_id_type msgID,const char * fmt,va_list va)90 void AppendString(message_id_type msgID, const char *fmt, va_list va) 91 { 92 _lock.Lock(); 93 94 if (!stringbuf) 95 stringbuf = (char*)OSCL_DEFAULT_MALLOC(LayoutBufferSize); 96 if (!stringbuf) 97 return;//out of memory! 98 int32 size; 99 char newline[2]; 100 newline[0] = 0x0D; 101 newline[1] = 0x0A; 102 103 size = _layout.FormatString(stringbuf, LayoutBufferSize, msgID, fmt, va); 104 105 if (_cache.ptr) 106 { 107 if (_cache.len + size + 2 < _cacheSize) 108 { 109 oscl_memcpy(OSCL_STATIC_CAST(uint8*, _cache.ptr) + _cache.len, stringbuf, size); 110 _cache.len += size; 111 oscl_memcpy(OSCL_STATIC_CAST(uint8*, _cache.ptr) + _cache.len, newline, 2); 112 _cache.len += 2; 113 } 114 else 115 { 116 _logFile.Write(_cache.ptr, sizeof(char), _cache.len); 117 _logFile.Write(stringbuf, sizeof(char), size); 118 _logFile.Write(newline, sizeof(char), 2); 119 _logFile.Flush(); 120 _cache.len = 0; 121 } 122 } 123 else 124 { 125 _logFile.Write(stringbuf, sizeof(char), size); 126 _logFile.Write(newline, sizeof(char), 2); 127 _logFile.Flush(); 128 } 129 130 _lock.Unlock(); 131 } 132 AppendBuffers(message_id_type msgID,int32 numPairs,va_list va)133 void AppendBuffers(message_id_type msgID, int32 numPairs, va_list va) 134 { 135 OSCL_UNUSED_ARG(msgID); 136 137 for (int32 i = 0; i < numPairs; i++) 138 { 139 int32 length = va_arg(va, int32); 140 uint8* buffer = va_arg(va, uint8*); 141 142 int32 jj; 143 for (jj = 10; jj < length; jj += 10) 144 { 145 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]); 146 buffer += 10; 147 } 148 149 uint8 remainderbuf[10]; 150 uint32 remainder = length - (jj - 10); 151 if (remainder > 0 && remainder <= 10) 152 { 153 oscl_memcpy(remainderbuf, buffer, remainder); 154 oscl_memset(remainderbuf + remainder, 0, 10 - remainder); 155 buffer = remainderbuf; 156 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]); 157 } 158 } 159 va_end(va); 160 } 161 TextFileAppender()162 TextFileAppender() 163 { 164 _cache.len = 0; 165 _cache.ptr = 0; 166 stringbuf = NULL; 167 } 168 169 private: AppendStringA(message_id_type msgID,const char * fmt,...)170 void AppendStringA(message_id_type msgID, const char *fmt, ...) 171 { 172 va_list arguments; 173 va_start(arguments, fmt); 174 AppendString(msgID, fmt, arguments); 175 va_end(arguments); 176 } 177 178 Layout _layout; 179 180 #ifdef T_ARM 181 //ADS 1.2 compiler doesn't interpret this correctly. 182 public: 183 #else 184 private: 185 #endif 186 Oscl_FileServer _fs; 187 Oscl_File _logFile; 188 OsclMemoryFragment _cache; 189 uint32 _cacheSize; 190 191 private: 192 Lock _lock; 193 char* stringbuf; 194 195 196 }; 197 198 class BinaryFileAppender : public PVLoggerAppender 199 { 200 public: 201 typedef PVLoggerAppender::message_id_type message_id_type; 202 203 static BinaryFileAppender* CreateAppender(const char* filename, uint32 cacheSize = 0) 204 { 205 206 BinaryFileAppender * appender = OSCL_NEW(BinaryFileAppender, ()); 207 if (NULL == appender) return NULL; 208 209 #ifdef T_ARM 210 //ADS 1.2 can't compile the auto ptr-- so don't use it. 211 #else 212 OSCLMemAutoPtr<BinaryFileAppender> holdAppender(appender); 213 #endif 214 215 if (0 != appender->_fs.Connect()) return NULL; 216 217 //set log file object options 218 //this has its own cache so there's no reason to use pv cache. 219 appender->_logFile.SetPVCacheSize(0); 220 //make sure there's no logging on this file or we get infinite loop! 221 appender->_logFile.SetLoggingEnable(false); 222 appender->_logFile.SetSummaryStatsLoggingEnable(false); 223 //end of log file object options. 224 225 if (0 != appender->_logFile.Open(filename, 226 Oscl_File::MODE_READWRITE | Oscl_File::MODE_BINARY, 227 appender->_fs)) 228 { 229 return NULL; 230 } 231 232 if (cacheSize) 233 { 234 appender->_cache.ptr = OSCL_MALLOC(cacheSize); 235 appender->_cache.len = 0; 236 } 237 appender->_cacheSize = cacheSize; 238 239 #ifdef T_ARM 240 return appender; 241 #else 242 return holdAppender.release(); 243 #endif 244 } 245 246 static BinaryFileAppender* CreateAppender(const OSCL_TCHAR * filename, uint32 cacheSize = 0) 247 { 248 249 BinaryFileAppender * appender = OSCL_NEW(BinaryFileAppender, ()); 250 if (NULL == appender) return NULL; 251 252 #ifdef T_ARM 253 //ADS 1.2 can't compile the auto ptr-- so don't use it. 254 #else 255 OSCLMemAutoPtr<BinaryFileAppender> holdAppender(appender); 256 #endif 257 258 if (0 != appender->_fs.Connect()) return NULL; 259 260 //set log file object options 261 //this has its own cache so there's no reason to use pv cache. 262 appender->_logFile.SetPVCacheSize(0); 263 //make sure there's no logging on this file or we get infinite loop! 264 appender->_logFile.SetLoggingEnable(false); 265 appender->_logFile.SetSummaryStatsLoggingEnable(false); 266 //end of log file object options. 267 268 if (0 != appender->_logFile.Open(filename, 269 Oscl_File::MODE_READWRITE | Oscl_File::MODE_BINARY, 270 appender->_fs)) 271 { 272 return NULL; 273 } 274 275 if (cacheSize) 276 { 277 appender->_cache.ptr = OSCL_MALLOC(cacheSize); 278 appender->_cache.len = 0; 279 } 280 appender->_cacheSize = cacheSize; 281 282 #ifdef T_ARM 283 return appender; 284 #else 285 return holdAppender.release(); 286 #endif 287 } 288 ~BinaryFileAppender()289 virtual ~BinaryFileAppender() 290 { 291 if (_cache.ptr) 292 { 293 _logFile.Write(_cache.ptr, sizeof(char), _cache.len); 294 OSCL_FREE(_cache.ptr); 295 } 296 _logFile.Close(); 297 _fs.Close(); 298 } 299 AppendString(message_id_type msgID,const char * fmt,va_list va)300 void AppendString(message_id_type msgID, const char *fmt, va_list va) 301 { 302 OSCL_UNUSED_ARG(msgID); 303 OSCL_UNUSED_ARG(fmt); 304 OSCL_UNUSED_ARG(va); 305 } 306 AppendBuffers(message_id_type msgID,int32 numPairs,va_list va)307 void AppendBuffers(message_id_type msgID, int32 numPairs, va_list va) 308 { 309 OSCL_UNUSED_ARG(msgID); 310 311 for (int32 i = 0; i < numPairs; i++) 312 { 313 int32 length = va_arg(va, int32); 314 void* buffer = va_arg(va, void*); 315 316 if (_cache.ptr) 317 { 318 if (_cache.len + length < _cacheSize) 319 { 320 oscl_memcpy(OSCL_STATIC_CAST(uint8*, _cache.ptr) + _cache.len, buffer, length); 321 _cache.len += length; 322 } 323 else 324 { 325 _logFile.Write(_cache.ptr, sizeof(uint8), _cache.len); 326 _logFile.Write(buffer, sizeof(uint8), length); 327 _logFile.Flush(); 328 _cache.len = 0; 329 } 330 } 331 else 332 { 333 _logFile.Write(buffer, sizeof(uint8), length); 334 _logFile.Flush(); 335 } 336 } 337 va_end(va); 338 } 339 AppendBuffers(message_id_type msgID,int32 numPairs,...)340 void AppendBuffers(message_id_type msgID, int32 numPairs, ...) 341 { 342 va_list args; 343 va_start(args, numPairs); 344 AppendBuffers(msgID, numPairs, args); 345 } 346 347 private: BinaryFileAppender()348 BinaryFileAppender() 349 { 350 _cache.len = 0; 351 _cache.ptr = 0; 352 } 353 354 Oscl_FileServer _fs; 355 Oscl_File _logFile; 356 OsclMemoryFragment _cache; 357 uint32 _cacheSize; 358 }; 359 360 361 362 363 #endif // PVLOGGER_FILE_APPENDER_H_INCLUDED 364 365 366