gfx/graphite2/src/XmlTraceLog.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/graphite2/src/XmlTraceLog.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,219 @@
     1.4 +/*  GRAPHITE2 LICENSING
     1.5 +
     1.6 +    Copyright 2010, SIL International
     1.7 +    All rights reserved.
     1.8 +
     1.9 +    This library is free software; you can redistribute it and/or modify
    1.10 +    it under the terms of the GNU Lesser General Public License as published
    1.11 +    by the Free Software Foundation; either version 2.1 of License, or
    1.12 +    (at your option) any later version.
    1.13 +
    1.14 +    This program is distributed in the hope that it will be useful,
    1.15 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.16 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.17 +    Lesser General Public License for more details.
    1.18 +
    1.19 +    You should also have received a copy of the GNU Lesser General Public
    1.20 +    License along with this library in the file named "LICENSE".
    1.21 +    If not, write to the Free Software Foundation, 51 Franklin Street, 
    1.22 +    Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 
    1.23 +    internet at http://www.fsf.org/licenses/lgpl.html.
    1.24 +
    1.25 +Alternatively, the contents of this file may be used under the terms of the
    1.26 +Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
    1.27 +License, as published by the Free Software Foundation, either version 2
    1.28 +of the License or (at your option) any later version.
    1.29 +*/
    1.30 +
    1.31 +#include <cstring>
    1.32 +#include <cstdarg>
    1.33 +#include "Main.h"
    1.34 +#include "XmlTraceLog.h"
    1.35 +
    1.36 +
    1.37 +using namespace graphite2;
    1.38 +
    1.39 +#ifndef DISABLE_TRACING
    1.40 +
    1.41 +/*static*/ XmlTraceLog XmlTraceLog::sm_NullLog(NULL, NULL, GRLOG_NONE);
    1.42 +XmlTraceLog * XmlTraceLog::sLog = &sm_NullLog;
    1.43 +
    1.44 +XmlTraceLog::XmlTraceLog(FILE * file, const char * ns, GrLogMask logMask)
    1.45 +                         : m_file(file), m_depth(0), m_mask(logMask)
    1.46 +{
    1.47 +    if (!m_file) return;
    1.48 +    int deep = 0;
    1.49 +#ifdef ENABLE_DEEP_TRACING
    1.50 +    deep = 1;
    1.51 +#endif
    1.52 +    fprintf(m_file, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%s xmlns=\"%s\" mask=\"%x\" deep=\"%d\">",
    1.53 +            xmlTraceLogElements[ElementTopLevel].mName, ns, logMask, deep);
    1.54 +    m_elementStack[m_depth++] = ElementTopLevel;
    1.55 +    m_elementEmpty = true;
    1.56 +    m_inElement = false;
    1.57 +    m_lastNodeText = false;
    1.58 +}
    1.59 +
    1.60 +XmlTraceLog::~XmlTraceLog()
    1.61 +{
    1.62 +    if (m_file && m_file != stdout && m_file != stderr)
    1.63 +    {
    1.64 +        assert(m_depth == 1);
    1.65 +        while (m_depth > 0)
    1.66 +        {
    1.67 +            closeElement(m_elementStack[m_depth-1]);
    1.68 +        }
    1.69 +        fclose(m_file);
    1.70 +        m_file = NULL;
    1.71 +    }
    1.72 +}
    1.73 +
    1.74 +void XmlTraceLog::addSingleElement(XmlTraceLogElement eId, const int value)
    1.75 +{
    1.76 +    if (!m_file) return;
    1.77 +    if (m_inElement)
    1.78 +    {
    1.79 +        if (xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
    1.80 +            fprintf(m_file, ">");
    1.81 +    }
    1.82 +    if (xmlTraceLogElements[eId].mFlags & m_mask)
    1.83 +    {
    1.84 +        if (!m_lastNodeText)
    1.85 +        {
    1.86 +            fprintf(m_file, "\n");
    1.87 +            for (size_t i = 0; i < m_depth; i++)
    1.88 +            {
    1.89 +                fprintf(m_file, " ");
    1.90 +            }
    1.91 +        }
    1.92 +        fprintf(m_file, "<%s val=\"%d\"/>", xmlTraceLogElements[eId].mName, value);
    1.93 +    }
    1.94 +    m_inElement = false;
    1.95 +    m_lastNodeText = false;
    1.96 +}
    1.97 +    
    1.98 +void XmlTraceLog::writeElementArray(XmlTraceLogElement eId, XmlTraceLogAttribute aId, int16 values [], size_t length)
    1.99 +{
   1.100 +    if (!m_file) return;
   1.101 +    if (xmlTraceLogElements[eId].mFlags & m_mask)
   1.102 +    {
   1.103 +        if(m_inElement && xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
   1.104 +        {
   1.105 +            fprintf(m_file, ">");
   1.106 +            m_inElement = false;
   1.107 +        }
   1.108 +        // line break after 5 columns
   1.109 +        for (size_t i = 0; i < length; i++)
   1.110 +        {
   1.111 +            if (i % 5 == 0)
   1.112 +            {
   1.113 +                fprintf(m_file, "\n");
   1.114 +                for (size_t j = 0; j < m_depth; j++)
   1.115 +                {
   1.116 +                    fprintf(m_file, " ");
   1.117 +                }
   1.118 +            }
   1.119 +            fprintf(m_file, "<%s index=\"%d\" %s=\"%d\"/>", xmlTraceLogElements[eId].mName, int(i),
   1.120 +                xmlTraceLogAttributes[aId], (int)values[i]);
   1.121 +        }
   1.122 +    }
   1.123 +}
   1.124 +
   1.125 +void XmlTraceLog::writeText(const char * utf8)
   1.126 +{
   1.127 +    if (!m_file) return;
   1.128 +    if (m_inElement)
   1.129 +    {
   1.130 +        if (xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
   1.131 +        {
   1.132 +            fprintf(m_file, ">");
   1.133 +        }
   1.134 +        m_inElement = false;
   1.135 +    }
   1.136 +    if (xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
   1.137 +    {
   1.138 +        escapeIfNeeded(utf8);
   1.139 +    }
   1.140 +    m_lastNodeText = true;
   1.141 +}
   1.142 +
   1.143 +void XmlTraceLog::writeUnicode(const uint32 code)
   1.144 +{
   1.145 +    if (!m_file) return;
   1.146 +    if (m_inElement)
   1.147 +    {
   1.148 +        if (xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
   1.149 +        {
   1.150 +            fprintf(m_file, ">");
   1.151 +        }
   1.152 +        m_inElement = false;
   1.153 +    }
   1.154 +    if (xmlTraceLogElements[m_elementStack[m_depth-1]].mFlags & m_mask)
   1.155 +    {
   1.156 +        fprintf(m_file, "&#x%02x;", code);
   1.157 +    }
   1.158 +    m_lastNodeText = true;
   1.159 +}
   1.160 +
   1.161 +void XmlTraceLog::escapeIfNeeded(const char * data)
   1.162 +{
   1.163 +    size_t length = strlen(data);
   1.164 +    for (size_t i = 0; i < length; i++)
   1.165 +    {
   1.166 +        switch (data[i])
   1.167 +        {
   1.168 +            case '<':
   1.169 +                fprintf(m_file, "&lt;");
   1.170 +                break;
   1.171 +            case '>':
   1.172 +                fprintf(m_file, "&gt;");
   1.173 +                break;
   1.174 +            case '&':
   1.175 +                fprintf(m_file, "&amp;");
   1.176 +                break;
   1.177 +            case '"':
   1.178 +                fprintf(m_file, "&#34;");
   1.179 +                break;
   1.180 +            default:
   1.181 +                fprintf(m_file, "%c", data[i]);
   1.182 +        }
   1.183 +    }
   1.184 +}
   1.185 +
   1.186 +static const int MAX_MSG_LEN = 1024;
   1.187 +
   1.188 +void XmlTraceLog::error(const char * msg, ...)
   1.189 +{
   1.190 +    if (!m_file) return;
   1.191 +    openElement(ElementError);
   1.192 +    va_list args;
   1.193 +    va_start(args, msg);
   1.194 +    char buffer[MAX_MSG_LEN];
   1.195 +#ifndef NDEBUG
   1.196 +    int len =
   1.197 +#endif
   1.198 +        vsnprintf(buffer, MAX_MSG_LEN, msg, args);
   1.199 +    assert(len + 1 < MAX_MSG_LEN);
   1.200 +    writeText(buffer);
   1.201 +    va_end(args);
   1.202 +    closeElement(ElementError);
   1.203 +}
   1.204 +
   1.205 +void XmlTraceLog::warning(const char * msg, ...)
   1.206 +{
   1.207 +    if (!m_file) return;
   1.208 +    openElement(ElementWarning);
   1.209 +    va_list args;
   1.210 +    va_start(args, msg);
   1.211 +    char buffer[MAX_MSG_LEN];
   1.212 +#ifndef NDEBUG
   1.213 +    int len =
   1.214 +#endif
   1.215 +        vsnprintf(buffer, MAX_MSG_LEN, msg, args);
   1.216 +    assert(len + 1 < MAX_MSG_LEN);
   1.217 +    writeText(buffer);
   1.218 +    va_end(args);
   1.219 +    closeElement(ElementWarning);
   1.220 +}
   1.221 +
   1.222 +#endif		//!DISABLE_TRACING

mercurial