Browse Source

Moved out non-core functions from the String type for easier maintenance.

David Piuva 5 years ago
parent
commit
fe47c67848

+ 8 - 8
Source/DFPSR/api/configAPI.cpp

@@ -32,21 +32,21 @@ void dsr::config_parse_ini(const ReadableString& content, ConfigIniCallback rece
 		// Get the current line
 		ReadableString command = lines[l];
 		// Skip comments
-		int commentIndex = command.findFirst(U';');
+		int commentIndex = string_findFirst(command, U';');
 		if (commentIndex > -1) {
-			command = command.before(commentIndex);
+			string_before(command, commentIndex);
 		}
 		// Find assignments
-		int assignmentIndex = command.findFirst(U'=');
+		int assignmentIndex = string_findFirst(command, U'=');
 		if (assignmentIndex > -1) {
-			ReadableString key = string_removeOuterWhiteSpace(command.before(assignmentIndex));
-			ReadableString value = string_removeOuterWhiteSpace(command.after(assignmentIndex));
+			ReadableString key = string_removeOuterWhiteSpace(string_before(command, assignmentIndex));
+			ReadableString value = string_removeOuterWhiteSpace(string_after(command, assignmentIndex));
 			receiverLambda(block, key, value);
 		} else {
-			int blockStartIndex = command.findFirst(U'[');
-			int blockEndIndex = command.findFirst(U']');
+			int blockStartIndex = string_findFirst(command, U'[');
+			int blockEndIndex = string_findFirst(command, U']');
 			if (blockStartIndex > -1 && blockEndIndex > -1) {
-				block = string_removeOuterWhiteSpace(command.inclusiveRange(blockStartIndex + 1, blockEndIndex - 1));
+				block = string_removeOuterWhiteSpace(string_inclusiveRange(command, blockStartIndex + 1, blockEndIndex - 1));
 			}
 		}
 	}

+ 47 - 47
Source/DFPSR/base/text.cpp

@@ -49,48 +49,6 @@ static bool isWhiteSpace(DsrChar c) {
 	return c <= U' ' || c == U'\t' || c == U'\r';
 }
 
-int ReadableString::findFirst(DsrChar toFind, int startIndex) const {
-	for (int i = startIndex; i < this->length(); i++) {
-		if (this->readSection[i] == toFind) {
-			return i;
-		}
-	}
-	return -1;
-}
-
-int ReadableString::findLast(DsrChar toFind) const {
-	for (int i = this->length() - 1; i >= 0; i--) {
-		if (this->readSection[i] == toFind) {
-			return i;
-		}
-	}
-	return -1;
-}
-
-ReadableString ReadableString::exclusiveRange(int inclusiveStart, int exclusiveEnd) const {
-	return this->getRange(inclusiveStart, exclusiveEnd - inclusiveStart);
-}
-
-ReadableString ReadableString::inclusiveRange(int inclusiveStart, int inclusiveEnd) const {
-	return this->getRange(inclusiveStart, inclusiveEnd + 1 - inclusiveStart);
-}
-
-ReadableString ReadableString::before(int exclusiveEnd) const {
-	return this->exclusiveRange(0, exclusiveEnd);
-}
-
-ReadableString ReadableString::until(int inclusiveEnd) const {
-	return this->inclusiveRange(0, inclusiveEnd);
-}
-
-ReadableString ReadableString::from(int inclusiveStart) const {
-	return this->exclusiveRange(inclusiveStart, this->length());
-}
-
-ReadableString ReadableString::after(int exclusiveStart) const {
-	return this->from(exclusiveStart + 1);
-}
-
 String& Printable::toStream(String& target) const {
 	return this->toStreamIndented(target, U"");
 }
@@ -217,7 +175,7 @@ ReadableString dsr::string_removeOuterWhiteSpace(const ReadableString &text) {
 		return ReadableString();
 	} else {
 		// Subset
-		return text.inclusiveRange(first, last);
+		return string_inclusiveRange(text, first, last);
 	}
 }
 
