static size_t raptor_www_curl_header_callback(void* ptr, size_t size, size_t nmemb, void *userdata) { raptor_www* www = (raptor_www*)userdata; size_t bytes = size * nmemb; int c; /* If WWW has been aborted, return nothing so that * libcurl will abort the transfer */ if(www->failed) return 0; #define CONTENT_TYPE_LEN 14 if(!raptor_strncasecmp((char*)ptr, "Content-Type: ", CONTENT_TYPE_LEN)) { size_t len = bytes - CONTENT_TYPE_LEN - 2; /* for \r\n */ char *type_buffer = RAPTOR_MALLOC(char*, len + 1); memcpy(type_buffer, (char*)ptr + 14, len); type_buffer[len]='\0'; if(www->type) RAPTOR_FREE(char*, www->type); www->type = type_buffer; www->free_type = 1; #if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 2 RAPTOR_DEBUG3("Got content type header '%s' (%d bytes)\n", type_buffer, len); #endif if(www->content_type) www->content_type(www, www->content_type_userdata, www->type); }
static size_t raptor_www_curl_header_callback(void* ptr, size_t size, size_t nmemb, void *userdata) { raptor_www* www=(raptor_www*)userdata; int bytes=size*nmemb; /* If WWW has been aborted, return nothing so that * libcurl will abort the transfer */ if(www->failed) return 0; if(!strncmp((char*)ptr, "Content-Type: ", 14)) { int len=bytes-16; char *type_buffer=(char*)RAPTOR_MALLOC(cstring, len+1); strncpy(type_buffer, (char*)ptr+14, len); type_buffer[len]='\0'; if(www->type) RAPTOR_FREE(cstring, www->type); www->type=type_buffer; www->free_type=1; #if RAPTOR_DEBUG > 2 RAPTOR_DEBUG3("Got content type '%s' (%d bytes)\n", type_buffer, len); #endif if(www->content_type) www->content_type(www, www->content_type_userdata, www->type); } return bytes; }
static void raptor_rss_emit(raptor_parser* rdf_parser) { raptor_rss_parser_context* rss_parser=(raptor_rss_parser_context*)rdf_parser->context; int i; raptor_rss_item* item; for(i=0; i< RAPTOR_RSS_COMMON_SIZE; i++) { if(!rss_parser->common[i].fields_count) continue; RAPTOR_DEBUG3("Emitting type %i - %s\n", i, raptor_rss_types_info[i].name); raptor_rss_emit_item(rdf_parser, &rss_parser->common[i]); /* Add connections to channel */ if(i != RAPTOR_RSS_CHANNEL) { raptor_rss_emit_connection(rdf_parser, &rss_parser->common[RAPTOR_RSS_CHANNEL].identifier, raptor_rss_types_info[i].uri, 0, &rss_parser->common[i].identifier); } } if(rss_parser->items_count) { raptor_identifier *items; /* make a new genid for the <rdf:Seq> node */ items=raptor_new_identifier(RAPTOR_IDENTIFIER_TYPE_ANONYMOUS, NULL, RAPTOR_URI_SOURCE_GENERATED, (const unsigned char*)raptor_generate_id(rdf_parser, 0, NULL), NULL, NULL, NULL); /* _:genid1 rdf:type rdf:Seq . */ raptor_rss_emit_type_triple(rdf_parser, items, RAPTOR_RDF_Seq_URI(rss_parser)); /* <channelURI> rss:items _:genid1 . */ raptor_rss_emit_connection(rdf_parser, &rss_parser->common[RAPTOR_RSS_CHANNEL].identifier, raptor_rss_fields_info[RAPTOR_RSS_FIELD_ITEMS].uri, 0, items); /* sequence of rss:item */ for(i=1, item=rss_parser->items; item; item=item->next, i++) { raptor_rss_emit_item(rdf_parser, item); raptor_rss_emit_connection(rdf_parser, items, NULL, i, &item->identifier); } raptor_free_identifier(items); } }
int raptor_rss_item_set_uri(raptor_rss_item *item, raptor_uri* uri) { RAPTOR_DEBUG3("Set node %p to URI <%s>\n", item, raptor_uri_as_string(uri)); item->uri = raptor_uri_copy(uri); if(!item->uri) return 1; item->term = raptor_new_term_from_uri(item->world, item->uri); return 0; }
raptor_rss_item* raptor_rss_model_add_common(raptor_rss_model* rss_model, raptor_rss_type type) { raptor_rss_item* item; item = raptor_new_rss_item(rss_model->world); if(!item) return NULL; if(rss_model->common[type] == NULL) { RAPTOR_DEBUG3("Adding common type %d - %s\n", type, raptor_rss_items_info[type].name); rss_model->common[type] = item; } else { raptor_rss_item* next; RAPTOR_DEBUG3("Appending common type %d - %s\n", type, raptor_rss_items_info[type].name); for(next = rss_model->common[type]; next->next; next = next->next) ; next->next = item; } return item; }
void raptor_rss_item_add_field(raptor_rss_item* item, int type, raptor_rss_field* field) { if(!item->fields[type]) { RAPTOR_DEBUG3("Adding first type %d field %s\n", type, raptor_rss_fields_info[type].name); item->fields_count++; item->fields[type] = field; } else { raptor_rss_field* cur; RAPTOR_DEBUG1("Adding subsequent field\n"); for(cur = item->fields[type]; cur->next; cur = cur->next) ; cur->next = field; } }
static void raptor_rss_parser_processNode(raptor_parser *rdf_parser) { raptor_rss_parser_context* rss_parser=(raptor_rss_parser_context*)rdf_parser->context; xmlTextReaderPtr reader=rss_parser->reader; xmlChar *name, *value; int type; name = xmlTextReaderName(reader); if (name == NULL) name = xmlStrdup(BAD_CAST "--"); value = xmlTextReaderValue(reader); type=xmlTextReaderNodeType(reader); switch(type) { case 1: /* start element */ if(rss_parser->current_type==RAPTOR_RSS_NONE) { if(!strcmp((const char*)name, "rss") || !strcmp((const char*)name, "rdf") || !strcmp((const char*)name, "RDF")) { break; } if(!strcmp((const char*)name, "item")) { raptor_rss_item_add(rss_parser); rss_parser->current_type=RAPTOR_RSS_ITEM; } else { int i; rss_parser->current_type=RAPTOR_RSS_UNKNOWN; for(i=0; i<RAPTOR_RSS_COMMON_SIZE; i++) if(!strcmp((const char*)name, raptor_rss_types_info[i].name)) { rss_parser->current_type=(raptor_rss_type)i; break; } } if(rss_parser->current_type==RAPTOR_RSS_UNKNOWN) { RAPTOR_DEBUG2("Unknown start element named %s\n", name); } else { RAPTOR_DEBUG3("FOUND type %d - %s\n", rss_parser->current_type, raptor_rss_types_info[rss_parser->current_type].name); } } else { /* have current_type, this is an element inside */ int i; raptor_rss_type old_type=rss_parser->current_type; /* check it is not a type here */ if(!strcmp((const char*)name, "item")) { raptor_rss_item_add(rss_parser); rss_parser->current_type=RAPTOR_RSS_ITEM; } else { for(i=0; i<RAPTOR_RSS_COMMON_SIZE; i++) if(!strcmp((const char*)name, raptor_rss_types_info[i].name)) { rss_parser->current_type=(raptor_rss_type)i; break; } } if(rss_parser->current_type != old_type) { RAPTOR_DEBUG6("FOUND element %s for type %d - %s INSIDE current type %d - %s\n", name, rss_parser->current_type, raptor_rss_types_info[rss_parser->current_type].name, old_type, raptor_rss_types_info[old_type].name); rss_parser->prev_type=old_type; break; } rss_parser->current_field=RAPTOR_RSS_FIELD_UNKNOWN; for(i=0; i<RAPTOR_RSS_FIELDS_SIZE; i++) if(!strcmp((const char*)name, raptor_rss_fields_info[i].name)) { rss_parser->current_field=(raptor_rss_fields_type)i; break; } if(rss_parser->current_field==RAPTOR_RSS_FIELD_UNKNOWN) { RAPTOR_DEBUG3("Unknown field element named %s inside type %s\n", name, raptor_rss_types_info[rss_parser->current_type].name); } else { RAPTOR_DEBUG4("FOUND field %d - %s inside type %s\n", rss_parser->current_field, raptor_rss_fields_info[rss_parser->current_field].name, raptor_rss_types_info[rss_parser->current_type].name); } } /* Now check for attributes */ while((xmlTextReaderMoveToNextAttribute(reader))) { xmlChar *attrName = xmlTextReaderName(reader); xmlChar *attrValue = xmlTextReaderValue(reader); RAPTOR_DEBUG3(" attribute %s=%s\n", attrName, attrValue); /* Pick a few attributes to care about */ if(!strcmp((const char*)attrName, "isPermaLink")) { if(!strcmp((const char*)name, "guid")) { /* <guid isPermaLink="..."> */ if(rss_parser->last) { /* rss_parser->last->guid_is_url=!strcmp(attrValue, "true"); */ } } } else if(!strcmp((const char*)attrName, "url")) { if(!strcmp((const char*)name, "source")) { /* <source url="...">foo</source> */ if(rss_parser->last) { /* rss_parser->last->source_url=attrValue; attrValue=NULL; */ } } } else if(!strcmp((const char*)attrName, "domain")) { if(!strcmp((const char*)name, "category")) { /* <category domain="URL">foo</source> */ if(rss_parser->last) { /* rss_parser->last->category_url=attrValue; attrValue=NULL; */ } } } xmlFree(attrName); if(attrValue) xmlFree(attrValue); } if(!xmlTextReaderIsEmptyElement(reader)) break; /* FALLTHROUGH if is empty element */ case 15: /* end element */ if(rss_parser->current_type != RAPTOR_RSS_NONE) { if(rss_parser->current_field != RAPTOR_RSS_FIELD_NONE) { RAPTOR_DEBUG3("Ending element %s field %s\n", name, raptor_rss_fields_info[rss_parser->current_field].name); rss_parser->current_field= RAPTOR_RSS_FIELD_NONE; } else { RAPTOR_DEBUG3("Ending element %s type %s\n", name, raptor_rss_types_info[rss_parser->current_type].name); if(rss_parser->prev_type != RAPTOR_RSS_NONE) { rss_parser->current_type=rss_parser->prev_type; rss_parser->prev_type=RAPTOR_RSS_NONE; RAPTOR_DEBUG3("Returning to type %d - %s\n", rss_parser->current_type, raptor_rss_types_info[rss_parser->current_type].name); } else rss_parser->current_type= RAPTOR_RSS_NONE; } } break; case 3: /* text */ if((rss_parser->current_type==RAPTOR_RSS_NONE || rss_parser->current_type==RAPTOR_RSS_UNKNOWN) || (rss_parser->current_field==RAPTOR_RSS_FIELD_NONE || rss_parser->current_field==RAPTOR_RSS_FIELD_UNKNOWN)) { char *p=(char*)value; while(*p) { if(!isspace(*p)) break; p++; } if(*p) RAPTOR_DEBUG2("IGNORING non-whitespace text node '%s'\n", value); break; } if(rss_parser->current_type != RAPTOR_RSS_ITEM && rss_parser->current_type >= RAPTOR_RSS_COMMON_IGNORED) { /* skipHours, skipDays common but IGNORED */ } else { raptor_rss_item* update_item; if(rss_parser->current_type == RAPTOR_RSS_ITEM) update_item=rss_parser->last; else update_item=&rss_parser->common[rss_parser->current_type]; RAPTOR_DEBUG4("Added text '%s' to field %s of type %s\n", value, raptor_rss_fields_info[rss_parser->current_field].name, raptor_rss_types_info[rss_parser->current_type].name); if(!update_item->fields[rss_parser->current_field]) update_item->fields_count++; update_item->fields[rss_parser->current_field]=(char*)value; value=NULL; } break; case 4: /* CData sections */ case 5: /* entity references */ case 6: /* entity declarations */ case 7: /* PIs */ case 8: /* comments */ case 9: /* document nodes */ case 10: /* DTD/Doctype nodes */ case 11: /* document fragment */ case 12: /* notation nodes */ break; default: #if defined(RAPTOR_DEBUG) RAPTOR_DEBUG3("depth %d type %d", xmlTextReaderDepth(reader), type); fprintf(stderr," name %s %s", name, xmlTextReaderIsEmptyElement(reader) ? "Empty" : ""); if (value == NULL) fprintf(stderr, "\n"); else { fprintf(stderr, " '%s'\n", value); } #endif RAPTOR_DEBUG2("Ignoring type %d\n", type); } xmlFree(name); if(value) xmlFree(value); }
static int raptor_ntriples_parse_chunk(raptor_parser* rdf_parser, const unsigned char *s, size_t len, int is_end) { unsigned char *buffer; unsigned char *ptr; unsigned char *start; raptor_ntriples_parser_context *ntriples_parser=(raptor_ntriples_parser_context*)rdf_parser->context; #if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 RAPTOR_DEBUG2("adding %d bytes to buffer\n", (unsigned int)len); #endif /* No data? It's the end */ if(!len) return 0; buffer=(unsigned char*)RAPTOR_MALLOC(cstring, ntriples_parser->line_length + len + 1); if(!buffer) { raptor_parser_fatal_error(rdf_parser, "Out of memory"); return 1; } if(ntriples_parser->line_length) { strncpy((char*)buffer, (const char*)ntriples_parser->line, ntriples_parser->line_length); RAPTOR_FREE(cstring, ntriples_parser->line); } ntriples_parser->line=buffer; /* move pointer to end of cdata buffer */ ptr=buffer+ntriples_parser->line_length; /* adjust stored length */ ntriples_parser->line_length += len; /* now write new stuff at end of cdata buffer */ strncpy((char*)ptr, (const char*)s, len); ptr += len; *ptr = '\0'; #if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 RAPTOR_DEBUG2("buffer now %d bytes\n", ntriples_parser->line_length); #endif ptr=buffer+ntriples_parser->offset; while(*(start=ptr)) { unsigned char *line_start=ptr; #if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 RAPTOR_DEBUG3("line buffer now '%s' (offset %d)\n", ptr, ptr-(buffer+ntriples_parser->offset)); #endif /* skip \n when just seen \r - i.e. \r\n or CR LF */ if(ntriples_parser->last_char == '\r' && *ptr == '\n') { #if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 RAPTOR_DEBUG1("skipping a \\n\n"); #endif ptr++; rdf_parser->locator.byte++; rdf_parser->locator.column=0; start=line_start=ptr; } while(*ptr && *ptr != '\n' && *ptr != '\r') ptr++; if(!*ptr) break; #if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 RAPTOR_DEBUG3("found newline \\x%02x at offset %d\n", *ptr, ptr-line_start); #endif ntriples_parser->last_char=*ptr; len=ptr-line_start; rdf_parser->locator.column=0; *ptr='\0'; if(raptor_ntriples_parse_line(rdf_parser,line_start,len)) return 1; rdf_parser->locator.line++; /* go past newline */ ptr++; rdf_parser->locator.byte++; #if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 /* Do not peek if too far */ if(ptr-buffer < ntriples_parser->line_length) RAPTOR_DEBUG2("next char is \\x%02x\n", *ptr); else RAPTOR_DEBUG1("next char unknown - end of buffer\n"); #endif } ntriples_parser->offset=start-buffer; len=ntriples_parser->line_length - ntriples_parser->offset; if(len) { /* collapse buffer */ #if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 RAPTOR_DEBUG3("collapsing buffer from %d to %d bytes\n", ntriples_parser->line_length, (unsigned int)len); #endif buffer=(unsigned char*)RAPTOR_MALLOC(cstring, len + 1); if(!buffer) { raptor_parser_fatal_error(rdf_parser, "Out of memory"); return 1; } strncpy((char*)buffer, (const char*)ntriples_parser->line+ntriples_parser->line_length-len, len); buffer[len]='\0'; RAPTOR_FREE(cstring, ntriples_parser->line); ntriples_parser->line=buffer; ntriples_parser->line_length -= ntriples_parser->offset; ntriples_parser->offset=0; #if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 RAPTOR_DEBUG3("buffer now '%s' (%d bytes)\n", ntriples_parser->line, ntriples_parser->line_length); #endif } /* exit now, no more input */ if(is_end) { if(ntriples_parser->offset != ntriples_parser->line_length) { raptor_parser_error(rdf_parser, "Junk at end of input.\""); return 1; } return 0; } return 0; }
static int raptor_ntriples_parse_line(raptor_parser* rdf_parser, unsigned char *buffer, size_t len) { int i; unsigned char *p; unsigned char *dest; unsigned char *terms[3]; int terms_allocated[3]; size_t term_lengths[3]; raptor_ntriples_term_type term_types[3]; size_t term_length= 0; unsigned char *object_literal_language=NULL; unsigned char *object_literal_datatype=NULL; int rc=0; for(i=0; i<3; i++) terms_allocated[i]=0; /* ASSERTION: * p always points to first char we are considering * p[len-1] always points to last char */ /* Handle empty lines */ if(!len) return 0; #if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 RAPTOR_DEBUG3("handling line '%s' (%d bytes)\n", buffer, (unsigned int)len); #endif p=buffer; while(len>0 && isspace((int)*p)) { p++; rdf_parser->locator.column++; rdf_parser->locator.byte++; len--; } /* Handle empty - all whitespace lines */ if(!len) return 0; /* Handle comment lines */ if(*p == '#') return 0; /* Remove trailing spaces */ while(len>0 && isspace((int)p[len-1])) { p[len-1]='\0'; len--; } /* can't be empty now - that would have been caught above */ /* Check for terminating '.' */ if(p[len-1] != '.') { /* Move current location to point to problem */ rdf_parser->locator.column += len-2; rdf_parser->locator.byte += len-2; raptor_parser_error(rdf_parser, "Missing . at end of line"); return 0; } p[len-1]='\0'; len--; /* Must be triple */ for(i=0; i<3; i++) { if(!len) { raptor_parser_error(rdf_parser, "Unexpected end of line"); goto cleanup; } /* Expect either <URI> or _:name */ if(i == 2) { if(*p != '<' && *p != '_' && *p != '"' && *p != 'x') { raptor_parser_error(rdf_parser, "Saw '%c', expected <URIref>, _:bnodeID or \"literal\"", *p); goto cleanup; } if(*p == 'x') { if(len < 4 || strncmp((const char*)p, "xml\"", 4)) { raptor_parser_error(rdf_parser, "Saw '%c', expected xml\"...\")", *p); goto cleanup; } } } else if(i == 1) { if(*p != '<') { raptor_parser_error(rdf_parser, "Saw '%c', expected <URIref>", *p); goto cleanup; } } else /* i==0 */ { if(*p != '<' && *p != '_') { raptor_parser_error(rdf_parser, "Saw '%c', expected <URIref> or _:bnodeID", *p); goto cleanup; } } switch(*p) { case '<': term_types[i]= RAPTOR_NTRIPLES_TERM_TYPE_URI_REF; dest=p; p++; len--; rdf_parser->locator.column++; rdf_parser->locator.byte++; if(raptor_ntriples_term(rdf_parser, (const unsigned char**)&p, dest, &len, &term_length, '>', RAPTOR_TERM_CLASS_URI, 0)) { rc=1; goto cleanup; } break; case '"': term_types[i]= RAPTOR_NTRIPLES_TERM_TYPE_LITERAL; dest=p; p++; len--; rdf_parser->locator.column++; rdf_parser->locator.byte++; if(raptor_ntriples_term(rdf_parser, (const unsigned char**)&p, dest, &len, &term_length, '"', RAPTOR_TERM_CLASS_STRING, 0)) { rc=1; goto cleanup; } if(len && (*p == '-' || *p == '@')) { if(*p == '-') raptor_parser_error(rdf_parser, "Old N-Triples language syntax using \"string\"-lang rather than \"string\"@lang."); object_literal_language=p; /* Skip - */ p++; len--; rdf_parser->locator.column++; rdf_parser->locator.byte++; if(!len) { raptor_parser_error(rdf_parser, "Missing language after \"string\"-"); goto cleanup; } if(raptor_ntriples_term(rdf_parser, (const unsigned char**)&p, object_literal_language, &len, NULL, '\0', RAPTOR_TERM_CLASS_LANGUAGE, 0)) { rc=1; goto cleanup; } } if(len >1 && *p == '^' && p[1] == '^') { object_literal_datatype=p; /* Skip ^^ */ p+= 2; len-= 2; rdf_parser->locator.column+= 2; rdf_parser->locator.byte+= 2; if(!len || (len && *p != '<')) { raptor_parser_error(rdf_parser, "Missing datatype URI-ref in\"string\"^^<URI-ref> after ^^"); goto cleanup; } p++; len--; rdf_parser->locator.column++; rdf_parser->locator.byte++; if(raptor_ntriples_term(rdf_parser, (const unsigned char**)&p, object_literal_datatype, &len, NULL, '>', RAPTOR_TERM_CLASS_URI, 0)) { rc=1; goto cleanup; } } if(object_literal_datatype && object_literal_language) { raptor_parser_warning(rdf_parser, "Typed literal used with a language - ignoring the language"); object_literal_language=NULL; } break; case '_': term_types[i]= RAPTOR_NTRIPLES_TERM_TYPE_BLANK_NODE; /* store where _ was */ dest=p; p++; len--; rdf_parser->locator.column++; rdf_parser->locator.byte++; if(!len || (len > 0 && *p != ':')) { raptor_parser_error(rdf_parser, "Illegal bNodeID - _ not followed by :"); goto cleanup; } /* Found ':' - move on */ p++; len--; rdf_parser->locator.column++; rdf_parser->locator.byte++; if(raptor_ntriples_term(rdf_parser, (const unsigned char**)&p, dest, &len, &term_length, '\0', RAPTOR_TERM_CLASS_BNODEID, 0)) { rc=1; goto cleanup; } if(!term_length) { raptor_parser_error(rdf_parser, "Bad or missing bNodeID after _:"); goto cleanup; } else { unsigned char *blank=(unsigned char*)RAPTOR_MALLOC(cstring, term_length+1); if(!blank) { raptor_parser_fatal_error(rdf_parser, "Out of memory"); rc=1; goto cleanup; } strcpy((char*)blank, (const char*)dest); dest=raptor_parser_internal_generate_id(rdf_parser, RAPTOR_GENID_TYPE_BNODEID, blank); terms_allocated[i]=1; } break; case 'x': raptor_parser_error(rdf_parser, "Old N-Triples XML using xml\"string\"-lang rather than \"string\"@lang^^<%s>.", raptor_xml_literal_datatype_uri_string); /* already know we have 'xml"' coming up */ term_types[i]= RAPTOR_NTRIPLES_TERM_TYPE_LITERAL; /* 3=strlen("xml") */ p+=3; len-=3; dest=p; p++; len--; rdf_parser->locator.column++; rdf_parser->locator.byte++; if(raptor_ntriples_term(rdf_parser, (const unsigned char**)&p, dest, &len, &term_length, '"', RAPTOR_TERM_CLASS_STRING, 0)) { rc=1; goto cleanup; } /* got XML literal string */ object_literal_datatype=(unsigned char*)raptor_xml_literal_datatype_uri_string; if(len && (*p == '-' || *p == '@')) { if(*p == '-') raptor_parser_error(rdf_parser, "Old N-Triples language syntax using xml\"string\"-lang rather than xml\"string\"@lang."); object_literal_language=p; /* Skip - */ p++; len--; rdf_parser->locator.column++; rdf_parser->locator.byte++; if(!len) { raptor_parser_error(rdf_parser, "Missing language in xml\"string\"-language after -"); goto cleanup; } if(raptor_ntriples_term(rdf_parser, (const unsigned char**)&p, object_literal_language, &len, NULL, '"', RAPTOR_TERM_CLASS_STRING, 0)) { rc=1; goto cleanup; } } if(len >1 && *p == '^' && p[1] == '^') { object_literal_datatype=p; /* Skip ^^ */ p+= 2; len-= 2; rdf_parser->locator.column+= 2; rdf_parser->locator.byte+= 2; if(!len || (len && *p != '<')) { raptor_parser_error(rdf_parser, "Missing datatype URI-ref in xml\"string\"^^<URI-ref> after ^^"); goto cleanup; } p++; len--; rdf_parser->locator.column++; rdf_parser->locator.byte++; if(raptor_ntriples_term(rdf_parser, (const unsigned char**)&p, object_literal_datatype, &len, NULL, '>', RAPTOR_TERM_CLASS_URI, 0)) { rc=1; goto cleanup; } } if(len) { if(*p != ' ') { raptor_parser_error(rdf_parser, "Missing terminating ' '"); return 0; } p++; len--; rdf_parser->locator.column++; rdf_parser->locator.byte++; } break; default: raptor_parser_fatal_error(rdf_parser, "Unknown term type"); rc=1; goto cleanup; } /* Store term */ terms[i]=dest; term_lengths[i]=term_length; /* Whitespace must separate the terms */ if(i<2 && !isspace((int)*p)) { raptor_parser_error(rdf_parser, "Missing whitespace after term '%s'", terms[i]); rc=1; goto cleanup; } /* Skip whitespace after terms */ while(len>0 && isspace((int)*p)) { p++; len--; rdf_parser->locator.column++; rdf_parser->locator.byte++; } #if defined(RAPTOR_DEBUG) && RAPTOR_DEBUG > 1 fprintf(stderr, "item %d: term '%s' len %d type %s\n", i, terms[i], (unsigned int)term_lengths[i], raptor_ntriples_term_as_string(term_types[i])); #endif } if(len) { raptor_parser_error(rdf_parser, "Junk before terminating \".\""); return 0; } if(object_literal_language) { unsigned char *q; /* Normalize language to lowercase * http://www.w3.org/TR/rdf-concepts/#dfn-language-identifier */ for(q=object_literal_language; *q; q++) { if(IS_ASCII_UPPER(*q)) *q=TO_ASCII_LOWER(*q); } } raptor_ntriples_generate_statement(rdf_parser, terms[0], term_types[0], terms[1], term_types[1], terms[2], term_types[2], object_literal_language, object_literal_datatype); rdf_parser->locator.byte += len; cleanup: for(i=0; i<3; i++) if(terms_allocated[i]) RAPTOR_FREE(cstring, terms[i]); return rc; }