Beispiel #1
0
/*!
 The type wxJSONTYPE_MEMORYBUFF is a \b wxJSON extension that is not correctly read by
 other JSON implementations.
 By default, the function writes such a type as an array of INTs as follows:
 \code
   [ 0,32,45,255,6,...]
 \endcode
 If the writer object was constructed using the \c wxJSONWRITER_MEMORYBUFF flag, then
 the output is much more compact and recognized by the \b wxJSON reader as a memory buffer
 type:
 \code
   '00203FFF06..'
 \endcode

*/
int
wxJSONWriter::WriteMemoryBuff( wxOutputStream& os, const wxMemoryBuffer& buff )
{
#define MAX_BYTES_PER_ROW	20
    char str[16];

    // if STYLED and SPLIT_STRING flags are set, the function writes 20 bytes on every row
    // the following is the counter of bytes written.
    // the string is splitted only for the special meory buffer type, not for array of INTs
    int bytesWritten = 0;
    bool splitString = false;
    if ( (m_style & wxJSONWRITER_STYLED) && 
               (m_style & wxJSONWRITER_SPLIT_STRING))   {
        splitString = true;
    }

    size_t buffLen = buff.GetDataLen();
    unsigned char* ptr = (unsigned char*) buff.GetData();
    wxASSERT( ptr );
    char openChar = '\'';
    char closeChar = '\'';
    bool asArray = false;

    if ( (m_style & wxJSONWRITER_MEMORYBUFF ) == 0 )  {
        // if the special flag is not specified, write as an array of INTs
        openChar = '[';
        closeChar = ']';
        asArray = true;
    }
    // write the open character
    os.PutC( openChar );

    for ( size_t i = 0; i < buffLen; i++ )  {
        unsigned char c = *ptr;
        ++ptr;

        if ( asArray )  {
            snprintf( str, 14, "%d", c );
            size_t len = strlen( str );
            wxASSERT( len <= 3 );
            wxASSERT( len >= 1 );
            str[len] = ',';
            // do not write the comma char for the last element
            if ( i < buffLen - 1 )    {
                ++len;
            }
            os.Write( str, len );
            if ( os.GetLastError() != wxSTREAM_NO_ERROR )    {
                return -1;
            }
        }
        else {
            // now convert the byte in two hex digits
            char c1 = c / 16;
            char c2 = c % 16;
            c1 += '0';
            c2 += '0';
            if ( c1 > '9' )  {
                c1 += 7;
            }
            if ( c2 > '9' )  {
                c2 += 7;
            }
            os.PutC( c1 );
            os.PutC( c2 );
            if ( os.GetLastError() != wxSTREAM_NO_ERROR )    {
                return -1;
            }
            if ( splitString )  {
                ++bytesWritten;
            }

            if (( bytesWritten >= MAX_BYTES_PER_ROW ) && ((buffLen - i ) >= 5 ))   {
                // split the string if we wrote 20 bytes, but only is we have to
                // write at least 5 bytes
                os.Write( "\'\n", 2 );
                int lastChar = WriteIndent( os, m_level + 2 );     // write indentation
                os.PutC( '\'' );               // reopen quotes
                if ( lastChar < 0 )  {
                    return lastChar;
                }
                bytesWritten = 0;
            }
        }
    }

    // write the close character
    os.PutC( closeChar );
    return closeChar;
}
Beispiel #2
0
// helper functions for writing ASCII strings (even in Unicode build)
static inline bool WriteAsciiChar(wxOutputStream& ostr, char ch)
{
    ostr.PutC(ch);
    return ostr.IsOk();
}
Beispiel #3
0
static inline bool WriteAsciiString(wxOutputStream& ostr, const char *p)
{
    return ostr.Write(p, strlen(p)).IsOk();
}
bool wxXPMHandler::SaveFile(wxImage * image,
                            wxOutputStream& stream, bool WXUNUSED(verbose))
{
    wxString tmp;
    char tmp_c;

    // 1. count colours:
    #define MaxCixels  92
    static const char Cixel[MaxCixels+1] =
                         " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjk"
                         "lzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
    int chars_per_pixel;
    int cols;
    int i, j, k;

    cols = image->CountColours();
    chars_per_pixel = 1;
    for ( k = MaxCixels; cols > k; k *= MaxCixels)
        chars_per_pixel++;

    // 2. write the header:
    wxString sName;
    if ( image->HasOption(wxIMAGE_OPTION_FILENAME) )
    {
        wxSplitPath(image->GetOption(wxIMAGE_OPTION_FILENAME),
                    NULL, &sName, NULL);
        sName << wxT("_xpm");
    }

    if ( !sName.IsEmpty() )
        sName = wxString(wxT("/* XPM */\nstatic char *")) + sName;
    else
        sName = wxT("/* XPM */\nstatic char *xpm_data");
    stream.Write( (const char*) sName.ToAscii(), sName.Len() );

    char tmpbuf[200];
    // VS: 200b is safe upper bound for anything produced by sprintf below
    //     (<101 bytes the string, neither %i can expand into more than 10 chars)
    sprintf(tmpbuf,
               "[] = {\n"
               "/* columns rows colors chars-per-pixel */\n"
               "\"%i %i %i %i\",\n",
               image->GetWidth(), image->GetHeight(), cols, chars_per_pixel);
    stream.Write(tmpbuf, strlen(tmpbuf));

    // 3. create color symbols table:
    wxImageHistogram histogram;
    image->ComputeHistogram(histogram);

    char *symbols_data = new char[cols * (chars_per_pixel+1)];
    char **symbols = new char*[cols];

    // 2a. find mask colour:
    unsigned long mask_key = 0x1000000 /*invalid RGB value*/;
    if (image->HasMask())
        mask_key = (image->GetMaskRed() << 16) |
                   (image->GetMaskGreen() << 8) | image->GetMaskBlue();

    // 2b. generate colour table:
    for (wxImageHistogram::iterator entry = histogram.begin();
         entry != histogram.end(); ++entry )
    {
        unsigned long index = entry->second.index;
        symbols[index] = symbols_data + index * (chars_per_pixel+1);
        char *sym = symbols[index];

        k = index % MaxCixels;
        sym[0] = Cixel[k];
        for (j = 1; j < chars_per_pixel; j++)
        {
            k = ((index - k) / MaxCixels) % MaxCixels;
            sym[j] = Cixel[k];
        }
        sym[j] = '\0';

        unsigned long key = entry->first;

        if (key == 0)
            sprintf( tmpbuf, "\"%s c Black\",\n", sym);
        else if (key == mask_key)
            sprintf( tmpbuf, "\"%s c None\",\n", sym);
        else
        {
            char rbuf[3];
            DecToHex( (unsigned char)(key >> 16), rbuf );
            char gbuf[3];
            DecToHex( (unsigned char)(key >> 8), gbuf );
            char bbuf[3];
            DecToHex( (unsigned char)(key), bbuf );
            sprintf( tmpbuf, "\"%s c #%s%s%s\",\n", sym, rbuf, gbuf, bbuf );
        }
        stream.Write( tmpbuf, strlen(tmpbuf) );
    }

    tmp = wxT("/* pixels */\n");
    stream.Write( (const char*) tmp.ToAscii(), tmp.Length() );

    unsigned char *data = image->GetData();
    for (j = 0; j < image->GetHeight(); j++)
    {
        tmp_c = '\"'; stream.Write(&tmp_c, 1);
        for (i = 0; i < image->GetWidth(); i++, data += 3)
        {
            unsigned long key = (data[0] << 16) | (data[1] << 8) | (data[2]);
            stream.Write(symbols[histogram[key].index], chars_per_pixel);
        }
        tmp_c = '\"'; stream.Write(&tmp_c, 1);
        if ( j + 1 < image->GetHeight() )
        {
            tmp_c = ','; stream.Write(&tmp_c, 1);
        }
        tmp_c = '\n'; stream.Write(&tmp_c, 1);
    }
    tmp = wxT("};\n");
    stream.Write( (const char*) tmp.ToAscii(), 3 );

    // Clean up:
    delete[] symbols;
    delete[] symbols_data;

    return true;
}