1 //this file is part of notepad++ 2 //Copyright (C)2003 Don HO <donho@altern.org> 3 // 4 //This program is free software; you can redistribute it and/or 5 //modify it under the terms of the GNU General Public License 6 //as published by the Free Software Foundation; either 7 //version 2 of the License, or (at your option) any later version. 8 // 9 //This program is distributed in the hope that it will be useful, 10 //but WITHOUT ANY WARRANTY; without even the implied warranty of 11 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 //GNU General Public License for more details. 13 // 14 //You should have received a copy of the GNU General Public License 15 //along with this program; if not, write to the Free Software 16 //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 /** 18 * 19 * 20 * Author: dokutoku, https://twitter.com/dokutoku3 21 * License: GPL-2.0 or later 22 */ 23 module npp_api.pluginfunc..string; 24 25 26 private static import std.format; 27 private static import std.traits; 28 29 template c_string(string input_string) 30 { 31 enum string c_string = (input_string.length == 0) ? ("\0") : ((input_string[$ - 1] != '\0') ? (input_string ~ "\0") : (input_string)); 32 } 33 34 template c_wstring(wstring input_string) 35 { 36 enum wstring c_wstring = (input_string.length == 0) ? ("\0"w) : ((input_string[$ - 1] != '\0') ? ((input_string ~ "\0"w)) : (input_string)); 37 } 38 39 pure nothrow @safe @nogc 40 void to_c_wstring(size_t LENGTH)(const wchar[] input, ref wchar[LENGTH] buffer) 41 42 in 43 { 44 assert(LENGTH >= (input.length + 1)); 45 } 46 47 do 48 { 49 size_t i = 0; 50 51 buffer[0 .. input.length] = input[0 .. input.length]; 52 buffer[input.length + 1] = '\0'; 53 } 54 55 pure nothrow @safe @nogc 56 size_t count_string(S)(const S c_wstring) 57 if (std.traits.isStaticArray!(S)) 58 59 do 60 { 61 size_t i = 0; 62 63 for (; (i < c_wstring.length) && (c_wstring[i] != '\0') && (c_wstring[i] != '\xFF'); i++) { 64 } 65 66 return i; 67 } 68 69 /** 70 * 文字列終端を'\0'にするようにしたしたコピー関数 71 */ 72 pragma(inline, true) 73 pure nothrow @safe @nogc 74 void copy_string(S_array, T_array)(ref S_array output_string, const T_array input_string) 75 if (std.traits.isArray!(S_array) && std.traits.isDynamicArray!(T_array)) 76 77 in 78 { 79 assert(input_string.length != 0); 80 assert(output_string.length != 0); 81 assert(output_string.length >= input_string.length); 82 83 //not dchar 84 assert(output_string[0].max >= wchar.max); 85 assert(output_string[0].max == input_string[0].max); 86 } 87 88 out 89 { 90 for (size_t i = 0; i < output_string.length; i++) { 91 assert(output_string[i] != '\xFF'); 92 } 93 94 assert(output_string[$ - 1] == '\0'); 95 } 96 97 do 98 { 99 output_string[] = '\0'; 100 size_t c_max = output_string.length - 1; 101 102 for (size_t i = 0; (i < c_max) && (i < input_string.length) && (input_string[i] != '\0') && (input_string[i] != '\xFF'); i++) { 103 output_string[i] = input_string[i]; 104 } 105 } 106 107 pure nothrow @safe @nogc 108 wchar[LENGTH] copy_string(size_t LENGTH)(const wchar[LENGTH] input_string) 109 110 out(result) 111 { 112 for (size_t i = 0; i < result.length; i++) { 113 assert(result[i] != '\xFF'); 114 } 115 116 assert(result[$ - 1] == '\0'); 117 } 118 119 do 120 { 121 wchar[LENGTH] output_string; 122 output_string[] = '\0'; 123 size_t c_max = output_string.length - 1; 124 125 for (size_t i = 0; (i < c_max) && (input_string[i] != '\0') && (input_string[i] != '\xFF'); i++) { 126 output_string[i] = input_string[i]; 127 } 128 129 return output_string; 130 } 131 132 version (Not_betterC): 133 134 pure nothrow @safe 135 wstring to_c_wstring(const wchar[] input) 136 137 do 138 { 139 return (input ~ '\0').idup; 140 } 141 142 pure nothrow @safe 143 immutable (C)[] from_stringz(C, size_t INPUT_LENGTH)(const ref C[INPUT_LENGTH] input) 144 if (std.traits.isSomeChar!(C)) 145 146 in 147 { 148 static assert(INPUT_LENGTH >= 1); 149 } 150 151 do 152 { 153 size_t i = 0; 154 155 for (; (i < INPUT_LENGTH) && (input[i] != '\0') && (input[i] != '\xFF'); i++) { 156 } 157 158 return input[0 .. i].idup; 159 } 160 161 pure nothrow @safe 162 immutable (C)[] from_stringz(C)(const ref C[] input) 163 if (std.traits.isSomeChar!(C)) 164 165 in 166 { 167 assert(input.length >= 1); 168 } 169 170 do 171 { 172 size_t i = 0; 173 174 for (; (i < input.length) && (input[i] != '\0') && (input[i] != '\xFF'); i++) { 175 } 176 177 return input[0 .. i].idup; 178 } 179 180 pure nothrow @trusted 181 immutable (C)[] from_stringz(C)(const C* input) 182 if (std.traits.isSomeChar!(C)) 183 184 do 185 { 186 size_t i = 0; 187 C[] output_buf; 188 189 for (; ((*(input + i)) != '\0') && (*(input + i)) != '\xFF'; i++) { 190 output_buf ~= *(input + i); 191 } 192 193 output_buf ~= '\0'; 194 195 return output_buf.idup; 196 } 197 198 pure nothrow @trusted 199 immutable (C)[] from_stringz(C)(const C* input, size_t max_length) 200 if (std.traits.isSomeChar!(C)) 201 202 do 203 { 204 if (max_length == 0) { 205 return null; 206 } 207 208 size_t i = 0; 209 C[] output_buf = new C[max_length]; 210 211 for (; (i < max_length) && ((*(input + i)) != '\0') && ((*(input + i)) != '\xFF'); i++) { 212 output_buf[i] = *(input + i); 213 } 214 215 return output_buf[0 .. i].idup; 216 } 217 218 pure nothrow @safe 219 immutable (C)[] to_cstring(C, size_t INPUT_LENGTH)(const ref C[INPUT_LENGTH] input) 220 if (std.traits.isSomeChar!(C)) 221 222 in 223 { 224 static assert(INPUT_LENGTH >= 2); 225 } 226 227 do 228 { 229 enum size_t c_max = INPUT_LENGTH - 1; 230 size_t i = 0; 231 C[INPUT_LENGTH] output_buf; 232 233 for (; (i < c_max) && (input[i] != '\0') && (input[i] != '\xFF'); i++) { 234 output_buf[i] = input[i]; 235 } 236 237 i++; 238 output_buf[i] = '\0'; 239 240 return output_buf[0 .. i].idup; 241 } 242 243 pure nothrow @safe 244 immutable (C)[] to_cstring(C, size_t INPUT_LENGTH, size_t OUTPUT_LENGTH)(const ref C[INPUT_LENGTH] input, ref C[OUTPUT_LENGTH] output_buf) 245 if (std.traits.isSomeChar!(C)) 246 247 in 248 { 249 static assert(input.length >= 2); 250 static assert(OUTPUT_LENGTH >= INPUT_LENGTH); 251 } 252 253 do 254 { 255 size_t i = 0; 256 size_t c_max = INPUT_LENGTH - 1; 257 258 for (; (i < c_max) && (input[i] != '\0') && (input[i] != '\xFF'); i++) { 259 output_buf[i] = input[i]; 260 } 261 262 i++; 263 output_buf[i] = '\0'; 264 265 return output_buf[0 .. i].idup; 266 } 267 268 pure nothrow @trusted 269 immutable (C)[] to_cstring(C)(const C* input, size_t max_length) 270 if (std.traits.isSomeChar!(C)) 271 272 do 273 { 274 if (max_length == 0) { 275 return null; 276 } 277 278 size_t i = 0; 279 size_t c_max = max_length - 1; 280 C[] output_buf = new C[max_length + 1]; 281 282 for (; (i < c_max) && ((*(input + i)) != '\0') && ((*(input + i)) != '\xFF'); i++) { 283 output_buf[i] = *(input + i); 284 } 285 286 i++; 287 output_buf[i] = '\0'; 288 289 return output_buf[0 .. i].idup; 290 }