Turn trace writer into a class.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Sat, 28 May 2011 09:37:12 +0000 (10:37 +0100)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Sat, 28 May 2011 09:37:12 +0000 (10:37 +0100)
gltrace.py
gui/saverthread.cpp
trace.py
trace_writer.cpp
trace_writer.hpp

index d4adf92..78cc14c 100644 (file)
@@ -334,13 +334,13 @@ class GlTracer(Tracer):
                     # Emit a fake function
                     print '        {'
                     print '            static const Trace::FunctionSig &__sig = %s ? __glEnableClientState_sig : __glDisableClientState_sig;' % flag_name
-                    print '            unsigned __call = Trace::BeginEnter(__sig);'
-                    print '            Trace::BeginArg(0);'
+                    print '            unsigned __call = __writer.beginEnter(__sig);'
+                    print '            __writer.beginArg(0);'
                     dump_instance(glapi.GLenum, enable_name)
-                    print '            Trace::EndArg();'
-                    print '            Trace::EndEnter();'
-                    print '            Trace::BeginLeave(__call);'
-                    print '            Trace::EndLeave();'
+                    print '            __writer.endArg();'
+                    print '            __writer.endEnter();'
+                    print '            __writer.beginLeave(__call);'
+                    print '            __writer.endLeave();'
                     print '        }'
 
             print '        return;'
@@ -424,19 +424,19 @@ class GlTracer(Tracer):
         Tracer.dispatch_function(self, function)
 
     def emit_memcpy(self, dest, src, length):
-        print '        unsigned __call = Trace::BeginEnter(__memcpy_sig);'
-        print '        Trace::BeginArg(0);'
-        print '        Trace::LiteralOpaque(%s);' % dest
-        print '        Trace::EndArg();'
-        print '        Trace::BeginArg(1);'
-        print '        Trace::LiteralBlob(%s, %s);' % (src, length)
-        print '        Trace::EndArg();'
-        print '        Trace::BeginArg(2);'
-        print '        Trace::LiteralUInt(%s);' % length
-        print '        Trace::EndArg();'
-        print '        Trace::EndEnter();'
-        print '        Trace::BeginLeave(__call);'
-        print '        Trace::EndLeave();'
+        print '        unsigned __call = __writer.beginEnter(__memcpy_sig);'
+        print '        __writer.beginArg(0);'
+        print '        __writer.writeOpaque(%s);' % dest
+        print '        __writer.endArg();'
+        print '        __writer.beginArg(1);'
+        print '        __writer.writeBlob(%s, %s);' % (src, length)
+        print '        __writer.endArg();'
+        print '        __writer.beginArg(2);'
+        print '        __writer.writeUInt(%s);' % length
+        print '        __writer.endArg();'
+        print '        __writer.endEnter();'
+        print '        __writer.beginLeave(__call);'
+        print '        __writer.endLeave();'
        
     buffer_targets = [
         'ARRAY_BUFFER',
@@ -482,15 +482,15 @@ class GlTracer(Tracer):
             print '    if (!__element_array_buffer) {'
             if isinstance(arg.type, stdapi.Array):
                 Tracer.dump_arg_instance(self, function, arg)
-                print '        Trace::BeginArray(%s);' % arg.type.length
+                print '        __writer.beginArray(%s);' % arg.type.length
                 print '        for(GLsizei i = 0; i < %s; ++i) {' % arg.type.length
-                print '            Trace::BeginElement();'
-                print '            Trace::LiteralBlob((const void *)%s, count[i]*__gl_type_size(type));' % (arg.name)
-                print '            Trace::EndElement();'
+                print '            __writer.beginElement();'
+                print '            __writer.writeBlob((const void *)%s, count[i]*__gl_type_size(type));' % (arg.name)
+                print '            __writer.endElement();'
                 print '        }'
-                print '        Trace::EndArray();'
+                print '        __writer.endArray();'
             else:
-                print '        Trace::LiteralBlob((const void *)%s, count*__gl_type_size(type));' % (arg.name)
+                print '        __writer.writeBlob((const void *)%s, count*__gl_type_size(type));' % (arg.name)
             print '    } else {'
             Tracer.dump_arg_instance(self, function, arg)
             print '    }'
@@ -547,19 +547,19 @@ class GlTracer(Tracer):
 
             # Emit a fake function
             self.array_trace_intermezzo(api, uppercase_name)
-            print '            unsigned __call = Trace::BeginEnter(__%s_sig);' % (function.name,)
+            print '            unsigned __call = __writer.beginEnter(__%s_sig);' % (function.name,)
             for arg in function.args:
                 assert not arg.output
-                print '            Trace::BeginArg(%u);' % (arg.index,)
+                print '            __writer.beginArg(%u);' % (arg.index,)
                 if arg.name != 'pointer':
                     dump_instance(arg.type, arg.name)
                 else:
-                    print '            Trace::LiteralBlob((const void *)%s, __size);' % (arg.name)
-                print '            Trace::EndArg();'
+                    print '            __writer.writeBlob((const void *)%s, __size);' % (arg.name)
+                print '            __writer.endArg();'
             
-            print '            Trace::EndEnter();'
-            print '            Trace::BeginLeave(__call);'
-            print '            Trace::EndLeave();'
+            print '            __writer.endEnter();'
+            print '            __writer.beginLeave(__call);'
+            print '            __writer.endLeave();'
             print '        }'
             print '    }'
             self.array_epilog(api, uppercase_name)
@@ -591,19 +591,19 @@ class GlTracer(Tracer):
         print '                size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)
 
         # Emit a fake function
-        print '                unsigned __call = Trace::BeginEnter(__%s_sig);' % (function.name,)
+        print '                unsigned __call = __writer.beginEnter(__%s_sig);' % (function.name,)
         for arg in function.args:
             assert not arg.output
-            print '                Trace::BeginArg(%u);' % (arg.index,)
+            print '                __writer.beginArg(%u);' % (arg.index,)
             if arg.name != 'pointer':
                 dump_instance(arg.type, arg.name)
             else:
-                print '                Trace::LiteralBlob((const void *)%s, __size);' % (arg.name)
-            print '                Trace::EndArg();'
+                print '                __writer.writeBlob((const void *)%s, __size);' % (arg.name)
+            print '                __writer.endArg();'
         
-        print '                Trace::EndEnter();'
-        print '                Trace::BeginLeave(__call);'
-        print '                Trace::EndLeave();'
+        print '                __writer.endEnter();'
+        print '                __writer.beginLeave(__call);'
+        print '                __writer.endLeave();'
         print '            }'
         print '        }'
         print '    }'
@@ -658,15 +658,15 @@ class GlTracer(Tracer):
         self.fake_call(function, [texture])
 
     def fake_call(self, function, args):
-        print '            unsigned __fake_call = Trace::BeginEnter(__%s_sig);' % (function.name,)
+        print '            unsigned __fake_call = __writer.beginEnter(__%s_sig);' % (function.name,)
         for arg, instance in zip(function.args, args):
             assert not arg.output
-            print '            Trace::BeginArg(%u);' % (arg.index,)
+            print '            __writer.beginArg(%u);' % (arg.index,)
             dump_instance(arg.type, instance)
-            print '            Trace::EndArg();'
-        print '            Trace::EndEnter();'
-        print '            Trace::BeginLeave(__fake_call);'
-        print '            Trace::EndLeave();'
+            print '            __writer.endArg();'
+        print '            __writer.endEnter();'
+        print '            __writer.beginLeave(__fake_call);'
+        print '            __writer.endLeave();'
 
 
 
index fe0f9a6..648de59 100644 (file)
@@ -118,7 +118,7 @@ deleteBitmaskSig(Trace::BitmaskSig *sig)
 }
 
 static void
