// RFC3501: astring = 1*ASTRING-CHAR / string // string = quoted / literal // This function leaves us off with fCurrentTokenPlaceHolder immediately after // the end of the Astring. Call AdvanceToNextToken() to get the token after it. char *nsIMAPGenericParser::CreateAstring() { if (*fNextToken == '{') return CreateLiteral(); // literal else if (*fNextToken == '"') return CreateQuoted(); // quoted else return CreateAtom(true); // atom }
// Create a string, which can either be quoted or literal, // but not an atom. // This function leaves us off with fCurrentTokenPlaceHolder immediately after // the end of the String. Call AdvanceToNextToken() to get the token after it. char *nsIMAPGenericParser::CreateString() { if (*fNextToken == '{') { char *rv = CreateLiteral(); // literal return (rv); } else if (*fNextToken == '"') { char *rv = CreateQuoted(); // quoted return (rv); } else { SetSyntaxError(true, "string does not start with '{' or '\"'"); return NULL; } }
void TokinizeAttribute (SBody *p_psoBody, std::basic_string<unsigned char> &p_strBin, SDoc &p_soDoc) { static u_int8 ui8CodePage = 0; SBody *psoBody; STokenInd soTokenInd; std::map<STokenInd, std::map<u_int8, u_int8>>::iterator iterTokenizer; std::map<u_int8, u_int8>::iterator iterToken; SWBXMLToken soToken = { 0 }; psoBody = p_psoBody; while (psoBody) { /* инициализируем структуру для поиска токена */ soTokenInd.m_strType = psoBody->m_strType; soTokenInd.m_strName = psoBody->m_strName; soTokenInd.m_strValue = psoBody->m_strValue; /* запрашиваем нобходимый токен */ iterTokenizer = g_mapTokenizer.find (soTokenInd); /* если токен не найден */ if (iterTokenizer == g_mapTokenizer.end () && soTokenInd.m_strValue.length ()) { soTokenInd.m_strValue = ""; /* ищем токен повторно для пустого значения */ iterTokenizer = g_mapTokenizer.find (soTokenInd); } /* если токен так и не найден */ if (iterTokenizer == g_mapTokenizer.end ()) { /* LITERAL */ soToken.m_uiToken = 0x04; p_strBin.append (&soToken.m_ui8Value, sizeof (soToken)); /* определяем индекс литерала */ std::basic_string<mb_u_int32> strInd; CreateLiteral (p_psoBody, p_soDoc, strInd); for (unsigned int i = 0; i < strInd.length (); i++) p_strBin.append (&(strInd[i].m_uiValue), 1); } else { /* формируем токен */ iterToken = iterTokenizer->second.find (ui8CodePage); /* если значение, соответствующее текущей кодовой странице, найдено */ if (iterToken == iterTokenizer->second.end ()) { iterToken = iterTokenizer->second.begin (); ui8CodePage = iterToken->first; p_strBin.append ((unsigned char*)"\x00", 1); p_strBin.append ((unsigned char*)&(iterToken->first), 1); } soToken.m_ui8Value = iterToken->second; /* формируем токен */ p_strBin.append (&soToken.m_ui8Value, sizeof (soToken)); } /* если значение не токенизировано */ if (psoBody->m_strValue.length () && 0 == soTokenInd.m_strValue.length ()) { /* ищем токенизированное значение */ soTokenInd.m_strType = "value"; soTokenInd.m_strName = psoBody->m_strValue; soTokenInd.m_strValue = ""; iterTokenizer = g_mapTokenizer.find (soTokenInd); /* если подходящий токен не найден */ if (iterTokenizer == g_mapTokenizer.end ()) { p_strBin.append ((unsigned char*)"\x03", 1); p_strBin.append ((unsigned char*)psoBody->m_strValue.c_str (), psoBody->m_strValue.length () + 1); } else { iterToken = iterTokenizer->second.find (ui8CodePage); if (iterToken == iterTokenizer->second.end ()) { iterToken = iterTokenizer->second.begin (); ui8CodePage = iterToken->first; p_strBin.append ((unsigned char*)"\x00", 1); p_strBin.append ((unsigned char*)&(iterToken->first), 1); } soToken.m_ui8Value = iterToken->second; p_strBin.append (&soToken.m_ui8Value, 1); } } psoBody = psoBody->m_psoNext; } }
// Call this to create a buffer containing all characters within // a given set of parentheses. // Call this with fNextToken[0]=='(', that is, the open paren // of the group. // It will allocate and return all characters up to and including the corresponding // closing paren, and leave the parser in the right place afterwards. char *nsIMAPGenericParser::CreateParenGroup() { NS_ASSERTION(fNextToken[0] == '(', "we don't have a paren group!"); int numOpenParens = 0; AdvanceTokenizerStartingPoint(fNextToken - fLineOfTokens); // Build up a buffer containing the paren group. nsCString returnString; char *parenGroupStart = fCurrentTokenPlaceHolder; NS_ASSERTION(parenGroupStart[0] == '(', "we don't have a paren group (2)!"); while (*fCurrentTokenPlaceHolder) { if (*fCurrentTokenPlaceHolder == '{') // literal { // Ensure it is a properly formatted literal. NS_ASSERTION(!strcmp("}\r\n", fCurrentTokenPlaceHolder + strlen(fCurrentTokenPlaceHolder) - 3), "not a literal"); // Append previous characters and the "{xx}\r\n" to buffer. returnString.Append(parenGroupStart); // Append literal itself. AdvanceToNextToken(); if (!ContinueParse()) break; char *lit = CreateLiteral(); NS_ASSERTION(lit, "syntax error or out of memory"); if (!lit) break; returnString.Append(lit); PR_Free(lit); if (!ContinueParse()) break; parenGroupStart = fCurrentTokenPlaceHolder; } else if (*fCurrentTokenPlaceHolder == '"') // quoted { // Append the _escaped_ version of the quoted string: // just skip it (because the quoted string must be on the same line). AdvanceToNextToken(); if (!ContinueParse()) break; char *q = CreateQuoted(); if (!q) break; PR_Free(q); if (!ContinueParse()) break; } else { // Append this character to the buffer. char c = *fCurrentTokenPlaceHolder++; if (c == '(') numOpenParens++; else if (c == ')') { numOpenParens--; if (numOpenParens == 0) break; } } } if (numOpenParens != 0 || !ContinueParse()) { SetSyntaxError(true, "closing ')' not found in paren group"); return nsnull; } returnString.Append(parenGroupStart, fCurrentTokenPlaceHolder - parenGroupStart); AdvanceToNextToken(); return ToNewCString(returnString); }