BString BJson::_ParseString(BString& JSON, int32& pos) { if (JSON[pos] != '"') // Verify we're at the start of a string. return BString(""); pos++; BString str; while (JSON[pos] != '"') { if (JSON[pos] == '\\') { pos++; switch (JSON[pos]) { case 'b': str += "\b"; break; case 'f': str += "\f"; break; case 'n': str += "\n"; break; case 'r': str += "\r"; break; case 't': str += "\t"; break; case 'u': // 4-byte hexadecimal Unicode char (e.g. "\uffff") { uint intValue; BString substr; JSON.CopyInto(substr, pos + 1, 4); if (sscanf(substr.String(), "%4x", &intValue) != 1) return str; // We probably hit the end of the string. // This probably should be counted as an error, // but for now let's soft-fail instead of hard-fail. char character[20]; char* ptr = character; BUnicodeChar::ToUTF8(intValue, &ptr); str.AppendChars(character, 1); pos += 4; break; } default: str += JSON[pos]; break; } } else str += JSON[pos]; pos++; } return str; }
void truncate_string(BString& string, uint32 mode, float width, const float* escapementArray, float fontSize, float ellipsisWidth, int32 charCount) { // add a tiny amount to the width to make floating point inaccuracy // not drop chars that would actually fit exactly width += 0.00001; switch (mode) { case B_TRUNCATE_BEGINNING: { float totalWidth = 0; for (int32 i = charCount - 1; i >= 0; i--) { float charWidth = escapementArray[i] * fontSize; if (totalWidth + charWidth > width) { // we need to truncate while (totalWidth + ellipsisWidth > width) { // remove chars until there's enough space for the // ellipsis if (++i == charCount) { // we've reached the end of the string and still // no space, so return an empty string string.Truncate(0); return; } totalWidth -= escapementArray[i] * fontSize; } string.RemoveChars(0, i + 1); string.PrependChars(B_UTF8_ELLIPSIS, 1); return; } totalWidth += charWidth; } break; } case B_TRUNCATE_END: { float totalWidth = 0; for (int32 i = 0; i < charCount; i++) { float charWidth = escapementArray[i] * fontSize; if (totalWidth + charWidth > width) { // we need to truncate while (totalWidth + ellipsisWidth > width) { // remove chars until there's enough space for the // ellipsis if (i-- == 0) { // we've reached the start of the string and still // no space, so return an empty string string.Truncate(0); return; } totalWidth -= escapementArray[i] * fontSize; } string.RemoveChars(i, charCount - i); string.AppendChars(B_UTF8_ELLIPSIS, 1); return; } totalWidth += charWidth; } break; } case B_TRUNCATE_MIDDLE: case B_TRUNCATE_SMART: { float leftWidth = 0; float rightWidth = 0; int32 leftIndex = 0; int32 rightIndex = charCount - 1; bool left = true; for (int32 i = 0; i < charCount; i++) { float charWidth = escapementArray[left ? leftIndex : rightIndex] * fontSize; if (leftWidth + rightWidth + charWidth > width) { // we need to truncate while (leftWidth + rightWidth + ellipsisWidth > width) { // remove chars until there's enough space for the // ellipsis if (leftIndex == 0 && rightIndex == charCount - 1) { // we've reached both ends of the string and still // no space, so return an empty string string.Truncate(0); return; } if (leftIndex > 0 && (rightIndex == charCount - 1 || leftWidth > rightWidth)) { // remove char on the left leftWidth -= escapementArray[--leftIndex] * fontSize; } else { // remove char on the right rightWidth -= escapementArray[++rightIndex] * fontSize; } } string.RemoveChars(leftIndex, rightIndex + 1 - leftIndex); string.InsertChars(B_UTF8_ELLIPSIS, 1, leftIndex); return; } if (left) { leftIndex++; leftWidth += charWidth; } else { rightIndex--; rightWidth += charWidth; } left = rightWidth > leftWidth; } break; } } // we've run through without the need to truncate, leave the string as it is }