// Reads over a boundary and sets start to the position after the end of the // boundary. Returns false if no boundary is found immediately. bool PushOverBoundary(const nsACString& aBoundaryString, nsACString::const_iterator& aStart, nsACString::const_iterator& aEnd) { // We copy the end iterator to keep the original pointing to the real end // of the string. nsACString::const_iterator end(aEnd); const char* beginning = aStart.get(); if (FindInReadable(aBoundaryString, aStart, end)) { // We either should find the body immediately, or after 2 chars with the // 2 chars being '-', everything else is failure. if ((aStart.get() - beginning) == 0) { aStart.advance(aBoundaryString.Length()); return true; } if ((aStart.get() - beginning) == 2) { if (*(--aStart) == '-' && *(--aStart) == '-') { aStart.advance(aBoundaryString.Length() + 2); return true; } } } return false; }
bool FindCharInReadable( char aChar, nsACString::const_iterator& aSearchStart, const nsACString::const_iterator& aSearchEnd ) { int32_t fragmentLength = aSearchEnd.get() - aSearchStart.get(); const char* charFoundAt = nsCharTraits<char>::find(aSearchStart.get(), fragmentLength, aChar); if ( charFoundAt ) { aSearchStart.advance( charFoundAt - aSearchStart.get() ); return true; } aSearchStart.advance(fragmentLength); return false; }
inline PRBool nsSMILParserUtils::ConsumeSubstring(nsACString::const_iterator& aIter, const nsACString::const_iterator& aIterEnd, const char *aSubstring) { size_t substrLen = PL_strlen(aSubstring); typedef nsACString::const_iterator::difference_type diff_type; if (aIterEnd.get() - aIter.get() < static_cast<diff_type>(substrLen)) return PR_FALSE; PRBool result = PR_FALSE; if (PL_strstr(aIter.get(), aSubstring) == aIter.get()) { aIter.advance(substrLen); result = PR_TRUE; } return result; }
inline double nsSMILParserUtils::GetFloat(nsACString::const_iterator& aIter, const nsACString::const_iterator& aIterEnd, nsresult *aErrorCode) { char *end; const char *start = aIter.get(); double value = PR_strtod(start, &end); nsresult rv = NS_OK; if (end == start || end > aIterEnd.get()) { rv = NS_ERROR_FAILURE; } else { aIter.advance(end - start); } if (aErrorCode) { *aErrorCode = rv; } return value; }
// The end of a body is marked by a CRLF followed by the boundary. So the // CRLF is part of the boundary and not the body, but any prior CRLFs are // part of the body. This will position the iterator at the beginning of the // boundary (after the CRLF). bool ParseBody(const nsACString& aBoundaryString, nsACString::const_iterator& aStart, nsACString::const_iterator& aEnd) { const char* beginning = aStart.get(); // Find the boundary marking the end of the body. nsACString::const_iterator end(aEnd); if (!FindInReadable(aBoundaryString, aStart, end)) { return false; } // We found a boundary, strip the just prior CRLF, and consider // everything else the body section. if (aStart.get() - beginning < 2) { // Only the first entry can have a boundary right at the beginning. Even // an empty body will have a CRLF before the boundary. So this is // a failure. return false; } // Check that there is a CRLF right before the boundary. aStart.advance(-2); // Skip optional hyphens. if (*aStart == '-' && *(aStart.get()+1) == '-') { if (aStart.get() - beginning < 2) { return false; } aStart.advance(-2); } if (*aStart != nsCRT::CR || *(aStart.get()+1) != nsCRT::LF) { return false; } nsAutoCString body(beginning, aStart.get() - beginning); // Restore iterator to after the \r\n as we promised. // We do not need to handle the extra hyphens case since our boundary // parser in PushOverBoundary() aStart.advance(2); if (!mFormData) { mFormData = new nsFormData(); } NS_ConvertUTF8toUTF16 name(mName); if (mFilename.IsVoid()) { mFormData->Append(name, NS_ConvertUTF8toUTF16(body)); } else { // Unfortunately we've to copy the data first since all our strings are // going to free it. We also need fallible alloc, so we can't just use // ToNewCString(). char* copy = static_cast<char*>(moz_xmalloc(body.Length())); if (!copy) { NS_WARNING("Failed to copy File entry body."); return false; } nsCString::const_iterator bodyIter, bodyEnd; body.BeginReading(bodyIter); body.EndReading(bodyEnd); char *p = copy; while (bodyIter != bodyEnd) { *p++ = *bodyIter++; } p = nullptr; nsRefPtr<Blob> file = File::CreateMemoryFile(mParentObject, reinterpret_cast<void *>(copy), body.Length(), NS_ConvertUTF8toUTF16(mFilename), NS_ConvertUTF8toUTF16(mContentType), /* aLastModifiedDate */ 0); Optional<nsAString> dummy; mFormData->Append(name, *file, dummy); } return true; }