@@ -264,8 +222,8 @@ String dsr::string_mangleQuote(const ReadableString &rawText) {
 }
 
 String dsr::string_unmangleQuote(const ReadableString& mangledText) {
-	int firstQuote = mangledText.findFirst('\"');
-	int lastQuote = mangledText.findLast('\"');
+	int firstQuote = string_findFirst(mangledText, '\"');
+	int lastQuote = string_findLast(mangledText, '\"');
 	String result;
 	if (firstQuote == -1 || lastQuote == -1 || firstQuote == lastQuote) {
 		throwError(U"Cannot unmangle using string_unmangleQuote without beginning and ending with quote signs!\n", mangledText, "\n");
@@ -708,12 +666,12 @@ void dsr::string_split_inPlace(List<ReadableString> &target, const ReadableStrin
 	for (int i = 0; i < source.length(); i++) {
 		DsrChar c = source[i];
 		if (c == separator) {
-			target.push(source.exclusiveRange(sectionStart, i));
+			target.push(string_exclusiveRange(source, sectionStart, i));
 			sectionStart = i + 1;
 		}
 	}
 	if (source.length() > sectionStart) {
-		target.push(source.exclusiveRange(sectionStart, source.length()));;
+		target.push(string_exclusiveRange(source, sectionStart, source.length()));;
 	}
 }
 
@@ -833,3 +791,45 @@ double dsr::string_toDouble(const ReadableString& source) {
 	}
 }
 
+int dsr::string_findFirst(const ReadableString& source, DsrChar toFind, int startIndex) {
+	for (int i = startIndex; i < source.length(); i++) {
+		if (source[i] == toFind) {
+			return i;
+		}
+	}
+	return -1;
+}
+
+int dsr::string_findLast(const ReadableString& source, DsrChar toFind) {
+	for (int i = source.length() - 1; i >= 0; i--) {
+		if (source[i] == toFind) {
+			return i;
+		}
+	}
+	return -1;
+}
+
+ReadableString dsr::string_exclusiveRange(const ReadableString& source, int inclusiveStart, int exclusiveEnd) {
+	return source.getRange(inclusiveStart, exclusiveEnd - inclusiveStart);
+}
+
+ReadableString dsr::string_inclusiveRange(const ReadableString& source, int inclusiveStart, int inclusiveEnd) {
+	return source.getRange(inclusiveStart, inclusiveEnd + 1 - inclusiveStart);
+}
+
+ReadableString dsr::string_before(const ReadableString& source, int exclusiveEnd) {
+	return string_exclusiveRange(source, 0, exclusiveEnd);
+}
+
+ReadableString dsr::string_until(const ReadableString& source, int inclusiveEnd) {
+	return string_inclusiveRange(source, 0, inclusiveEnd);
+}
+
+ReadableString dsr::string_from(const ReadableString& source, int inclusiveStart) {
+	return string_exclusiveRange(source, inclusiveStart, source.length());
+}
+
+ReadableString dsr::string_after(const ReadableString& source, int exclusiveStart) {
+	return string_from(source, exclusiveStart + 1);
+}
+

+ 13 - 21
Source/DFPSR/base/text.h

@@ -62,34 +62,18 @@ protected:
 	bool checkBound(int start, int length, bool warning = true) const;
 	// Internal constructor
 	ReadableString(const DsrChar *content, int sectionLength);
+public:
 	// Create a string from an existing string
 	// When there's no reference counter, it's important that the memory remains allocated until the application terminates
 	// Just like when reading elements in a for loop, out-of-range only causes an exception if length > 0
 	//   Length lesser than 1 will always return an empty string
 	virtual ReadableString getRange(int start, int length) const;
-public:
 	// Converting to unknown character encoding using only the ascii character subset
 	// A bug in GCC linking forces these to be virtual
 	virtual std::ostream& toStream(std::ostream& out) const;
 	virtual std::string toStdString() const;
 public:
-	// Get the index of the first character in content matching toFind, or -1 if it doesn't exist.
-	int findFirst(DsrChar toFind, int startIndex = 0) const;
-	// Get the index of the last character in content matching toFind, or -1 if it doesn't exist.
-	int findLast(DsrChar toFind) const;
-	// Exclusive intervals represent the divisions between characters |⁰ A |¹ B |² C |³...
-	//   0..2 of "ABC" then equals "AB", which has length 2 just like the index difference
-	//   0..3 gets the whole "ABC" range, by starting from zero and ending with the character count
-	ReadableString exclusiveRange(int inclusiveStart, int exclusiveEnd) const;
-	// Inclusive intervals represent whole characters | A⁰ | B¹ | C² |...
-	//   0..2 of "ABC" then equals "ABC", by taking character 0 (A), 1 (B) and 2 (C)
-	ReadableString inclusiveRange(int inclusiveStart, int inclusiveEnd) const;
-	// Simplified ranges
-	ReadableString before(int exclusiveEnd) const;
-	ReadableString until(int inclusiveEnd) const;
-	ReadableString from(int inclusiveStart) const;
-	ReadableString after(int exclusiveStart) const;
-	// Value conversion
+	// TODO: Remove
 	int64_t toInteger() const;
 	double toDouble() const;
 };
