1 /******************************************************************************* 2 3 copyright: Copyright (c) 2006 Keinfarbton. All rights reserved 4 5 license: BSD style: $(LICENSE) 6 7 version: Initial release: October 2006 8 9 author: Keinfarbton & Kris 10 11 *******************************************************************************/ 12 13 module tango.stdc.stringz; 14 15 /********************************* 16 * Convert array of chars to a C-style 0 terminated string. 17 * Providing a tmp will use that instead of the heap, where 18 * appropriate. 19 * 20 * Warning, don't read from the memory pointed to in the tmp variable after calling this function. 21 */ 22 23 inout(char)* toStringz (inout(char)[] s, char[] tmp=null) 24 { 25 auto len = s.length; 26 if (s.ptr) 27 { 28 if (len is 0) 29 { 30 s = cast(inout(char)[])("\0".dup); 31 } 32 else if (s[len-1] != 0) 33 { 34 if (tmp.length <= len) 35 tmp = new char[len+1]; 36 tmp [0..len] = s[]; 37 tmp [len] = 0; 38 s = cast(inout(char)[])tmp; 39 } 40 } 41 return s.ptr; 42 } 43 44 /********************************* 45 * Convert a series of char[] to C-style 0 terminated strings, using 46 * tmp as a workspace and dst as a place to put the resulting char*'s. 47 * This is handy for efficiently converting multiple strings at once. 48 * 49 * Returns a populated slice of dst 50 * 51 * Warning, don't read from the memory pointed to in the tmp variable after calling this function. 52 * 53 * Since: 0.99.7 54 */ 55 56 inout(char)*[] toStringz (char[] tmp, inout(char)*[] dst, inout(char)[][] strings...) 57 { 58 assert (dst.length >= strings.length); 59 60 auto len = strings.length; 61 foreach (s; strings) 62 len += s.length; 63 if (tmp.length < len) 64 tmp.length = len; 65 66 foreach (i, s; strings) 67 { 68 dst[i] = toStringz (s, tmp); 69 tmp = tmp [s.length + 1 .. len]; 70 } 71 return dst [0 .. strings.length]; 72 } 73 74 /********************************* 75 * Convert a C-style 0 terminated string to an array of char 76 */ 77 78 inout(char)[] fromStringz (inout(char)* s) 79 { 80 return s ? s[0 .. strlenz(s)] : null; 81 } 82 83 /********************************* 84 * Convert array of wchars s[] to a C-style 0 terminated string. 85 */ 86 87 inout(wchar)* toString16z (inout(wchar)[] s) 88 { 89 if (s.ptr) 90 if (! (s.length && s[$-1] is 0)) 91 s = cast(inout(wchar)[])(s ~ "\0"w); 92 return s.ptr; 93 } 94 95 /********************************* 96 * Convert a C-style 0 terminated string to an array of wchar 97 */ 98 99 inout(wchar)[] fromString16z (inout(wchar)* s) 100 { 101 return s ? s[0 .. strlenz(s)] : null; 102 } 103 104 /********************************* 105 * Convert array of dchars s[] to a C-style 0 terminated string. 106 */ 107 108 inout(dchar)* toString32z (inout(dchar)[] s) 109 { 110 if (s.ptr) 111 if (! (s.length && s[$-1] is 0)) 112 s = cast(inout(dchar)[])(s ~ "\0"d); 113 return s.ptr; 114 } 115 116 /********************************* 117 * Convert a C-style 0 terminated string to an array of dchar 118 */ 119 120 inout(dchar)[] fromString32z (inout(dchar)* s) 121 { 122 return s ? s[0 .. strlenz(s)] : null; 123 } 124 125 /********************************* 126 * portable strlen 127 */ 128 129 size_t strlenz(T) (const(T)* s) 130 { 131 size_t i; 132 133 if (s) 134 while (*s++) 135 ++i; 136 return i; 137 } 138 139 140 141 debug (UnitTest) 142 { 143 import tango.stdc.stdio; 144 145 unittest 146 { 147 debug(string) printf("stdc.stringz.unittest\n"); 148 149 const(char)* p = toStringz("foo"); 150 assert(strlenz(p) == 3); 151 const(char)[] foo = "abbzxyzzy"; 152 p = toStringz(foo[3..5]); 153 assert(strlenz(p) == 2); 154 155 const(char)[] test = "\0"; 156 p = toStringz(test); 157 assert(*p == 0); 158 assert(p == test.ptr); 159 } 160 } 161