Home | History | Annotate | Download | only in src
      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