misc.cpp revision 54b6cfa9a9e5b861a9930af873580d6dc20f773c
1/*
2 * Copyright (C) 2005 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//
18// Miscellaneous utility functions.
19//
20#include <utils/misc.h>
21
22#include <sys/stat.h>
23#include <string.h>
24#include <errno.h>
25#include <assert.h>
26#include <stdio.h>
27
28using namespace android;
29
30namespace android {
31
32/*
33 * Like strdup(), but uses C++ "new" operator instead of malloc.
34 */
35char* strdupNew(const char* str)
36{
37    char* newStr;
38    int len;
39
40    if (str == NULL)
41        return NULL;
42
43    len = strlen(str);
44    newStr = new char[len+1];
45    memcpy(newStr, str, len+1);
46
47    return newStr;
48}
49
50/*
51 * Concatenate an argument vector.
52 */
53char* concatArgv(int argc, const char* const argv[])
54{
55    char* newStr = NULL;
56    int len, totalLen, posn, idx;
57
58    /*
59     * First, figure out the total length.
60     */
61    totalLen = idx = 0;
62    while (1) {
63        if (idx == argc || argv[idx] == NULL)
64            break;
65        if (idx)
66            totalLen++;  // leave a space between args
67        totalLen += strlen(argv[idx]);
68        idx++;
69    }
70
71    /*
72     * Alloc the string.
73     */
74    newStr = new char[totalLen +1];
75    if (newStr == NULL)
76        return NULL;
77
78    /*
79     * Finally, allocate the string and copy data over.
80     */
81    idx = posn = 0;
82    while (1) {
83        if (idx == argc || argv[idx] == NULL)
84            break;
85        if (idx)
86            newStr[posn++] = ' ';
87
88        len = strlen(argv[idx]);
89        memcpy(&newStr[posn], argv[idx], len);
90        posn += len;
91
92        idx++;
93    }
94
95    assert(posn == totalLen);
96    newStr[posn] = '\0';
97
98    return newStr;
99}
100
101/*
102 * Count the #of args in an argument vector.  Don't count the final NULL.
103 */
104int countArgv(const char* const argv[])
105{
106    int count = 0;
107
108    while (argv[count] != NULL)
109        count++;
110
111    return count;
112}
113
114
115#include <stdio.h>
116/*
117 * Get a file's type.
118 */
119FileType getFileType(const char* fileName)
120{
121    struct stat sb;
122
123    if (stat(fileName, &sb) < 0) {
124        if (errno == ENOENT || errno == ENOTDIR)
125            return kFileTypeNonexistent;
126        else {
127            fprintf(stderr, "getFileType got errno=%d on '%s'\n",
128                errno, fileName);
129            return kFileTypeUnknown;
130        }
131    } else {
132        if (S_ISREG(sb.st_mode))
133            return kFileTypeRegular;
134        else if (S_ISDIR(sb.st_mode))
135            return kFileTypeDirectory;
136        else if (S_ISCHR(sb.st_mode))
137            return kFileTypeCharDev;
138        else if (S_ISBLK(sb.st_mode))
139            return kFileTypeBlockDev;
140        else if (S_ISFIFO(sb.st_mode))
141            return kFileTypeFifo;
142#ifdef HAVE_SYMLINKS
143        else if (S_ISLNK(sb.st_mode))
144            return kFileTypeSymlink;
145        else if (S_ISSOCK(sb.st_mode))
146            return kFileTypeSocket;
147#endif
148        else
149            return kFileTypeUnknown;
150    }
151}
152
153/*
154 * Get a file's modification date.
155 */
156time_t getFileModDate(const char* fileName)
157{
158    struct stat sb;
159
160    if (stat(fileName, &sb) < 0)
161        return (time_t) -1;
162
163    return sb.st_mtime;
164}
165
166/*
167 * Round up to the next highest power of 2.
168 *
169 * Found on http://graphics.stanford.edu/~seander/bithacks.html.
170 */
171unsigned int roundUpPower2(unsigned int val)
172{
173    val--;
174    val |= val >> 1;
175    val |= val >> 2;
176    val |= val >> 4;
177    val |= val >> 8;
178    val |= val >> 16;
179    val++;
180
181    return val;
182}
183
184}; // namespace android
185
186