@@ -128,13 +112,12 @@ protected:
 	std::shared_ptr<Buffer> buffer;
 	// Same as readSection, but with write access
 	char32_t* writeSection = nullptr;
+	// Internal constructor
+	String(std::shared_ptr<Buffer> buffer, DsrChar *content, int sectionLength);
 public:
 	// The number of DsrChar characters that can be contained in the allocation before reaching the buffer's end
 	//   This doesn't imply that it's always okay to write to the remaining space, because the buffer may be shared
 	int capacity();
-protected:
-	// Internal constructor
-	String(std::shared_ptr<Buffer> buffer, DsrChar *content, int sectionLength);
 	// Create a string from the existing buffer without allocating any heap memory
 	ReadableString getRange(int start, int length) const override;
 private:
@@ -215,6 +198,15 @@ std::ostream& string_toStream(std::ostream& target, const T& source) {
 // ---------------- Procedural API ----------------
 
 
+int string_findFirst(const ReadableString& source, DsrChar toFind, int startIndex = 0);
+int string_findLast(const ReadableString& source, DsrChar toFind);
+ReadableString string_exclusiveRange(const ReadableString& source, int inclusiveStart, int exclusiveEnd);
+ReadableString string_inclusiveRange(const ReadableString& source, int inclusiveStart, int inclusiveEnd);
+ReadableString string_before(const ReadableString& source, int exclusiveEnd);
+ReadableString string_until(const ReadableString& source, int inclusiveEnd);
+ReadableString string_from(const ReadableString& source, int inclusiveStart);
+ReadableString string_after(const ReadableString& source, int exclusiveStart);
+
 // Post-condition:
 //   Returns a list of strings from source by splitting along separator.
 // The separating characters are excluded from the resulting strings.

+ 3 - 3
Source/DFPSR/font/Font.cpp

@@ -160,7 +160,7 @@ void RasterFontImpl::printMultiLine(ImageRgbaU8& target, const ReadableString& c
 		DsrChar code = content[i];
 		if (code == 10) {
 			// Print the completed line
-			this->printLine(target, content.exclusiveRange(rowStartIndex, i), IVector2D(bound.left(), y), color);
+			this->printLine(target, string_exclusiveRange(content, rowStartIndex, i), IVector2D(bound.left(), y), color);
 			y += this->size; if (y + this->size > bound.bottom()) { return; }
 			lineWidth = 0;
 			rowStartIndex = i + 1;
@@ -181,7 +181,7 @@ void RasterFontImpl::printMultiLine(ImageRgbaU8& target, const ReadableString& c
 						// The word is too big to be printed as a whole
 						splitIndex = i;
 					}
-					ReadableString partialLine = content.exclusiveRange(rowStartIndex, splitIndex);
+					ReadableString partialLine = string_exclusiveRange(content, rowStartIndex, splitIndex);
 					int partialLength = this->getLineWidth(partialLine);
 					if (partialLength <= bound.width()) {
 						this->printLine(target, partialLine, IVector2D(bound.left(), y), color);
@@ -205,7 +205,7 @@ void RasterFontImpl::printMultiLine(ImageRgbaU8& target, const ReadableString& c
 			}
 		}
 	}
-	this->printLine(target, content.from(rowStartIndex), IVector2D(bound.left(), y), color);
+	this->printLine(target, string_from(content, rowStartIndex), IVector2D(bound.left(), y), color);
 }
 
 int32_t RasterFontImpl::getLineWidth(const ReadableString& content) const {

+ 6 - 6
Source/DFPSR/gui/FlexRegion.cpp

@@ -28,17 +28,17 @@ using namespace dsr;
 PERSISTENT_DEFINITION(FlexValue)
 
 bool FlexValue::assignValue(const ReadableString &text) {
-	int perCentIndex = text.findFirst('%');
+	int perCentIndex = string_findFirst(text, U'%');
 	if (perCentIndex > -1) {
 		// Explicit %
-		ReadableString leftSide = text.before(perCentIndex);
-		ReadableString rightSide = text.after(perCentIndex);
-		this->ratio = leftSide.toInteger();
-		this->offset = rightSide.toInteger();
+		ReadableString leftSide = string_before(text, perCentIndex);
+		ReadableString rightSide = string_after(text, perCentIndex);
+		this->ratio = string_toInteger(leftSide);
+		this->offset = string_toInteger(rightSide);
 	} else {
 		// Implicitly 0%
 		this->ratio = 0;
-		this->offset = text.toInteger();
+		this->offset = string_toInteger(text);
 	}
 	return true; // TODO: Discriminate bad input
 }

+ 10 - 10
Source/DFPSR/machine/VirtualMachine.cpp

@@ -43,15 +43,15 @@ VirtualMachine::VirtualMachine(const ReadableString& code, const std::shared_ptr
 	for (int l = 0; l < lines.length(); l++) {
 		ReadableString currentLine = lines[l];
 		// If the line has a comment, then skip everything from #
-		int commentIndex = currentLine.findFirst(U'#');
+		int commentIndex = string_findFirst(currentLine, U'#');
 		if (commentIndex > -1) {
-			currentLine = currentLine.before(commentIndex);
+			currentLine = string_before(currentLine, commentIndex);
 		}
 		currentLine = string_removeOuterWhiteSpace(currentLine);
-		int colonIndex = currentLine.findFirst(U':');
+		int colonIndex = string_findFirst(currentLine, U':');
 		if (colonIndex > -1) {
-			ReadableString command = string_removeOuterWhiteSpace(currentLine.before(colonIndex));
-			ReadableString argumentLine = currentLine.after(colonIndex);
+			ReadableString command = string_removeOuterWhiteSpace(string_before(currentLine, colonIndex));
+			ReadableString argumentLine = string_after(currentLine, colonIndex);
 			string_split_inPlace(arguments, argumentLine, U',');
 			this->interpretMachineWord(command, arguments);
 		} else if (currentLine.length() > 0) {
@@ -192,12 +192,12 @@ VMA VirtualMachine::VMAfromText(int methodIndex, const ReadableString& content)
 	} else if (first >= U'0' && first <= U'9') {
 		return VMA(FixedPoint::fromText(content));
 	} else {
-		int leftIndex = content.findFirst(U'<');
-		int rightIndex = content.findLast(U'>');
+		int leftIndex = string_findFirst(content, U'<');
+		int rightIndex = string_findLast(content, U'>');
 		if (leftIndex > -1 && rightIndex > -1) {
-			ReadableString name = string_removeOuterWhiteSpace(content.before(leftIndex));
-			ReadableString typeName = string_removeOuterWhiteSpace(content.inclusiveRange(leftIndex + 1, rightIndex - 1));
-			ReadableString remainder = string_removeOuterWhiteSpace(content.after(rightIndex));
+			ReadableString name = string_removeOuterWhiteSpace(string_before(content, leftIndex));
+			ReadableString typeName = string_removeOuterWhiteSpace(string_inclusiveRange(content, leftIndex + 1, rightIndex - 1));
+			ReadableString remainder = string_removeOuterWhiteSpace(string_after(content, rightIndex));
 			if (remainder.length() > 0) {
 				throwError("No code allowed after > for in-place temp declarations!\n");
 			}

+ 7 - 7
Source/DFPSR/math/FixedPoint.cpp

@@ -255,15 +255,15 @@ FixedPoint FixedPoint::fromMantissa(int64_t mantissa) {
 
 FixedPoint FixedPoint::fromText(const ReadableString& text) {
 	ReadableString content = string_removeOuterWhiteSpace(text);
-	bool isSigned = content.findFirst(U'-') > -1; // Should also be last
-	int decimal = content.findFirst(U'.');
-	int colon = content.findFirst(U':');
+	bool isSigned = string_findFirst(content, U'-') > -1; // Should also be last
+	int decimal = string_findFirst(content, U'.');
+	int colon = string_findFirst(content, U':');
 	int64_t result = 0;
 	if (decimal > -1 && colon == -1) {
 		// Floating-point decimal
 		// TODO: Give warnings for incorrect whole integers
-		int64_t wholeInteger = string_parseInteger(content.before(decimal));
-		ReadableString decimals = content.after(decimal);
+		int64_t wholeInteger = string_parseInteger(string_before(content, decimal));
+		ReadableString decimals = string_after(content, decimal);
 		uint64_t fraction = 0; // Extra high precision for accumulation
 		for (int i = 0; i < decimals.length(); i++) {
 			DsrChar digit = decimals[i];
@@ -278,8 +278,8 @@ FixedPoint FixedPoint::fromText(const ReadableString& text) {
 	} else if (decimal == -1 && colon > -1) {
 		// Whole integer and 16-bit fraction
 		// TODO: Give warnings for incorrect integers
-		int64_t wholeInteger = string_parseInteger(content.before(colon));
-		int64_t fraction = string_parseInteger(content.after(colon));
+		int64_t wholeInteger = string_parseInteger(string_before(content, colon));
+		int64_t fraction = string_parseInteger(string_after(content, colon));
 		clampForSaturatedWhole(wholeInteger);
 		if (isSigned) { fraction = -fraction; }
 		result = (wholeInteger * 65536) + fraction;

+ 6 - 6
Source/DFPSR/persistent/ClassFactory.cpp

@@ -141,19 +141,19 @@ std::shared_ptr<Persistent> dsr::createPersistentClassFromText(const ReadableStr
 	List<ReadableString> lines = string_split(text, U'\n');
 	for (int l = 0; l < lines.length(); l++) {
 		ReadableString line = lines[l];
-		int equalityIndex = line.findFirst('=');
+		int equalityIndex = string_findFirst(line, '=');
 		if (equalityIndex > -1) {
 			// Assignment
-			String key = string_removeOuterWhiteSpace(line.before(equalityIndex));
-			String value = string_removeOuterWhiteSpace(line.after(equalityIndex));
+			String key = string_removeOuterWhiteSpace(string_before(line, equalityIndex));
+			String value = string_removeOuterWhiteSpace(string_after(line, equalityIndex));
 			stack.last()->setProperty(key, value);
 		} else {
-			int colonIndex = line.findFirst(':');
+			int colonIndex = string_findFirst(line, ':');
 			if (colonIndex > -1) {
 				// Declaration
-				String keyword = string_removeOuterWhiteSpace(line.before(colonIndex));
+				String keyword = string_removeOuterWhiteSpace(string_before(line, colonIndex));
 				if (string_caseInsensitiveMatch(keyword, U"Begin")) {
-					String type = string_removeOuterWhiteSpace(line.after(colonIndex));
+					String type = string_removeOuterWhiteSpace(string_after(line, colonIndex));
 					newObject = dsr::createPersistentClass(type);
 					if (rootObject.get() == nullptr) {
 						rootObject = newObject;

+ 1 - 1
Source/DFPSR/persistent/atomic/PersistentStringList.cpp

@@ -41,7 +41,7 @@ bool PersistentStringList::assignValue(const ReadableString &text) {
 				i++; // Skip the following character as content
 			} else if (c == U'\"') { // Quote sign
 				// End the quote
-				String content = string_unmangleQuote(string_removeOuterWhiteSpace(text.inclusiveRange(start, i)));
+				String content = string_unmangleQuote(string_removeOuterWhiteSpace(string_inclusiveRange(text, start, i)));
 				this->value.push(content);
 				hadComma = false;
 				quoted = false;

+ 2 - 2
Source/DFPSR/render/ResourcePool.cpp

@@ -45,9 +45,9 @@ const ImageRgbaU8 BasicResourcePool::fetchImageRgba(const String& name) {
 		int existingIndex = this->findImageRgba(name);
 		if (existingIndex > -1) {
 			result = imageRgbaList[existingIndex].ref;
-		} else if (name.findFirst(U'.') > -1) {
+		} else if (string_findFirst(name, U'.') > -1) {
 			throwError("The image \"", name, "\" had a forbidden dot in the name. Images in resource pools are fetched without the extension to allow changing image format without changing what it's called in other resources.\n");
-		} else if (name.findFirst(U'/') > -1 && name.findFirst(U'\\') > -1) {
+		} else if (string_findFirst(name, U'/') > -1 && string_findFirst(name, U'\\') > -1) {
 			throwError("The image \"", name, "\" contained a path separator, which is not allowed because of ambiguity. The same file can have multiple paths to the same folder and multiple files can have the same name in different folders.\n");
 		} else {
 			// Look for a png image

+ 4 - 4
Source/DFPSR/render/model/format/dmf1.cpp

@@ -229,7 +229,7 @@ static void readToken(ParserState &state, const String &fileContent, int start,
 		if (fileContent[start] == U'(' && fileContent[end] == U')') {
 			// Property
 			if (state.parserState == ParserState_WaitForProperty || state.parserState == ParserState_WaitForIndexOrProperty) {
-				setProperty(state, state.lastPropertyName, state.propertyIndex, fileContent.inclusiveRange(start + 1, end - 1));
+				setProperty(state, state.lastPropertyName, state.propertyIndex, string_inclusiveRange(fileContent, start + 1, end - 1));
 				state.parserState = ParserState_WaitForStatement;
 				state.propertyIndex = 0; // Reset index for the next property
 			} else {
@@ -238,7 +238,7 @@ static void readToken(ParserState &state, const String &fileContent, int start,
 		} else if (fileContent[start] == U'[' && fileContent[end] == U']') {
 			// Index
 			if (state.parserState == ParserState_WaitForIndexOrProperty) {
-				state.propertyIndex = roundIndex(string_parseDouble(fileContent.inclusiveRange(start + 1, end - 1)));
+				state.propertyIndex = roundIndex(string_parseDouble(string_inclusiveRange(fileContent, start + 1, end - 1)));
 			} else {
 				printText("Unexpected index!\n");
 			}
@@ -249,7 +249,7 @@ static void readToken(ParserState &state, const String &fileContent, int start,
 					printText("Name of namespace is too long!\n");
 				} else {
 					// Change namespace and create things
-					changeNamespace(state, fileContent.inclusiveRange(start + 1, end - 1));
+					changeNamespace(state, string_inclusiveRange(fileContent, start + 1, end - 1));
 				}
 			} else {
 				printText("Change of namespace before finishing the last statement!\n");
@@ -261,7 +261,7 @@ static void readToken(ParserState &state, const String &fileContent, int start,
 				if (end - start > 258) {
 					printText("Name of property is too long!\n");
 				} else {
-					state.lastPropertyName = fileContent.inclusiveRange(start, end);
+					state.lastPropertyName = string_inclusiveRange(fileContent, start, end);
 					state.parserState = ParserState_WaitForIndexOrProperty;
 				}
 			}

+ 2 - 2
Source/SDK/sandbox/sprite/spriteAPI.cpp

@@ -979,8 +979,8 @@ static bool approximateTextMatch(const ReadableString &a, const ReadableString &
 			while (isDigit(a[readerA])) { readerA++; }
 			while (isDigit(b[readerB])) { readerB++; }
 			// Approximate values
-			double valueA = string_parseDouble(a.exclusiveRange(startA, readerA));
-			double valueB = string_parseDouble(b.exclusiveRange(startB, readerB));
+			double valueA = string_parseDouble(string_exclusiveRange(a, startA, readerA));
+			double valueB = string_parseDouble(string_exclusiveRange(b, startB, readerB));
 			// Check the difference
 			double diff = valueB - valueA;
 			if (diff > tolerance || diff < -tolerance) {

+ 13 - 13
Source/SDK/sandbox/tool.cpp

@@ -597,11 +597,11 @@ static void loadPlyModel(ParserState& state, const ReadableString& content, bool
 }
 
 static void loadModel(ParserState& state, const ReadableString& filename, bool shadow, bool flipX) {
-	int lastDotIndex = filename.findLast(U'.');
+	int lastDotIndex = string_findLast(filename, U'.');
 	if (lastDotIndex == -1) {
 		printText("The model's filename ", filename, " does not have an extension!\n");
 	} else {
-		ReadableString extension = filename.after(lastDotIndex);
+		ReadableString extension = string_after(filename, lastDotIndex);
 		if (string_caseInsensitiveMatch(extension, U"PLY")) {
 			// Store the whole model file in a string for fast reading
 			String content = string_load(state.sourcePath + filename);
@@ -729,23 +729,23 @@ static void parse_dsm(ParserState& state, const ReadableString& content) {
 		// Get the current line
 		ReadableString line = lines[l];
 		// Skip comments
-		int commentIndex = line.findFirst(U';');
+		int commentIndex = string_findFirst(line, U';');
 		if (commentIndex > -1) {
-			line = string_removeOuterWhiteSpace(line.before(commentIndex));
+			line = string_removeOuterWhiteSpace(string_before(line, commentIndex));
 		}
 		if (line.length() > 0) {
 			// Find assignments
-			int assignmentIndex = line.findFirst(U'=');
-			int colonIndex = line.findFirst(U':');
-			int blockStartIndex = line.findFirst(U'<');
-			int blockEndIndex = line.findFirst(U'>');
+			int assignmentIndex = string_findFirst(line, U'=');
+			int colonIndex = string_findFirst(line, U':');
+			int blockStartIndex = string_findFirst(line, U'<');
+			int blockEndIndex = string_findFirst(line, U'>');
 			if (assignmentIndex > -1) {
-				ReadableString key = string_removeOuterWhiteSpace(line.before(assignmentIndex));
-				ReadableString value = string_removeOuterWhiteSpace(line.after(assignmentIndex));
+				ReadableString key = string_removeOuterWhiteSpace(string_before(line, assignmentIndex));
+				ReadableString value = string_removeOuterWhiteSpace(string_after(line, assignmentIndex));
 				parse_assignment(state, key, value);
 			} else if (colonIndex > -1) {
-				ReadableString command = string_removeOuterWhiteSpace(line.before(colonIndex));
-				ReadableString argContent = line.after(colonIndex);
+				ReadableString command = string_removeOuterWhiteSpace(string_before(line, colonIndex));
+				ReadableString argContent = string_after(line, colonIndex);
 				string_split_inPlace(args, argContent, U',');
 				for (int a = 0; a < args.length(); a++) {
 					args[a] = string_removeOuterWhiteSpace(args[a]);
@@ -758,7 +758,7 @@ static void parse_dsm(ParserState& state, const ReadableString& content) {
 					printText("    Unrecognized command ", command, ".\n");
 				}
 			} else if (blockStartIndex > -1 && blockEndIndex > -1) {
-				String block = string_removeOuterWhiteSpace(line.inclusiveRange(blockStartIndex + 1, blockEndIndex - 1));
+				String block = string_removeOuterWhiteSpace(string_inclusiveRange(line, blockStartIndex + 1, blockEndIndex - 1));
 				parse_scope(state, block);
 			} else {
 				printText("Unrecognized content \"", line, "\" on line ", l + 1, ".\n");

+ 9 - 9
Source/test/tests/StringTest.cpp

@@ -46,15 +46,15 @@ START_TEST(String)
 	{ // Sub-strings
 		dsr::ReadableString abcd = U"abcd";
 		dsr::String efgh = U"efgh";
-		ASSERT_MATCH(abcd.inclusiveRange(0, 3), U"abcd");
-		ASSERT_MATCH(abcd.exclusiveRange(1, 2), U"b");
-		ASSERT_MATCH(efgh.inclusiveRange(2, 3), U"gh");
-		ASSERT_MATCH(efgh.exclusiveRange(3, 4), U"h");
-		ASSERT_MATCH(dsr::string_combine(abcd.from(2), efgh.before(2)), U"cdef");
-		ASSERT_MATCH(abcd.exclusiveRange(0, 0), U""); // No size returns nothing
-		ASSERT_MATCH(abcd.exclusiveRange(-1, -2), U""); // A negative size doesn't have to be inside
-		ASSERT_CRASH(abcd.inclusiveRange(-1, -1)); // Index below bound expected
-		ASSERT_CRASH(abcd.inclusiveRange(4, 4)); // Index above bound expected
+		ASSERT_MATCH(dsr::string_inclusiveRange(abcd, 0, 3), U"abcd");
+		ASSERT_MATCH(dsr::string_exclusiveRange(abcd, 1, 2), U"b");
+		ASSERT_MATCH(dsr::string_inclusiveRange(efgh, 2, 3), U"gh");
+		ASSERT_MATCH(dsr::string_exclusiveRange(efgh, 3, 4), U"h");
+		ASSERT_MATCH(dsr::string_combine(string_from(abcd, 2), string_before(efgh, 2)), U"cdef");
+		ASSERT_MATCH(dsr::string_exclusiveRange(abcd, 0, 0), U""); // No size returns nothing
+		ASSERT_MATCH(dsr::string_exclusiveRange(abcd, -1, -2), U""); // A negative size doesn't have to be inside
+		ASSERT_CRASH(dsr::string_inclusiveRange(abcd, -1, -1)); // Index below bound expected
+		ASSERT_CRASH(dsr::string_inclusiveRange(abcd, 4, 4)); // Index above bound expected
 	}
 	{ // Processing
 		dsr::String buffer = U"Garbage";