Index: branches/chucko/i386/libsaio/xml.c =================================================================== --- branches/chucko/i386/libsaio/xml.c (revision 2320) +++ branches/chucko/i386/libsaio/xml.c (revision 2321) @@ -340,216 +340,239 @@ if (length == -1) return -1; pos = length; - if (!strncmp(tagName, kXMLTagPList, 6)) - { - length = 0; - } - /***** dict ****/ - else if (!strcmp(tagName, kXMLTagDict)) - { - length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0); - } - else if (!strncmp(tagName, kXMLTagDict, strlen(kXMLTagDict)) && tagName[strlen(tagName)-1] == '/') - { - length = ParseTagList(buffer + pos, tag, kTagTypeDict, 1); - } - else if (!strncmp(tagName, kXMLTagDict " ", strlen(kXMLTagDict " "))) - { - length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0); - } + + /* Check most common cases first, make them fast */ + /***** key ****/ - else if (!strcmp(tagName, kXMLTagKey)) + if (!strcmp(tagName, kXMLTagKey)) { length = ParseTagKey(buffer + pos, tag); } - + /***** string ****/ - else if (!strcmp(tagName, kXMLTagString)) - { - length = ParseTagString(buffer + pos, tag); - } - else if (!strncmp(tagName, kXMLTagString " ", strlen(kXMLTagString " "))) - { - // TODO: save tag if if found - if(!strncmp(tagName + strlen(kXMLTagString " "), kXMLStringID, strlen(kXMLStringID))) - { - // ID= - int id = 0; - int cnt = strlen(kXMLTagString " " kXMLStringID "\"") + 1; - while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; - tagName[cnt] = 0; - char* val = tagName + strlen(kXMLTagString " " kXMLStringID "\""); - while(*val) - { - if ((*val >= '0' && *val <= '9')) // 0 - 9 - { - id = (id * 10) + (*val++ - '0'); - } - else - { - printf("ParseStringID error (0x%x)\n", *val); - getchar(); - return -1; - } - } - length = ParseTagString(buffer + pos, tag); + else if (!strncmp(tagName, kXMLTagString, strlen(kXMLTagString))) { + if (!tagName[strlen(kXMLTagString)]) /* */ + { + length = ParseTagString(buffer + pos, tag); + } + else if (' ' == tagName[strlen(kXMLTagString)]) /* */ + { + // TODO: save tag if if found + if(!strncmp(tagName + strlen(kXMLTagString " "), kXMLStringID, strlen(kXMLStringID))) /* */ + { + // ID= + int id = 0; + int cnt = strlen(kXMLTagString " " kXMLStringID "\"") + 1; + while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; + tagName[cnt] = 0; + char* val = tagName + strlen(kXMLTagString " " kXMLStringID "\""); + while(*val) + { + if ((*val >= '0' && *val <= '9')) // 0 - 9 + { + id = (id * 10) + (*val++ - '0'); + } + else + { + printf("ParseStringID error (0x%x)\n", *val); + getchar(); + return -1; + } + } + length = ParseTagString(buffer + pos, tag); - SaveRefString(buffer + pos, id); - } - else if(!strncmp(tagName + strlen(kXMLTagString " "), kXMLStringIDRef, strlen(kXMLStringIDRef))) - { - // IDREF= - int id = 0; - int cnt = strlen(kXMLTagString " " kXMLStringIDRef "\"") + 1; - while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; - tagName[cnt] = 0; - char* val = tagName + strlen(kXMLTagString " " kXMLStringIDRef "\""); - while(*val) - { - if ((*val >= '0' && *val <= '9')) // 0 - 9 - { - id = (id * 10) + (*val++ - '0'); - } - else - { - printf("ParseStringIDREF error (0x%x)\n", *val); - getchar(); - return -1; - } - } - char* str = GetRefString(id); + SaveRefString(buffer + pos, id); + } + else if(!strncmp(tagName + strlen(kXMLTagString " "), kXMLStringIDRef, strlen(kXMLStringIDRef))) /* */ + { + // IDREF= + int id = 0; + int cnt = strlen(kXMLTagString " " kXMLStringIDRef "\"") + 1; + while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; + tagName[cnt] = 0; + char* val = tagName + strlen(kXMLTagString " " kXMLStringIDRef "\""); + while(*val) + { + if ((*val >= '0' && *val <= '9')) // 0 - 9 + { + id = (id * 10) + (*val++ - '0'); + } + else + { + printf("ParseStringIDREF error (0x%x)\n", *val); + getchar(); + return -1; + } + } + char* str = GetRefString(id); - TagPtr tmpTag = NewTag(); - tmpTag->type = kTagTypeString; - tmpTag->string = str; - tmpTag->tag = 0; - tmpTag->tagNext = 0; - tmpTag->offset = buffer_start ? buffer - buffer_start + pos : 0; - *tag = tmpTag; + TagPtr tmpTag = NewTag(); + tmpTag->type = kTagTypeString; + tmpTag->string = str; + tmpTag->tag = 0; + tmpTag->tagNext = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start + pos : 0; + *tag = tmpTag; - length = 0; - //printf("Located IDREF, id = %d, string = %s\n", id, str); - } - } + length = 0; + //printf("Located IDREF, id = %d, string = %s\n", id, str); + } + } + else /* unrecognized */ + { + *tag = 0; + length = 0; + } + } /***** integer ****/ - else if (!strcmp(tagName, kXMLTagInteger)) - { - length = ParseTagInteger(buffer + pos, tag); - } - else if (!strncmp(tagName, kXMLTagInteger " ", strlen(kXMLTagInteger " "))) - { - if(!strncmp(tagName + strlen(kXMLTagInteger " "), kXMLStringID, strlen(kXMLStringID))) - { - // ID= - int id = 0; - int cnt = strlen(kXMLTagInteger " " kXMLStringID "\"") + 1; - while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; - tagName[cnt] = 0; - char* val = tagName + strlen(kXMLTagInteger " " kXMLStringID "\""); - while(*val) - { - if ((*val >= '0' && *val <= '9')) // 0 - 9 - { - id = (id * 10) + (*val++ - '0'); - } - else - { - printf("ParseIntegerID error (0x%x)\n", *val); - getchar(); - return -1; - } - } - length = ParseTagInteger(buffer + pos, tag); + else if (!strncmp(tagName, kXMLTagInteger, strlen(kXMLTagInteger))) { + if (!tagName[strlen(kXMLTagInteger)]) /* */ + { + length = ParseTagInteger(buffer + pos, tag); + } + else if (' ' == tagName[strlen(kXMLTagInteger)]) /* */ + { + if(!strncmp(tagName + strlen(kXMLTagInteger " "), kXMLStringID, strlen(kXMLStringID))) /* */ + { + // ID= + int id = 0; + int cnt = strlen(kXMLTagInteger " " kXMLStringID "\"") + 1; + while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; + tagName[cnt] = 0; + char* val = tagName + strlen(kXMLTagInteger " " kXMLStringID "\""); + while(*val) + { + if ((*val >= '0' && *val <= '9')) // 0 - 9 + { + id = (id * 10) + (*val++ - '0'); + } + else + { + printf("ParseIntegerID error (0x%x)\n", *val); + getchar(); + return -1; + } + } + length = ParseTagInteger(buffer + pos, tag); - SaveRefString((*tag)->string, id); - } - else if(!strncmp(tagName + strlen(kXMLTagInteger " "), kXMLStringIDRef, strlen(kXMLStringIDRef))) - { - // IDREF= - int id = 0; - int cnt = strlen(kXMLTagInteger " " kXMLStringIDRef "\"") + 1; - while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; - tagName[cnt] = 0; - char* val = tagName + strlen(kXMLTagInteger " " kXMLStringIDRef "\""); - while(*val) - { - if ((*val >= '0' && *val <= '9')) // 0 - 9 - { - id = (id * 10) + (*val++ - '0'); - } - else - { - printf("ParseStringIDREF error (0x%x)\n", *val); - getchar(); - return -1; - } - } - int integer = (int)GetRefString(id); + SaveRefString((*tag)->string, id); + } + else if(!strncmp(tagName + strlen(kXMLTagInteger " "), kXMLStringIDRef, strlen(kXMLStringIDRef))) /* */ + { + // IDREF= + int id = 0; + int cnt = strlen(kXMLTagInteger " " kXMLStringIDRef "\"") + 1; + while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; + tagName[cnt] = 0; + char* val = tagName + strlen(kXMLTagInteger " " kXMLStringIDRef "\""); + while(*val) + { + if ((*val >= '0' && *val <= '9')) // 0 - 9 + { + id = (id * 10) + (*val++ - '0'); + } + else + { + printf("ParseStringIDREF error (0x%x)\n", *val); + getchar(); + return -1; + } + } + int integer = (int)GetRefString(id); - TagPtr tmpTag = NewTag(); - tmpTag->type = kTagTypeInteger; - tmpTag->string = (char*) integer; - tmpTag->tag = 0; - tmpTag->tagNext = 0; - tmpTag->offset = buffer_start ? buffer - buffer_start + pos : 0; + TagPtr tmpTag = NewTag(); + tmpTag->type = kTagTypeInteger; + tmpTag->string = (char*) integer; + tmpTag->tag = 0; + tmpTag->tagNext = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start + pos : 0; - *tag = tmpTag; + *tag = tmpTag; - length = 0; - //printf("Located IDREF, id = %d, string = %s\n", id, str); - } - else - { - length = ParseTagInteger(buffer + pos, tag); - } - } + length = 0; + //printf("Located IDREF, id = %d, string = %s\n", id, str); + } + else /* presume ... */ + { + length = ParseTagInteger(buffer + pos, tag); + } + } + else /* unrecognized */ + { + *tag = 0; + length = 0; + } + } - /***** data ****/ - else if (!strcmp(tagName, kXMLTagData)) - { - length = ParseTagData(buffer + pos, tag); - } - else if (!strncmp(tagName, kXMLTagData " ", strlen(kXMLTagData " "))) - { - length = ParseTagData(buffer + pos, tag); - } - else if (!strcmp(tagName, kXMLTagDate)) - { - length = ParseTagDate(buffer + pos, tag); - } - - /***** date ****/ - else if (!strncmp(tagName, kXMLTagDate " ", strlen(kXMLTagDate " "))) - { - length = ParseTagDate(buffer + pos, tag); - } - /***** false ****/ else if (!strcmp(tagName, kXMLTagFalse)) { length = ParseTagBoolean(buffer + pos, tag, kTagTypeFalse); } + /***** true ****/ else if (!strcmp(tagName, kXMLTagTrue)) { length = ParseTagBoolean(buffer + pos, tag, kTagTypeTrue); } - - /***** array ****/ - else if (!strcmp(tagName, kXMLTagArray)) + + /***** plist ****/ + else if (!strncmp(tagName, kXMLTagPList, 6)) { - length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0); + length = 0; } - else if (!strncmp(tagName, kXMLTagArray " ", strlen(kXMLTagArray " "))) + + /***** dict ****/ + else if (!strncmp(tagName, kXMLTagDict, strlen(kXMLTagDict))) { + if (!strncmp(tagName, kXMLTagDict, strlen(kXMLTagDict)) && tagName[strlen(tagName)-1] == '/') /* */ + { + length = ParseTagList(buffer + pos, tag, kTagTypeDict, 1); + } + else if (!tagName[strlen(kXMLTagDict)] || ' ' == tagName[strlen(kXMLTagDict)]) /* or */ + { + length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0); + } + else /* unrecognized */ + { + *tag = 0; + length = 0; + } + } + + /***** data ****/ + else if ((!strncmp(tagName, kXMLTagData, strlen(kXMLTagData))) + && (!tagName[strlen(kXMLTagData)] /* */ + || ' ' == tagName[strlen(kXMLTagData)])) /* */ { - length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0); + length = ParseTagData(buffer + pos, tag); } - else if (!strcmp(tagName, kXMLTagArray "/")) + + /***** date ****/ + else if ((!strncmp(tagName, kXMLTagDate, strlen(kXMLTagDate))) + && (!tagName[strlen(kXMLTagDate)] /* */ + || ' ' == tagName[strlen(kXMLTagDate)])) /* */ { - length = ParseTagList(buffer + pos, tag, kTagTypeArray, 1); + length = ParseTagDate(buffer + pos, tag); } + /***** array ****/ + else if (!strncmp(tagName, kXMLTagArray, strlen(kXMLTagArray))) { /* */ + char c = tagName[strlen(kXMLTagArray)]; + if ('/' == c) /* */ + { + length = ParseTagList(buffer + pos, tag, kTagTypeArray, 1); + } + else if ('\0' == c || ' ' == c) /* or */ + { + length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0); + } + else /* unrecognized */ + { + *tag = 0; + length = 0; + } + } /***** unknown ****/ else { @@ -877,26 +900,42 @@ static long GetNextTag( char * buffer, char ** tag, long * start ) { - long cnt, cnt2; + char* tagStart = buffer; + char* tagEnd; + char c; - if (tag == 0) return -1; + if (!tag) + return -1; - // Find the start of the tag. - cnt = 0; - while ((buffer[cnt] != '\0') && (buffer[cnt] != '<')) cnt++; - if (buffer[cnt] == '\0') return -1; - - // Find the end of the tag. - cnt2 = cnt + 1; - while ((buffer[cnt2] != '\0') && (buffer[cnt2] != '>')) cnt2++; - if (buffer[cnt2] == '\0') return -1; + /* Find the start of the tag. */ + do { + c = *tagStart++; + if (c == '<') break; + } while (c); + if (!c) + return -1; - // Fix the tag data. - *tag = buffer + cnt + 1; - buffer[cnt2] = '\0'; - if (start) *start = cnt; - - return cnt2 + 1; + /* tagStart points just past the '<' */ + /* Find the end of the tag. */ + tagEnd = tagStart; + do { + c = *tagEnd++; + if (c == '>') break; + } while (c); + if (!c) + return -1; + + /* tagEnd points just past the '>' */ + /* Fix up tag data by nulling out the '>' */ + --tagEnd; + *tagEnd = '\0'; + + *tag = tagStart; /* first char after initial '<' */ + if (start) + *start = (long) (tagStart - buffer) - 1; /* offset of the initial '<' itself */ + + /* Return offset to the char after '>' */ + return (long) (tagEnd - buffer) + 1; } //==========================================================================