Example #1
0
static KeyValueMap retrieveKeyValuePairs(WebCore::SharedBufferChunkReader* buffer)
{
    KeyValueMap keyValuePairs;
    String line;
    String key;
    StringBuilder value;
    while (!(line = buffer->nextChunkAsUTF8StringWithLatin1Fallback()).isNull()) {
        if (line.isEmpty())
            break; // Empty line means end of key/value section.
        if (line[0] == '\t') {
            ASSERT(!key.isEmpty());
            value.append(line.substring(1));
            continue;
        }
        // New key/value, store the previous one if any.
        if (!key.isEmpty()) {
            if (keyValuePairs.find(key) != keyValuePairs.end())
                LOG_ERROR("Key duplicate found in MIME header. Key is '%s', previous value replaced.", key.ascii().data());
            keyValuePairs.add(key, value.toString().stripWhiteSpace());
            key = String();
            value.clear();
        }
        size_t semiColonIndex = line.find(':');
        if (semiColonIndex == notFound) {
            // This is not a key value pair, ignore.
            continue;
        }
        key = line.substring(0, semiColonIndex).lower().stripWhiteSpace();
        value.append(line.substring(semiColonIndex + 1));
    }
    // Store the last property if there is one.
    if (!key.isEmpty())
        keyValuePairs.set(key, value.toString().stripWhiteSpace());
    return keyValuePairs;
}
Example #2
0
static void commitLiteralToken(StringBuilder& literalBuffer,
                               StringBuilder& converted) {
  if (literalBuffer.length() <= 0)
    return;
  DateTimeFormat::quoteAndappend(literalBuffer.toString(), converted);
  literalBuffer.clear();
}
TEST_F(SecurityOriginTest, SuboriginsParsing)
{
    RuntimeEnabledFeatures::setSuboriginsEnabled(true);
    String host, realHost, suborigin;
    host = "test.com";
    EXPECT_FALSE(SecurityOrigin::deserializeSuboriginAndHost(host, suborigin, realHost));

    host = "foobar_test.com";
    EXPECT_TRUE(SecurityOrigin::deserializeSuboriginAndHost(host, suborigin, realHost));
    EXPECT_EQ("test.com", realHost);
    EXPECT_EQ("foobar", suborigin);

    RefPtr<SecurityOrigin> origin;
    StringBuilder builder;

    origin = SecurityOrigin::createFromString("https://foobar_test.com");
    origin->buildRawString(builder);
    EXPECT_EQ("https://foobar_test.com", builder.toString());

    builder.clear();
    origin = SecurityOrigin::createFromString("https://test.com");
    origin->addSuborigin("foobar");
    origin->buildRawString(builder);
    EXPECT_EQ("https://foobar_test.com", builder.toString());
}
Example #4
0
String WTFLoggingAccumulator::getAndResetAccumulatedLogs()
{
    Locker<Lock> locker(accumulatorLock);
    String result = loggingAccumulator.toString();
    loggingAccumulator.clear();
    return result;
}
Example #5
0
TEST(StringBuilderTest, Clear)
{
    StringBuilder builder;
    builder.append("0123456789");
    builder.clear();
    expectEmpty(builder);
}
Example #6
0
static void commitLiteralToken(StringBuilder& literalBuffer, Vector<DateFormatToken>& tokens)
{
    if (literalBuffer.length() <= 0)
        return;
    tokens.append(DateFormatToken(literalBuffer.toString()));
    literalBuffer.clear();
}
Example #7
0
 void XmlContext::flush() {
     if (text.length() > 0) {
         exprs.addAtEnd(ALLOC(LiteralString, (text.str(), text_start)));
         /*
         char buf[500];
         getn(buf, text.str(), 500);
         puts(buf);
          */
         text.clear();
     }
 }
