m3g/m3gcore11/src/m3g_symbian.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 14 Sep 2010 23:50:05 +0300
branchRCL_3
changeset 177 183e23d95fab
parent 0 5d03bc08d59c
permissions -rw-r--r--
Revision: 201029 Kit: 201035

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: Symbian debugging and profiling functions
*
*/

#include "m3g_defs.h"
#include <e32base.h>
#include <f32file.h>
#include <ezlib.h>

#if defined(M3G_SYMBIAN_REMOTE_LOGGING)
#include <EcmtClient.h>
#endif

struct M3GLogger
{
    M3Gint refCount;
    
#   if defined(M3G_SYMBIAN_REMOTE_LOGGING)
    REcmt iEcmt;
#   endif

#   if defined(M3G_ENABLE_PROFILING)
    M3Guint tickCount[M3G_STAT_MAX];
    M3Guint lastOutputTickCount;
#   endif
};

/*----------------------------------------------------------------------
 * Internal functions
 *--------------------------------------------------------------------*/

/*!
 * \brief Symbian implementation of the block inflation function for
 * the Loader class
 */
extern "C" M3Gsizei m3gSymbianInflateBlock(M3Gsizei srcLength,
                                           const M3Gubyte *src,
                                           M3Gsizei dstLength,
                                           M3Gubyte *dst)
{
    M3G_ASSERT(src);
    M3G_ASSERT(dst);
    M3G_ASSERT(srcLength > 0);

    {
        uLongf len = (uLongf) dstLength;
        if (uncompress((Bytef *) dst, &len,
                       (const Bytef *) src, (uLong) srcLength) != Z_OK) {
            return 0;
        }
        return (M3Gsizei) len;
    }
}

/*!
 * \brief Logging function
 *
 * \note This currently creates a session to the file server for each
 * message, so performance will be sub-optimal if logging is frequent
 */
extern "C" void m3gLogMessage(const char *format, ...)
{    
#   if !defined(M3G_SYMBIAN_REMOTE_LOGGING)
    _LIT(KFileName, "c:\\m3g_event.log");

    RFs fileSrv;
    RFile file;

    if (fileSrv.Connect() != KErrNone) {
        return;
    }

    TInt accessMode = EFileWrite|EFileShareExclusive;
    TInt err = file.Open(fileSrv, KFileName, accessMode);

    // If the file exists, seek to the end; if it doesn't, create it
    
    if (err == KErrNone) {
        TInt pos = 0;
        file.Seek(ESeekEnd, pos);
    }
    else if (err == KErrNotFound) {
        if (file.Create(fileSrv, KFileName, accessMode) != KErrNone) {
            fileSrv.Close();
            return;
        }
    }
#   endif // !M3G_SYMBIAN_REMOTE_LOGGING

    // Format and write the message

    TBuf8<1024> msg;
    TPtrC8 aFormat((const TUint8 *) format);
    
    VA_LIST aList;
    VA_START(aList, format);

    msg.FormatList(aFormat, aList);

    VA_END(aList);

#   if defined(M3G_SYMBIAN_REMOTE_LOGGING)

    M3GLogger *logger = (M3GLogger*) Dll::Tls();

    if (logger) {
        TBuf16<1024> msg16;
        msg16.Copy(msg);
        logger->iEcmt.Write(msg16);
    }
    
#   else
    file.Write(msg);

    // Close the file and the server connection
    
    file.Flush();
    file.Close();
    fileSrv.Close();
    
#   endif // !M3G_SYMBIAN_REMOTE_LOGGING
}

/*!
 * \brief Create new log file
 */
extern "C" void m3gBeginLog(void)
{
#   if defined(M3G_SYMBIAN_REMOTE_LOGGING)

    M3GLogger *logger = (M3GLogger*) Dll::Tls();
    
    if (!logger) {
        logger = new M3GLogger();
        logger->refCount = 0;
        logger->lastOutputTickCount = User::TickCount();
        Dll::SetTls(logger);
    }

    if (++logger->refCount == 1) {
        logger->iEcmt.Connect();
    }

#   else
    
    /* Just delete any existing log file */
    
    _LIT(KFileName, "c:\\m3g_event.log");

    RFs fileSrv;
    RFile file;

    if (fileSrv.Connect() != KErrNone) {
        return;
    }

    TInt accessMode = EFileWrite|EFileShareExclusive;
    if (file.Replace(fileSrv, KFileName, accessMode) == KErrNone) {
        file.Flush();
        file.Close();
    }
    fileSrv.Close();
    
#   endif // !M3G_SYMBIAN_REMOTE_LOGGING
    
    /* Output initial message(s) */
    
    m3gLogMessage("--- M3G event log ---\n");
}

/*!
 * \brief End logging
 */
extern "C" void m3gEndLog(void)
{
#   if defined(M3G_SYMBIAN_REMOTE_LOGGING)

    M3GLogger *logger = (M3GLogger*) Dll::Tls();
    if (logger) {
        if (--logger->refCount == 0) {
            logger->iEcmt.Close();
            Dll::FreeTls();
            delete logger;
        }
    }

#   endif
    
    m3gLogMessage("--- end of log ---\n");
}

/*!
 * \brief Assertion handler
 */
extern "C" void m3gAssertFailed(const char *filename, int line)
{
    M3G_LOG2(M3G_LOG_ALL, "Assertion failed: %s, line %d\n", filename, line);
    User::Panic(_L("M3G-ASSERT"), line);
}

#if defined(M3G_BUILD_DLL)
/*!
 * \brief DLL load check
 */
#ifndef EKA2
GLDEF_C TInt E32Dll( TDllReason /* aReason */ )
{
    return KErrNone;
}
#endif
#endif /* M3G_BUILD_DLL */

/*----------------------------------------------------------------------
 * Profiling
 *--------------------------------------------------------------------*/

#if defined(M3G_ENABLE_PROFILING)

extern "C" void m3gCleanupProfile(void)
{
    ;
}

extern "C" void m3gBeginProfile(int stat)
{
    M3GLogger *logger = (M3GLogger*) Dll::Tls();
    if (logger) {
        logger->tickCount[stat] = User::TickCount();
    }
}

extern "C" int m3gEndProfile(int stat)
{
    M3GLogger *logger = (M3GLogger*) Dll::Tls();
    if (logger) {
        return User::TickCount() - logger->tickCount[stat];
    }
    return 0;
}

extern "C" M3Gint m3gProfileTriggered(void)
{
#   if (M3G_PROFILE_LOG_INTERVAL > 0)
    M3GLogger *logger = (M3GLogger*) Dll::Tls();
    if (logger) {
        M3Guint tickCount = User::TickCount();
        M3Guint delta = tickCount - logger->lastOutputTickCount;
        if (delta >= M3G_PROFILE_LOG_INTERVAL) {
            logger->lastOutputTickCount = tickCount;
            return (M3Gint) delta;
        }
    }
#   endif
    return 0;
}

#endif