2011-09-05 191 views
1

我一定在做错事......或者这可能是YAJL中的一个错误,但我非常怀疑这一点。 我无法从json对象中检索第一个元素。我回到YAJL源代码,用parse_config.c来测试它,但它也失败了。用C语言解析json与YAJL

使用sample.config

/* 
* The configuration file for Yahoo! BrowserPlus, included in the YAJL 
* tree as a sample configuration file for parsing. 
* 
* This is the configuration file for BrowserPlus 
*/ 

{ 
    // The type of build this is, which is accessible to JavaScript via 
    // BrowserPlus.getPlatformInfo(); 
    // Different build types should only differ in signatures accepted 
    // (BrowserPlus.crt) and configured distribution servers. 
    "BuildType": "ephemeral", 

    // the base url for the "primary" distribution server. This server will 
    // be the single source of truth for Permissions, and will used to 
    // attain services 
    "DistServer": "http://browserplus.yahoo.com", 

    // An array of "secondary" distribution servers, which will be checked 
    // in order for services if the primary server has no components 
    // available which match an issued require statement. 
    "SecondaryDistServers": [ 
     "http://first.fictional.server", 
     "http://second.fictional.server" 
    ], 

    // Logging Setup 
    "Logging" : 
    { 
     // Log level. Values: "debug"|"info"|"warn"|"error"|"fatal"|"off" 
     "level": "BP_LOG_LEVEL", 

     // Destination. Values: "file"|"console"|"win32" 
     "dest": "BP_LOG_DEST", 

     // Log message layout. Values: "standard"|"source"|"raw" 
     "layout": "standard", 

     // Time format. Values: "utc"|"local"|"msec" 
     "timeFormat": "utc", 

     // File size in KB which will trigger a rollover 
     "fileRolloverKB": 2048, 

     // Whether to send file logging from each service to a distinct file. 
     // Values: "combined"|"separate" 
     "serviceLogMode": "combined" 
    }, 

    // Daemon setup 
    // Syntax: "Options": "option1 option2 etc" 
    // -fg  run in foreground, log to console 
    "Options":"", 

    // Auto-shutdown daemon if idle for this time. Use 0 for no auto-shutdown. 
    "MaxIdleSecs": 5, 

    // At the end of each BrowserPlus session a small web request is made 
    // to yahoo to indicate that BrowserPlus was used. This report includes 
    // * information about the browser being used 
    // * an "installation id", which is a unique token that's generated 
    // the first time BrowserPlus runs. 
    // 
    // By design, there is *no information* in this request that gives 
    // Yahoo! information about: 
    // a) the site that the user is visiting (see, "url": false) 
    // b) who the user is (the installation token cannot be tracked to a 
    //  specific user). 
    // 
    // This information is primarily captured to help Yahoo! understand 
    // adoption and usage of the BrowserPlus platform. 
    "UsageReporting": 
    { 
     "enabled": true, 
     "url": false, 
     "id": true 
    }, 

    // "Breakpoints" is an array of strings holding named breakpoints. 
    // Platform code checks for specific entries at certain key points, and if 
    // a matching entry is found here a DebugBreak will be performed. 
    // For developers with Visual Studio installed, the DebugBreak will cause an 
    // opportunity to perform just-in-time attachment of an existing or new 
    // debugger instance. 
    // The currently-defined breakpoints are listed below: 
    //  runServiceProcess - A DebugBreak is performed in the service 
    //       "harness" just prior to service load. 
    //  ax.FinalConstruct - A DebugBreak is performed at entry to 
    //       FinalConstruct of the ActiveX plugin. 
    //  PluginInit -  Very early in the NPAPI plugin initialization. 
    //       A wonderful spot to stop and set more 
    //       breakpoints. 
    //"Breakpoints": ["runServiceProcess"], 

    // How often we check for service updates. We guarantee at least this 
    // much time will pass between checks, though the true time may be 
    // much more if sites which use browserplus are not visited. 
    // The time is in seconds. 
    "ServiceUpdatePollPeriod": 86400 
} 