Example #8
0
TEST_F(SecurityOriginTest, SuboriginsParsing) {
  RuntimeEnabledFeatures::setSuboriginsEnabled(true);
  String protocol, realProtocol, host, realHost, suborigin;
  protocol = "https";
  host = "test.com";
  EXPECT_FALSE(SecurityOrigin::deserializeSuboriginAndProtocolAndHost(
      protocol, host, suborigin, realProtocol, realHost));

  protocol = "https-so";
  host = "foobar.test.com";
  EXPECT_TRUE(SecurityOrigin::deserializeSuboriginAndProtocolAndHost(
      protocol, host, suborigin, realProtocol, realHost));
  EXPECT_EQ("https", realProtocol);
  EXPECT_EQ("test.com", realHost);
  EXPECT_EQ("foobar", suborigin);

  RefPtr<SecurityOrigin> origin;
  StringBuilder builder;

  origin = SecurityOrigin::createFromString("https-so://foobar.test.com");
  origin->buildRawString(builder, true);
  EXPECT_EQ("https-so://foobar.test.com", builder.toString());
  EXPECT_EQ("https-so://foobar.test.com", origin->toString());
  builder.clear();
  origin->buildRawString(builder, false);
  EXPECT_EQ("https://test.com", builder.toString());
  EXPECT_EQ("https://test.com", origin->toPhysicalOriginString());

  Suborigin suboriginObj;
  suboriginObj.setName("foobar");
  builder.clear();
  origin = SecurityOrigin::createFromString("https://test.com");
  origin->addSuborigin(suboriginObj);
  origin->buildRawString(builder, true);
  EXPECT_EQ("https-so://foobar.test.com", builder.toString());
  EXPECT_EQ("https-so://foobar.test.com", origin->toString());
  builder.clear();
  origin->buildRawString(builder, false);
  EXPECT_EQ("https://test.com", builder.toString());
  EXPECT_EQ("https://test.com", origin->toPhysicalOriginString());
}
Example #9
0
 static bool consumeNamedEntity(SegmentedString& source, StringBuilder& decodedEntity, bool& notEnoughCharacters, UChar additionalAllowedCharacter, UChar& cc)
 {
     StringBuilder consumedCharacters;
     HTMLEntitySearch entitySearch;
     while (!source.isEmpty()) {
         cc = source.currentChar();
         entitySearch.advance(cc);
         if (!entitySearch.isEntityPrefix())
             break;
         consumedCharacters.append(cc);
         source.advance();
     }
     notEnoughCharacters = source.isEmpty();
     if (notEnoughCharacters) {
         // We can't an entity because there might be a longer entity
         // that we could match if we had more data.
         unconsumeCharacters(source, consumedCharacters);
         return false;
     }
     if (!entitySearch.mostRecentMatch()) {
         unconsumeCharacters(source, consumedCharacters);
         return false;
     }
     if (entitySearch.mostRecentMatch()->length != entitySearch.currentLength()) {
         // We've consumed too many characters. We need to walk the
         // source back to the point at which we had consumed an
         // actual entity.
         unconsumeCharacters(source, consumedCharacters);
         consumedCharacters.clear();
         const int length = entitySearch.mostRecentMatch()->length;
         const LChar* reference = entitySearch.mostRecentMatch()->entity;
         for (int i = 0; i < length; ++i) {
             cc = source.currentChar();
             ASSERT_UNUSED(reference, cc == *reference++);
             consumedCharacters.append(cc);
             source.advance();
             ASSERT(!source.isEmpty());
         }
         cc = source.currentChar();
     }
     if (entitySearch.mostRecentMatch()->lastCharacter() == ';'
         || !additionalAllowedCharacter
         || !(isASCIIAlphanumeric(cc) || cc == '=')) {
         decodedEntity.append(entitySearch.mostRecentMatch()->firstValue);
         if (entitySearch.mostRecentMatch()->secondValue)
             decodedEntity.append(entitySearch.mostRecentMatch()->secondValue);
         return true;
     }
     unconsumeCharacters(source, consumedCharacters);
     return false;
 }
