Selaa lähdekoodia

Merge pull request #333 from bmx-ng/task/splitbuffer-split

Added TSplitBuffer Split() method
Brucey 9 kuukautta sitten
vanhempi
commit
9d3103a2d3

+ 11 - 1
stringbuilder.mod/common.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2018-2023 Bruce A Henderson
+' Copyright (c) 2018-2024 Bruce A Henderson
 ' 
 ' This software is provided 'as-is', without any express or implied
 ' warranty. In no event will the authors be held liable for any damages
@@ -89,6 +89,16 @@ Extern
 	Function bmx_stringbuilder_splitbuffer_text:String(splitPtr:Byte Ptr, index:Int)
 	Function bmx_stringbuilder_splitbuffer_free(splitPtr:Byte Ptr)
 	Function bmx_stringbuilder_splitbuffer_toarray:String[](splitPtr:Byte Ptr)
+	Function bmx_stringbuilder_splitbuffer_split:Byte Ptr(splitPtr:Byte Ptr, separator:String, index:Int)
+	Function bmx_stringbuilder_splitbuffer_toint:Int(splitPtr:Byte Ptr, index:Int)
+	Function bmx_stringbuilder_splitbuffer_tofloat:Float(splitPtr:Byte Ptr, index:Int)
+	Function bmx_stringbuilder_splitbuffer_todouble:Double(splitPtr:Byte Ptr, index:Int)
+	Function bmx_stringbuilder_splitbuffer_tolong:Long(splitPtr:Byte Ptr, index:Int)
+	Function bmx_stringbuilder_splitbuffer_toulong:ULong(splitPtr:Byte Ptr, index:Int)
+	Function bmx_stringbuilder_splitbuffer_toshort:Short(splitPtr:Byte Ptr, index:Int)
+	Function bmx_stringbuilder_splitbuffer_touint:UInt(splitPtr:Byte Ptr, index:Int)
+	Function bmx_stringbuilder_splitbuffer_tosizet:Size_T(splitPtr:Byte Ptr, index:Int)
+	Function bmx_stringbuilder_splitbuffer_tobyte:Byte(splitPtr:Byte Ptr, index:Int)
 
 End Extern
 

+ 378 - 1
stringbuilder.mod/glue.c

@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 2018-2023 Bruce A Henderson
+  Copyright (c) 2018-2024 Bruce A Henderson
   
   This software is provided 'as-is', without any express or implied
   warranty. In no event will the authors be held liable for any damages
