1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_INSTALLER_MINI_INSTALLER_MINI_STRING_H_ 6 #define CHROME_INSTALLER_MINI_INSTALLER_MINI_STRING_H_ 7 8 #ifndef COMPILE_ASSERT 9 // COMPILE_ASSERT macro borrowed from basictypes.h 10 template <bool> 11 struct CompileAssert {}; 12 #define COMPILE_ASSERT(expr, msg) \ 13 typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] 14 #endif 15 16 namespace mini_installer { 17 18 // NOTE: Do not assume that these string functions support UTF encoding. 19 // This is fine for the purposes of the mini_installer, but you have 20 // been warned! 21 22 // Formats a sequence of |bytes| as hex. The |str| buffer must have room for 23 // at least 2*|size| + 1. 24 bool HexEncode(const void* bytes, size_t size, wchar_t* str, size_t str_size); 25 26 // Counts the number of characters in the string up to a maximum of 27 // alloc_size. The highest return value from this function can therefore be 28 // alloc_size - 1 since |alloc_size| includes the \0 terminator. 29 size_t SafeStrLen(const wchar_t* str, size_t alloc_size); 30 31 // Simple replacement for CRT string copy method that does not overflow. 32 // Returns true if the source was copied successfully otherwise returns false. 33 // Parameter src is assumed to be NULL terminated and the NULL character is 34 // copied over to string dest. 35 bool SafeStrCopy(wchar_t* dest, size_t dest_size, const wchar_t* src); 36 37 // Simple replacement for CRT string copy method that does not overflow. 38 // Returns true if the source was copied successfully otherwise returns false. 39 // Parameter src is assumed to be NULL terminated and the NULL character is 40 // copied over to string dest. If the return value is false, the |dest| 41 // string should be the same as it was before. 42 bool SafeStrCat(wchar_t* dest, size_t dest_size, const wchar_t* src); 43 44 // Function to check if a string (specified by str) ends with another string 45 // (specified by end_str). 46 bool StrEndsWith(const wchar_t* str, const wchar_t* end_str); 47 48 // Function to check if a string (specified by str) starts with another string 49 // (specified by start_str). 50 bool StrStartsWith(const wchar_t* str, const wchar_t* start_str); 51 52 // Case insensitive search of the first occurrence of |find| in |source|. 53 const wchar_t* SearchStringI(const wchar_t* source, const wchar_t* find); 54 55 // Searches for |tag| within |str|. Returns true if |tag| is found and is 56 // immediately followed by '-' or is at the end of the string. If |position| 57 // is non-NULL, the location of the tag is returned in |*position| on success. 58 bool FindTagInStr(const wchar_t* str, const wchar_t* tag, 59 const wchar_t** position); 60 61 // Takes the path to file and returns a pointer to the filename component. For 62 // example for input of c:\full\path\to\file.ext it returns pointer to file.ext. 63 // It returns NULL if extension or path separator is not found. 64 // |size| is the number of characters in |path| not including the string 65 // terminator. 66 wchar_t* GetNameFromPathExt(wchar_t* path, size_t size); 67 68 // A string class that manages a fixed size buffer on the stack. 69 // The methods in the class are based on the above string methods and the 70 // class additionally is careful about proper buffer termination. 71 template <size_t kCapacity> 72 class StackString { 73 public: StackString()74 StackString() { 75 COMPILE_ASSERT(kCapacity != 0, invalid_buffer_size); 76 buffer_[kCapacity] = L'\0'; // We always reserve 1 more than asked for. 77 clear(); 78 } 79 80 // We do not expose a constructor that accepts a string pointer on purpose. 81 // We expect the caller to call assign() and handle failures. 82 83 // Returns the number of reserved characters in this buffer, _including_ 84 // the reserved char for the terminator. capacity()85 size_t capacity() const { 86 return kCapacity; 87 } 88 get()89 wchar_t* get() { 90 return buffer_; 91 } 92 assign(const wchar_t * str)93 bool assign(const wchar_t* str) { 94 return SafeStrCopy(buffer_, kCapacity, str); 95 } 96 append(const wchar_t * str)97 bool append(const wchar_t* str) { 98 return SafeStrCat(buffer_, kCapacity, str); 99 } 100 clear()101 void clear() { 102 buffer_[0] = L'\0'; 103 } 104 length()105 size_t length() const { 106 return SafeStrLen(buffer_, kCapacity); 107 } 108 109 // Does a case insensitive search for a substring. findi(const wchar_t * find)110 const wchar_t* findi(const wchar_t* find) const { 111 return SearchStringI(buffer_, find); 112 } 113 114 // Case insensitive string compare. comparei(const wchar_t * str)115 int comparei(const wchar_t* str) const { 116 return lstrcmpiW(buffer_, str); 117 } 118 119 // Case sensitive string compare. compare(const wchar_t * str)120 int compare(const wchar_t* str) const { 121 return lstrcmpW(buffer_, str); 122 } 123 124 // Terminates the string at the specified location. 125 // Note: this method has no effect if this object's length is less than 126 // |location|. truncate_at(size_t location)127 bool truncate_at(size_t location) { 128 if (location >= kCapacity) 129 return false; 130 buffer_[location] = L'\0'; 131 return true; 132 } 133 134 protected: 135 // We reserve 1 more than what is asked for as a safeguard against 136 // off-by-one errors. 137 wchar_t buffer_[kCapacity + 1]; 138 139 private: 140 StackString(const StackString&); 141 StackString& operator=(const StackString&); 142 }; 143 144 } // namespace mini_installer 145 146 #endif // CHROME_INSTALLER_MINI_INSTALLER_MINI_STRING_H_ 147