void MarkupAccumulator::generateUniquePrefix(QualifiedName& prefixedName, const Namespaces& namespaces)
{
    // http://www.w3.org/TR/DOM-Level-3-Core/namespaces-algorithms.html#normalizeDocumentAlgo
    // Find a prefix following the pattern "NS" + index (starting at 1) and make sure this
    // prefix is not declared in the current scope.
    StringBuilder builder;
    do {
        builder.clear();
        builder.append("NS");
        builder.appendNumber(++m_prefixLevel);
        const AtomicString& name = builder.toAtomicString();
        if (!namespaces.get(name.impl())) {
            prefixedName.setPrefix(name);
            return;
        }
    } while (true);
}
TEST(StringBuilderTest, ToAtomicStringOnEmpty)
{
    { // Default constructed.
        StringBuilder builder;
        AtomicString atomicString = builder.toAtomicString();
        EXPECT_EQ(emptyAtom, atomicString);
    }
    { // With capacity.
        StringBuilder builder;
        builder.reserveCapacity(64);
        AtomicString atomicString = builder.toAtomicString();
        EXPECT_EQ(emptyAtom, atomicString);
    }
    { // AtomicString constructed from a null string.
        StringBuilder builder;
        builder.append(String());
        AtomicString atomicString = builder.toAtomicString();
        EXPECT_EQ(emptyAtom, atomicString);
    }
    { // AtomicString constructed from an empty string.
        StringBuilder builder;
        builder.append(emptyString());
        AtomicString atomicString = builder.toAtomicString();
        EXPECT_EQ(emptyAtom, atomicString);
    }
    { // AtomicString constructed from an empty StringBuilder.
        StringBuilder builder;
        StringBuilder emptyBuilder;
        builder.append(emptyBuilder);
        AtomicString atomicString = builder.toAtomicString();
        EXPECT_EQ(emptyAtom, atomicString);
    }
    { // AtomicString constructed from an empty char* string.
        StringBuilder builder;
        builder.append("", 0);
        AtomicString atomicString = builder.toAtomicString();
        EXPECT_EQ(emptyAtom, atomicString);
    }
    { // Cleared StringBuilder.
        StringBuilder builder;
        builder.appendLiteral("WebKit");
        builder.clear();
        AtomicString atomicString = builder.toAtomicString();
        EXPECT_EQ(emptyAtom, atomicString);
    }
}
Example #12
0
void FileReader::convertToDataURL(const Vector<char>& rawData, const String& fileType, StringBuilder& builder)
{
    builder.clear();
    builder.append("data:");

    if (!rawData.size())
        return;

    if (!fileType.isEmpty()) {
        builder.append(fileType);
        builder.append(";base64,");
    } else
        builder.append("base64,");

    Vector<char> out;
    base64Encode(rawData, out);
    out.append('\0');
    builder.append(out.data());
}
Example #13
0
static void fillContainerFromString(ContainerNode* paragraph,
                                    const String& string) {
  Document& document = paragraph->document();

  if (string.isEmpty()) {
    paragraph->appendChild(HTMLBRElement::create(document));
    return;
  }

  DCHECK_EQ(string.find('\n'), kNotFound) << string;

  Vector<String> tabList;
  string.split('\t', true, tabList);
  StringBuilder tabText;
  bool first = true;
  size_t numEntries = tabList.size();
  for (size_t i = 0; i < numEntries; ++i) {
    const String& s = tabList[i];

    // append the non-tab textual part
    if (!s.isEmpty()) {
      if (!tabText.isEmpty()) {
        paragraph->appendChild(
            createTabSpanElement(document, tabText.toString()));
        tabText.clear();
      }
      Text* textNode = document.createTextNode(
          stringWithRebalancedWhitespace(s, first, i + 1 == numEntries));
      paragraph->appendChild(textNode);
    }

    // there is a tab after every entry, except the last entry
    // (if the last character is a tab, the list gets an extra empty entry)
    if (i + 1 != numEntries)
      tabText.append('\t');
    else if (!tabText.isEmpty())
      paragraph->appendChild(
          createTabSpanElement(document, tabText.toString()));

    first = false;
  }
}
/**
* Destructor
*/
STM32F7USB::~STM32F7USB() {
  _accumulator.clear();
}
Example #15
0
void ProcessDiskInfo(wstring apiKey, wstring envKey, SOCKET socketHandle, sockaddr_in remoteServAddr, int interval)
{
    StringBuilder sb;

    int sleepTime = interval * 1000;
    wchar_t driveLetter[_MAX_PATH + 1];
    HRESULT hr;
    ULARGE_INTEGER freeBytesAvailable;
    ULARGE_INTEGER totalNumberOfBytes;
    ULARGE_INTEGER totalNumberOfFreeBytes;
    
    while (true)
    {
        if (g_servicePaused == FALSE)
        {
            sb.clear();

            sb.push_back(L"{");

            sb.push_back(L"\"" + StorageInfo::Members::disk + L"\":");
            sb.push_back(L"[");

            DWORD dwNeedLength = ::GetLogicalDriveStrings(0, NULL);

            wchar_t *pWchBuf = nullptr;
            wchar_t *pHead = nullptr;

            do
            {
                if (dwNeedLength != 0)
                {
                    pWchBuf = new wchar_t[dwNeedLength + 1];
                    if (pWchBuf == nullptr)
                    {
                        break;
                    }

                    pHead = pWchBuf;

                    DWORD dwResult = ::GetLogicalDriveStrings(dwNeedLength, pWchBuf);

                    while (dwResult > 0)
                    {
                        hr = StringCchPrintf(driveLetter, _MAX_PATH, L"%s", pWchBuf);
                        if (FAILED(hr) == TRUE)
                        {
                            break;
                        }

                        int length = wcslen(driveLetter) + 1;
                        if (length < 2)
                        {
                            break;
                        }

                        dwResult -= length;
                        pWchBuf += length;

                        if (::GetDiskFreeSpaceEx(driveLetter, &freeBytesAvailable, &totalNumberOfBytes, &totalNumberOfFreeBytes) == FALSE)
                        {
                            break;
                        }

                        driveLetter[1] = '\0';

                        sb.push_back(L"{ \"" + DiskInfo::Members::name + L"\": \"");
                        sb.push_back(driveLetter);
                        sb.push_back(L"\", ");

                        sb.push_back(L"\"" + DiskInfo::Members::size + L"\": ");
                        sb.push_back((__int64)totalNumberOfBytes.QuadPart);
                        sb.push_back(L", ");

                        sb.push_back(L"\"" + DiskInfo::Members::current + L"\": ");
                        sb.push_back((__int64)(totalNumberOfBytes.QuadPart - totalNumberOfFreeBytes.QuadPart));
                        sb.push_back(L"}");

                        if (dwResult > 0)
                        {
                            sb.push_back(L",");
                        }
                    }
                }
            } while (false);

            if (pHead != nullptr)
            {
                delete[] pHead;
            }

            sb.push_back(L"],");

            sb.push_back(L"\"" + PacketBase::Members::groupKey + L"\":");
            sb.push_back(L"\"");
            sb.push_back(apiKey);
            sb.push_back(L"\",");

            sb.push_back(L"\"" + PacketBase::Members::machineId + L"\":");
            sb.push_back(L"\"");
            sb.push_back(envKey);
            sb.push_back(L"\"");

            sb.push_back(L"}");
        }

#if defined(_DEBUG)
        // ::OutputDebugString(sb.ToString().c_str());
#endif

        SendToServer(socketHandle, remoteServAddr, sb);

        if (g_isConsoleApp == TRUE)
        {
            printf(":");
        }

        DWORD dwEventResult = ::WaitForSingleObject(g_killServiceEvent, sleepTime);
        if (dwEventResult == WAIT_TIMEOUT)
        {
            continue;
        }

#if defined(_DEBUG)
        ::OutputDebugString(L"ProcessDiskInfo-thread exited.");
#endif
        break;
    }
}
Example #16
0
void ProcessCpuMemInfo(wstring apiKey, wstring envKey, SOCKET socketHandle, sockaddr_in remoteServAddr, int interval)
{
    StringBuilder sb;
    int sleepTime = interval * 1000;

    while (true)
    {
        if (g_servicePaused == FALSE)
        {
            sb.clear();

            sb.push_back(L"{");
            {
                sb.push_back(L"\"" + SystemInfo::Members::cpuUsage + L"\":");
                sb.push_back(L"{");
                {
                    float totalUsage = 0.0f;
                    sb.push_back(L"\"" + CpuInfo::Members::unit + L"\":[");
                    if (RetrieveCpuInfo(sb, &totalUsage) == false)
                    {
                        Sleep(1000);
                        continue;
                    }

                    sb.push_back(L"]");

                    wchar_t buf[40];
                    StringCchPrintf(buf, 40, L", \"%s\": %.2f", CpuInfo::Members::total.c_str(), totalUsage / 100);
                    sb.push_back(buf);
                }
                sb.push_back(L"},");

                __int64 maxMemory;
                __int64 currentUsage;
                GetMemoryInfo(&maxMemory, &currentUsage);

                sb.push_back(L"\"" + SystemInfo::Members::memoryUsage + L"\":");
                {
                    sb.push_back(L"{\"" + MemoryInfo::Members::max + L"\":");
                    sb.push_back(maxMemory);

                    sb.push_back(L", \"" + MemoryInfo::Members::current + L"\":");
                    sb.push_back(currentUsage);
                    sb.push_back(L"},");
                }

                sb.push_back(L"\"" + PacketBase::Members::groupKey + L"\":");
                sb.push_back(L"\"");
                sb.push_back(apiKey);
                sb.push_back(L"\",");

                sb.push_back(L"\"" + PacketBase::Members::machineId + L"\":");
                sb.push_back(L"\"");
                sb.push_back(envKey);
                sb.push_back(L"\"");
            }

            sb.push_back(L"}");

            SendToServer(socketHandle, remoteServAddr, sb);

            if (g_isConsoleApp == TRUE)
            {
                printf(".");
            }
        }

        if (::WaitForSingleObject(g_killServiceEvent, sleepTime) == WAIT_TIMEOUT)
        {
            continue;
        }

#if defined(_DEBUG)
        ::OutputDebugString(L"ProcessCpuMemInfo-thread exited.");
#endif

        break;
    }
}
Example #17
0
void WTFLoggingAccumulator::resetAccumulatedLogs()
{
    Locker<Lock> locker(accumulatorLock);
    loggingAccumulator.clear();
}
Example #18
0
bool DateTimeFormat::parse(const String& source, TokenHandler& tokenHandler)
{
    enum State {
        StateInQuote,
        StateInQuoteQuote,
        StateLiteral,
        StateQuote,
        StateSymbol,
    } state = StateLiteral;

    FieldType fieldType = FieldTypeLiteral;
    StringBuilder literalBuffer;
    int fieldCounter = 0;

    for (unsigned index = 0; index < source.length(); ++index) {
        const UChar ch = source[index];
        switch (state) {
        case StateInQuote:
            if (ch == '\'') {
                state = StateInQuoteQuote;
                break;
            }

            literalBuffer.append(ch);
            break;

        case StateInQuoteQuote:
            if (ch == '\'') {
                literalBuffer.append('\'');
                state = StateInQuote;
                break;
            }

            fieldType = mapCharacterToFieldType(ch);
            if (fieldType == FieldTypeInvalid)
                return false;

            if (fieldType == FieldTypeLiteral) {
                literalBuffer.append(ch);
                state = StateLiteral;
                break;
            }

            if (literalBuffer.length()) {
                tokenHandler.visitLiteral(literalBuffer.toString());
                literalBuffer.clear();
            }

            fieldCounter = 1;
            state = StateSymbol;
            break;

        case StateLiteral:
            if (ch == '\'') {
                state = StateQuote;
                break;
            }

            fieldType = mapCharacterToFieldType(ch);
            if (fieldType == FieldTypeInvalid)
                return false;

            if (fieldType == FieldTypeLiteral) {
                literalBuffer.append(ch);
                break;
            }

            if (literalBuffer.length()) {
                tokenHandler.visitLiteral(literalBuffer.toString());
                literalBuffer.clear();
            }

            fieldCounter = 1;
            state = StateSymbol;
            break;

        case StateQuote:
            literalBuffer.append(ch);
            state = ch == '\'' ? StateLiteral : StateInQuote;
            break;

        case StateSymbol: {
            ASSERT(fieldType != FieldTypeInvalid);
            ASSERT(fieldType != FieldTypeLiteral);
            ASSERT(literalBuffer.isEmpty());

            FieldType fieldType2 = mapCharacterToFieldType(ch);
            if (fieldType2 == FieldTypeInvalid)
                return false;

            if (fieldType == fieldType2) {
                ++fieldCounter;
                break;
            }

            tokenHandler.visitField(fieldType, fieldCounter);

            if (fieldType2 == FieldTypeLiteral) {
                if (ch == '\'') {
                    state = StateQuote;
                } else {
                    literalBuffer.append(ch);
                    state = StateLiteral;
                }
                break;
            }

            fieldCounter = 1;
            fieldType = fieldType2;
            break;
        }
        }
    }

    ASSERT(fieldType != FieldTypeInvalid);

    switch (state) {
    case StateLiteral:
    case StateInQuoteQuote:
        if (literalBuffer.length())
            tokenHandler.visitLiteral(literalBuffer.toString());
        return true;

    case StateQuote:
    case StateInQuote:
        if (literalBuffer.length())
            tokenHandler.visitLiteral(literalBuffer.toString());
        return false;

    case StateSymbol:
        ASSERT(fieldType != FieldTypeLiteral);
        ASSERT(!literalBuffer.length());
        tokenHandler.visitField(fieldType, fieldCounter);
        return true;
    }

    ASSERT_NOT_REACHED();
    return false;
}
Example #19
0
PassRefPtr<SharedBuffer> MHTMLArchive::generateMHTMLData(Page* page, bool useBinaryEncoding)
{
    Vector<PageSerializer::Resource> resources;
    PageSerializer pageSerializer(&resources);
    pageSerializer.serialize(page);

    String boundary = generateRandomBoundary();
    String endOfResourceBoundary = makeString("--", boundary, "\r\n");

    tm localTM;
    getCurrentLocalTime(&localTM);
    String dateString = makeRFC2822DateString(localTM.tm_wday, localTM.tm_mday, localTM.tm_mon, 1900 + localTM.tm_year, localTM.tm_hour, localTM.tm_min, localTM.tm_sec, calculateUTCOffset() / (1000 * 60));

    StringBuilder stringBuilder;
    stringBuilder.append("From: <Saved by WebKit>\r\n");
    stringBuilder.append("Subject: ");
    // We replace non ASCII characters with '?' characters to match IE's behavior.
    stringBuilder.append(replaceNonPrintableCharacters(page->mainFrame()->document()->title()));
    stringBuilder.append("\r\nDate: ");
    stringBuilder.append(dateString);
    stringBuilder.append("\r\nMIME-Version: 1.0\r\n");
    stringBuilder.append("Content-Type: multipart/related;\r\n");
    stringBuilder.append("\ttype=\"");
    stringBuilder.append(page->mainFrame()->document()->suggestedMIMEType());
    stringBuilder.append("\";\r\n");
    stringBuilder.append("\tboundary=\"");
    stringBuilder.append(boundary);
    stringBuilder.append("\"\r\n\r\n");

    // We use utf8() below instead of ascii() as ascii() replaces CRLFs with ?? (we still only have put ASCII characters in it).
    ASSERT(stringBuilder.toString().containsOnlyASCII());
    CString asciiString = stringBuilder.toString().utf8();
    RefPtr<SharedBuffer> mhtmlData = SharedBuffer::create();
    mhtmlData->append(asciiString.data(), asciiString.length());

    for (size_t i = 0; i < resources.size(); ++i) {
        const PageSerializer::Resource& resource = resources[i];

        stringBuilder.clear();
        stringBuilder.append(endOfResourceBoundary);
        stringBuilder.append("Content-Type: ");
        stringBuilder.append(resource.mimeType);

        const char* contentEncoding = 0;
        if (useBinaryEncoding)
            contentEncoding = binary;
        else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(resource.mimeType) || MIMETypeRegistry::isSupportedNonImageMIMEType(resource.mimeType))
            contentEncoding = quotedPrintable;
        else
            contentEncoding = base64;

        stringBuilder.append("\r\nContent-Transfer-Encoding: ");
        stringBuilder.append(contentEncoding);
        stringBuilder.append("\r\nContent-Location: ");
        stringBuilder.append(resource.url);
        stringBuilder.append("\r\n\r\n");

        asciiString = stringBuilder.toString().utf8();
        mhtmlData->append(asciiString.data(), asciiString.length());

        if (!strcmp(contentEncoding, binary)) {
            const char* data;
            size_t position = 0;
            while (size_t length = resource.data->getSomeData(data, position)) {
                mhtmlData->append(data, length);
                position += length;
            }
        } else {
            // FIXME: ideally we would encode the content as a stream without having to fetch it all.
            const char* data = resource.data->data();
            size_t dataLength = resource.data->size();
            Vector<char> encodedData;
            if (!strcmp(contentEncoding, quotedPrintable)) {
                quotedPrintableEncode(data, dataLength, encodedData);
                mhtmlData->append(encodedData.data(), encodedData.size());
                mhtmlData->append("\r\n", 2);
            } else {
                ASSERT(!strcmp(contentEncoding, base64));
                // We are not specifying insertLFs = true below as it would cut the lines with LFs and MHTML requires CRLFs.
                base64Encode(data, dataLength, encodedData);
                const size_t maximumLineLength = 76;
                size_t index = 0;
                size_t encodedDataLength = encodedData.size();
                do {
                    size_t lineLength = std::min(encodedDataLength - index, maximumLineLength);
                    mhtmlData->append(encodedData.data() + index, lineLength);
                    mhtmlData->append("\r\n", 2);
                    index += maximumLineLength;
                } while (index < encodedDataLength);
            }
        }
    }

    asciiString = makeString("--", boundary, "--\r\n").utf8();
    mhtmlData->append(asciiString.data(), asciiString.length());

    return mhtmlData.release();
}
Example #20
0
	void RotLibConvert_Dunbrack_BBDep::readLib( const std::string& _LibraryFilename, RotamerLibrary& _RotLib )
	{
		StringBuilder sb;
		std::ifstream* p_torsionFile;
		try
		{
			if( _RotLib.isFinalised() ) 
				throw ProcedureException("readLib() is not allowed, the rotamer library has been finalised, no further import can occur");

			// Mappings for things like HIS -> HIE HID HIP
			_RotLib.addIonisationAliasWorkingDefaults();

			// Make sure Alanine and Glycine are defined non-rotamer residues (the library itself ignores them)
			_RotLib.addAsBlankRotamer("ALA");
			_RotLib.addAsBlankRotamer("GLY");

			p_torsionFile = new std::ifstream(_LibraryFilename.c_str(), std::ifstream::in);
			std::ifstream& torsionFile = *p_torsionFile;
			if( !torsionFile.is_open() ) 
				throw(IOException( "Dunbrack BB-independent torsional definition file not found: '" + _LibraryFilename + "'!" ));
		
			ParseData pd;
			ContainerType data; 
	
			StringBuilder prevResName(3);
			StringBuilder currResName(4);
			StringBuilder cacheLine;

			while( true )
			{
				if( cacheLine.size() > 0 )
				{
					sb.setTo(cacheLine);
					cacheLine.clear();
				}
				else if( !(sb << torsionFile) )
				{
					break;
				}

				sb.Trim();
				if( sb.size() == 0 ) 
					continue; // blank line

				currResName.setTo(sb,0,3);

				if( prevResName.size() == 0 )
				{
					prevResName.setTo( currResName );
					ASSERT( pd.parse( sb ), ParseException, "Malformed line");
					data.push_back( pd );
				}
				else if( prevResName.compare( currResName, 0, 3, 0 ) )
				{
					// Woooo - we found one :-D
					ASSERT( pd.parse( sb ), ParseException, "Malformed line");
					data.push_back( pd );
				}
				else
				{					
					if( data.size() > 0 )
					{
						processResData( prevResName.toString(), data, _RotLib, switchImportMode );
						ASSERT( data.size() == 0, CodeException, "CodeFail");
					}
					prevResName.setTo( currResName );
					cacheLine.setTo( sb ); // we havent actually processed the current line! Store it.
				}
			}
			if( data.size() > 0 )
			{
				processResData( prevResName.toString(), data, _RotLib, switchImportMode );
				ASSERT( data.size() == 0, CodeException, "CodeFail");
			}
			
			// Ensure file-handle cleanup
			p_torsionFile->close();
			delete p_torsionFile;
		}
		catch( ExceptionBase ex )
		{
			// Ensure file-handle cleanup
			p_torsionFile->close();
			delete p_torsionFile;
			throw ex;
		}
	}
