shuichan_old/V1.3/STM32F103_App1/m_app/proto.c

199 lines
5.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}