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.
5 #include "chrome/installer/mini_installer/mini_string.h"
11 // Returns true if the given two ASCII characters are same (ignoring case).
12 bool EqualASCIICharI(wchar_t a
, wchar_t b
) {
13 if (a
>= L
'A' && a
<= L
'Z')
15 if (b
>= L
'A' && b
<= L
'Z')
22 namespace mini_installer
{
24 // Formats a sequence of |bytes| as hex. The |str| buffer must have room for
25 // at least 2*|size| + 1.
26 bool HexEncode(const void* bytes
, size_t size
, wchar_t* str
, size_t str_size
) {
27 if (str_size
<= (size
* 2))
30 static const wchar_t kHexChars
[] = L
"0123456789ABCDEF";
32 str
[size
* 2] = L
'\0';
34 for (size_t i
= 0; i
< size
; ++i
) {
35 char b
= reinterpret_cast<const char*>(bytes
)[i
];
36 str
[(i
* 2)] = kHexChars
[(b
>> 4) & 0xf];
37 str
[(i
* 2) + 1] = kHexChars
[b
& 0xf];
43 size_t SafeStrLen(const wchar_t* str
, size_t alloc_size
) {
44 if (!str
|| !alloc_size
)
47 while (--alloc_size
&& str
[len
] != L
'\0')
52 bool SafeStrCopy(wchar_t* dest
, size_t dest_size
, const wchar_t* src
) {
53 if (!dest
|| !dest_size
)
56 wchar_t* write
= dest
;
57 for (size_t remaining
= dest_size
; remaining
!= 0; --remaining
) {
58 if ((*write
++ = *src
++) == L
'\0')
62 // If we fail, we do not want to leave the string with partially copied
63 // contents. The reason for this is that we use these strings mostly for
64 // named objects such as files. If we copy a partial name, then that could
65 // match with something we do not want it to match with.
66 // Furthermore, since SafeStrCopy is called from SafeStrCat, we do not
67 // want to mutate the string in case the caller handles the error of a
68 // failed concatenation. For example:
70 // wchar_t buf[5] = {0};
71 // if (!SafeStrCat(buf, arraysize(buf), kLongName))
72 // SafeStrCat(buf, arraysize(buf), kShortName);
74 // If we were to return false in the first call to SafeStrCat but still
75 // mutate the buffer, the buffer will be in an unexpected state.
80 // Safer replacement for lstrcat function.
81 bool SafeStrCat(wchar_t* dest
, size_t dest_size
, const wchar_t* src
) {
82 // Use SafeStrLen instead of lstrlen just in case the |dest| buffer isn't
84 int str_len
= SafeStrLen(dest
, dest_size
);
85 return SafeStrCopy(dest
+ str_len
, dest_size
- str_len
, src
);
88 bool StrEndsWith(const wchar_t* str
, const wchar_t* end_str
) {
89 if (str
== NULL
|| end_str
== NULL
)
92 for (int i
= lstrlen(str
) - 1, j
= lstrlen(end_str
) - 1; j
>= 0; --i
, --j
) {
93 if (i
< 0 || !EqualASCIICharI(str
[i
], end_str
[j
]))
100 bool StrStartsWith(const wchar_t* str
, const wchar_t* start_str
) {
101 if (str
== NULL
|| start_str
== NULL
)
104 for (int i
= 0; start_str
[i
] != L
'\0'; ++i
) {
105 if (!EqualASCIICharI(str
[i
], start_str
[i
]))
112 const wchar_t* SearchStringI(const wchar_t* source
, const wchar_t* find
) {
113 if (!find
|| find
[0] == L
'\0')
116 const wchar_t* scan
= source
;
118 const wchar_t* s
= scan
;
119 const wchar_t* f
= find
;
121 while (*s
&& *f
&& EqualASCIICharI(*s
, *f
))
133 bool FindTagInStr(const wchar_t* str
,
135 const wchar_t** position
) {
136 int tag_length
= ::lstrlen(tag
);
137 const wchar_t* scan
= str
;
138 for (const wchar_t* tag_start
= SearchStringI(scan
, tag
);
140 tag_start
= SearchStringI(scan
, tag
)) {
141 scan
= tag_start
+ tag_length
;
142 if (*scan
== L
'-' || *scan
== L
'\0') {
143 if (position
!= NULL
)
144 *position
= tag_start
;
151 wchar_t* GetNameFromPathExt(wchar_t* path
, size_t size
) {
155 wchar_t* current
= &path
[size
- 1];
156 while (current
!= path
&& L
'\\' != *current
)
159 return (current
== path
) ? NULL
: (current
+ 1);
162 } // namespace mini_installer