int parse_trying (uint8_t *data, int data_len, uint8_t *out_bssid, uint8_t **out_ssid, int *out_ssid_len) { // Trying to associate with AB:CD:EF:01:23:45 (SSID='Some SSID' freq=2462 MHz) int p; if (!(p = data_begins_with((char *)data, data_len, "Trying to associate with "))) { return 0; } data += p; data_len -= p; for (int i = 0; i < 6; i++) { uint8_t d1; uint8_t d2; if (data_len < 2 || !parse_hex_digit(data[0], &d1) || !parse_hex_digit(data[1], &d2)) { return 0; } data += 2; data_len -= 2; out_bssid[i] = ((d1 << 4) | d2); if (i != 5) { if (data_len < 1 || data[0] != ':') { return 0; } data += 1; data_len -= 1; } } if (!(p = data_begins_with((char *)data, data_len, " (SSID='"))) { return 0; } data += p; data_len -= p; // find last ' uint8_t *q = NULL; for (int i = data_len; i > 0; i--) { if (data[i - 1] == '\'') { q = &data[i - 1]; break; } } if (!q) { return 0; } *out_ssid = data; *out_ssid_len = q - data; return 1; }
static void rsp_write_mem ( const rsp_buf * const buf ) { unsigned int addr; int len; assert( buf->data[0] == 'M' ); if ( 2 != sscanf( buf->data, "M%x,%x:", &addr, &len ) ) { throw std::runtime_error( "Illegal write memory packet." ); } // Find the start of the data and check there is the amount we expect. const char * const symdat = ((const char *)memchr( buf->data, ':', GDB_BUF_MAX ) ) + 1; const int datlen = buf->len - (symdat - buf->data); // Sanity check. if ( len * 2 != datlen ) { throw std::runtime_error( format_msg( "Illegal write memory packet: Write of %d data hex digits requested, but %d digits were supplied.", len * 2, datlen ) ); } // Write the bytes to memory. // Put all the data into a single buffer, so it can be burst-written via JTAG. // One burst is much faster than many single-byte transactions. // NOTE: We don't support burst data accesses any more, but that may change in the future. std::vector< uint8_t > data; for ( int off = 0; off < len; off++ ) { const unsigned char nyb1 = parse_hex_digit( symdat[ off * 2 ] ); const unsigned char nyb2 = parse_hex_digit( symdat[ off * 2 + 1 ] ); data.push_back( (nyb1 << 4) | nyb2 ); } const bool error_bit = dbg_cpu0_write_mem( addr, len, &data ); if ( error_bit ) put_str_packet( rsp.client_fd, STD_ERROR_CODE ); else send_ok_packet( rsp.client_fd ); }
prange_t parse_hex_string(const char *string) { if(string[0] == '0' && string[1] == 'x') { string += 2; } const char *in = string; size_t len = strlen(string); size_t out_len = (len + 1)/2; uint8_t *out = malloc(out_len); prange_t result = (prange_t) {out, out_len}; if(len % 2) { *out++ = parse_hex_digit(*in++, string); } while(out_len--) { uint8_t a = parse_hex_digit(*in++, string); uint8_t b = parse_hex_digit(*in++, string); *out++ = (uint8_t) ((a * 0x10) + b); } return result; }
bool rgb_color_t::try_parse_rgb(const wcstring &name) { bzero(&data, sizeof data); /* We support the following style of rgb formats (case insensitive): #FA3 #F3A035 FA3 F3A035 */ size_t digit_idx = 0, len = name.size(); /* Skip any leading # */ if (len > 0 && name.at(0) == L'#') digit_idx++; bool success = false; size_t i; if (len - digit_idx == 3) { // type FA3 for (i=0; i < 3; i++) { int val = parse_hex_digit(name.at(digit_idx++)); if (val < 0) break; data.rgb[i] = val*16+val; } success = (i == 3); } else if (len - digit_idx == 6) { // type F3A035 for (i=0; i < 3; i++) { int hi = parse_hex_digit(name.at(digit_idx++)); int lo = parse_hex_digit(name.at(digit_idx++)); if (lo < 0 || hi < 0) break; data.rgb[i] = hi*16+lo; } success = (i == 3); } if (success) { this->type = type_rgb; } return success; }
int RichTextBox::process_tag(const char* text, int index, Font*& font) { if (text[index] == '<') { char tag[64]; int i = 0; while (text[index] && (text[index] != '>')) tag[i++] = text[index++]; if (text[index] == '>') tag[i++] = text[index++]; tag[i] = 0; switch (tag[1]) { case 'c': case 'C': if (_strnicmp(tag+1, "color", 5) == 0) { int r = 0; int g = 0; int b = 0; if (i > 12) { r = 16 * parse_hex_digit(tag[ 7]) + parse_hex_digit(tag[ 8]); g = 16 * parse_hex_digit(tag[ 9]) + parse_hex_digit(tag[10]); b = 16 * parse_hex_digit(tag[11]) + parse_hex_digit(tag[12]); } font->SetColor(Color(r,g,b)); } break; case 'f': case 'F': if (_strnicmp(tag+1, "font", 4) == 0) { Color current_color = Color::White; if (font) current_color = font->GetColor(); tag[i-1] = 0; font = FontMgr::Find(tag+6); font->SetColor(current_color); } break; } } return index; }
int parse_hex_color(const char* str, unsigned char *r, unsigned char *g, unsigned char *b) { if(str[0] == '#') { ++str; } if(strlen(str) != 6) { return 1; } for(int i = 0; i < 6; ++i) { if(!isxdigit(str[i])) { return 1; } } *r = (parse_hex_digit(str[0]) << 4) + parse_hex_digit(str[1]); *g = (parse_hex_digit(str[2]) << 4) + parse_hex_digit(str[3]); *b = (parse_hex_digit(str[4]) << 4) + parse_hex_digit(str[5]); return 0; }
char lexer::parse_escape_sequence() { char c = next_char(); if (c == '\0') { return c; } switch (c) { case '\'': return '\''; case '"': return '"'; case '?': return '?'; case '\\': return '\\'; case '0': return '\0'; case 'a': return '\a'; case 'b': return '\b'; case 'f': return '\f'; case 'n': return '\n'; case 'r': return '\r'; case 't': return '\t'; case 'v': return '\v'; case 'x': case 'X': { char firstDigit = next_char(); if (firstDigit == '\0') { return firstDigit; } if (!isxdigit(firstDigit)) { logger.error(make_location(), format("invalid hex digit '%c' following hex escape") % firstDigit); move_back(); return '\0'; } uint8_t parsed_int = parse_hex_digit(firstDigit); // check if it's a two digit hex escape if (current != end && isxdigit(*current)) { parsed_int = (parsed_int * 16) + parse_hex_digit(next_char()); } if (parsed_int & 0x80) { logger.warning(make_location(), boost::format("invalid 7-bit ASCII character '%#02x'") % parsed_int); } return parsed_int; } default: logger.error(make_location(), format("unrecognized escape character '%c'") % c); return c; } }
std::vector<uint8_t> parse_hex_file(const std::string& filename) { std::ifstream fin(filename); // store chunks of data, then merge them // this allows to check for overlaps struct Chunk { uint32_t addr; std::vector<uint8_t> data; uint32_t addr_end() const { return addr + data.size(); } }; std::vector<Chunk> chunks; std::string line; unsigned int lineno = 0; uint32_t ex_addr_mask = 0; bool eof = false; while(std::getline(fin, line)) { if(eof) { throw hex_parsing_error(lineno, "end of file record not in the last line"); } lineno++; // strip CR/LF size_t pos = line.find_first_of("\r\n"); if(pos != std::string::npos) { // should always be true line.erase(pos); } if(line.size() < 11) { throw hex_parsing_error(lineno, "line is too short"); } if(line[0] != ':') { throw hex_parsing_error(lineno, "invalid start code (':' expected)"); } if((line.size()-1) % 2 != 0) { throw hex_parsing_error(lineno, "odd number of hex digits"); } // parse line bytes std::vector<uint8_t> bytes((line.size()-1)/2); for(unsigned int i=1; i<line.size(); i+=2) { int d0 = parse_hex_digit(line[i]); int d1 = parse_hex_digit(line[i+1]); if(d0 == -1 || d1 == -1) { throw hex_parsing_error(lineno, "invalid hex digit"); } bytes[(i-1)/2] = (d0 << 4) + d1; } // check checksum uint8_t checksum = 0; for(unsigned int i=0; i<bytes.size(); i++) { checksum = (checksum + bytes[i]) & 0xff; } if(checksum != 0) { throw hex_parsing_error(lineno, "checksum mismatch"); } // check byte count unsigned int byte_count = bytes[0]; if(byte_count != bytes.size()-5) { throw hex_parsing_error(lineno, "invalid byte count"); } uint16_t address = (bytes[1] << 8) + bytes[2]; switch(bytes[3]) { case 0: { // data uint32_t data_addr = address | ex_addr_mask; if(data_addr >= 0x800000) { break; // RAM data, ignore } const std::vector<uint8_t> chunk_data(bytes.begin() + 4, bytes.begin() + 4 + byte_count); chunks.push_back({data_addr, std::move(chunk_data)}); break; } case 1: // end of file if(byte_count != 0) { throw hex_parsing_error(lineno, "unexpected data in end of file record"); } eof = true; break; case 2: // extended segment address if(byte_count != 2) { throw hex_parsing_error(lineno, "invalid byte count for extended segment address record"); } if(address != 0) { throw hex_parsing_error(lineno, "address must be 0000 for extended segment address record"); } if((bytes[5] & 0xf) != 0) { throw hex_parsing_error(lineno, "extended segment address least-signficant digit must be 0"); } ex_addr_mask &= ~0x000ffff0; ex_addr_mask |= (((uint32_t)bytes[4] << 8) + bytes[5]) << 4; break; case 3: // start segment address record // ignored break; case 4: // extended linear address if(byte_count != 2) { throw hex_parsing_error(lineno, "invalid byte count for extended linear address record"); } if(address != 0) { throw hex_parsing_error(lineno, "address must be 0000 for extended linear address record"); } if((bytes[5] & 0xf) != 0) { throw hex_parsing_error(lineno, "extended linear address least-signficant digit must be 0"); } ex_addr_mask &= 0x0000ffff; ex_addr_mask |= (((uint32_t)bytes[4] << 8) + bytes[5]) << 16; break; case 5: // start linear address record // ignored break; default: throw hex_parsing_error(lineno, "invalid record type"); } } // sort chunks, check for overlaps and merge them if(chunks.empty()) { throw hex_parsing_error(0, "no data"); } std::sort(chunks.begin(), chunks.end(), [](const auto& a, const auto& b) { return a.addr < b.addr; }); uint32_t total_size = chunks.back().addr_end(); // align the end if needed if(total_size % 2 == 1) { total_size += 1; } std::vector<uint8_t> ret(total_size, 0xff); uint32_t previous_addr = 0; for(auto const& chunk : chunks) { if(chunk.addr < previous_addr) { throw hex_parsing_error(0, fmt::format("data overlap at {}", chunk.addr)); } std::copy(chunk.data.begin(), chunk.data.end(), ret.begin() + chunk.addr); } return ret; }