Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(580)

Side by Side Diff: base/strings/safe_sprintf.h

Issue 665483002: SafeSPrintf: use C++ variadic template (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use sizeof... Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/strings/OWNERS ('k') | base/strings/safe_sprintf_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_STRINGS_SAFE_SPRINTF_H_ 5 #ifndef BASE_STRINGS_SAFE_SPRINTF_H_
6 #define BASE_STRINGS_SAFE_SPRINTF_H_ 6 #define BASE_STRINGS_SAFE_SPRINTF_H_
7 7
8 #include "build/build_config.h" 8 #include "build/build_config.h"
9 9
10 #include <stddef.h> 10 #include <stddef.h>
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 #if !defined(NDEBUG) 211 #if !defined(NDEBUG)
212 // In debug builds, allow unit tests to artificially lower the kSSizeMax 212 // In debug builds, allow unit tests to artificially lower the kSSizeMax
213 // constant that is used as a hard upper-bound for all buffers. In normal 213 // constant that is used as a hard upper-bound for all buffers. In normal
214 // use, this constant should always be std::numeric_limits<ssize_t>::max(). 214 // use, this constant should always be std::numeric_limits<ssize_t>::max().
215 BASE_EXPORT void SetSafeSPrintfSSizeMaxForTest(size_t max); 215 BASE_EXPORT void SetSafeSPrintfSSizeMaxForTest(size_t max);
216 BASE_EXPORT size_t GetSafeSPrintfSSizeMaxForTest(); 216 BASE_EXPORT size_t GetSafeSPrintfSSizeMaxForTest();
217 #endif 217 #endif
218 218
219 } // namespace internal 219 } // namespace internal
220 220
221 // TODO(markus): C++11 has a much more concise and readable solution for 221 template<typename... Args>
222 // expressing what we are doing here. 222 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, Args... args) {
223
224 template<class T0, class T1, class T2, class T3, class T4,
225 class T5, class T6, class T7, class T8, class T9>
226 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
227 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
228 T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) {
229 // Use Arg() object to record type information and then copy arguments to an 223 // Use Arg() object to record type information and then copy arguments to an
230 // array to make it easier to iterate over them. 224 // array to make it easier to iterate over them.
231 const internal::Arg arg_array[] = { 225 const internal::Arg arg_array[] = { args... };
232 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 226 return internal::SafeSNPrintf(buf, N, fmt, arg_array, sizeof...(args));
233 };
234 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
235 } 227 }
236 228
237 template<size_t N, 229 template<size_t N, typename... Args>
238 class T0, class T1, class T2, class T3, class T4, 230 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, Args... args) {
239 class T5, class T6, class T7, class T8, class T9>
240 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt,
241 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
242 T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9) {
243 // Use Arg() object to record type information and then copy arguments to an 231 // Use Arg() object to record type information and then copy arguments to an
244 // array to make it easier to iterate over them. 232 // array to make it easier to iterate over them.
245 const internal::Arg arg_array[] = { 233 const internal::Arg arg_array[] = { args... };
246 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 234 return internal::SafeSNPrintf(buf, N, fmt, arg_array, sizeof...(args));
247 };
248 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
249 }
250
251 template<class T0, class T1, class T2, class T3, class T4,
252 class T5, class T6, class T7, class T8>
253 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
254 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
255 T5 arg5, T6 arg6, T7 arg7, T8 arg8) {
256 // Use Arg() object to record type information and then copy arguments to an
257 // array to make it easier to iterate over them.
258 const internal::Arg arg_array[] = {
259 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
260 };
261 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
262 }
263
264 template<size_t N,
265 class T0, class T1, class T2, class T3, class T4, class T5,
266 class T6, class T7, class T8>
267 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt,
268 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
269 T5 arg5, T6 arg6, T7 arg7, T8 arg8) {
270 // Use Arg() object to record type information and then copy arguments to an
271 // array to make it easier to iterate over them.
272 const internal::Arg arg_array[] = {
273 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
274 };
275 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
276 }
277
278 template<class T0, class T1, class T2, class T3, class T4, class T5,
279 class T6, class T7>
280 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
281 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
282 T5 arg5, T6 arg6, T7 arg7) {
283 // Use Arg() object to record type information and then copy arguments to an
284 // array to make it easier to iterate over them.
285 const internal::Arg arg_array[] = {
286 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7
287 };
288 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
289 }
290
291 template<size_t N,
292 class T0, class T1, class T2, class T3, class T4, class T5,
293 class T6, class T7>
294 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt,
295 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
296 T5 arg5, T6 arg6, T7 arg7) {
297 // Use Arg() object to record type information and then copy arguments to an
298 // array to make it easier to iterate over them.
299 const internal::Arg arg_array[] = {
300 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7
301 };
302 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
303 }
304
305 template<class T0, class T1, class T2, class T3, class T4, class T5,
306 class T6>
307 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
308 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
309 T5 arg5, T6 arg6) {
310 // Use Arg() object to record type information and then copy arguments to an
311 // array to make it easier to iterate over them.
312 const internal::Arg arg_array[] = {
313 arg0, arg1, arg2, arg3, arg4, arg5, arg6
314 };
315 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
316 }
317
318 template<size_t N,
319 class T0, class T1, class T2, class T3, class T4, class T5,
320 class T6>
321 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt,
322 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5,
323 T6 arg6) {
324 // Use Arg() object to record type information and then copy arguments to an
325 // array to make it easier to iterate over them.
326 const internal::Arg arg_array[] = {
327 arg0, arg1, arg2, arg3, arg4, arg5, arg6
328 };
329 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
330 }
331
332 template<class T0, class T1, class T2, class T3, class T4, class T5>
333 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
334 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) {
335 // Use Arg() object to record type information and then copy arguments to an
336 // array to make it easier to iterate over them.
337 const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3, arg4, arg5 };
338 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
339 }
340
341 template<size_t N,
342 class T0, class T1, class T2, class T3, class T4, class T5>
343 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt,
344 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) {
345 // Use Arg() object to record type information and then copy arguments to an
346 // array to make it easier to iterate over them.
347 const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3, arg4, arg5 };
348 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
349 }
350
351 template<class T0, class T1, class T2, class T3, class T4>
352 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
353 T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
354 // Use Arg() object to record type information and then copy arguments to an
355 // array to make it easier to iterate over them.
356 const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3, arg4 };
357 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
358 }
359
360 template<size_t N, class T0, class T1, class T2, class T3, class T4>
361 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, T0 arg0, T1 arg1,
362 T2 arg2, T3 arg3, T4 arg4) {
363 // Use Arg() object to record type information and then copy arguments to an
364 // array to make it easier to iterate over them.
365 const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3, arg4 };
366 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
367 }
368
369 template<class T0, class T1, class T2, class T3>
370 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
371 T0 arg0, T1 arg1, T2 arg2, T3 arg3) {
372 // Use Arg() object to record type information and then copy arguments to an
373 // array to make it easier to iterate over them.
374 const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3 };
375 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
376 }
377
378 template<size_t N, class T0, class T1, class T2, class T3>
379 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt,
380 T0 arg0, T1 arg1, T2 arg2, T3 arg3) {
381 // Use Arg() object to record type information and then copy arguments to an
382 // array to make it easier to iterate over them.
383 const internal::Arg arg_array[] = { arg0, arg1, arg2, arg3 };
384 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
385 }
386
387 template<class T0, class T1, class T2>
388 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt,
389 T0 arg0, T1 arg1, T2 arg2) {
390 // Use Arg() object to record type information and then copy arguments to an
391 // array to make it easier to iterate over them.
392 const internal::Arg arg_array[] = { arg0, arg1, arg2 };
393 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
394 }
395
396 template<size_t N, class T0, class T1, class T2>
397 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, T0 arg0, T1 arg1,
398 T2 arg2) {
399 // Use Arg() object to record type information and then copy arguments to an
400 // array to make it easier to iterate over them.
401 const internal::Arg arg_array[] = { arg0, arg1, arg2 };
402 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
403 }
404
405 template<class T0, class T1>
406 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, T0 arg0, T1 arg1) {
407 // Use Arg() object to record type information and then copy arguments to an
408 // array to make it easier to iterate over them.
409 const internal::Arg arg_array[] = { arg0, arg1 };
410 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
411 }
412
413 template<size_t N, class T0, class T1>
414 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, T0 arg0, T1 arg1) {
415 // Use Arg() object to record type information and then copy arguments to an
416 // array to make it easier to iterate over them.
417 const internal::Arg arg_array[] = { arg0, arg1 };
418 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
419 }
420
421 template<class T0>
422 ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, T0 arg0) {
423 // Use Arg() object to record type information and then copy arguments to an
424 // array to make it easier to iterate over them.
425 const internal::Arg arg_array[] = { arg0 };
426 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
427 }
428
429 template<size_t N, class T0>
430 ssize_t SafeSPrintf(char (&buf)[N], const char* fmt, T0 arg0) {
431 // Use Arg() object to record type information and then copy arguments to an
432 // array to make it easier to iterate over them.
433 const internal::Arg arg_array[] = { arg0 };
434 return internal::SafeSNPrintf(buf, N, fmt, arg_array, arraysize(arg_array));
435 } 235 }
436 236
437 // Fast-path when we don't actually need to substitute any arguments. 237 // Fast-path when we don't actually need to substitute any arguments.
438 BASE_EXPORT ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt); 238 BASE_EXPORT ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt);
439 template<size_t N> 239 template<size_t N>
440 inline ssize_t SafeSPrintf(char (&buf)[N], const char* fmt) { 240 inline ssize_t SafeSPrintf(char (&buf)[N], const char* fmt) {
441 return SafeSNPrintf(buf, N, fmt); 241 return SafeSNPrintf(buf, N, fmt);
442 } 242 }
443 243
444 } // namespace strings 244 } // namespace strings
445 } // namespace base 245 } // namespace base
446 246
447 #endif // BASE_STRINGS_SAFE_SPRINTF_H_ 247 #endif // BASE_STRINGS_SAFE_SPRINTF_H_
OLDNEW
« no previous file with comments | « base/strings/OWNERS ('k') | base/strings/safe_sprintf_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698