@@ -19,6 +19,9 @@
 */ 
 
 #include "glue.h"
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
 
 static int utf32strlen( const BBUINT *p ){
 	const BBUINT *t=p;
@@ -810,6 +813,58 @@ void bmx_stringbuilder_toutf8_buffer(BBString *str, char * buf, size_t length) {
 	*q=0;
 }
 
+void bmx_stringbuilder_toutf8_sbuffer(BBChar * p, int len, char * buf, size_t length) {
+	int i=0;
+	int out=0;
+	char *q=buf;
+
+	while (i < len && out < length) {
+		unsigned int c=*p++;
+		if(0xd800 <= c && c <= 0xdbff && i < len - 1) {
+			/* surrogate pair */
+			unsigned int c2 = *p;
+			if(0xdc00 <= c2 && c2 <= 0xdfff) {
+				/* valid second surrogate */
+				c = ((c - 0xd800) << 10) + (c2 - 0xdc00) + 0x10000;
+				++p;
+				++i;
+			}
+		}
+		if( c<0x80 ){
+			*q++=c;
+			out++;
+		}else if( c<0x800 ){
+			if (out > length - 2) {
+				break;
+			}
+			*q++=0xc0|(c>>6);
+			*q++=0x80|(c&0x3f);
+			out += 2;
+		}else if(c < 0x10000) { 
+			if (out > length - 3) {
+				break;
+			}
+			*q++=0xe0|(c>>12);
+			*q++=0x80|((c>>6)&0x3f);
+			*q++=0x80|(c&0x3f);
+			out += 3;
+		}else if(c <= 0x10ffff) {
+			if (out > length - 4) {
+				break;
+			}
+			*q++ = 0xf0|(c>>18);
+			*q++ = 0x80|((c>>12)&0x3f);
+			*q++ = 0x80|((c>>6)&0x3f);
+			*q++ = 0x80|((c&0x3f));
+			out += 4;
+		}else{
+			bbExThrowCString( "Unicode character out of UTF-8 range" );
+		}
+		++i;
+	}
+	*q=0;
+}
+
 void bmx_stringbuilder_format_string(struct MaxStringBuilder * buf, BBString * formatText, BBString * value) {
 	char formatBuf[256];
 	bmx_stringbuilder_toutf8_buffer(formatText, formatBuf, sizeof(formatBuf));
@@ -974,3 +1029,325 @@ BBArray * bmx_stringbuilder_splitbuffer_toarray(struct MaxSplitBuffer * buf) {
 	}
 	return bits;
 }
+
+struct MaxSplitBuffer * bmx_stringbuilder_splitbuffer_split(struct MaxSplitBuffer * splitBuffer, BBString * separator, int index) {
+    if (index < 0 || index >= splitBuffer->count) {
+        return NULL;
+    }
+
+    // Extract the segment we want to split further
+    int start = splitBuffer->startIndex[index];
+    int end = splitBuffer->endIndex[index];
+    
+    // Create a temporary buffer for just this segment
+    struct MaxStringBuilder tempBuf;
+    tempBuf.buffer = splitBuffer->buffer->buffer + start;
+    tempBuf.count = end - start;
+    tempBuf.capacity = end - start;
+    tempBuf.hash = 0;
+
+    // First, count how many new segments we will create
+    int count = 1;
+    int offset = 0;
+    int i = 0;
+
+    while ((offset = bmx_stringbuilder_find(&tempBuf, separator, i)) != -1) {
+        ++count;
+        i = offset + separator->length;
+    }
+
+    // Allocate memory for new split buffer
+    struct MaxSplitBuffer * newSplitBuffer = malloc(sizeof(struct MaxSplitBuffer));
+    newSplitBuffer->buffer = splitBuffer->buffer; // Reference the original buffer
+    newSplitBuffer->count = count;
+    newSplitBuffer->startIndex = malloc(count * sizeof(int));
+    newSplitBuffer->endIndex = malloc(count * sizeof(int));
+
+    int * bufferStartIndex = newSplitBuffer->startIndex;
+    int * bufferEndIndex = newSplitBuffer->endIndex;
+
+    // Perform the actual split
+    i = 0;
+    int subSegmentStart = 0;
+    while ((offset = bmx_stringbuilder_find(&tempBuf, separator, i)) != -1) {
+        *bufferStartIndex++ = start + subSegmentStart;
+        *bufferEndIndex++ = start + offset;
+        subSegmentStart = offset + separator->length;
+        i = subSegmentStart;
+    }
+
+    // Handle the last segment (or the whole segment if no separator was found)
+    *bufferStartIndex++ = start + subSegmentStart;
+    *bufferEndIndex++ = end;
+
+    return newSplitBuffer;
+}
+
+int bmx_stringbuilder_splitbuffer_toint(struct MaxSplitBuffer * splitBuffer, int index) {
+    if (index < 0 || index >= splitBuffer->count) {
+        return 0;
+    }
+
+    // Get the start and end positions of the segment in the original buffer
+    int start = splitBuffer->startIndex[index];
+    int end = splitBuffer->endIndex[index];
+
+    int length = end - start;
+
+    // If the segment is empty, return 0
+    if (length == 0) {
+        return 0;
+    }
+
+    char *segment = (char *) &(splitBuffer->buffer->buffer[start]);
+
+	char numbuf[256];
+	bmx_stringbuilder_toutf8_sbuffer(segment, length, numbuf, sizeof(numbuf));
+
+    char *endPtr;
+    errno = 0;
+    long result = strtol(numbuf, &endPtr, 10);
+
+    // Make sure that endPtr does not exceed the bounds of the segment
+    if (endPtr > numbuf + length) {
+        return 0;
+    }
+
+    if (errno == ERANGE || result > INT_MAX || result < INT_MIN || endPtr == numbuf) {
+        return 0;
+    }
+
+    return (int)result;
+}
+
+unsigned int bmx_stringbuilder_splitbuffer_touint(struct MaxSplitBuffer * splitBuffer, int index) {
+    if (index < 0 || index >= splitBuffer->count) {
+        return 0;
+    }
+
+    int start = splitBuffer->startIndex[index];
+    int end = splitBuffer->endIndex[index];
+    int length = end - start;
+
+    if (length == 0) {
+        return 0;
+    }
+
+    char *segment = (char *) &(splitBuffer->buffer->buffer[start]);
+
+	char numbuf[256];
+	bmx_stringbuilder_toutf8_sbuffer(segment, length, numbuf, sizeof(numbuf));
+
+    char *endPtr;
+    errno = 0;
+    unsigned long result = strtoul(numbuf, &endPtr, 10);
+
+    if (endPtr > numbuf + length || errno == ERANGE || endPtr == numbuf || result > UINT_MAX) {
+        return 0;
+    }
+
+    return (unsigned int)result;
+}
+
+float bmx_stringbuilder_splitbuffer_tofloat(struct MaxSplitBuffer * splitBuffer, int index) {
+    if (index < 0 || index >= splitBuffer->count) {
+        return 0.0f;
+    }
+
+    int start = splitBuffer->startIndex[index];
+    int end = splitBuffer->endIndex[index];
+    int length = end - start;
+
+    if (length == 0) {
+        return 0.0f;
+    }
+
+    char *segment = (char *) &(splitBuffer->buffer->buffer[start]);
+
+	char numbuf[256];
+	bmx_stringbuilder_toutf8_sbuffer(segment, length, numbuf, sizeof(numbuf));
+
+    char *endPtr;
+    errno = 0;
+    float result = strtof(numbuf, &endPtr);
+
+    if (endPtr > numbuf + length || errno == ERANGE || endPtr == numbuf) {
+        return 0.0f;
+    }
+
+    return result;
+}
+
+double bmx_stringbuilder_splitbuffer_todouble(struct MaxSplitBuffer * splitBuffer, int index) {
+    if (index < 0 || index >= splitBuffer->count) {
+        return 0.0;
+    }
+
+    int start = splitBuffer->startIndex[index];
+    int end = splitBuffer->endIndex[index];
+    int length = end - start;
+
+    if (length == 0) {
+        return 0.0;
+    }
+
+    char *segment = (char *) &(splitBuffer->buffer->buffer[start]);
+	
+	char numbuf[256];
+	bmx_stringbuilder_toutf8_sbuffer(segment, length, numbuf, sizeof(numbuf));
+
+    char *endPtr;
+    errno = 0;
+    double result = strtod(numbuf, &endPtr);
+
+    if (endPtr > numbuf + length || errno == ERANGE || endPtr == numbuf) {
+        return 0.0;
+    }
+
+    return result;
+}
+
+BBInt64 bmx_stringbuilder_splitbuffer_tolong(struct MaxSplitBuffer * splitBuffer, int index) {
+    if (index < 0 || index >= splitBuffer->count) {
+        return 0;
+    }
+
+    int start = splitBuffer->startIndex[index];
+    int end = splitBuffer->endIndex[index];
+    int length = end - start;
+
+    if (length == 0) {
+        return 0;
+    }
+
+    char *segment = (char *) &(splitBuffer->buffer->buffer[start]);
+
+	char numbuf[256];
+	bmx_stringbuilder_toutf8_sbuffer(segment, length, numbuf, sizeof(numbuf));
+
+    char *endPtr;
+    errno = 0;
+    BBInt64 result = strtoll(numbuf, &endPtr, 10);
+
+    if (endPtr > numbuf + length || errno == ERANGE || endPtr == numbuf) {
+        return 0;
+    }
+
+    return result;
+}
+
+BBUInt64 bmx_stringbuilder_splitbuffer_toulong(struct MaxSplitBuffer * splitBuffer, int index) {
+    if (index < 0 || index >= splitBuffer->count) {
+        return 0;
+    }
+
+    int start = splitBuffer->startIndex[index];
+    int end = splitBuffer->endIndex[index];
+    int length = end - start;
+
+    if (length == 0) {
+        return 0;
+    }
+
+    char *segment = (char *) &(splitBuffer->buffer->buffer[start]);
+
+	char numbuf[256];
+	bmx_stringbuilder_toutf8_sbuffer(segment, length, numbuf, sizeof(numbuf));
+
+    char *endPtr;
+    errno = 0;
+    BBUInt64 result = strtoull(numbuf, &endPtr, 10);
+
+    if (endPtr > numbuf + length || errno == ERANGE || endPtr == numbuf) {
+        return 0;
+    }
+
+    return result;
+}
+
+size_t bmx_stringbuilder_splitbuffer_tosizet(struct MaxSplitBuffer * splitBuffer, int index) {
+    if (index < 0 || index >= splitBuffer->count) {
+        return 0;
+    }
+
+    int start = splitBuffer->startIndex[index];
+    int end = splitBuffer->endIndex[index];
+    int length = end - start;
+
+    if (length == 0) {
+        return 0;
+    }
+
+    char *segment = (char *) &(splitBuffer->buffer->buffer[start]);
+
+	char numbuf[256];
+	bmx_stringbuilder_toutf8_sbuffer(segment, length, numbuf, sizeof(numbuf));
+
+    char *endPtr;
+    errno = 0;
+    unsigned long long result = strtoull(numbuf, &endPtr, 10);
+
+    if (endPtr > numbuf + length || errno == ERANGE || endPtr == numbuf) {
+        return 0;
+    }
+
+    return (size_t)result;
+}
+
+BBSHORT bmx_stringbuilder_splitbuffer_toshort(struct MaxSplitBuffer * splitBuffer, int index) {
+    if (index < 0 || index >= splitBuffer->count) {
+        return 0;
+    }
+
+    int start = splitBuffer->startIndex[index];
+    int end = splitBuffer->endIndex[index];
+    int length = end - start;
+
+    if (length == 0) {
+        return 0;
+    }
+
+    char *segment = (char *) &(splitBuffer->buffer->buffer[start]);
+
+	char numbuf[256];
+	bmx_stringbuilder_toutf8_sbuffer(segment, length, numbuf, sizeof(numbuf));
+
+    char *endPtr;
+    errno = 0;
+    long result = strtol(numbuf, &endPtr, 10);
+
+    if (endPtr > numbuf + length || errno == ERANGE || endPtr == numbuf || result < 0 || result > USHRT_MAX) {
+        return 0;
+    }
+
+    return (BBSHORT)result;
+}
+
+BBBYTE bmx_stringbuilder_splitbuffer_tobyte(struct MaxSplitBuffer * splitBuffer, int index) {
+    if (index < 0 || index >= splitBuffer->count) {
+        return 0;
+    }
+
+    int start = splitBuffer->startIndex[index];
+    int end = splitBuffer->endIndex[index];
+    int length = end - start;
+
+    if (length == 0) {
+        return 0;
+    }
+
+    char *segment = (char *) &(splitBuffer->buffer->buffer[start]);
+
+	char numbuf[256];
+	bmx_stringbuilder_toutf8_sbuffer(segment, length, numbuf, sizeof(numbuf));
+
+    char *endPtr;
+    errno = 0;
+    long result = strtol(numbuf, &endPtr, 10);
+
+    if (endPtr > numbuf + length || errno == ERANGE || endPtr == numbuf || result < 0 || result > UCHAR_MAX) {
+        return 0;
+    }
+
+    return (BBBYTE)result;
+}

+ 12 - 1
stringbuilder.mod/glue.h

@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 2018-2023 Bruce A Henderson
+  Copyright (c) 2018-2024 Bruce A Henderson
   
   This software is provided 'as-is', without any express or implied
   warranty. In no event will the authors be held liable for any damages
@@ -89,6 +89,7 @@ void bmx_stringbuilder_rightalign(struct MaxStringBuilder * buf, int length);
 char * bmx_stringbuilder_toutf8string(struct MaxStringBuilder * buf);
 BBChar * bmx_stringbuilder_towstring(struct MaxStringBuilder * buf);
 void bmx_stringbuilder_toutf8_buffer(BBString *str, char * buf, size_t length);
+void bmx_stringbuilder_toutf8_sbuffer(BBChar * p, int len, char * buf, size_t length);
 void bmx_stringbuilder_format_string(struct MaxStringBuilder * buf, BBString * formatText, BBString * value);
 void bmx_stringbuilder_format_byte(struct MaxStringBuilder * buf, BBString * formatText, BBBYTE value);
 void bmx_stringbuilder_format_short(struct MaxStringBuilder * buf, BBString * formatText, BBSHORT value);
@@ -109,5 +110,15 @@ int bmx_stringbuilder_splitbuffer_length(struct MaxSplitBuffer * buf);
 BBString * bmx_stringbuilder_splitbuffer_text(struct MaxSplitBuffer * buf, int index);
 void bmx_stringbuilder_splitbuffer_free(struct MaxSplitBuffer * buf);
 BBArray * bmx_stringbuilder_splitbuffer_toarray(struct MaxSplitBuffer * buf);
+struct MaxSplitBuffer * bmx_stringbuilder_splitbuffer_split(struct MaxSplitBuffer * splitBuffer, BBString * separator, int index);
+int bmx_stringbuilder_splitbuffer_toint(struct MaxSplitBuffer * splitBuffer, int index);
+unsigned int bmx_stringbuilder_splitbuffer_touint(struct MaxSplitBuffer * splitBuffer, int index);
+float bmx_stringbuilder_splitbuffer_tofloat(struct MaxSplitBuffer * splitBuffer, int index);
+double bmx_stringbuilder_splitbuffer_todouble(struct MaxSplitBuffer * splitBuffer, int index);
+BBInt64 bmx_stringbuilder_splitbuffer_tolong(struct MaxSplitBuffer * splitBuffer, int index);
+BBUInt64 bmx_stringbuilder_splitbuffer_toulong(struct MaxSplitBuffer * splitBuffer, int index);
+size_t bmx_stringbuilder_splitbuffer_tosizet(struct MaxSplitBuffer * splitBuffer, int index);
+BBSHORT bmx_stringbuilder_splitbuffer_toshort(struct MaxSplitBuffer * splitBuffer, int index);
+BBBYTE bmx_stringbuilder_splitbuffer_tobyte(struct MaxSplitBuffer * splitBuffer, int index);
 
 #endif

+ 88 - 3
stringbuilder.mod/stringbuilder.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2018-2023 Bruce A Henderson
+' Copyright (c) 2018-2024 Bruce A Henderson
 ' 
 ' This software is provided 'as-is', without any express or implied
 ' warranty. In no event will the authors be held liable for any damages
@@ -23,10 +23,13 @@ bbdoc: A string builder.
 End Rem	
 Module BRL.StringBuilder
 
-ModuleInfo "Version: 1.18"
+ModuleInfo "Version: 1.19"
 ModuleInfo "License: zlib/libpng"
-ModuleInfo "Copyright: 2018-2023 Bruce A Henderson"
+ModuleInfo "Copyright: 2018-2024 Bruce A Henderson"
 
+ModuleInfo "History: 1.19"
+ModuleInfo "History: Added TSplitBuffer Split() method."
+ModuleInfo "History: Added TSplitBuffer to number methods."
 ModuleInfo "History: 1.18"
 ModuleInfo "History: Added optional startIndex to StartsWith()."
 ModuleInfo "History: 1.17"
@@ -972,6 +975,88 @@ Public
 		Return bmx_stringbuilder_splitbuffer_toarray(splitPtr)
 	End Method
 
+	Rem
+	bbdoc: Returns the split element at the specified index as an #Int.
+	about: If the element is not a valid #Int, 0 is returned.
+	End Rem
+	Method ToInt:Int(index:Int)
+		Return bmx_stringbuilder_splitbuffer_toint(splitPtr, index)
+	End Method
+
+	Rem
+	bbdoc: Returns the split element at the specified index as a #Float.
+	about: If the element is not a valid #Float, 0.0 is returned.
+	End Rem
+	Method ToFloat:Float(index:Int)
+		Return bmx_stringbuilder_splitbuffer_tofloat(splitPtr, index)
+	End Method
+
+	Rem
+	bbdoc: Returns the split element at the specified index as a #Double.
+	about: If the element is not a valid #Double, 0.0 is returned.
+	End Rem
+	Method ToDouble:Double(index:Int)
+		Return bmx_stringbuilder_splitbuffer_todouble(splitPtr, index)
+	End Method
+
+	Rem
+	bbdoc: Returns the split element at the specified index as a #Long.
+	about: If the element is not a valid #Long, 0 is returned.
+	End Rem
+	Method ToLong:Long(index:Int)
+		Return bmx_stringbuilder_splitbuffer_tolong(splitPtr, index)
+	End Method
+
+	Rem
+	bbdoc: Returns the split element at the specified index as a #ULong.
+	about: If the element is not a valid #ULong, 0 is returned.
+	End Rem
+	Method ToULong:ULong(index:Int)
+		Return bmx_stringbuilder_splitbuffer_toulong(splitPtr, index)
+	End Method
+
+	Rem
+	bbdoc: Returns the split element at the specified index as a #UInt.
+	about: If the element is not a valid #UInt, 0 is returned.
+	End Rem
+	Method ToUInt:UInt(index:Int)
+		Return bmx_stringbuilder_splitbuffer_touint(splitPtr, index)
+	End Method
+
+	Rem
+	bbdoc: Returns the split element at the specified index as a #Short.
+	about: If the element is not a valid #Short, 0 is returned.
+	End Rem
+	Method ToShort:Short(index:Int)
+		Return bmx_stringbuilder_splitbuffer_toshort(splitPtr, index)
+	End Method
+
+	Rem
+	bbdoc: Returns the split element at the specified index as a #Byte.
+	about: If the element is not a valid #Byte, 0 is returned.
+	End Rem
+	Method ToByte:Byte(index:Int)
+		Return bmx_stringbuilder_splitbuffer_tobyte(splitPtr, index)
+	End Method
+
+	Rem
+	bbdoc: Returns the split element at the specified index as a #Size_T.
+	about: If the element is not a valid #Size_T, 0 is returned.
+	End Rem
+	Method ToSizeT:Size_T(index:Int)
+		Return bmx_stringbuilder_splitbuffer_tosizet(splitPtr, index)
+	End Method
+
+	Rem
+	bbdoc: Creates a new split buffer of the split element at the specified index.
+	End Rem
+	Method Split:TSplitBuffer(index:Int, separator:String)
+		Local buf:TSplitBuffer = New TSplitBuffer
+		buf.buffer = buffer
+		buf.splitPtr = bmx_stringbuilder_splitbuffer_split(splitPtr, separator, index)
+		Return buf
+	End Method
+
 	Method ObjectEnumerator:TSplitBufferEnum()
 		Local enumeration:TSplitBufferEnum = New TSplitBufferEnum
 		enumeration.buffer = Self

+ 210 - 0
stringbuilder.mod/tests/test.bmx

@@ -188,3 +188,213 @@ Type TStringBuilderTest Extends TTest
 	End Method
 
 End Type
+
+Type TSplitBufferTest Extends TTest
+
+	Field sb:TStringBuilder
+	
+	Method setup() { before }
+		sb = New TStringBuilder
+	End Method
+
+	Method testSplitBuffer() { test }
+		sb.Append("a,b,c,d,e,f,g")
+
+		Local split:TSplitBuffer = sb.Split(",")
+
+		assertEquals(7, split.Length())
+		assertEquals("a", split.Text(0))
+		assertEquals("d", split.Text(3))
+		assertEquals("g", split.Text(6))
+		
+	End Method
+
+	Method testSplitBufferEmpty() { test }
+		sb.Append("a,b,c,d,e,f,g")
+
+		Local split:TSplitBuffer = sb.Split(" ")
+
+		assertEquals(1, split.Length())
+		assertEquals("a,b,c,d,e,f,g", split.Text(0))
+		
+	End Method
+
+	Method testSplitBufferEmptyString() { test }
+		sb.Append("")
+
+		Local split:TSplitBuffer = sb.Split(",")
+
+		assertEquals(1, split.Length())
+		assertEquals("", split.Text(0))
+		
+	End Method
+
+	Method testSplitBufferEmptySeparator() { test }
+		sb.Append("a,b,c,d,e,f,g")
+
+		Local split:TSplitBuffer = sb.Split("")
+
+		assertEquals(1, split.Length())
+		assertEquals("a,b,c,d,e,f,g", split.Text(0))
+		
+	End Method
+
+	Method testSplitBufferEmptyFields() { test }
+		sb.Append("1,,,3,4,5")
+
+		Local split:TSplitBuffer = sb.Split(",")
+
+		assertEquals(6, split.Length())
+		assertEquals("1", split.Text(0))
+		assertEquals("", split.Text(1))
+		assertEquals("3", split.Text(3))
+		assertEquals("5", split.Text(5))
+
+	End Method
+
+	Method testSplitBufferSplit() { test }
+		sb.Append("1,2,3|4,5,6|7,8,9")
+
+		Local split:TSplitBuffer = sb.Split("|")
+
+		assertEquals(3, split.Length())
+		assertEquals("1,2,3", split.Text(0))
+
+		Local split2:TSplitBuffer = split.Split(0, ",")
+
+		assertEquals(3, split2.Length())
+
+		assertEquals("1", split2.Text(0))
+		assertEquals("2", split2.Text(1))
+		assertEquals("3", split2.Text(2))
+	End Method
+
+	Method testSplitBufferSplitEmptyFields() { test }
+		sb.Append("1,2,3|4,,6|7,8,9")
+
+		Local split:TSplitBuffer = sb.Split("|")
+
+		assertEquals(3, split.Length())
+		assertEquals("4,,6", split.Text(1))
+
+		Local split2:TSplitBuffer = split.Split(1, ",")
+
+		assertEquals(3, split2.Length())
+
+		assertEquals("4", split2.Text(0))
+		assertEquals("", split2.Text(1))
+		assertEquals("6", split2.Text(2))
+	End Method
+
+	Method testSplitBufferSplitEmptyFields2() { test }
+		sb.Append("1,2,3||7,8,9")
+
+		Local split:TSplitBuffer = sb.Split("|")
+
+		assertEquals(3, split.Length())
+		assertEquals("", split.Text(1))
+
+		Local split2:TSplitBuffer = split.Split(1, ",")
+
+		assertEquals(1, split2.Length())
+		assertEquals("", split2.Text(0))
+	End Method
+
+	Method testSplitBufferEnumeration() { test }
+		sb.Append("a,b,c,d,e,f,g")
+
+		Local split:TSplitBuffer = sb.Split(",")
+
+		Local txt:String
+		For Local s:String = EachIn split
+			txt :+ s
+		Next
+
+		assertEquals("abcdefg", txt)
+	End Method
+
+	Method testSplitBufferSplitEnumeration() { test }
+		sb.Append("1,2,3|4,5,6|7,8,9")
+
+		Local split:TSplitBuffer = sb.Split("|")
+		Local split2:TSplitBuffer = split.Split(1, ",")
+
+		Local txt:String
+		For Local s:String = EachIn split2
+			txt :+ s
+		Next
+
+		assertEquals("456", txt)
+	End Method
+
+	Method testSplitBufferToInt() { test }
+		sb.Append("1,22,333,4444,-55555,666666,777777,8888888,99999999")
+
+		Local split:TSplitBuffer = sb.Split(",")
+
+		assertEquals(1, split.ToInt(0))
+		assertEquals(-55555, split.ToInt(4))
+		assertEquals(99999999, split.ToInt(8))
+	End Method
+
+	Method testSplitBufferToFloat() { test }
+		sb.Append("1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,-9.9")
+
+		Local split:TSplitBuffer = sb.Split(",")
+
+		assertEquals(1.1, split.ToFloat(0), 0.0001)
+		assertEquals(5.5, split.ToFloat(4), 0.0001)
+		assertEquals(-9.9, split.ToFloat(8), 0.0001)
+	End Method
+
+	Method testSplitBufferToDouble() { test }
+		sb.Append("1.1,2.2,3.3,4.4,-5.5,6.6,7.7,8.8,9.9")
+
+		Local split:TSplitBuffer = sb.Split(",")
+
+		assertEquals(1.1, split.ToDouble(0), 0.0001)
+		assertEquals(-5.5, split.ToDouble(4), 0.0001)
+		assertEquals(9.9, split.ToDouble(8), 0.0001)
+	End Method
+
+	Method testSplitBufferToShort() { test }
+		sb.Append("1,2,3,4,5,6,7,8,9")
+
+		Local split:TSplitBuffer = sb.Split(",")
+
+		assertEquals(1, split.ToShort(0))
+		assertEquals(5, split.ToShort(4))
+		assertEquals(9, split.ToShort(8))
+	End Method
+
+	Method testSplitBufferToByte() { test }
+		sb.Append("1,2,3,4,5,6,7,8,9")
+
+		Local split:TSplitBuffer = sb.Split(",")
+
+		assertEquals(1, split.ToByte(0))
+		assertEquals(5, split.ToByte(4))
+		assertEquals(9, split.ToByte(8))
+	End Method
+
+	Method testSplitBufferToLong() { test }
+		sb.Append("-1,2,3,4,5,6,7,8,9")
+
+		Local split:TSplitBuffer = sb.Split(",")
+
+		assertEquals(-1, split.ToLong(0))
+		assertEquals(5, split.ToLong(4))
+		assertEquals(9, split.ToLong(8))
+	End Method
+
+	Method testSplitBufferToULong() { test }
+		sb.Append("1111,22222,333333,4444444,55555555,666666666,777777777,8888888,99999999999")
+
+		Local split:TSplitBuffer = sb.Split(",")
+
+		assertEquals(1111, split.ToULong(0))
+		assertEquals(55555555, split.ToULong(4))
+		assertEquals(99999999999:ULong, split.ToULong(8))
+	End Method
+
+End Type