Cjson Source code Interpretation (c) parsing strings, numbers, arrays, objects

Source: Internet
Author: User

1. Parsing numbers

static const char *parse_number (Cjson *item,const char *num) {double n=0,sign=1, Scale=0;int subscale=0,signsubscale=1;if (*num== '-') sign=-1,num++;/* have sign? */if (*num== ' 0 ') num++;/* is zero */if (*num>= ' 1 ' && *num<= ' 9 ') don= (n*10.0) + (*num++-' 0 '), while (*num>= ' 0 ' && *num<= ' 9 '); */* number? */if (*num== '. && num[1]>= ' 0 ' && num[1]<= ' 9 ') {num++;d on= (n*10.0) + (*num++-' 0 '), scale--; while ( *num>= ' 0 ' && *num<= ' 9 ');} /* Fractional part? */if (*num== ' e ' | | *num== ' e ')/* Exponent? */{num++;if (*num== ' + ') num++;else if (*num== '-') signsubscale=-1,num++;/* with sign? */while (*num>= ' 0 ' && *n um<= ' 9 ') subscale= (subscale*10) + (*num++-' 0 '); */* number? */}n=sign*n*pow (10.0, (Scale+subscale*signsubscale));/* Number = +/-number.fraction * 10^+/-exponent */item-> valuedouble=n;item->valueint= (int) N;item->type=cjson_number;return num;} 

Item is a Cjson object that is passed in, and Num is the starting number.

1. Resolve the positive and negative, sign mark, 1 is negative

2. Judging is not 0

3. Determine the number before the decimal point, that is-3.2 e 5, the preceding 3.2, this is divided into two parts, before and after the decimal point

4. E or E, which is the second half of the scientific count, is the time to deal with the question of whether the scientific count is positive or negative and is recorded with Signsubscale.

5. And then directly parse, here the author used a small technique, the author directly in the analysis of the front base of the part, parsing out is an integer, with scale record, finally with science and technology get back on OK, very ingenious.

6. Then return the number and parse out an object.

2. Parsing strings

static const char *parse_string (Cjson *item,const char *str) {const char *ptr=str+1;char *ptr2;char *out;int Len=0;unsigne D uc,uc2;if (*str!= ' "') {Ep=str;return 0;} /* Not a string! */while (*ptr!= ' \ ' && *ptr && ++len) if (*ptr++ = = ' \ \ ') ptr++;/* Skip escaped quotes. *///Jump to the last of the string to out= (char*) Cjson_malloc (len+1); */* This is what long we need for the string, roughly.                                                                        *///Pre-Request a space size of a string if (!out) return 0;                                                                        If the application is unsuccessful, exit ptr=str+1;ptr2=out;                                                    Start again, PTR2 set to the point where the out begins while (*ptr!= ' \ ' && *ptr) {if (*ptr!= ' \ \ ') *ptr2++=*ptr++;                                     Under normal circumstances, run straight down the line Else{ptr++;switch (*ptr) {case ' B ': *ptr2++= ' \b '; In special cases, the case ' F ': *ptr2++= ' \f '; Break;case ' n ': *ptr2++= ' \ n '; Break;case ' R ': *ptr2++= ' \ r '; Break;case ' t ': *ptr2++ = ' \ t '; break;case ' u ':/* transcodeUtf16 to UTF8. *///unicode to handle the uc=parse_hex4 (ptr+1);p tr+=4;/* get the Unicode char. *///parse hex in the back, just put the last four bits out, if ((uc>=0xdc00 && uc<=0xdfff) | | uc==0) break;/* Check for invalid.*/if (uc>=0xd800 && uc<=0x DBFF)/* UTF16 surrogate pairs.*/{if (ptr[1]!= ' \ \ ' | | ptr[2]!= ' u ') break;/* missing second-half of Surrogate.*/uc2=parse_ Hex4 (ptr+3);p tr+=6;if (uc2<0xdc00 | | uc2>0xdfff) break;/* Invalid second-half of surrogate.*/uc=0x10000 + ((UC &AMP;0X3FF) <<10) | (UC2&AMP;0X3FF));} Len=4;if (uc<0x80) Len=1;else if (uc<0x800) Len=2;else if (uc<0x10000) len=3; Ptr2+=len;switch (len) {case 4: *--PTR2 = ((UC | 0x80) & 0xBF); UC >>= 6;case 3: *--ptr2 = ((UC | 0x80) & 0xBF ); UC >>= 6;case 2: *--ptr2 = (UC | 0x80) & 0xBF); UC >>= 6;case 1: *--ptr2 = (UC | firstbytemark[len]);} Ptr2+=len;break;default: *ptr2++=*ptr; break;} ptr++;}} *ptr2=0;if (*ptr== ' \ "') Ptr++;item->valuestring=out;item->type=cjson_strinG;return ptr;} 

static unsigned parse_hex4 (const char *str) {unsigned h=0;if (*str>= ' 0 ' && *str<= ' 9 ') h+= (*str)-' 0 '; else if (*str>= ' A ' && *str<= ' F ') h+=10+ (*str)-' A '; else if (*str>= ' a ' && *str<= ' F ') h+=10+ (*STR)-' a '; else return 0;h=h<<4;str++;if (*str>= ' 0 ' && *str<= ' 9 ') h+= (*str)-' 0 '; else if (*str>= ' a ' && *str<= ' F ') h+=10+ (*str)-' A '; else if (*str>= ' a ' && *str<= ' F ') h+=10+ (*STR)-' a '; else return 0;h=h<<4;str++;if (*str>= ' 0 ' && *str<= ' 9 ') h+= (*str)-' 0 '; else if (*str>= ' a ' && *str<= ' F ') h+=10+ (*str)-' A '; else if (*str>= ' a ' && *str<= ' F ') h+=10+ (*STR)-' a '; else return 0;h=h<<4;str++;if (*str>= ' 0 ' && *str<= ' 9 ') h+= (*str)-' 0 '; else if (*str>= ' a ' && *str<= ' F ') h+=10+ (*str)-' A '; else if (*str>= ' a ' && *str<= ' F ') h+=10+ (*STR)-' a '; else return 0;return H;}

In addition to transcoding, the rest is relatively simple, is to apply a string, and then copy the past.

3. Parsing an array

static const char *parse_array (Cjson *item,const char *value) {Cjson *child;if (*value!= ' [') {Ep=value;return 0;} /* Not an array! */item->type=cjson_array;value=skip (value+1), if (*value== ') ') return value+1;/* empty Array. */item->child=child=cjson_new_item (); if (!item->child) return 0; /* Memory fail */value=skip (Parse_value (Child,skip (value)));/* Skip any spacing, get the value. */if (!value) return 0;while (*value== ', ') {Cjson *new_item;if (!) ( New_item=cjson_new_item ())) return 0; /* Memory fail */child->next=new_item;new_item->prev=child;child=new_item;value=skip (Parse_value (child,skip (value+1))); if (!value) return 0;/* memory fail */}if (*value== '] ') return value+1;/* end of array */ep=value;return 0;/* malformed. */}

If the content is not empty, then parse it down. It's OK.

4. Parse the object with {} to indicate

static const char *parse_object (Cjson *item,const char *value) {Cjson *child;if (*value!= ' {') {Ep=value;return 0;} /* Not an object! */item->type=cjson_object;value=skip (value+1); if (*value== '} ') return value+1;/* empty array. */item->child=child=cjson_new_item (); if (!item->child) return 0;value=skip (parse_string (Child,skip (value))) if (!value) return 0;child->string=child->valuestring;child->valuestring=0;if (*value!= ': ') {ep=value; return 0;} /* fail! */value=skip (Parse_value (Child,skip (value+1)));/* Skip any spacing, get the value. */if (!value) return 0;while (*value== ', ') {Cjson *new_item;if (!) ( New_item=cjson_new_item ())) return 0; /* Memory fail */child->next=new_item;new_item->prev=child;child=new_item;value=skip (parse_string (Child, Skip (value+1))); if (!value) return 0;child->string=child->valuestring;child->valuestring=0;if (*value!= ': ') {Ep=value;return 0;} /* fail! */value=skip (Parse_value (Child,skip (value+1)));/* Skip any spacing, get the value. */if(!value) return 0;} if (*value== '} ') return value+1;/* end of array */ep=value;return 0;/* malformed. */}

is a value, a value is rolled down, and its values are recorded in the child record, the previous position. There is no big difference with the array.

These are the four main one.

Cjson Source code Interpretation (c) parsing strings, numbers, arrays, objects

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.