blob: 02bccd0209cd4939c299a73604e0060bdba94378 [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
David Landell9146bfa2016-06-22 10:13:45 +020012#include <stdlib.h>
13
Jamie Madill8c5aeb62015-05-21 08:17:18 -040014#include <fstream>
15#include <sstream>
16
Jamie Madill8b9b7922016-05-19 13:13:37 -040017#include "common/platform.h"
18
Jamie Madill8c5aeb62015-05-21 08:17:18 -040019namespace angle
20{
21
Corentin Wallez47ac69c2015-11-24 11:15:57 -050022const char kWhitespaceASCII[] = " \f\n\r\t\v";
Jamie Madill8c5aeb62015-05-21 08:17:18 -040023
Corentin Wallez47ac69c2015-11-24 11:15:57 -050024std::vector<std::string> SplitString(const std::string &input,
25 const std::string &delimiters,
26 WhitespaceHandling whitespace,
27 SplitResult resultType)
28{
29 std::vector<std::string> result;
30 if (input.empty())
Jamie Madill8c5aeb62015-05-21 08:17:18 -040031 {
Corentin Wallez47ac69c2015-11-24 11:15:57 -050032 return result;
33 }
34
35 std::string::size_type start = 0;
36 while (start != std::string::npos)
37 {
38 auto end = input.find_first_of(delimiters, start);
39
40 std::string piece;
41 if (end == std::string::npos)
Jamie Madill8c5aeb62015-05-21 08:17:18 -040042 {
Corentin Wallez47ac69c2015-11-24 11:15:57 -050043 piece = input.substr(start);
44 start = std::string::npos;
45 }
46 else
47 {
48 piece = input.substr(start, end - start);
49 start = end + 1;
50 }
51
52 if (whitespace == TRIM_WHITESPACE)
53 {
54 piece = TrimString(piece, kWhitespaceASCII);
55 }
56
57 if (resultType == SPLIT_WANT_ALL || !piece.empty())
58 {
59 result.push_back(piece);
Jamie Madill8c5aeb62015-05-21 08:17:18 -040060 }
61 }
Corentin Wallez47ac69c2015-11-24 11:15:57 -050062
63 return result;
Jamie Madill8c5aeb62015-05-21 08:17:18 -040064}
65
66void SplitStringAlongWhitespace(const std::string &input,
67 std::vector<std::string> *tokensOut)
68{
Jamie Madill8c5aeb62015-05-21 08:17:18 -040069
70 std::istringstream stream(input);
71 std::string line;
72
73 while (std::getline(stream, line))
74 {
75 size_t prev = 0, pos;
Corentin Wallez47ac69c2015-11-24 11:15:57 -050076 while ((pos = line.find_first_of(kWhitespaceASCII, prev)) != std::string::npos)
Jamie Madill8c5aeb62015-05-21 08:17:18 -040077 {
78 if (pos > prev)
79 tokensOut->push_back(line.substr(prev, pos - prev));
80 prev = pos + 1;
81 }
82 if (prev < line.length())
83 tokensOut->push_back(line.substr(prev, std::string::npos));
84 }
85}
86
Corentin Wallez47ac69c2015-11-24 11:15:57 -050087std::string TrimString(const std::string &input, const std::string &trimChars)
88{
89 auto begin = input.find_first_not_of(trimChars);
90 if (begin == std::string::npos)
91 {
92 return "";
93 }
94
95 std::string::size_type end = input.find_last_not_of(trimChars);
96 if (end == std::string::npos)
97 {
98 return input.substr(begin);
99 }
100
101 return input.substr(begin, end - begin + 1);
102}
103
Jamie Madill8c5aeb62015-05-21 08:17:18 -0400104bool HexStringToUInt(const std::string &input, unsigned int *uintOut)
105{
Jamie Madillc7be82a2015-06-01 14:14:04 -0400106 unsigned int offset = 0;
107
108 if (input.size() >= 2 && input[0] == '0' && input[1] == 'x')
109 {
110 offset = 2u;
111 }
112
Jamie Madill8c5aeb62015-05-21 08:17:18 -0400113 // Simple validity check
Jamie Madillc7be82a2015-06-01 14:14:04 -0400114 if (input.find_first_not_of("0123456789ABCDEFabcdef", offset) != std::string::npos)
Jamie Madill8c5aeb62015-05-21 08:17:18 -0400115 {
116 return false;
117 }
118
119 std::stringstream inStream(input);
120 inStream >> std::hex >> *uintOut;
121 return !inStream.fail();
122}
123
124bool ReadFileToString(const std::string &path, std::string *stringOut)
125{
126 std::ifstream inFile(path.c_str());
Jamie Madillc7be82a2015-06-01 14:14:04 -0400127 if (inFile.fail())
128 {
129 return false;
130 }
Jamie Madill8c5aeb62015-05-21 08:17:18 -0400131
132 inFile.seekg(0, std::ios::end);
Jamie Madillc7be82a2015-06-01 14:14:04 -0400133 stringOut->reserve(static_cast<std::string::size_type>(inFile.tellg()));
Jamie Madill8c5aeb62015-05-21 08:17:18 -0400134 inFile.seekg(0, std::ios::beg);
135
Jamie Madillc7be82a2015-06-01 14:14:04 -0400136 stringOut->assign(std::istreambuf_iterator<char>(inFile), std::istreambuf_iterator<char>());
Jamie Madill8c5aeb62015-05-21 08:17:18 -0400137 return !inFile.fail();
138}
139
Jamie Madill8b9b7922016-05-19 13:13:37 -0400140Optional<std::vector<wchar_t>> WidenString(size_t length, const char *cString)
141{
142 std::vector<wchar_t> wcstring(length + 1);
143#if !defined(ANGLE_PLATFORM_WINDOWS)
144 size_t written = mbstowcs(wcstring.data(), cString, length + 1);
145 if (written == 0)
146 {
147 return Optional<std::vector<wchar_t>>::Invalid();
148 }
149#else
150 size_t convertedChars = 0;
151 errno_t err = mbstowcs_s(&convertedChars, wcstring.data(), length + 1, cString, _TRUNCATE);
152 if (err != 0)
153 {
154 return Optional<std::vector<wchar_t>>::Invalid();
155 }
156#endif
157 return Optional<std::vector<wchar_t>>(wcstring);
Jamie Madill8c5aeb62015-05-21 08:17:18 -0400158}
Jamie Madill8b9b7922016-05-19 13:13:37 -0400159
160} // namespace angle