Beispiel #1
0
packet build_packet(int sz, char * data) {

   int escapes = count_escapes(sz, data);
   int i, offset;
   
   packet res;
   res.sz = sz + escapes + OVERHEAD;
   res.data = (unsigned char*)malloc(res.sz);

   /* TODO: escape size bytes and checksum */
   res.data[0] = 0x7E;
   res.data[1] = (sz >> 8) & 0xFF;
   res.data[2] = sz & 0xFF;

   char checksum = 0;
   offset = 3;
   for( i = 0; i < sz; i++ ) {
      if( is_escape(data[i]) ) {
         res.data[i + offset] = 0x7D;
         offset++;
         res.data[i + offset] = data[i] ^ 0x20;
      } else {
         res.data[i + offset] = data[i];
      }
      checksum += data[i];
   }

   checksum = 0xFF - checksum;
   res.data[i + offset] = checksum;

   return res;
}
Beispiel #2
0
/* Expands escape sequences within a string
 *
 * src must be a string with a NUL terminator
 *
 * NUL characters are not expanded to \0 (otherwise how would we know when
 * the input string ends?)
 *
 * Adapted from http://stackoverflow.com/questions/3535023/convert-characters-in-a-c-string-to-their-escape-sequences
 */
char *expand_escapes(const char* src)
{
    char* dest;
    char* d;

    if ((src == NULL) || ( strlen(src) == 0)) {
        dest = malloc(sizeof(char));
        d = dest;
    } else {
        // escaped lengths must take NUL terminator into account
        int dest_len = strlen(src) + count_escapes(src) + 1;
        dest = malloc(dest_len * sizeof(char));
        d = dest;

        char c = *(src++);

        while (c) {
            switch(c) {
                case '\\':
                    *(d++) = '\\';
                    *(d++) = '\\';
                    break;
                case '\"':
                    *(d++) = '\\';
                    *(d++) = '\"';
                    break;
                default:
                    *(d++) = c;
            }
            c = *(src++);
        }
    }

    *d = '\0'; /* Ensure NUL terminator */

    return(dest);
}
Beispiel #3
0
/* 
 * escape_to_html
 */
VALUE escape_to_html(VALUE self, VALUE rawdata)
{
    VALUE result;

    if (rawdata == Qnil) {
        return rb_str_new2("");
    }

    if (TYPE(rawdata) != T_STRING) {
        rb_raise(rb_eTypeError, "invalid type for rawdata");
        return Qnil;
    }

    char *dataStr = StringValueCStr(rawdata);
    size_t dataStrLen = strlen(dataStr);
    char code[CODE_BUF_SIZE];
    bool inCode = false;
    size_t in_pos = 0, scratch_pos = 0, code_pos = 0;

    /*
     * Pre alloc scratch space that's at least as big as the input string, plus
     * some space for inserted span elements.
     *
     * Every string gets wrapped in a <span class="ansible_none"></span>
     *
     * Assume that every new escape code that's encountered will produce open
     * and close span tags that together consume 100 bytes (this allows for 3-5
     * codes per span, which is generous).  This should be good enough for
     * pretty much everything.  If it's not, we'll still notice when we run out
     * of space and try to realloc.
     */
    int spans = 1 + count_escapes(dataStr, dataStrLen);
    size_t scratchLen = dataStrLen + (spans * MAX_SPAN_SIZE);
    char *scratch = malloc(scratchLen);
    memset(scratch, 0, scratchLen);

    write_scratch((char *)SPAN_START(ansible_none),
            sizeof(SPAN_START(ansible_none))-1, &scratch, &scratch_pos,
            &scratchLen);


    for (; in_pos < dataStrLen; in_pos++) {
        char c = dataStr[in_pos];

        /*
         * Copy characters into scratch that arent within an escape code block.
         */
        if (c == '\033') {          // Enter escape code on ^[
            inCode = true;
            code_pos = 0;
        } else if (c == 'm') { 
            if (inCode) {           // Exit escape code on m
                inCode = false;
                code[code_pos] = 0;
                DBG("code: %s\n", code);
                write_span(code, &scratch, &scratch_pos, &scratchLen);
            } else {                // Copy an m that's not terminating an escape code
                write_scratch(&c, 1, &scratch, &scratch_pos, &scratchLen);
            }
        } else if (!inCode) {       // Copy everything else
            write_scratch(&c, 1, &scratch, &scratch_pos, &scratchLen);
        } else {                    // fill code buffer
           if (code_pos < sizeof(code)) {
              code[code_pos++] = c;
           }
        } 
    }

    write_scratch((char *)SPAN_CLOSE, sizeof(SPAN_CLOSE)-1, &scratch, &scratch_pos, &scratchLen);

    result = rb_enc_str_new(scratch, scratch_pos, rb_enc_find("BINARY"));
    free(scratch);

    return result;
}