JSMN API的问题

时间:2017-05-06 21:30:39

标签: c json jsmn

我正在努力弄清楚jsmn库是如何工作的。这是我目前的代码及其产生的代码。我的问题仅基于derefBy函数

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#include "jsmnutil.h"

char * jsmnTypes[] = {"undefined","object","array","string","primitive"};

const jsmnmarker_t jsmnErrorMarker = {NULL,-1};

jsmnmarker_t
makeMarker(jsmndata_t * data) {
  jsmnmarker_t marker;
  marker.data = data;
  marker.index = 0;
  return marker;
}

int
areEqualMarkers(jsmnmarker_t marker1, jsmnmarker_t marker2) {
  return marker1.data == marker2.data && marker1.index == marker2.index;
}

int
isErrorMarker(jsmnmarker_t marker) {
  return areEqualMarkers(marker,jsmnErrorMarker);
}

jsmnmarker_t
objectDeref(jsmnmarker_t marker, char * key) {
  if (marker.index == -1) return marker;
  int childCnt = TOKEN_SIZE(marker);
  jsmnmarker_t child = marker;
  child.index++;
  while (childCnt > 0) {
    if (TOKEN_PARENT(child) == marker.index) {
      if (strncmp(TOKEN_ADDR(child),key,TOKEN_LENGTH(child)) == 0) {
        child.index++;
        return child;
      }
      childCnt--;
    }
    child.index++;
  }
  return jsmnErrorMarker;
}


jsmnmarker_t
arrayDeref(jsmnmarker_t marker, int index) {
  if (marker.index == -1) return marker;
  int childCnt = TOKEN_SIZE(marker);
  if (index >= childCnt) return jsmnErrorMarker;
  jsmnmarker_t child = marker;
  child.index++;
  while (1) {
    if (TOKEN_PARENT(child) == marker.index) {
      if (index == 0) {
        return child;
      }
      index--;
    }
    child.index++;
  }
  return jsmnErrorMarker;
}

jsmnmarker_t
derefBy(jsmnmarker_t marker, char * fmt, ...) {
  va_list ap;
  char * s;
  int d;
  jsmnmarker_t holder = marker;

  va_start(ap,fmt);
  while (*fmt) {
    switch(*fmt++) {
     case 's':
        s = va_arg(ap,char *);
        printf("string %s\n",s);
        break;
     case 'd':
        d = va_arg(ap,int);
        printf("%d\n",d);
        break;
    }
  }
  va_end(ap);
}

jsmnmarker_t
nextKeyForObject(jsmnmarker_t objMarker, jsmnmarker_t keyMarker) {

}

jsmnmarker_t
valueForKey(jsmnmarker_t keyMarker) {
  keyMarker.index++;
  return keyMarker;
}

char * *
keysForObject(jsmnmarker_t marker) {
  if (marker.index == -1) return NULL;
  if (TOKEN_TYPE(marker) != JSMN_OBJECT) return NULL;
  int childSize = TOKEN_SIZE(marker);
  char * * keys = malloc((childSize + 1) * sizeof(char *));
  jsmnmarker_t child = marker;
  child.index++;
  int cnt = 0;
  while (cnt < childSize) {
    if (TOKEN_PARENT(child) == marker.index) {
      keys[cnt] = tokenText(child);
      cnt++;
    }
    child.index++;
  }
  keys[cnt] = NULL;
  return keys;
}

char *
tokenText(jsmnmarker_t marker) {
  if (marker.index < 0) return NULL;
  return strndup(TOKEN_ADDR(marker),TOKEN_LENGTH(marker));
}

void
printToken(FILE * fh, jsmnmarker_t marker) {
  if (marker.index >= 0 ) {
    fprintf(fh,"%.*s",TOKEN_LENGTH(marker),TOKEN_ADDR(marker));
  }
  else {
    fprintf(fh,"unresolved reference");
  }
}

void
dprintToken(int fd, jsmnmarker_t marker) {
  if (marker.index >= 0 ) {
    dprintf(fd,"%.*s",TOKEN_LENGTH(marker),TOKEN_ADDR(marker));
  }
  else {
    dprintf(fd,"unresolved reference");
  }
}

我知道我必须返回一个jsmn标记,但我不太确定如何使用第一个或最后一个名称来创建它。以下是使用此函数的示例代码。

    char * firstName = tokenText(derefBy(faculty,"ds",i,"firstName"));
    char * lastName = tokenText(derefBy(faculty,"ds",i,"lastName"));
    fprintf(stdout,"Prof. %s %s \n",firstName,lastName);

我的困惑是基于结果。我得到

似乎是完全随机的
Faculty Schedules
0
string firstName
0
string lastName
Prof. (null) (null)
0
string classes
Segmentation fault (core dumped)

或者我没有改变任何事情就得到了这个

Faculty Schedules
0
string firstName
Segmentation fault (core dumped)

我希望它只是简单地生成

Prof. <firstName> <lastName>
Classes: ...

fmt是一个's'和'd'字符的字符串,用于描述其余参数是对象键还是数组索引。例如,derefBy(marker,“sds”,key1,sub1,key2)将首先通过key1取消引用标记,然后是index sub1,最后是key2

0 个答案:

没有答案