Przeglądaj źródła

Added ToUTF8String() and ToWString() methods.

woollybah 5 lat temu
rodzic
commit
17092f2f69

+ 2 - 0
stringbuilder.mod/common.bmx

@@ -65,6 +65,8 @@ Extern
 	Function bmx_stringbuilder_compare:Int(buffer:Byte Ptr, buffer2:Byte Ptr)
 	Function bmx_stringbuilder_leftalign(buffer:Byte Ptr, length:Int)
 	Function bmx_stringbuilder_rightalign(buffer:Byte Ptr, length:Int)
+	Function bmx_stringbuilder_toutf8string:Byte Ptr(buffer:Byte Ptr)
+	Function bmx_stringbuilder_towstring:Short Ptr(buffer:Byte Ptr)
 	
 	Function bmx_stringbuilder_splitbuffer_length:Int(splitPtr:Byte Ptr)
 	Function bmx_stringbuilder_splitbuffer_text:String(splitPtr:Byte Ptr, index:Int)

+ 56 - 0
stringbuilder.mod/glue.c

@@ -649,6 +649,62 @@ void bmx_stringbuilder_rightalign(struct MaxStringBuilder * buf, int length) {
 	buf->count = length;
 }
 
+char * bmx_stringbuilder_toutf8string(struct MaxStringBuilder * buf) {
+	int i = 0;
+	int count = buf->count;
+	if (count == 0) {
+		return NULL;
+	}
+	char *ubuf = (char*)bbMemAlloc( count * 4 + 1 );
+	char *q = ubuf;
+	unsigned short *p = buf->buffer;
+	while (i < count) {
+		unsigned int c=*p++;
+		if (0xd800 <= c && c <= 0xdbff && i < count - 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;
+		} else if (c < 0x800){
+			*q++ = 0xc0 | (c >> 6);
+			*q++ = 0x80 | (c & 0x3f);
+		} else if (c < 0x10000) { 
+			*q++ = 0xe0 | (c >> 12);
+			*q++ = 0x80 | ((c >> 6) & 0x3f);
+			*q++ = 0x80 | (c & 0x3f);
+		} else if (c <= 0x10ffff) {
+			*q++ = 0xf0 | (c >> 18);
+			*q++ = 0x80 | ((c >> 12) & 0x3f);
+			*q++ = 0x80 | ((c >> 6) & 0x3f);
+			*q++ = 0x80 | ((c & 0x3f));
+		} else {
+			bbExThrowCString( "Unicode character out of UTF-8 range" );
+		}
+		++i;
+	}
+	*q=0;
+	return ubuf;
+}
+
+BBChar * bmx_stringbuilder_towstring(struct MaxStringBuilder * buf) {
+	int k;
+	int count = buf->count;
+	if (count == 0) {
+		return NULL;
+	}
+	BBChar *p = (BBChar*)bbMemAlloc((count + 1) * sizeof(BBChar));
+	memcpy(p, buf->buffer, count * sizeof(BBChar));
+	p[count] = 0;
+	return p;
+}
+
 /* ----------------------------------------------------- */
 
 int bmx_stringbuilder_splitbuffer_length(struct MaxSplitBuffer * buf) {

+ 21 - 1
stringbuilder.mod/stringbuilder.bmx

@@ -23,10 +23,12 @@ bbdoc: A string builder.
 End Rem	
 Module BRL.StringBuilder
 
-ModuleInfo "Version: 1.08"
+ModuleInfo "Version: 1.09"
 ModuleInfo "License: zlib/libpng"
 ModuleInfo "Copyright: 2018-2019 Bruce A Henderson"
 
+ModuleInfo "History: 1.09"
+ModuleInfo "History: Added ToUTF8String() and ToWString() methods."
 ModuleInfo "History: 1.08"
 ModuleInfo "History: Added LeftAlign() and RightAlign() methods."
 ModuleInfo "History: 1.07"
@@ -627,6 +629,24 @@ Public
 		Return bmx_stringbuilder_tostring(buffer)
 	End Method
 
+	Rem
+	bbdoc: Converts the value of the string builder to a UTF-8 formatted #Byte sequence.
+	returns: A pointer to a sequence of Bytes, or #Null if the string builder is empty.
+	about: The resulting Byte Ptr must be freed with #MemFree.
+	End Rem
+	Method ToUTF8String:Byte Ptr()
+		Return bmx_stringbuilder_toutf8string(buffer)
+	End Method
+
+	Rem
+	bbdoc: Converts the value of the string builder to a sequence of Shorts.
+	returns: A pointer to a sequence of Shorts, or #Null if the string builder is empty.
+	about: The resulting Short Ptr must be freed with #MemFree.
+	End Rem
+	Method ToWString:Short Ptr()
+		Return bmx_stringbuilder_towstring(buffer)
+	End Method
+	
 	Rem
 	bbdoc: Returns #True if @obj is equal to this string builder.
 	End Rem

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

@@ -44,4 +44,51 @@ Type TStringBuilderTest Extends TTest
 		assertEquals("          ", sb.ToString())
 	End Method
 
+	Method testToUTF8String() { test }
+		Local s:String = "@825B"
+		sb.Append(s)
+	
+		Local b1:Byte Ptr = s.ToUTF8String()
+		Local b2:Byte Ptr = sb.ToUTF8String()
+		
+		assertNotNull(b2)
+		assertEquals(strlen_(b1), strlen_(b2))
+		
+		For Local i:Int = 0 Until strlen_(b1)
+			assertEquals(b1[0], b2[0])
+		Next
+		
+		MemFree(b1)
+		MemFree(b2)
+	End Method
+
+	Method testEmptyToUTF8String() { test }
+	
+		assertNull(sb.ToUTF8String())
+		
+	End Method
+
+	Method testToWString() { test }
+		Local s:String = "@825B"
+		sb.Append(s)
+	
+		Local s1:Short Ptr = s.ToWString()
+		Local s2:Short Ptr = sb.ToWString()
+		
+		assertNotNull(s2)
+		
+		For Local i:Int = 0 Until 6
+			assertEquals(s1[0], s2[0])
+		Next
+		
+		MemFree(s1)
+		MemFree(s2)
+	End Method
+
+	Method testEmptyToWString() { test }
+	
+		assertNull(sb.ToWString())
+		
+	End Method
+
 End Type