mini_string.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_INSTALLER_MINI_INSTALLER_MINI_STRING_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_INSTALLER_MINI_INSTALLER_MINI_STRING_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef COMPILE_ASSERT 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// COMPILE_ASSERT macro borrowed from basictypes.h 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <bool> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CompileAssert {}; 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPILE_ASSERT(expr, msg) \ 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace mini_installer { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NOTE: Do not assume that these string functions support UTF encoding. 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is fine for the purposes of the mini_installer, but you have 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// been warned! 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Formats a sequence of |bytes| as hex. The |str| buffer must have room for 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// at least 2*|size| + 1. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HexEncode(const void* bytes, size_t size, wchar_t* str, size_t str_size); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Counts the number of characters in the string up to a maximum of 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// alloc_size. The highest return value from this function can therefore be 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// alloc_size - 1 since |alloc_size| includes the \0 terminator. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t SafeStrLen(const wchar_t* str, size_t alloc_size); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simple replacement for CRT string copy method that does not overflow. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if the source was copied successfully otherwise returns false. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Parameter src is assumed to be NULL terminated and the NULL character is 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copied over to string dest. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SafeStrCopy(wchar_t* dest, size_t dest_size, const wchar_t* src); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simple replacement for CRT string copy method that does not overflow. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if the source was copied successfully otherwise returns false. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Parameter src is assumed to be NULL terminated and the NULL character is 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copied over to string dest. If the return value is false, the |dest| 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// string should be the same as it was before. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SafeStrCat(wchar_t* dest, size_t dest_size, const wchar_t* src); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Function to check if a string (specified by str) ends with another string 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (specified by end_str). 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StrEndsWith(const wchar_t* str, const wchar_t* end_str); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Function to check if a string (specified by str) starts with another string 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (specified by start_str). 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool StrStartsWith(const wchar_t* str, const wchar_t* start_str); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Case insensitive search of the first occurrence of |find| in |source|. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t* SearchStringI(const wchar_t* source, const wchar_t* find); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Searches for |tag| within |str|. Returns true if |tag| is found and is 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// immediately followed by '-' or is at the end of the string. If |position| 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is non-NULL, the location of the tag is returned in |*position| on success. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FindTagInStr(const wchar_t* str, const wchar_t* tag, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t** position); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Takes the path to file and returns a pointer to the filename component. For 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// example for input of c:\full\path\to\file.ext it returns pointer to file.ext. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It returns NULL if extension or path separator is not found. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |size| is the number of characters in |path| not including the string 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// terminator. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)wchar_t* GetNameFromPathExt(wchar_t* path, size_t size); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A string class that manages a fixed size buffer on the stack. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The methods in the class are based on the above string methods and the 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// class additionally is careful about proper buffer termination. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <size_t kCapacity> 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class StackString { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StackString() { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(kCapacity != 0, invalid_buffer_size); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_[kCapacity] = L'\0'; // We always reserve 1 more than asked for. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clear(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We do not expose a constructor that accepts a string pointer on purpose. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We expect the caller to call assign() and handle failures. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the number of reserved characters in this buffer, _including_ 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the reserved char for the terminator. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t capacity() const { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kCapacity; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wchar_t* get() { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return buffer_; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool assign(const wchar_t* str) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SafeStrCopy(buffer_, kCapacity, str); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool append(const wchar_t* str) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SafeStrCat(buffer_, kCapacity, str); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void clear() { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_[0] = L'\0'; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t length() const { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SafeStrLen(buffer_, kCapacity); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Does a case insensitive search for a substring. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* findi(const wchar_t* find) const { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SearchStringI(buffer_, find); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Case insensitive string compare. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int comparei(const wchar_t* str) const { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return lstrcmpiW(buffer_, str); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Case sensitive string compare. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int compare(const wchar_t* str) const { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return lstrcmpW(buffer_, str); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Terminates the string at the specified location. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: this method has no effect if this object's length is less than 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |location|. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool truncate_at(size_t location) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (location >= kCapacity) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_[location] = L'\0'; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We reserve 1 more than what is asked for as a safeguard against 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // off-by-one errors. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wchar_t buffer_[kCapacity + 1]; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StackString(const StackString&); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StackString& operator=(const StackString&); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace mini_installer 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CHROME_INSTALLER_MINI_INSTALLER_MINI_STRING_H_ 147