static void ParseNotes(StringX &sxNotes, std::vector<StringX> &vsxnotes_lines) { if (!sxNotes.empty()) { // Use \n and \r to tokenise this line StringX::size_type st_start(0), st_end(0); const StringX sxdelim = _T("\r\n"); StringX sxline; StringX::size_type st_index; while (st_end != StringX::npos) { st_end = sxNotes.find(sxdelim, st_start); sxline = (sxNotes.substr(st_start, (st_end == StringX::npos) ? StringX::npos : st_end - st_start)); st_index = 0; // Remove all tabs - \t for (;;) { st_index = sxline.find(_T("\\t"), st_index); if (st_index == StringX::npos) break; sxline.replace(st_index, 2, _T("")); st_index += 1; } vsxnotes_lines.push_back(sxline); st_start = ((st_end > (StringX::npos - sxdelim.size())) ? StringX::npos : st_end + sxdelim.size()); } } }
StringX PWSAuxParse::GetAutoTypeString(const StringX &sx_in_autotype, const StringX &sx_group, const StringX &sx_title, const StringX &sx_user, const StringX &sx_pwd, const StringX &sx_notes, const StringX &sx_url, const StringX &sx_email, std::vector<size_t> &vactionverboffsets) { StringX sxtmp(_T("")); StringX sxNotes(sx_notes); TCHAR curChar; StringX sx_autotype(sx_in_autotype); StringX::size_type st_index; std::vector<StringX> vsxnotes_lines; vactionverboffsets.clear(); // If empty, try the database default if (sx_autotype.empty()) { sx_autotype = PWSprefs::GetInstance()-> GetPref(PWSprefs::DefaultAutotypeString); // If still empty, take this default if (sx_autotype.empty()) { // checking for user and password for default settings if (!sx_pwd.empty()){ if (!sx_user.empty()) sx_autotype = DEFAULT_AUTOTYPE; else sx_autotype = _T("\\p\\n"); } } } // No recursive substitution (e.g. \p or \u), although '\t' will be replaced by a tab if (!sx_notes.empty()) { // Use \n and \r to tokenise this line StringX::size_type st_start(0), st_end(0); const StringX sxdelim = _T("\r\n"); StringX sxline; while (st_end != StringX::npos) { st_end = sxNotes.find_first_of(sxdelim, st_start); sxline = (sxNotes.substr(st_start, (st_end == StringX::npos) ? StringX::npos : st_end - st_start)); st_index = 0; for (;;) { st_index = sxline.find(_T("\\t"), st_index); if (st_index == StringX::npos) break; sxline.replace(st_index, 2, _T("\t")); st_index += 1; } vsxnotes_lines.push_back(sxline); // If we just hit a "\r\n", move past it. Or else, it is a "\r" without // a following "\n" or a "\n", so just move past one single char if (st_end != StringX::npos) { st_start = st_end + (sxNotes.compare(st_end, 2, sxdelim) == 0 ? 2 : 1); if (st_start >= sxNotes.length()) break; } } // Now change '\n' to '\r' in the complete notes field st_index = 0; for (;;) { st_index = sxNotes.find(sxdelim, st_index); if (st_index == StringX::npos) break; sxNotes.replace(st_index, 2, _T("\r")); st_index += 1; } st_index = 0; for (;;) { st_index = sxNotes.find(_T("\\t"), st_index); if (st_index == StringX::npos) break; sxNotes.replace(st_index, 2, _T("\t")); st_index += 1; } } const size_t N = sx_autotype.length(); const StringX sxZeroes = _T("000"); int gNumIts; for (size_t n = 0; n < N; n++){ curChar = sx_autotype[n]; if (curChar == TCHAR('\\')) { n++; if (n < N) curChar = sx_autotype[n]; switch (curChar){ case TCHAR('\\'): sxtmp += TCHAR('\\'); break; case TCHAR('n'): case TCHAR('r'): sxtmp += TCHAR('\r'); break; case TCHAR('t'): sxtmp += TCHAR('\t'); break; case TCHAR('s'): sxtmp += TCHAR('\v'); break; case TCHAR('g'): sxtmp += sx_group; break; case TCHAR('i'): sxtmp += sx_title; break; case TCHAR('u'): sxtmp += sx_user; break; case TCHAR('p'): sxtmp += sx_pwd; break; case TCHAR('l'): sxtmp += sx_url; break; case TCHAR('m'): sxtmp += sx_email; break; case TCHAR('o'): { if (n == (N - 1)) { // This was the last character - send the lot! sxtmp += sxNotes; break; } size_t line_number(0); gNumIts = 0; for (n++; n < N && (gNumIts < 3); ++gNumIts, n++) { if (_istdigit(sx_autotype[n])) { line_number *= 10; line_number += (sx_autotype[n] - TCHAR('0')); } else break; // for loop } if (line_number == 0) { // Send the lot sxtmp += sx_notes; } else if (line_number <= vsxnotes_lines.size()) { // User specifies a too big a line number - ignore the lot sxtmp += vsxnotes_lines[line_number - 1]; } // Backup the extra character that delimited the \oNNN string n--; break; // case 'o' } // Action Verbs: // These are the only ones processed specially by the UI as they involve // actions it performs whilst doing the key sending. // Copy them to output string unchanged. case TCHAR('b'): // backspace! case TCHAR('z'): // Use older method vactionverboffsets.push_back(sxtmp.length()); sxtmp += _T("\\"); sxtmp += curChar; break; // case 'b' & 'z' case TCHAR('d'): // Delay case TCHAR('w'): // Wait milli-seconds case TCHAR('W'): // Wait seconds { // Need to ensure that the field length is 3, even if it wasn't vactionverboffsets.push_back(sxtmp.length()); sxtmp += _T("\\"); sxtmp += curChar; gNumIts = 0; size_t i = n; for (i++; i < N && (gNumIts < 3); ++gNumIts, i++) { if (!_istdigit(sx_autotype[i])) break; } // Insert sufficient zeroes to ensure field is 3 characters long sxtmp += sxZeroes.substr(0, 3 - gNumIts); break; // case 'd', 'w' & 'W' } // Also copy explicit control characters to output string unchanged. case TCHAR('a'): // bell (can't hear it during testing!) case TCHAR('v'): // vertical tab case TCHAR('f'): // form feed case TCHAR('e'): // escape case TCHAR('x'): // hex digits (\xNN) // and any others we have forgotten! // '\cC', '\uXXXX', '\OOO', '\<any other charatcer not recognised above>' default: sxtmp += L'\\'; sxtmp += curChar; break; } } else sxtmp += curChar; } vsxnotes_lines.clear(); return sxtmp; }