Calculating Content Length

Hi All…

Here is my code to do some horrible things with sending data between the Spark and a server. Please bear in mind that this comes from a real project, so it might not be as clear as it could be.

The first bit defines some complex data structures.

#define CIRCUIT_COUNT 8

struct teridianBillingPosStruct {
    unsigned int start;
    unsigned int last;
    struct {
        unsigned int PP_POS_CNT;
        unsigned int PQ_POS_CNT;
        unsigned int PS_CNT;
    } count[CIRCUIT_COUNT + 1];
};

struct teridianBillingPosStruct teridianBillingPos;

char v_energy_pos[160];

This is standard C stuff. v_energy_pos is the variable that actually gets either pulled or pushed to the server. It is a base 64 representation of the raw data in the data structure. In this case we are talking mostly unsigned int, but it could be any C structure.

The next bit of code requests that the variables are encoded. This happens on every loop in my case when the underlying data has been updated.

void saveVariables(){
    base64_encode ((char *)&teridianBillingPos, sizeof (teridianBillingPos), v_energy_pos);

}

The previous function calls the following one, which returns Base64 data. The advantage with Base64 is that it can deal with binary data. It sends four characters for three bytes. There are standard Javascript functions to do the decode.

//
// Library Code
//

// base 64 - Convert from a binary blob to a string.
 static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
                                'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
                                'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
                                'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
                                'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
                                'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
                                'w', 'x', 'y', 'z', '0', '1', '2', '3',
                                '4', '5', '6', '7', '8', '9', '+', '/'};
                                
static int mod_table[] = {0, 2, 1};


void base64_encode(char *data,
                    size_t input_length,
                    char *encoded_data) {
    // From http://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c

    int  output_length = ((input_length - 1) / 3) * 4 + 4;
    encoded_data[output_length] = 0;

    for (unsigned int i = 0, j = 0; i < input_length;) {

        unsigned int octet_a = i < input_length ? (unsigned char)data[i++] : 0;
        unsigned int octet_b = i < input_length ? (unsigned char)data[i++] : 0;
        unsigned int octet_c = i < input_length ? (unsigned char)data[i++] : 0;

        unsigned int triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;

        encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
        encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
        encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
        encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];

    }
    
    for (int i = 0; i < mod_table[input_length % 3]; i++)
        encoded_data[output_length - 1 - i] = '=';
}

I hope this helps. Let me know if you have any questions.