string_as_bin::string_as_bin(const string_as_hex & encoded) { try { // "ff020a" = ff , 02 , 0a // "020a" = 02 , 0a // "20a" = 02 , 0a _info("Processing string: ["<< (encoded.data) << "]"); const auto es = encoded.data.size(); if (!es) return; // empty string encoded --> empty binary string size_t retsize = es/2; // size of finall string of bytes data if (0 != (es % 2)) retsize++; assert(retsize > 0); // the binary string will be not-empty (empty case is covered already) assert( (retsize < es) || ((retsize==1)&&(es==1)) ); // binary string is smaller -or- both are ==1 for e.g. encoded "a" means "0a" so it should result in ---> a 1-byte binary string bytes.resize(retsize); size_t pos=0, out=0; // position of input, and output for( ; pos<es ; pos+=2, ++out) { // _info("pos="<<pos<<" out="<<out<<" encoded="<<encoded.data); // "02" -> cl="2" ch="0" // "2" -> cl="2" ch="0" char cl,ch; if (pos+1 < es) { // pos and pos+1 are valid positions in string ch = encoded.data.at(pos); cl = encoded.data.at(pos+1); } else { ch = '0'; cl = encoded.data.at(pos); } unsigned char octet = hexchar2int(ch)*16 + hexchar2int(cl); bytes.at(out) = octet; } assert( out == retsize ); // all expected positions of data allocated above in .resize() were written } catch(std::exception &e) { _erro("Failed to parse string [" << encoded.data <<"]"); throw ; } }
static char * find_star( char *s ) { for ( ; *s; ++s ) { switch ( *s ) { case '*': return s; case '\\': ++s; if ( hexchar2int(s[0]) >= 0 && hexchar2int(s[1]) >= 0 ) ++s; default: break; } } return NULL; }
int Util::hexmakebuf(const char *hexstr, int len, uint8_t buf[]) { int i = 0, j = 0; if ((len % 2) == 0) { while (i < len) { int c0 = hexchar2int(hexstr[i]); int c1 = hexchar2int(hexstr[i+1]); if ((c0 >= 0) && (c1 >= 0)) { uint8_t c = (uint8_t)((c0 * 16) + c1); buf[j++] = c; i += 2; } else break; } } return i; }
long hexstr2int(const char* hexstr, const int len){ long intstr, i, base; int intchar; intstr = 0; base = 1; for(i=1;i<=len;i++){ intchar = hexchar2int(hexstr[len-i]); if(intchar > -1){ intstr += intchar * base; base *= 16; } else return -1; } return intstr; }
/* * Undo in place both LDAPv2 (RFC-1960) and LDAPv3 (hexadecimal) escape * sequences within the null-terminated string 'val'. The resulting value * may contain null characters. * * If 'val' contains invalid escape sequences we return -1. * Otherwise the length of the unescaped value is returned. */ static int unescape_filterval( char *val ) { int escape, firstdigit, ival; char *s, *d; escape = firstdigit = 0; for ( s = d = val; *s; s++ ) { if ( escape ) { /* * first try LDAPv3 escape (hexadecimal) sequence */ if (( ival = hexchar2int( *s )) < 0 ) { if ( firstdigit ) { /* * LDAPv2 (RFC1960) escape sequence */ *d++ = *s; escape = 0; } else { return(-1); } } if ( firstdigit ) { *d = ( ival<<4 ); firstdigit = 0; } else { *d++ |= ival; escape = 0; } } else if ( *s != '\\' ) { *d++ = *s; escape = 0; } else { escape = 1; firstdigit = 1; } } return( d - val ); }
int main() { printf("Testing conversions.c. All errors will be reported as failed assertions.\n"); printf("Testing hexchar2int()\n"); /** Testing hexchar2int() **/ assert(hexchar2int('!') == -1); assert(hexchar2int('0') == 0); assert(hexchar2int('9') == 9); assert(hexchar2int(':') == -1); assert(hexchar2int('@') == -1); assert(hexchar2int('A') == 10); assert(hexchar2int('F') == 15); assert(hexchar2int('G') == -1); assert(hexchar2int('`') == -1); assert(hexchar2int('a') == 10); assert(hexchar2int('f') == 15); assert(hexchar2int('g') == -1); /** Testing degMinToDeg() **/ printf("Testing degMinToDeg()\n"); // 40 degrees, 41 arc minutes = 40.68 assert(degMinToDeg(40, 41) - 40.68333 < .001); // 0 degrees, 0 arc minutes = 0 assert(degMinToDeg(0, 0) - 0 < .001); // 122 degrees, 24 arc minutes = 122.4 assert(degMinToDeg(122, 24) - (122.4) < .001); return 0; }
const AVOption *av_set_string2(void *obj, const char *name, const char *val, int alloc){ const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){ return set_all_opt(obj, o->unit, o->default_val); } if(!o || !val || o->offset<=0) return NULL; if(o->type == FF_OPT_TYPE_BINARY){ uint8_t **dst = (uint8_t **)(((uint8_t*)obj) + o->offset); int *lendst = (int *)(dst + 1); uint8_t *bin, *ptr; int len = strlen(val); av_freep(dst); *lendst = 0; if (len & 1) return NULL; len /= 2; ptr = bin = av_malloc(len); while (*val) { int a = hexchar2int(*val++); int b = hexchar2int(*val++); if (a < 0 || b < 0) { av_free(bin); return NULL; } *ptr++ = (a << 4) | b; } *dst = bin; *lendst = len; return o; } if(o->type != FF_OPT_TYPE_STRING){ int notfirst=0; for(;;){ int i; char buf[256]; int cmd=0; double d; const char *error = NULL; if(*val == '+' || *val == '-') cmd= *(val++); for(i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++) buf[i]= val[i]; buf[i]=0; d = ff_eval2(buf, (double *)const_values, (const char **)const_names, NULL, NULL, NULL, NULL, NULL, &error); if(isnan(d)) { const AVOption *o_named= av_find_opt(obj, buf, o->unit, 0, 0); if(o_named && o_named->type == FF_OPT_TYPE_CONST) d= o_named->default_val; else if(!strcmp(buf, "default")) d= o->default_val; else if(!strcmp(buf, "max" )) d= o->max; else if(!strcmp(buf, "min" )) d= o->min; else if(!strcmp(buf, "none" )) d= 0; else if(!strcmp(buf, "all" )) d= ~0; else { if (error) av_log(NULL, AV_LOG_ERROR, "Unable to parse option value \"%s\": %s\n", val, error); return NULL; } } if(o->type == FF_OPT_TYPE_FLAGS){ if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d; else if(cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d; }else{ if (cmd=='+') d= notfirst*av_get_double(obj, name, NULL) + d; else if(cmd=='-') d= notfirst*av_get_double(obj, name, NULL) - d; } if (!av_set_number(obj, name, d, 1, 1)) return NULL; val+= i; if(!*val) return o; notfirst=1; } return NULL; } if(alloc){ av_free(*(void**)(((uint8_t*)obj) + o->offset)); val= av_strdup(val); } memcpy(((uint8_t*)obj) + o->offset, &val, sizeof(val)); return o; }
/*! * Interrupt routine notifying us a new character is available from the * GPS's uart module. * This function buffers a valid (structure and checksum) RMC sentence. The * used buffer is nmea_buffer_RMC. */ void __attribute__((__interrupt__, __shadow__, __auto_psv__)) _U2RXInterrupt(void) { unsigned char c = U2RXREG; //uart1_putc(c); if (c == '$') // Beginnng of new sequence { state = 1; checksum = 0; } else if (c == '*') { if (state == 7) state = 98; else if (state == 11) state = 90; } else if (state == 90) { checksum -= (hexchar2int(c)*16); state = 91; } else if (state == 91) { nmea_buffer_GGA[nmea_buffer_GGA_counter++] = '\0'; checksum -= (hexchar2int(c)); if (checksum == 0) gga_sentence_number++; state = 92; #ifndef TEST static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR( xGpsSemaphore, &xHigherPriorityTaskWoken ); #endif } else if (state == 98) { checksum -= (hexchar2int(c)*16); state = 99; } else if (state == 99) { nmea_buffer_RMC[nmea_buffer_RMC_counter++] = '\0'; checksum -= (hexchar2int(c)); if (checksum == 0) rmc_sentence_number++; state = 100; // small test programs don't use FreeRTOS so we need a way to avoid #ifndef TEST static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR( xGpsSemaphore, &xHigherPriorityTaskWoken ); #endif } else { checksum ^= c; switch(state) { case 1: if (c == 'G') state = 2; break; case 2: if (c == 'P') state = 3; break; case 3: if (c == 'R') state = 4; else if (c == 'G') state = 8; break; case 4: if (c == 'M') state = 5; break; case 5: if (c == 'C') state = 6; break; case 6: if (c == ',') { state = 7; nmea_buffer_RMC_counter = 0; } break; case 7: if (nmea_buffer_RMC_counter < 100) nmea_buffer_RMC[nmea_buffer_RMC_counter++] = c; break; case 8: if (c == 'G') state = 9; break; case 9: if (c == 'A') state = 10; break; case 10: if (c == ',') state = 11; nmea_buffer_GGA_counter = 0; break; case 11: if (nmea_buffer_GGA_counter < 100) nmea_buffer_GGA[nmea_buffer_GGA_counter++] = c; break; default: nmea_buffer_RMC_counter = 0; nmea_buffer_GGA_counter = 0; } } _U2RXIF = 0; }
unsigned char doublehexchar2int(string s) { if (s.size()!=2) throw std::invalid_argument("Invalid double-hex string: '"+s+"'"); unsigned char h = s.at(0); unsigned char l = s.at(1); return hexchar2int(h)*16 + hexchar2int(l); }