Example #21
0
void predict(Options::PredictEnum mode, ReportWriter *writer, const RomAccessor &rom, Trace &trace, const AnnotationResolver &annotations) {

	if (mode == Options::PRD_NEVER)
		return;

	bool limit_to_functions = mode == Options::PRD_FUNCTIONS;

	Profile profile("Predict", true);

	struct PredictBranch {
		const Annotation *annotation;
		Pointer from_pc;
		Pointer pc;
		uint16_t DP, P;
		uint8_t DB;
	};

	std::vector<PredictBranch> predict_brances;
	LargeBitfield has_op(256*64*1024);
	LargeBitfield inside_op(256 * 64 * 1024);

	for (auto opsit : trace.ops) {
		const Pointer pc = opsit.first;

		const Trace::OpVariantLookup &vl = opsit.second;
		const OpInfo &example = trace.variant(vl, 0);

		const uint8_t* data = rom.evalPtr(pc);
		const uint8_t opcode = data[0];

		uint32_t op_size = instruction_size(opcode, is_memory_accumulator_wide(example.P), is_index_wide(example.P));

		for (uint32_t i = 0; i < op_size; ++i) {
			has_op.set_bit(bank_add(pc, i));
			if (i!=0) inside_op.set_bit(bank_add(pc, i));
		}

		StringBuilder sb;

		Pointer target_jump, target_no_jump;
		bool branch_or_jump = decode_static_jump(opcode, rom, pc, &target_jump, &target_no_jump);

		const Hint *hint = annotations.hint(pc);
		if (hint && hint->has_hint(Hint::BRANCH_ALWAYS)) {
			target_no_jump = INVALID_POINTER;
		}
		if (hint && hint->has_hint(Hint::BRANCH_NEVER)) {
			target_jump = INVALID_POINTER;
		}

		if (!branch_or_jump)
			continue;

		const Annotation *source_annotation = nullptr, *target_annotation = nullptr;
		annotations.resolve_annotation(pc,          &source_annotation);

		if (target_jump != INVALID_POINTER) {
			trace.labels.set_bit(target_jump);
			annotations.resolve_annotation(target_jump, &target_annotation);
		}

		if (source_annotation || !limit_to_functions) {
			PredictBranch p;
			p.annotation = source_annotation;
			p.from_pc = pc;
			p.DB = example.DB;
			p.DP = example.DP;
			p.P  = example.P;
			if (target_jump != INVALID_POINTER && (target_annotation == source_annotation || !limit_to_functions)) {
				p.pc = target_jump;
				CUSTOM_ASSERT(target_jump != INVALID_POINTER);
				predict_brances.push_back(p);
			}
			if (target_no_jump != INVALID_POINTER && (!limit_to_functions || (target_no_jump >= source_annotation->startOfRange && target_no_jump <= source_annotation->endOfRange))) {
				// BRA,BRL and the jumps always branches/jumps
				p.pc = target_no_jump;
				CUSTOM_ASSERT(target_no_jump != INVALID_POINTER);
				predict_brances.push_back(p);
			}
		}
	}

	StringBuilder sb;
	sb.clear();

	if (writer)
		writer->writeSeperator("Prediction diagnostics");

	for (int pbi=0; pbi<(int)predict_brances.size(); ++pbi) {
		const PredictBranch pb = predict_brances[pbi];

		Pointer pc = pb.pc;
		Pointer r0 = limit_to_functions ? pb.annotation->startOfRange : 0, r1 = limit_to_functions ? pb.annotation->endOfRange : 0xFFFFFF;
		uint16_t P = pb.P, DP = pb.DP;
		uint8_t DB = pb.DB;

		bool P_unknown = false;

		if (inside_op[pc]) {
			if (writer) {
				sb.clear();
				sb.format("Predicted jump at %06X jumped inside instruction at %06X. Consider adding a \"hint branch_always/branch_never %06X\" annotation.", pc, pb.from_pc, pb.from_pc);
				writer->writeComment(sb);
			}
			printf("Warning; predicted jump went inside instruction at %06X (from %06X)\n", pc, pb.from_pc);
		}

		while (!has_op[pc] && pc >= r0 && pc <= r1) {

			// Make sure we don't run into a data scope
			const Annotation *data_scope = nullptr, *function_scope = nullptr;
			annotations.resolve_annotation(pc, &function_scope, &data_scope);
			if (data_scope)
				continue;
			if (function_scope && function_scope != pb.annotation)
				continue;

			uint8_t opcode = rom.evalByte(pc);

			bool abort_unknown_P = P_unknown;

			if (P_unknown) {
				switch(opcode) {
				case 0x02: // COP const
				case 0x40: // RTI
				case 0x6B: // RTL
				case 0x60: // RTS
				case 0x3B: // TSC
				case 0xBA: // TSX
				case 0x8A: // TXA
				case 0x9A: // TXS
				case 0x9B: // TXY
				case 0x98: // TYA
				case 0xBB: // TYX
				case 0xCB: // WAI
				case 0xEB: // XBA
				case 0xFB: // XCE
				case 0xAA: // TAX
				case 0xA8: // TAY
				case 0x5B: // TCD
				case 0x1B: // TCS
				case 0x7B: // TDC
				case 0xDB: // STP
				case 0x38: // SEC
				case 0xF8: // SED
				case 0x78: // SEI
				case 0xE2: // SEP
				case 0xC2: // REP
				case 0x18: // CLC
				case 0xD8: // CLD
				case 0x58: // CLI
				case 0xB8: // CLV
				case 0xCA: // DEX
				case 0x88: // DEY
				case 0xE8: // INX
				case 0xC8: // INY
				case 0xEA: // NOP
				case 0x8B: // PHB
				case 0x0B: // PHD
				case 0x4B: // PHK
				case 0x08: // PHP
				case 0xDA: // PHX
				case 0x5A: // PHY
				case 0x68: // PLA
				case 0xAB: // PLB
				case 0x2B: // PLD
				case 0x28: // PLP
				case 0xFA: // PLX
				case 0x7A: // PLY
					abort_unknown_P = false;
				}
			}

			if (abort_unknown_P) {
				if (writer) {
					sb.clear();
					sb.format("Aborting trace at %06X due to unknown processor status", pc);
					if (pb.annotation)
						sb.format("(in %s)", pb.annotation->name.c_str());
					writer->writeComment(sb);
				}
				break;
			}

			uint8_t operand = rom.evalByte(pc + 1);

			Pointer target_jump, target_no_jump;
			bool is_jump_or_branch = decode_static_jump(opcode, rom, pc, &target_jump, &target_no_jump);

			{
				Trace::OpVariantLookup l;
				l.count = 1;
				l.offset = (uint32_t)trace.ops_variants.size();
				trace.ops[pc] = l;
				OpInfo info;
				info.P = P_unknown ? 0 : P;
				info.DB = DB;
				info.DP = DP;
				info.X = info.Y = 0;
				info.jump_target = target_jump;
				info.indirect_base_pointer = INVALID_POINTER; // TODO: We should be able to set this one sometimes
				trace.ops_variants.push_back(info);

				// Note that DB and DP here represent a lie :)
			}

			const int op_size = instruction_size(rom.evalByte(pc), is_memory_accumulator_wide(P), is_index_wide(P));

			for (int i=0; i<op_size; ++i) {
				// TODO: We should do overlap test for entire range we are "using" now
				//       Also first might not always be best!
				trace.is_predicted.set_bit(bank_add(pc, i));
				has_op.set_bit(bank_add(pc, i));
				if (i != 0) inside_op.set_bit(bank_add(pc, i));
			}

			const Hint *hint = annotations.hint(pc);
			if (hint && hint->has_hint(Hint::BRANCH_NEVER)) {
				target_jump = INVALID_POINTER;
			}

			bool is_jsr = opcode == 0x20||opcode==0x22||opcode==0xFC;

			if (hint && hint->has_hint(Hint::JUMP_IS_JSR)) {
				 is_jump_or_branch = false;
				 is_jsr = true;
			}

			if (is_jump_or_branch) {
				const Annotation *function = nullptr;
				if (target_jump != INVALID_POINTER) {
					annotations.resolve_annotation(target_jump, &function);
					trace.labels.set_bit(target_jump);
				}

				if (limit_to_functions && writer && (!function || function != pb.annotation)) {
					sb.clear();
					sb.format("Branch going out of %s to ", pb.annotation->name.c_str());
					if (function) {
						sb.format("%s [%06X]", function->name.c_str(), target_jump);
					} else {
						sb.format("%06X", target_jump);
					}
					sb.format(". Not following due to range restriction.");
					writer->writeComment(sb);
				}
				
				if (target_jump != INVALID_POINTER) {
					PredictBranch npb = pb;
					npb.from_pc = pc;
					npb.pc = target_jump;
					predict_brances.push_back(npb);
				}

				if (hint && hint->has_hint(Hint::BRANCH_ALWAYS)) {
					// Never continoue after this op since it always diverges control flow
					continue;
				}

			} else if (opcode == 0xE2) {
				//	TODO:
				//	* When we get a REP or SEP parts or P become known again. We could track unknown per the three flags and update.
				//	* Updating DB/DP might be interesting
				if (operand & 0x10) P |= 0x0010;
				if (operand & 0x20) P |= 0x0020;
			} else if (opcode == 0xC2) {
				if (operand & 0x10) P &= ~0x0010;
				if (operand & 0x20) P &= ~0x0020;
			} else if (opcode == 0x28 || opcode == 0xFB) {
				P_unknown = true; // PLP or XCE
				// A jump or BRA, stop execution flow (not JSR or non-BRA-branch)
			} else if (opcode == 0x4C||opcode==0x5C||opcode==0x6C||opcode==0x7C||opcode==0x80) {
				if (writer && opcode != 0x80) {
					sb.clear();
					sb.format("Not following jump (opcode %02X) at %06X in %s. Only absolute jumps supported.", opcode, pc, pb.annotation->name.c_str());
					writer->writeComment(sb);
				}
				// TODO: if there is a trace annotation about jmp being jsr we could go on
				continue;
			} else if (is_jsr) {
				if (writer) {
					sb.clear();
					sb.format("Not following jump with subroutine (opcode %02X) at %06X", opcode, pc);
					if (pb.annotation)
						sb.format(" in %s.", pb.annotation->name.c_str());
					writer->writeComment(sb);
				}
			} else if (opcode == 0x40 || opcode == 0x6B || opcode == 0x60) {
				// some sort of return, stop execution flow
				continue;
			}
			pc += op_size;
		}
	}
}