Convert a string representing an amount of memory into the number of * bytes, so for instance memtoll("1Gb") will return 1073741824 that is * (1024*1024*1024). * * On parsing error, if *err is not NULL, it's set to 1, otherwise it's * set to 0. On error the function return value is 0, regardless of the * fact 'err' is NULL or not. */
| 193 | * set to 0. On error the function return value is 0, regardless of the |
| 194 | * fact 'err' is NULL or not. */ |
| 195 | long long memtoll(const char *p, int *err) { |
| 196 | const char *u; |
| 197 | char buf[128]; |
| 198 | long mul; /* unit multiplier */ |
| 199 | long long val; |
| 200 | unsigned int digits; |
| 201 | |
| 202 | if (err) *err = 0; |
| 203 | |
| 204 | /* Search the first non digit character. */ |
| 205 | u = p; |
| 206 | if (*u == '-') u++; |
| 207 | while(*u && isdigit(*u)) u++; |
| 208 | if (*u == '\0' || !strcasecmp(u,"b")) { |
| 209 | mul = 1; |
| 210 | } else if (!strcasecmp(u,"k")) { |
| 211 | mul = 1000; |
| 212 | } else if (!strcasecmp(u,"kb")) { |
| 213 | mul = 1024; |
| 214 | } else if (!strcasecmp(u,"m")) { |
| 215 | mul = 1000*1000; |
| 216 | } else if (!strcasecmp(u,"mb")) { |
| 217 | mul = 1024*1024; |
| 218 | } else if (!strcasecmp(u,"g")) { |
| 219 | mul = 1000L*1000*1000; |
| 220 | } else if (!strcasecmp(u,"gb")) { |
| 221 | mul = 1024L*1024*1024; |
| 222 | } else { |
| 223 | if (err) *err = 1; |
| 224 | return 0; |
| 225 | } |
| 226 | |
| 227 | /* Copy the digits into a buffer, we'll use strtoll() to convert |
| 228 | * the digit (without the unit) into a number. */ |
| 229 | digits = u-p; |
| 230 | if (digits >= sizeof(buf)) { |
| 231 | if (err) *err = 1; |
| 232 | return 0; |
| 233 | } |
| 234 | memcpy(buf,p,digits); |
| 235 | buf[digits] = '\0'; |
| 236 | |
| 237 | char *endptr; |
| 238 | errno = 0; |
| 239 | val = strtoll(buf,&endptr,10); |
| 240 | if ((val == 0 && errno == EINVAL) || *endptr != '\0') { |
| 241 | if (err) *err = 1; |
| 242 | return 0; |
| 243 | } |
| 244 | return val*mul; |
| 245 | } |
| 246 | |
| 247 | /* Search a memory buffer for any set of bytes, like strpbrk(). |
| 248 | * Returns pointer to first found char or NULL. |
no test coverage detected