int StringCell::compare(const StringCell *other, UnicodeChar (*converter)(UnicodeChar)) const { const std::uint8_t *ourScanPtr = const_cast<StringCell*>(this)->utf8Data(); const std::uint8_t *ourEndPtr = &constUtf8Data()[byteLength()]; const std::uint8_t *theirScanPtr = const_cast<StringCell*>(other)->utf8Data(); const std::uint8_t *theirEndPtr = &other->constUtf8Data()[other->byteLength()]; while(true) { int ourEnd = ourScanPtr == ourEndPtr; int theirEnd = theirScanPtr == theirEndPtr; if (ourEnd || theirEnd) { // One of the strings ended return theirEnd - ourEnd; } const UnicodeChar ourChar = utf8::decodeChar(&ourScanPtr); const UnicodeChar theirChar = utf8::decodeChar(&theirScanPtr); int charCompare = ourChar.compare(theirChar, converter); if (charCompare != 0) { return charCompare; } } return 0; }
SymbolCell* SymbolCell::copy(alloc::Heap &heap) { void *cellPlacement = heap.allocate(); if (dataIsInline()) { auto inlineThis = static_cast<InlineSymbolCell*>(this); auto inlineCopy = new (cellPlacement) InlineSymbolCell( inlineThis->inlineByteLength(), inlineThis->inlineCharLength() ); memcpy(inlineCopy->m_inlineData, constUtf8Data(), inlineThis->inlineByteLength()); return inlineCopy; } else { auto heapThis = static_cast<HeapSymbolCell*>(this); return new (cellPlacement) HeapSymbolCell( heapThis->heapByteArray()->ref(), heapThis->heapByteLength(), heapThis->heapCharLength() ); } }
int StringCell::compare(const StringCell *other) const { ByteLengthType compareBytes = std::min(byteLength(), other->byteLength()); // Bytewise comparisons in UTF-8 sort Unicode code points correctly int result = memcmp(constUtf8Data(), other->constUtf8Data(), compareBytes); if (result != 0) { return result; } else { return byteLength() - other->byteLength(); } }
StringCell *StringCell::toConvertedString(World &world, UnicodeChar (*converter)(UnicodeChar)) { const std::uint8_t *scanPtr = utf8Data(); const std::uint8_t *endPtr = &constUtf8Data()[byteLength()]; StringCellBuilder builder(charLength()); while(scanPtr != endPtr) { const UnicodeChar originalChar = utf8::decodeChar(&scanPtr); const UnicodeChar convertedChar = (*converter)(originalChar); builder << convertedChar; } return builder.result(world); }