shuichan_old/V1.4-Chinese/STM32F103_App1/m_app/proto.c

199 lines
5.1 KiB
C
Raw Normal View History

#include "proto.h"
#include <string.h>
const char *proto_locate(const char *json, const char *key)
{
char pat[24];
int klen = (int)strlen(key);
const char *p = json;
if (klen <= 0 || klen + 3 > (int)sizeof(pat)) return 0;
pat[0] = '"';
memcpy(pat + 1, key, klen);
pat[klen + 1] = '"';
pat[klen + 2] = '\0';
while ((p = strstr(p, pat)) != 0) {
const char *q = p + klen + 2;
while (*q == ' ' || *q == '\t') q++;
if (*q == ':') {
q++;
while (*q == ' ' || *q == '\t') q++;
return q;
}
/* 命中的是字符串值里的子串而非键名,继续向后找 */
p += 2;
}
return 0;
}
/* 提取 key 的值区域到 buf带花括号深度跟踪嵌套对象整体取出
* 1 0 */
static int proto_value_region(const char *json, const char *key, char *buf, int cap)
{
const char *p = proto_locate(json, key);
int i = 0;
int depth = 0;
if (!p) return 0;
while (p[i] && i < cap - 1) {
char c = p[i];
if (c == '{') {
depth++;
} else if (c == '}') {
if (depth == 0) break; /* 不属于本值的右括号 */
depth--;
if (depth == 0) { i++; break; } /* 嵌套对象结束 */
} else if (c == ',' && depth == 0) {
break; /* 顶层下一个字段 */
}
buf[i] = c;
i++;
}
buf[i] = '\0';
return 1;
}
int proto_get_bool(const char *json, const char *key, int *val)
{
char region[96];
char *q;
int len;
if (!proto_value_region(json, key, region, sizeof(region))) return 0;
len = (int)strlen(region);
/* 在值区域内找最先出现的 true/false 令牌(排除键名里的子串) */
for (q = region; q < region + len; q++) {
if (q + 4 <= region + len && strncmp(q, "true", 4) == 0 && (q == region || q[-1] != '"')) {
*val = 1;
return 1;
}
if (q + 5 <= region + len && strncmp(q, "false", 5) == 0 && (q == region || q[-1] != '"')) {
*val = 0;
return 1;
}
}
/* 兼容 0/1 */
if (region[0] == '0' || region[0] == '1') {
*val = region[0] - '0';
return 1;
}
return 0;
}
int proto_get_u32(const char *json, const char *key, uint32_t *val)
{
const char *p = proto_locate(json, key);
uint32_t v = 0;
if (!p || *p < '0' || *p > '9') return 0;
while (*p >= '0' && *p <= '9') {
v = v * 10 + (uint32_t)(*p - '0');
p++;
}
*val = v;
return 1;
}
int proto_get_hex16(const char *json, const char *key, uint16_t *val)
{
const char *p = proto_locate(json, key);
uint16_t v = 0;
int n = 0;
if (!p) return 0;
if (*p == '"') p++;
while (n < 4) {
char c = *p;
uint8_t d;
if (c >= '0' && c <= '9') d = (uint8_t)(c - '0');
else if (c >= 'a' && c <= 'f') d = (uint8_t)(c - 'a' + 10);
else if (c >= 'A' && c <= 'F') d = (uint8_t)(c - 'A' + 10);
else break;
v = (uint16_t)((v << 4) | d);
p++;
n++;
}
if (n == 0) return 0;
*val = v;
return 1;
}
int proto_get_str(const char *json, const char *key, char *out, int cap)
{
const char *p = proto_locate(json, key);
int i = 0;
if (!p || *p != '"' || cap <= 0) return 0;
p++;
while (p[i] && p[i] != '"' && i < cap - 1) {
out[i] = p[i];
i++;
}
out[i] = '\0';
return (i > 0) ? 1 : 0;
}
int proto_get_id(const char *json, char *out, int cap)
{
const char *p = proto_locate(json, "id");
int i = 0;
if (!p || cap <= 0) return 0;
if (*p == '"') {
p++;
while (i < cap - 1 &&
((p[i] >= '0' && p[i] <= '9') ||
(p[i] >= 'a' && p[i] <= 'z') ||
(p[i] >= 'A' && p[i] <= 'Z'))) {
out[i] = p[i];
i++;
}
} else {
while (i < cap - 1 && p[i] >= '0' && p[i] <= '9') {
out[i] = p[i];
i++;
}
}
out[i] = '\0';
return (i > 0) ? 1 : 0;
}
int proto_get_kg100(const char *json, const char *key, uint16_t *val)
{
char region[64];
const char *p;
const char *vp;
uint16_t v = 0;
if (!proto_value_region(json, key, region, sizeof(region))) return 0;
/* 嵌套对象时取 "value" 字段,否则直接用区域本身 */
vp = proto_locate(region, "value");
p = vp ? vp : region;
/* 跳过空白、引号、冒号 */
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n' || *p == '"' || *p == ':') p++;
if (*p < '0' || *p > '9') return 0;
while (*p >= '0' && *p <= '9') {
v = (uint16_t)(v * 10 + (*p - '0'));
p++;
}
if (*p == '.') {
p++;
if (*p >= '0' && *p <= '9') {
v = (uint16_t)(v * 10 + (*p - '0'));
} else {
v = (uint16_t)(v * 10); /* 整数补一位小数 */
}
/* 忽略第二位小数 */
} else {
v = (uint16_t)(v * 10); /* 整数转 0.1KG */
}
*val = v;
return 1;
}