- int i;
- size_t line_len;
-
- if (!line || !*line)
- return -E_UNKNOWN_STAT_ITEM;
- line_len = strlen(line);
- FOR_EACH_STATUS_ITEM(i) {
- const char *s = status_item_list[i];
- size_t item_len = strlen(s);
-
- if (line_len > item_len && line[item_len] == ':' &&
- !strncmp(line, s, item_len))
- return i;
+ char *buf = item_buf;
+ int len = num_bytes;
+
+ for (;;) {
+ int i, ret, item_len, item_num = 0;
+ if (len < MIN_STAT_ITEM_LEN)
+ break;
+ ret = read_size_header(buf);
+ if (ret < 0)
+ return ret;
+ item_len = ret;
+ if (item_len > len - 5) /* item not complete */
+ break;
+ for (i = 0; i < 2; i++) {
+ unsigned char c = buf[5 + i];
+ item_num <<= 4;
+ if (c >= '0' && c <= '9') {
+ item_num += c - '0';
+ continue;
+ }
+ if (c >= 'a' && c <= 'f') {
+ item_num += c - 'a' + 10;
+ continue;
+ }
+ return -E_STAT_ITEM_PARSE;
+ }
+ if (buf[7] != ':' || buf[5 + item_len - 1] != '\n')
+ return -E_STAT_ITEM_PARSE;
+ buf[5 + item_len - 1] = '\0';
+ if (item_num >= NUM_STAT_ITEMS)
+ PARA_WARNING_LOG("unknown status item %d: %s\n",
+ item_num, buf + 8);
+ else {
+ ret = item_handler(item_num, buf + 8);
+ if (ret < 0)
+ return ret;
+ }
+ buf += 5 + item_len;
+ len -= 5 + item_len;
+ assert(len >= 0 && buf <= item_buf + num_bytes);