1 /*
2 DSFML - The Simple and Fast Multimedia Library for D
3 
4 Copyright (c) 2013 - 2015 Jeremy DeHaan (dehaan.jeremiah@gmail.com)
5 
6 This software is provided 'as-is', without any express or implied warranty.
7 In no event will the authors be held liable for any damages arising from the use of this software.
8 
9 Permission is granted to anyone to use this software for any purpose, including commercial applications,
10 and to alter it and redistribute it freely, subject to the following restrictions:
11 
12 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
13 If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
14 
15 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
16 
17 3. This notice may not be removed or altered from any source distribution
18 */
19 
20 /**
21  *A module containing functions for interacting with strings going to and from 
22  *a C/C++ library as well as converting between D's string types. This module has no dependencies
23  *except for std.utf.
24  */
25 module dsfml.system..string;
26 
27 ///Returns a D string copy of a zero terminated C style string
28 ///
29 ///Params:
30 ///		str = The C style string to convert.
31 ///
32 ///Returns: the D style string copy.
33 immutable(T)[] toString(T)(in const(T)* str) pure
34 	if (is(T == dchar)||is(T == wchar)||is(T == char))
35 {
36 	return str[0..strlen(str)].idup;
37 }
38 
39 ///Returns a pointer to a C style string created from a D string type
40 ///
41 ///Params:
42 ///		str = The D style string to convert.
43 ///
44 ///Returns: the C style string pointer.
45 const(T)* toStringz(T)(in immutable(T)[] str) nothrow 
46 	if (is(T == dchar)||is(T == wchar)||is(T == char))
47 {
48 	//TODO: get rid of GC usage without adding dependencies?
49 
50 	//a means to store the copy after returning the address
51 	static T[] copy;
52 
53 	//if str is just ""
54 	if(str.length == 0)
55 	{
56 		copy = new T[1];
57 		copy[0] = 0;
58 		return copy.ptr;
59 	}
60 
61 	//Already zero terminated
62 	if(str[$-1] == 0)
63 	{
64 		return str.ptr;
65 	}
66 	//not zero terminated
67 	else
68 	{
69 		copy = new T[str.length+1];
70 		copy[0..str.length] = str[];
71 		copy[$-1] = 0;
72 
73 		return copy.ptr;
74 
75 	}
76 }
77 
78 ///Returns the same string in a different utf encoding
79 ///
80 ///Params:
81 ///		str = The string to convert.
82 ///
83 ///Returns: the C style string pointer.
84 immutable(U)[] stringConvert(T, U)(in immutable(T)[] str) pure
85 if ((is(T == dchar)||is(T == wchar)||is(T == char)) &&	
86 	(is(U == dchar)||is(U == wchar)||is(U == char)))
87 {
88 	import std.utf;
89 
90 	static if(is(U == char))
91 	{
92 		return toUTF8(str);
93 	}
94 
95 	else static if(is(U == wchar))
96 	{
97 		return toUTF16(str);
98 	}
99 	else
100 	{
101 		return toUTF32(str);
102 	}
103 
104 }
105 
106 
107 ///Get the length of a C style string
108 ///
109 ///Params:
110 ///		str = The C style string.
111 ///
112 ///Returns: The C string's length.
113 private size_t strlen(T)(in const(T)* str) pure nothrow
114 if (is(T == dchar)||is(T == wchar)||is(T == char))
115 {
116 	size_t n = 0;
117 	for (; str[n] != 0; ++n) {}
118 	return n;
119 }
120 
121 unittest
122 {
123 	version(DSFML_Unittest_System)
124 	{
125 		import std.stdio;
126 		
127 		writeln("Unit test for string functions");
128 
129 		string str1 = "Hello, World";
130 		wstring str2 = "Hello, World";
131 		dstring str3 = "Hello, World";
132 
133 		const(char)* cstr1 = toStringz(str1);
134 		const(wchar)* cstr2 = toStringz(str2);
135 		const(dchar)* cstr3 = toStringz(str3);
136 
137 		assert(strlen(cstr1) == 12);
138 		assert(strlen(cstr2) == 12);
139 		assert(strlen(cstr3) == 12);
140 
141 	}
142 
143 }