-writeValue(const QVariant &var, unsigned &id)
+writeValue(Trace::Writer &writer, const QVariant &var, unsigned &id)
 {
     int arrayType   = QMetaType::type("ApiArray");
     int bitmaskType = QMetaType::type("ApiBitmask");
@@ -129,73 +129,73 @@ writeValue(const QVariant &var, unsigned &id)
 
     switch(type) {
     case QVariant::Bool:
-        Trace::LiteralBool(var.toBool());
+        writer.writeBool(var.toBool());
         break;
     case QVariant::ByteArray: {
         QByteArray ba = var.toByteArray();
-        Trace::LiteralBlob((const void*)ba.constData(), ba.size());
+        writer.writeBlob((const void*)ba.constData(), ba.size());
     }
         break;
     case QVariant::Double:
-        Trace::LiteralDouble(var.toDouble());
+        writer.writeDouble(var.toDouble());
         break;
     case QMetaType::Float:
-        Trace::LiteralFloat(var.toFloat());
+        writer.writeFloat(var.toFloat());
         break;
     case QVariant::Int:
-        Trace::LiteralSInt(var.toInt());
+        writer.writeSInt(var.toInt());
         break;
     case QVariant::LongLong:
-        Trace::LiteralSInt(var.toLongLong());
+        writer.writeSInt(var.toLongLong());
         break;
     case QVariant::String: {
         QString str = var.toString();
-        Trace::LiteralString(str.toLocal8Bit().constData(), str.length());
+        writer.writeString(str.toLocal8Bit().constData(), str.length());
     }
         break;
     case QVariant::UInt:
-        Trace::LiteralUInt(var.toInt());
+        writer.writeUInt(var.toInt());
         break;
     case QVariant::ULongLong:
-        Trace::LiteralUInt(var.toLongLong());
+        writer.writeUInt(var.toLongLong());
         break;
     default:
         if (type == arrayType) {
             ApiArray array = var.value<ApiArray>();
             QList<QVariant> vals = array.values();
-            Trace::BeginArray(vals.count());
+            writer.beginArray(vals.count());
             foreach(QVariant el, vals) {
-                Trace::BeginElement();
-                writeValue(el, ++id);
-                Trace::EndElement();
+                writer.beginElement();
+                writeValue(writer, el, ++id);
+                writer.endElement();
             }
-            Trace::EndArray();
+            writer.endArray();
         } else if (type == bitmaskType) {
             ApiBitmask bm = var.value<ApiBitmask>();
             Trace::BitmaskSig *sig = createBitmaskSig(bm, ++id);
-            LiteralBitmask(*sig, bm.value());
+            writer.writeBitmask(*sig, bm.value());
             deleteBitmaskSig(sig);
         } else if (type == structType) {
             ApiStruct apiStr = var.value<ApiStruct>();
             QList<QVariant> vals = apiStr.values();
             Trace::StructSig *str = createStructSig(apiStr, ++id);
-            Trace::BeginStruct(str);
+            writer.beginStruct(str);
             foreach(QVariant val, vals) {
-                writeValue(val, ++id);
+                writeValue(writer, val, ++id);
             }
-            Trace::EndStruct();
+            writer.endStruct();
             deleteStructSig(str);
         } else if (type == pointerType) {
             ApiPointer apiPtr = var.value<ApiPointer>();
-            //Trace::BeginArray(1);
-            //Trace::BeginElement();
-            Trace::LiteralOpaque((const void*)apiPtr.value());
-            //Trace::EndElement();
-            //Trace::EndArray();
+            //writer.beginArray(1);
+            //writer.beginElement();
+            writer.writeOpaque((const void*)apiPtr.value());
+            //writer.endElement();
+            //writer.endArray();
         } else if (type == enumType) {
             ApiEnum apiEnum = var.value<ApiEnum>();
             Trace::EnumSig *sig = createEnumSig(apiEnum, ++id);
-            Trace::LiteralEnum(sig);
+            writer.writeEnum(sig);
             deleteEnumSig(sig);
         } else {
             qWarning()<<"Unsupported write variant : "
@@ -219,39 +219,39 @@ void SaverThread::saveFile(const QString &fileName,
 
 void SaverThread::run()
 {
-    qputenv("TRACE_FILE", m_fileName.toLocal8Bit());
     unsigned id = 0;
-    qDebug()<<"saver thread!";
-    Trace::Open();
+    qDebug() << "Saving  : " << m_fileName;
+    Trace::Writer writer;
+    writer.open(m_fileName.toLocal8Bit());
     for (int i = 0; i < m_calls.count(); ++i) {
         ApiTraceCall *call = m_calls[i];
         Trace::FunctionSig *funcSig = createFunctionSig(call, ++id);
-        unsigned callNo = Trace::BeginEnter(*funcSig);
+        unsigned callNo = writer.beginEnter(*funcSig);
         {
             //args
             QVariantList vars = call->arguments();
             int index = 0;
             foreach(QVariant var, vars) {
-                Trace::BeginArg(index++);
-                writeValue(var, ++id);
-                Trace::EndArg();
+                writer.beginArg(index++);
+                writeValue(writer, var, ++id);
+                writer.endArg();
             }
         }
-        Trace::EndEnter();
-        Trace::BeginLeave(callNo);
+        writer.endEnter();
+        writer.beginLeave(callNo);
         {
             QVariant ret = call->returnValue();
             if (!ret.isNull()) {
-                Trace::BeginReturn();
-                writeValue(ret, ++id);
-                Trace::EndReturn();
+                writer.beginReturn();
+                writeValue(writer, ret, ++id);
+                writer.endReturn();
             }
         }
-        Trace::EndLeave();
+        writer.endLeave();
 
         deleteFunctionSig(funcSig);
     }
-    Trace::Close();
+    writer.close();
 
     emit traceSaved();
 }
index c83d713..618fbad 100644 (file)
--- a/trace.py
+++ b/trace.py
@@ -60,10 +60,10 @@ class DumpDeclarator(stdapi.OnceVisitor):
         print '    static const Trace::StructSig sig = {'
         print '       %u, "%s", %u, members' % (int(struct.id), struct.name, len(struct.members))
         print '    };'
-        print '    Trace::BeginStruct(&sig);'
+        print '    __writer.beginStruct(&sig);'
         for type, name in struct.members:
             dump_instance(type, 'value.%s' % (name,))
-        print '    Trace::EndStruct();'
+        print '    __writer.endStruct();'
         print '}'
         print
 
@@ -90,10 +90,10 @@ class DumpDeclarator(stdapi.OnceVisitor):
             print '        sig = &sig%u;' % i
             print '        break;'
         print '    default:'
-        print '        Trace::LiteralSInt(value);'
+        print '        __writer.writeSInt(value);'
         print '        return;'
         print '    }'
-        print '    Trace::LiteralEnum(sig);'
+        print '    __writer.writeEnum(sig);'
         print '}'
         print
 
@@ -140,13 +140,13 @@ class DumpImplementer(stdapi.Visitor):
     '''Dump an instance.'''
 
     def visit_literal(self, literal, instance):
-        print '    Trace::Literal%s(%s);' % (literal.format, instance)
+        print '    __writer.write%s(%s);' % (literal.format, instance)
 
     def visit_string(self, string, instance):
         if string.length is not None:
-            print '    Trace::LiteralString((const char *)%s, %s);' % (instance, string.length)
+            print '    __writer.writeString((const char *)%s, %s);' % (instance, string.length)
         else:
-            print '    Trace::LiteralString((const char *)%s);' % instance
+            print '    __writer.writeString((const char *)%s);' % instance
 
     def visit_const(self, const, instance):
         self.visit(const.type, instance)
@@ -157,36 +157,36 @@ class DumpImplementer(stdapi.Visitor):
     def visit_array(self, array, instance):
         print '    if (%s) {' % instance
         index = '__i' + array.type.id
-        print '        Trace::BeginArray(%s);' % (array.length,)
+        print '        __writer.beginArray(%s);' % (array.length,)
         print '        for (int %s = 0; %s < %s; ++%s) {' % (index, index, array.length, index)
-        print '            Trace::BeginElement();'
+        print '            __writer.beginElement();'
         self.visit(array.type, '(%s)[%s]' % (instance, index))
-        print '            Trace::EndElement();'
+        print '            __writer.endElement();'
         print '        }'
-        print '        Trace::EndArray();'
+        print '        __writer.endArray();'
         print '    }'
         print '    else'
-        print '        Trace::LiteralNull();'
+        print '        __writer.writeNull();'
 
     def visit_blob(self, blob, instance):
-        print '    Trace::LiteralBlob(%s, %s);' % (instance, blob.size)
+        print '    __writer.writeBlob(%s, %s);' % (instance, blob.size)
 
     def visit_enum(self, enum, instance):
         print '    __traceEnum%s(%s);' % (enum.id, instance)
 
     def visit_bitmask(self, bitmask, instance):
-        print '    Trace::LiteralBitmask(__bitmask%s_sig, %s);' % (bitmask.id, instance)
+        print '    __writer.writeBitmask(__bitmask%s_sig, %s);' % (bitmask.id, instance)
 
     def visit_pointer(self, pointer, instance):
         print '    if (%s) {' % instance
-        print '        Trace::BeginArray(1);'
-        print '        Trace::BeginElement();'
+        print '        __writer.beginArray(1);'
+        print '        __writer.beginElement();'
         dump_instance(pointer.type, "*" + instance)
-        print '        Trace::EndElement();'
-        print '        Trace::EndArray();'
+        print '        __writer.endElement();'
+        print '        __writer.endArray();'
         print '    }'
         print '    else'
-        print '        Trace::LiteralNull();'
+        print '        __writer.writeNull();'
 
     def visit_handle(self, handle, instance):
         self.visit(handle.type, instance)
@@ -195,10 +195,10 @@ class DumpImplementer(stdapi.Visitor):
         self.visit(alias.type, instance)
 
     def visit_opaque(self, opaque, instance):
-        print '    Trace::LiteralOpaque((const void *)%s);' % instance
+        print '    __writer.writeOpaque((const void *)%s);' % instance
 
     def visit_interface(self, interface, instance):
-        print '    Trace::LiteralOpaque((const void *)&%s);' % instance
+        print '    __writer.writeOpaque((const void *)&%s);' % instance
 
 
 dump_instance = DumpImplementer().visit
@@ -307,7 +307,8 @@ class Tracer:
         self.footer(api)
 
     def header(self, api):
-        pass
+        print 'Trace::Writer __writer;'
+        print
 
     def footer(self, api):
         pass
@@ -344,21 +345,21 @@ class Tracer:
         print
 
     def trace_function_impl_body(self, function):
-        print '    unsigned __call = Trace::BeginEnter(__%s_sig);' % (function.name,)
+        print '    unsigned __call = __writer.beginEnter(__%s_sig);' % (function.name,)
         for arg in function.args:
             if not arg.output:
                 self.unwrap_arg(function, arg)
                 self.dump_arg(function, arg)
-        print '    Trace::EndEnter();'
+        print '    __writer.endEnter();'
         self.dispatch_function(function)
-        print '    Trace::BeginLeave(__call);'
+        print '    __writer.beginLeave(__call);'
         for arg in function.args:
             if arg.output:
                 self.dump_arg(function, arg)
                 self.wrap_arg(function, arg)
         if function.type is not stdapi.Void:
             self.dump_ret(function, "__result")
-        print '    Trace::EndLeave();'
+        print '    __writer.endLeave();'
 
     def dispatch_function(self, function):
         if function.type is stdapi.Void:
@@ -369,9 +370,9 @@ class Tracer:
         print '    %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args]))
 
     def dump_arg(self, function, arg):
-        print '    Trace::BeginArg(%u);' % (arg.index,)
+        print '    __writer.beginArg(%u);' % (arg.index,)
         self.dump_arg_instance(function, arg)
-        print '    Trace::EndArg();'
+        print '    __writer.endArg();'
 
     def dump_arg_instance(self, function, arg):
         dump_instance(arg.type, arg.name)
@@ -383,9 +384,9 @@ class Tracer:
         unwrap_instance(arg.type, arg.name)
 
     def dump_ret(self, function, instance):
-        print '    Trace::BeginReturn();'
+        print '    __writer.beginReturn();'
         dump_instance(function.type, instance)
-        print '    Trace::EndReturn();'
+        print '    __writer.endReturn();'
 
     def wrap_ret(self, function, instance):
         wrap_instance(function.type, instance)
@@ -409,10 +410,10 @@ class Tracer:
         print method.prototype(interface_wrap_name(interface) + '::' + method.name) + ' {'
         print '    static const char * __args[%u] = {%s};' % (len(method.args) + 1, ', '.join(['"this"'] + ['"%s"' % arg.name for arg in method.args]))
         print '    static const Trace::FunctionSig __sig = {%u, "%s", %u, __args};' % (int(method.id), interface.name + '::' + method.name, len(method.args) + 1)
-        print '    unsigned __call = Trace::BeginEnter(__sig);'
-        print '    Trace::BeginArg(0);'
-        print '    Trace::LiteralOpaque((const void *)m_pInstance);'
-        print '    Trace::EndArg();'
+        print '    unsigned __call = __writer.beginEnter(__sig);'
+        print '    __writer.beginArg(0);'
+        print '    __writer.writeOpaque((const void *)m_pInstance);'
+        print '    __writer.endArg();'
         for arg in method.args:
             if not arg.output:
                 self.unwrap_arg(method, arg)
@@ -422,19 +423,19 @@ class Tracer:
         else:
             print '    %s __result;' % method.type
             result = '__result = '
-        print '    Trace::EndEnter();'
+        print '    __writer.endEnter();'
         print '    %sm_pInstance->%s(%s);' % (result, method.name, ', '.join([str(arg.name) for arg in method.args]))
-        print '    Trace::BeginLeave(__call);'
+        print '    __writer.beginLeave(__call);'
         for arg in method.args:
             if arg.output:
                 self.dump_arg(method, arg)
                 self.wrap_arg(method, arg)
         if method.type is not stdapi.Void:
-            print '    Trace::BeginReturn();'
+            print '    __writer.beginReturn();'
             dump_instance(method.type, "__result")
-            print '    Trace::EndReturn();'
+            print '    __writer.endReturn();'
             wrap_instance(method.type, '__result')
-        print '    Trace::EndLeave();'
+        print '    __writer.endLeave();'
         if method.name == 'QueryInterface':
             print '    if (ppvObj && *ppvObj) {'
             print '        if (*ppvObj == m_pInstance) {'
index ad6df89..18261f5 100644 (file)
@@ -30,8 +30,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <vector>
-
 #include <zlib.h>
 
 #include "os.hpp"
 namespace Trace {
 
 
-static gzFile g_gzFile = NULL;
-static void _Close(void) {
+Writer::Writer() :
+    g_gzFile(NULL),
+    call_no(0)
+{
+    close();
+};
+
+Writer::~Writer() {
+    close();
+};
+
+void
+Writer::close(void) {
     if (g_gzFile != NULL) {
         gzclose(g_gzFile);
         g_gzFile = NULL;
     }
 }
 
-static void _Open(const char *szExtension) {
-    _Close();
+bool
+Writer::open(const char *filename) {
+    close();
+
+    g_gzFile = gzopen(filename, "wb");
+    if (!g_gzFile) {
+        return false;
+    }
+
+    call_no = 0;
+    functions = std::vector<bool>();
+    structs = std::vector<bool>();
+    enums = std::vector<bool>();
+    bitmasks = std::vector<bool>();
+
+    _writeUInt(TRACE_VERSION);
+
+    return true;
+}
+
+void
+Writer::open(void) {
 
     static unsigned dwCounter = 0;
 
+    const char *szExtension = "trace";
     char szFileName[PATH_MAX];
     const char *lpFileName;
 
@@ -70,41 +100,42 @@ static void _Open(const char *szExtension) {
 
         for (;;) {
             FILE *file;
+
             if (dwCounter)
                 snprintf(szFileName, PATH_MAX, "%s%c%s.%u.%s", szCurrentDir, PATH_SEP, szProcessName, dwCounter, szExtension);
             else
                 snprintf(szFileName, PATH_MAX, "%s%c%s.%s", szCurrentDir, PATH_SEP, szProcessName, szExtension);
+
             file = fopen(szFileName, "rb");
             if (file == NULL)
                 break;
+
             fclose(file);
+
             ++dwCounter;
         }
     }
 
     OS::DebugMessage("apitrace: tracing to %s\n", szFileName);
 
-    g_gzFile = gzopen(szFileName, "wb");
+    open(szFileName);
 }
 
-static inline void Write(const void *sBuffer, size_t dwBytesToWrite) {
+void inline
+Writer::_write(const void *sBuffer, size_t dwBytesToWrite) {
     if (g_gzFile == NULL)
         return;
 
     gzwrite(g_gzFile, sBuffer, dwBytesToWrite);
 }
 
-static inline void 
-WriteByte(char c) {
-    Write(&c, 1);
+void inline
+Writer::_writeByte(char c) {
+    _write(&c, 1);
 }
 
-void inline 
-WriteUInt(unsigned long long value) {
+void inline
+Writer::_writeUInt(unsigned long long value) {
     char buf[2 * sizeof value];
     unsigned len;
 
@@ -119,37 +150,28 @@ WriteUInt(unsigned long long value) {
     assert(len);
     buf[len - 1] &= 0x7f;
 
-    Write(buf, len);
+    _write(buf, len);
 }
 
-static inline void 
-WriteFloat(float value) {
+void inline
+Writer::_writeFloat(float value) {
     assert(sizeof value == 4);
-    Write((const char *)&value, sizeof value);
+    _write((const char *)&value, sizeof value);
 }
 
-static inline void 
-WriteDouble(double value) {
+void inline
+Writer::_writeDouble(double value) {
     assert(sizeof value == 8);
-    Write((const char *)&value, sizeof value);
+    _write((const char *)&value, sizeof value);
 }
 
-static inline void 
-WriteString(const char *str) {
+void inline
+Writer::_writeString(const char *str) {
     size_t len = strlen(str);
-    WriteUInt(len);
-    Write(str, len);
-}
-
-void Open(void) {
-    if (!g_gzFile) {
-        _Open("trace");
-        WriteUInt(TRACE_VERSION);
-    }
+    _writeUInt(len);
+    _write(str, len);
 }
 
-static unsigned call_no = 0;
-
 inline bool lookup(std::vector<bool> &map, size_t index) {
     if (index >= map.size()) {
         map.resize(index + 1);
@@ -159,219 +181,180 @@ inline bool lookup(std::vector<bool> &map, size_t index) {
     }
 }
 
-static std::vector<bool> functions;
-static std::vector<bool> structs;
-static std::vector<bool> enums;
-static std::vector<bool> bitmasks;
-
+unsigned Writer::beginEnter(const FunctionSig &function) {
+    OS::AcquireMutex();
 
-void Close(void) {
-    _Close();
-    call_no = 0;
-    functions = std::vector<bool>();
-    structs = std::vector<bool>();
-    enums = std::vector<bool>();
-    bitmasks = std::vector<bool>();
-}
+    if (!g_gzFile) {
+        open();
+    }
 
-unsigned BeginEnter(const FunctionSig &function) {
-    OS::AcquireMutex();
-    Open();
-    WriteByte(Trace::EVENT_ENTER);
-    WriteUInt(function.id);
+    _writeByte(Trace::EVENT_ENTER);
+    _writeUInt(function.id);
     if (!lookup(functions, function.id)) {
-        WriteString(function.name);
-        WriteUInt(function.num_args);
+        _writeString(function.name);
+        _writeUInt(function.num_args);
         for (unsigned i = 0; i < function.num_args; ++i) {
-            WriteString(function.args[i]);
+            _writeString(function.args[i]);
         }
         functions[function.id] = true;
     }
+
     return call_no++;
 }
 
-void EndEnter(void) {
-    WriteByte(Trace::CALL_END);
+void Writer::endEnter(void) {
+    _writeByte(Trace::CALL_END);
     gzflush(g_gzFile, Z_SYNC_FLUSH);
     OS::ReleaseMutex();
 }
 
-void BeginLeave(unsigned call) {
+void Writer::beginLeave(unsigned call) {
     OS::AcquireMutex();
-    WriteByte(Trace::EVENT_LEAVE);
-    WriteUInt(call);
+    _writeByte(Trace::EVENT_LEAVE);
+    _writeUInt(call);
 }
 
-void EndLeave(void) {
-    WriteByte(Trace::CALL_END);
+void Writer::endLeave(void) {
+    _writeByte(Trace::CALL_END);
     gzflush(g_gzFile, Z_SYNC_FLUSH);
     OS::ReleaseMutex();
 }
 
-void BeginArg(unsigned index) {
-    WriteByte(Trace::CALL_ARG);
-    WriteUInt(index);
+void Writer::beginArg(unsigned index) {
+    _writeByte(Trace::CALL_ARG);
+    _writeUInt(index);
 }
 
-void BeginReturn(void) {
-    WriteByte(Trace::CALL_RET);
+void Writer::beginReturn(void) {
+    _writeByte(Trace::CALL_RET);
 }
 
-void BeginArray(size_t length) {
-    WriteByte(Trace::TYPE_ARRAY);
-    WriteUInt(length);
+void Writer::beginArray(size_t length) {
+    _writeByte(Trace::TYPE_ARRAY);
+    _writeUInt(length);
 }
 
-void BeginStruct(const StructSig *sig) {
-    WriteByte(Trace::TYPE_STRUCT);
-    WriteUInt(sig->id);
+void Writer::beginStruct(const StructSig *sig) {
+    _writeByte(Trace::TYPE_STRUCT);
+    _writeUInt(sig->id);
     if (!lookup(structs, sig->id)) {
-        WriteString(sig->name);
-        WriteUInt(sig->num_members);
+        _writeString(sig->name);
+        _writeUInt(sig->num_members);
         for (unsigned i = 0; i < sig->num_members; ++i) {
-            WriteString(sig->members[i]);
+            _writeString(sig->members[i]);
         }
         structs[sig->id] = true;
     }
 }
 
-void LiteralBool(bool value) {
-    WriteByte(value ? Trace::TYPE_TRUE : Trace::TYPE_FALSE);
+void Writer::writeBool(bool value) {
+    _writeByte(value ? Trace::TYPE_TRUE : Trace::TYPE_FALSE);
 }
 
-void LiteralSInt(signed long long value) {
+void Writer::writeSInt(signed long long value) {
     if (value < 0) {
-        WriteByte(Trace::TYPE_SINT);
-        WriteUInt(-value);
+        _writeByte(Trace::TYPE_SINT);
+        _writeUInt(-value);
     } else {
-        WriteByte(Trace::TYPE_UINT);
-        WriteUInt(value);
+        _writeByte(Trace::TYPE_UINT);
+        _writeUInt(value);
     }
 }
 
-void LiteralUInt(unsigned long long value) {
-    WriteByte(Trace::TYPE_UINT);
-    WriteUInt(value);
+void Writer::writeUInt(unsigned long long value) {
+    _writeByte(Trace::TYPE_UINT);
+    _writeUInt(value);
 }
 
-void LiteralFloat(float value) {
-    WriteByte(Trace::TYPE_FLOAT);
-    WriteFloat(value);
+void Writer::writeFloat(float value) {
+    _writeByte(Trace::TYPE_FLOAT);
+    _writeFloat(value);
 }
 
-void LiteralDouble(double value) {
-    WriteByte(Trace::TYPE_DOUBLE);
-    WriteDouble(value);
+void Writer::writeDouble(double value) {
+    _writeByte(Trace::TYPE_DOUBLE);
+    _writeDouble(value);
 }
 
-void LiteralString(const char *str) {
+void Writer::writeString(const char *str) {
     if (!str) {
-        LiteralNull();
+        Writer::writeNull();
         return;
     }
-    WriteByte(Trace::TYPE_STRING);
-    WriteString(str);
+    _writeByte(Trace::TYPE_STRING);
+    _writeString(str);
 }
 
-void LiteralString(const char *str, size_t len) {
+void Writer::writeString(const char *str, size_t len) {
     if (!str) {
-        LiteralNull();
+        Writer::writeNull();
         return;
     }
-    WriteByte(Trace::TYPE_STRING);
-    WriteUInt(len);
-    Write(str, len);
+    _writeByte(Trace::TYPE_STRING);
+    _writeUInt(len);
+    _write(str, len);
 }
 
-void LiteralWString(const wchar_t *str) {
+void Writer::writeWString(const wchar_t *str) {
     if (!str) {
-        LiteralNull();
+        Writer::writeNull();
         return;
     }
-    WriteByte(Trace::TYPE_STRING);
-    WriteString("<wide-string>");
+    _writeByte(Trace::TYPE_STRING);
+    _writeString("<wide-string>");
 }
 
-void LiteralBlob(const void *data, size_t size) {
+void Writer::writeBlob(const void *data, size_t size) {
     if (!data) {
-        LiteralNull();
+        Writer::writeNull();
         return;
     }
-    WriteByte(Trace::TYPE_BLOB);
-    WriteUInt(size);
+    _writeByte(Trace::TYPE_BLOB);
+    _writeUInt(size);
     if (size) {
-        Write(data, size);
+        _write(data, size);
     }
 }
 
-void LiteralEnum(const EnumSig *sig) {
-    WriteByte(Trace::TYPE_ENUM);
-    WriteUInt(sig->id);
+void Writer::writeEnum(const EnumSig *sig) {
+    _writeByte(Trace::TYPE_ENUM);
+    _writeUInt(sig->id);
     if (!lookup(enums, sig->id)) {
-        WriteString(sig->name);
-        LiteralSInt(sig->value);
+        _writeString(sig->name);
+        Writer::writeSInt(sig->value);
         enums[sig->id] = true;
     }
 }
 
-void LiteralBitmask(const BitmaskSig &bitmask, unsigned long long value) {
-    WriteByte(Trace::TYPE_BITMASK);
-    WriteUInt(bitmask.id);
+void Writer::writeBitmask(const BitmaskSig &bitmask, unsigned long long value) {
+    _writeByte(Trace::TYPE_BITMASK);
+    _writeUInt(bitmask.id);
     if (!lookup(bitmasks, bitmask.id)) {
-        WriteUInt(bitmask.count);
+        _writeUInt(bitmask.count);
         for (unsigned i = 0; i < bitmask.count; ++i) {
             if (i != 0 && bitmask.values[i].value == 0) {
                 OS::DebugMessage("apitrace: bitmask %s is zero but is not first flag\n", bitmask.values[i].name);
             }
-            WriteString(bitmask.values[i].name);
-            WriteUInt(bitmask.values[i].value);
+            _writeString(bitmask.values[i].name);
+            _writeUInt(bitmask.values[i].value);
         }
         bitmasks[bitmask.id] = true;
     }
-    WriteUInt(value);
+    _writeUInt(value);
 }
 
-void LiteralNull(void) {
-    WriteByte(Trace::TYPE_NULL);
+void Writer::writeNull(void) {
+    _writeByte(Trace::TYPE_NULL);
 }
 
-void LiteralOpaque(const void *addr) {
+void Writer::writeOpaque(const void *addr) {
     if (!addr) {
-        LiteralNull();
+        Writer::writeNull();
         return;
     }
-    WriteByte(Trace::TYPE_OPAQUE);
-    WriteUInt((size_t)addr);
+    _writeByte(Trace::TYPE_OPAQUE);
+    _writeUInt((size_t)addr);
 }
 
 } /* namespace Trace */
 
-
-#ifdef _WIN32
-
-#if 0
-BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
-    switch(fdwReason) {
-    case DLL_PROCESS_ATTACH:
-    case DLL_THREAD_ATTACH:
-        return TRUE;
-    case DLL_THREAD_DETACH:
-        return TRUE;
-    case DLL_PROCESS_DETACH:
-        Trace::Close();
-        return TRUE;
-    }
-    (void)hinstDLL;
-    (void)lpvReserved;
-    return TRUE;
-}
-#endif
-
-#else
-
-static void _uninit(void) __attribute__((destructor));
-static void _uninit(void) {
-    Trace::Close();
-}
-
-#endif
index f76cd3f..5e7416b 100644 (file)
@@ -32,6 +32,8 @@
 
 #include <stddef.h>
 
+#include <vector>
+
 namespace Trace {
 
     typedef unsigned Id;
@@ -67,43 +69,68 @@ namespace Trace {
         const BitmaskVal *values;
     };
 
-    void Open(void);
-    void Close(void);
-
-    unsigned BeginEnter(const FunctionSig &function);
-    void EndEnter(void);
-
-    void BeginLeave(unsigned call);
-    void EndLeave(void);
-
-    void BeginArg(unsigned index);
-    inline void EndArg(void) {}
-
-    void BeginReturn(void);
-    inline void EndReturn(void) {}
+    class Writer {
+    protected:
+        void *g_gzFile;
+        unsigned call_no;
+
+        std::vector<bool> functions;
+        std::vector<bool> structs;
+        std::vector<bool> enums;
+        std::vector<bool> bitmasks;
+
+    public:
+        Writer();
+        ~Writer();
+
+        void open(void);
+        bool open(const char *filename);
+        void close(void);
+
+        unsigned beginEnter(const FunctionSig &function);
+        void endEnter(void);
+
+        void beginLeave(unsigned call);
+        void endLeave(void);
+
+        void beginArg(unsigned index);
+        inline void endArg(void) {}
+
+        void beginReturn(void);
+        inline void endReturn(void) {}
+
+        void beginArray(size_t length);
+        inline void endArray(void) {}
+
+        inline void beginElement(void) {}
+        inline void endElement(void) {}
+
+        void beginStruct(const StructSig *sig);
+        inline void endStruct(void) {}
+
+        void writeBool(bool value);
+        void writeSInt(signed long long value);
+        void writeUInt(unsigned long long value);
+        void writeFloat(float value);
+        void writeDouble(double value);
+        void writeString(const char *str);
+        void writeString(const char *str, size_t size);
+        void writeWString(const wchar_t *str);
+        void writeBlob(const void *data, size_t size);
+        void writeEnum(const EnumSig *sig);
+        void writeBitmask(const BitmaskSig &bitmask, unsigned long long value);
+        void writeNull(void);
+        void writeOpaque(const void *ptr);
+
+    protected:
+        void inline _write(const void *sBuffer, size_t dwBytesToWrite);
+        void inline _writeByte(char c);
+        void inline _writeUInt(unsigned long long value);
+        void inline _writeFloat(float value);
+        void inline _writeDouble(double value);
+        void inline _writeString(const char *str);
 
-    void BeginArray(size_t length);
-    inline void EndArray(void) {}
-
-    inline void BeginElement(void) {}
-    inline void EndElement(void) {}
-
-    void BeginStruct(const StructSig *sig);
-    inline void EndStruct(void) {}
-
-    void LiteralBool(bool value);
-    void LiteralSInt(signed long long value);
-    void LiteralUInt(unsigned long long value);
-    void LiteralFloat(float value);
-    void LiteralDouble(double value);
-    void LiteralString(const char *str);
-    void LiteralString(const char *str, size_t size);
-    void LiteralWString(const wchar_t *str);
-    void LiteralBlob(const void *data, size_t size);
-    void LiteralEnum(const EnumSig *sig);
-    void LiteralBitmask(const BitmaskSig &bitmask, unsigned long long value);
-    void LiteralNull(void);
-    void LiteralOpaque(const void *ptr);
+    };
 }
 
 #endif /* _TRACE_WRITER_HPP_ */