我尝试找回 “BuildType” < - JSON对象的第一要素。

我改变了parse_config.c文件做到这一点...这里是代码:

int 
main(void) 
{ 
    size_t rd; 
    yajl_val node; 
    char errbuf[1024]; 

    /* null plug buffers */ 
    fileData[0] = errbuf[0] = 0; 

    /* read the entire config file */ 
    rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin); 

    /* file read error handling */ 
    if (rd == 0 && !feof(stdin)) { 
     fprintf(stderr, "error encountered on file read\n"); 
     return 1; 
    } else if (rd >= sizeof(fileData) - 1) { 
     fprintf(stderr, "config file too big\n"); 
     return 1; 
    } 

    /* we have the whole config file in memory. let's parse it ... */ 
    node = yajl_tree_parse((const char *) fileData, errbuf, sizeof(errbuf)); 

    /* parse error handling */ 
    if (node == NULL) { 
     fprintf(stderr, "parse_error: "); 
     if (strlen(errbuf)) fprintf(stderr, " %s", errbuf); 
     else fprintf(stderr, "unknown error"); 
     fprintf(stderr, "\n"); 
     return 1; 
    } 

    /* ... and extract a nested value from the config file */ 
    { 
     //const char * path[] = { "Logging", "timeFormat", (const char *) 0 }; 

注意:如果我试图让“DistServer”它工作得很好,但“BuildType”返回NULL。

 const char * path[] = { "BuildType", (const char *) 0 }; 
     //const char * path[] = { "DistServer", (const char *) 0 }; 
     yajl_val v = yajl_tree_get(node, path, yajl_t_string); 
     if (v) printf("%s: %s\n", path[0], YAJL_GET_STRING(v)); 
     else printf("no such node: %s\n", path[0]); 
     //if (v) printf("%s/%s: %s\n", path[0], path[1], YAJL_GET_STRING(v)); 
     //else printf("no such node: %s/%s\n", path[0], path[1]); 
    } 

    yajl_tree_free(node); 

    return 0; 
} 

我正在使用最新的YAJL版本:2.0.2。

在此先感谢!

编辑:

这里是我的命令输出:

./parse_config < ../../example/sample.config 
no such node: BuildType 

注意,我参加竞选是在一个在构建/ example目录

我的gcc版本的parse_config是: gcc版本4.4.5(Ubuntu/Linaro 4.4.4-14ubuntu5)

编辑2 有关记录,这是随附的示例代码此代码随YAJL一起提供。我故意使用它而不是我自己的代码来确保问题不仅与我的应用程序有关。同时,我通过使用回拨机制,图书馆提供和使用

yajl_parse() 
and 
yajl_complete_parse() 

解决该问题的工作,但我还是想知道为什么原来的代码是行不通的。

+1

我试了一下你的代码和yajl版本一样,但是BuildType返回给我的是''ephemeral'' ... – Fred

+0

真的!?这很有趣......你正在运行的命令是什么?你使用的是什么版本的gcc? –

+1

我不认为这是问题,但你没有用NUL字节正确地终止fileData。在适当的地方添加'fileData [rd] ='\ 0';' –

回答

4

我刚刚碰到了这个相同的错误,使用版本2.0.2。它似乎是yajl中的一个bug,并已在github中修复(“验证yajl_tree_get中正确对象的长度”,提交9c2948a33165c650122d131f31140c15321908f5)。

我已经应用了这个补丁,现在我可以读取第一个项目。

+0

终于!另一个人有这个问题:)感谢您的更新! –

+0

谢谢!我也花了几个小时想知道我做错了什么,拒绝相信一些基本的东西,因为这可以通过测试套件。 – jdo

1

这看起来就像是一个bug in yajl...

哇,我没想到会是这样。