Strings.cpp

// Strings.cpp
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2007

#include "Ceda/cxUtils/xstring.h"
#include "Ceda/cxUtils/TracerUtils.h"
@import "Ceda/cxPython/cxPython.h"

///////////////////////////////////////////////////////////////////////////////////////////////////
/*
Strings
-------

Marshalling of a string.

Both xstring and SubString can be passed and returned from reflected functions
*/

namespace Strings1
{
    // Holds an array of statics in type T and gives them out in round robin fashion.
    // This is done to avoid allocating on the heap (to avoid memory leaks), and to avoid
    // aliasing when testing nested functions calls such as s8(s8(a)).
    template<typename T> T& GetStatic()
    {
	    const int NUM = 10;
	    static T buffer[NUM];
	    static int n = 0;
	    n = (n+1) % NUM;
	    return buffer[n++];
	}

	$function+ string8 x8(ceda::string8 x)
	{
	    return ceda::string8("x8 ") + x;
	}

	$function+ string16 x16(ceda::string16 x)
	{
	    return ceda::string16( (const ceda::char16*) L"x16 ") + x;
	}
	
	$function+ ceda::SubString8 s8(ceda::SubString8 x)
	{
	    ceda::string8& r = GetStatic<ceda::string8>();
	    r = "s8 ";
	    r += x.GetString();
	    return r;
	}
    
	$function+ ceda::SubString16 s16(ceda::SubString16 x)
	{
	    ceda::string16& r = GetStatic<ceda::string16>();
	    r = (const ceda::char16*) L"s16 ";
	    r += x.GetString();
	    return r;
	}

	$function+ ceda::ConstString8Z z8(ceda::ConstString8Z x)
	{
	    ceda::string8& r = GetStatic<ceda::string8>();
	    r = "z8 ";
	    r += x;
	    return r.c_str();
	}
    
	$function+ ceda::ConstString16Z z16(ceda::ConstString16Z x)
	{
	    ceda::string16& r = GetStatic<ceda::string16>();
	    r = (const ceda::char16*) L"z16 ";
	    r += x;
	    return r.c_str();
	}

    /*
    todo: After an error occurs we often have a subsequent assertion failure
        cxAssert(g_ClassVariableWrapper_count == 0)
    */
	void Run()
	{
        /*
        Note
        ----
        
        Perhaps surpisingly, unicode strings can be converted to SubString8.
        This is because the python interpreter allows a unicode PyObject be seen 
        as an const char* as long as the conversion succeeds
        For this reason s8(u'x') works
        */

		ceda::TraceGroup g("Strings example 1");
		
        PyRun_SimpleString(
            @strx
            (
                x8 = rootnamespace.Strings1.x8
                x16 = rootnamespace.Strings1.x16
                s8 = rootnamespace.Strings1.s8
                s16 = rootnamespace.Strings1.s16
                z8 = rootnamespace.Strings1.z8
                z16 = rootnamespace.Strings1.z16
                
                a = 'a'
                u = u'u'

                print x8(a)
                print x8(u)
                print x16(a)
                print x16(u)
                print

                print s8(a)
                print s8(u)
                #print s16(a)                 No conversion from 8 bit string to SubString16
                print s16(u)
                print

                print z8(a)
                print z8(u)
                #print z16(a)                 No conversion from 8 bit string to ConstString16Z
                print z16(u)
                print
                
                print x8(x8(a))
                print x8(x8(u))
                print x8(x16(a))
                print x8(x16(u))
                print x16(x8(a))
                print x16(x8(u))
                print x16(x16(a))
                print x16(x16(u))
                print

                print x8(s8(a))
                print x8(s8(u))
                #print x8(s16(a))             No conversion from 8 bit string to SubString16
                print x8(s16(u))
                print x16(s8(a))
                print x16(s8(u))
                #print x16(s16(a))            No conversion from 8 bit string to SubString16
                print x16(s16(u))
                print

                print x8(z8(a))
                print x8(z8(u))
                #print x8(z16(a))
                print x8(z16(u))
                print x16(z8(a))
                print x16(z8(u))
                #print x16(z16(a))
                print x16(z16(u))
                print
                
                print s8(x8(a))
                print s8(x8(u))
                print s8(x16(a))
                print s8(x16(u))
                #print s16(x8(a))             No conversion from 8 bit string to SubString16     
                #print s16(x8(u))             No conversion from 8 bit string to SubString16
                print s16(x16(a))
                print s16(x16(u))
                print

                print s8(s8(a))
                print s8(s8(u))
                #print s8(s16(a))             No conversion from 8 bit string to SubString16
                #print s8(s16(u))             No conversion from SubString16 to SubString8
                #print s16(s8(a))             No conversion from SubString8 to SubString16
                #print s16(s8(u))             No conversion from SubString8 to SubString16
                #print s16(s16(a))            No conversion from 8 bit string to SubString16
                print s16(s16(u))
                print

                print s8(z8(a))
                print s8(z8(u))
                #print s8(z16(a))
                #print s8(z16(u))
                #print s16(z8(a))
                #print s16(z8(u))
                #print s16(z16(a))
                print s16(z16(u))
                print

                print z8(x8(a))
                print z8(x8(u))
                print z8(x16(a))
                print z8(x16(u))
                #print z16(x8(a))
                #print z16(x8(u))
                print z16(x16(a))
                print z16(x16(u))
                print

                #print z8(s8(a))
                #print z8(s8(u))
                #print z8(s16(a))
                #print z8(s16(u))
                #print z16(s8(a))
                #print z16(s8(u))
                #print z16(s16(a))
                #print z16(s16(u))
                #print

                print z8(z8(a))
                print z8(z8(u))
                #print z8(z16(a))
                #print z8(z16(u))
                #print z16(z8(a))
                #print z16(z8(u))
                #print z16(z16(a))
                print z16(z16(u))
                print
            ));
	}
}

namespace Strings
{
    void Run()
    {
        Strings1::Run();
    }
}