blob: 73da759977641b23ccca6cf8d07039fb959e0c13 [file] [log] [blame]
Jamie Madill8c5aeb62015-05-21 08:17:18 -04001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// string_utils:
7// String helper functions.
8//
9
10#include "string_utils.h"
11
12#include <fstream>
13#include <sstream>
14
Jamie Madill8b9b7922016-05-19 13:13:37 -040015#include "common/platform.h"
16
Jamie Madill8c5aeb62015-05-21 08:17:18 -040017namespace angle
18{
19
Corentin Wallez47ac69c2015-11-24 11:15:57 -050020const char kWhitespaceASCII[] = " \f\n\r\t\v";
Jamie Madill8c5aeb62015-05-21 08:17:18 -040021
Corentin Wallez47ac69c2015-11-24 11:15:57 -050022std::vector<std::string> SplitString(const std::string &input,
23 const std::string &delimiters,
24 WhitespaceHandling whitespace,
25 SplitResult resultType)
26{
27 std::vector<std::string> result;
28 if (input.empty())
Jamie Madill8c5aeb62015-05-21 08:17:18 -040029 {
Corentin Wallez47ac69c2015-11-24 11:15:57 -050030 return result;
31 }
32
33 std::string::size_type start = 0;
34 while (start != std::string::npos)
35 {
36 auto end = input.find_first_of(delimiters, start);
37
38 std::string piece;
39 if (end == std::string::npos)
Jamie Madill8c5aeb62015-05-21 08:17:18 -040040 {
Corentin Wallez47ac69c2015-11-24 11:15:57 -050041 piece = input.substr(start);
42 start = std::string::npos;
43 }
44 else
45 {
46 piece = input.substr(start, end - start);
47 start = end + 1;
48 }
49
50 if (whitespace == TRIM_WHITESPACE)
51 {
52 piece = TrimString(piece, kWhitespaceASCII);
53 }
54
55 if (resultType == SPLIT_WANT_ALL || !piece.empty())
56 {
57 result.push_back(piece);
Jamie Madill8c5aeb62015-05-21 08:17:18 -040058 }
59 }
Corentin Wallez47ac69c2015-11-24 11:15:57 -050060
61 return result;
Jamie Madill8c5aeb62015-05-21 08:17:18 -040062}
63
64void SplitStringAlongWhitespace(const std::string &input,
65 std::vector<std::string> *tokensOut)
66{
Jamie Madill8c5aeb62015-05-21 08:17:18 -040067
68 std::istringstream stream(input);
69 std::string line;
70
71 while (std::getline(stream, line))
72 {
73 size_t prev = 0, pos;
Corentin Wallez47ac69c2015-11-24 11:15:57 -050074 while ((pos = line.find_first_of(kWhitespaceASCII, prev)) != std::string::npos)
Jamie Madill8c5aeb62015-05-21 08:17:18 -040075 {
76 if (pos > prev)
77 tokensOut->push_back(line.substr(prev, pos - prev));
78 prev = pos + 1;
79 }
80 if (prev < line.length())
81 tokensOut->push_back(line.substr(prev, std::string::npos));
82 }
83}
84
Corentin Wallez47ac69c2015-11-24 11:15:57 -050085std::string TrimString(const std::string &input, const std::string &trimChars)
86{
87 auto begin = input.find_first_not_of(trimChars);
88 if (begin == std::string::npos)
89 {
90 return "";
91 }
92
93 std::string::size_type end = input.find_last_not_of(trimChars);
94 if (end == std::string::npos)
95 {
96 return input.substr(begin);
97 }
98
99 return input.substr(begin, end - begin + 1);
100}
101
Jamie Madill8c5aeb62015-05-21 08:17:18 -0400102bool HexStringToUInt(const std::string &input, unsigned int *uintOut)
103{
Jamie Madillc7be82a2015-06-01 14:14:04 -0400104 unsigned int offset = 0;
105
106 if (input.size() >= 2 && input[0] == '0' && input[1] == 'x')
107 {
108 offset = 2u;
109 }
110
Jamie Madill8c5aeb62015-05-21 08:17:18 -0400111 // Simple validity check
Jamie Madillc7be82a2015-06-01 14:14:04 -0400112 if (input.find_first_not_of("0123456789ABCDEFabcdef", offset) != std::string::npos)
Jamie Madill8c5aeb62015-05-21 08:17:18 -0400113 {
114 return false;
115 }
116
117 std::stringstream inStream(input);
118 inStream >> std::hex >> *uintOut;
119 return !inStream.fail();
120}
121
122bool ReadFileToString(const std::string &path, std::string *stringOut)
123{
124 std::ifstream inFile(path.c_str());
Jamie Madillc7be82a2015-06-01 14:14:04 -0400125 if (inFile.fail())
126 {
127 return false;
128 }
Jamie Madill8c5aeb62015-05-21 08:17:18 -0400129
130 inFile.seekg(0, std::ios::end);
Jamie Madillc7be82a2015-06-01 14:14:04 -0400131 stringOut->reserve(static_cast<std::string::size_type>(inFile.tellg()));
Jamie Madill8c5aeb62015-05-21 08:17:18 -0400132 inFile.seekg(0, std::ios::beg);
133
Jamie Madillc7be82a2015-06-01 14:14:04 -0400134 stringOut->assign(std::istreambuf_iterator<char>(inFile), std::istreambuf_iterator<char>());
Jamie Madill8c5aeb62015-05-21 08:17:18 -0400135 return !inFile.fail();
136}
137
Jamie Madill8b9b7922016-05-19 13:13:37 -0400138Optional<std::vector<wchar_t>> WidenString(size_t length, const char *cString)
139{
140 std::vector<wchar_t> wcstring(length + 1);
141#if !defined(ANGLE_PLATFORM_WINDOWS)
142 size_t written = mbstowcs(wcstring.data(), cString, length + 1);
143 if (written == 0)
144 {
145 return Optional<std::vector<wchar_t>>::Invalid();
146 }
147#else
148 size_t convertedChars = 0;
149 errno_t err = mbstowcs_s(&convertedChars, wcstring.data(), length + 1, cString, _TRUNCATE);
150 if (err != 0)
151 {
152 return Optional<std::vector<wchar_t>>::Invalid();
153 }
154#endif
155 return Optional<std::vector<wchar_t>>(wcstring);
Jamie Madill8c5aeb62015-05-21 08:17:18 -0400156}
Jamie Madill8b9b7922016-05-19 13:13:37 -0400157
158} // namespace angle