private static unsafe void ParseAttributes(char* pFirstSymbol, char* p, char* pEnd, TokenList tokens) { // avoid the end of self-closing tags if (*(pEnd - 1) == '/') --pEnd; while (p != pEnd) { // skip whitespace while (p != pEnd && (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')) ++p; if (p != pEnd) { char* attrNameStart = p; long namePrefixLength = 0; // read until "=" while (*p != '=') { if (*p == ':' && namePrefixLength == 0) namePrefixLength = (p - attrNameStart); ++p; } long attrNameLength = p - attrNameStart; // find quote while (*p != '"' && *p != '\'') ++p; char quote = *p; ++p; char* attrValStart = p; // find matching quote while (*p != quote) ++p; long attrValLength = p - attrValStart; tokens.AddAttr(attrNameStart - pFirstSymbol, attrNameLength, namePrefixLength, attrValStart - attrNameStart, attrValLength); ++p; } } }