Пример #1
0
/**
 * raptor_new_iostream_from_handler:
 * @world: raptor_world object
 * @user_data: pointer to context information to pass in to calls
 * @handler: pointer to handler methods
 *
 * Create a new iostream over a user-defined handler
 *
 * Return value: new #raptor_iostream object or NULL on failure
 **/
raptor_iostream*
raptor_new_iostream_from_handler(raptor_world *world,
                                 void *user_data,
                                 const raptor_iostream_handler* const handler)
{
  raptor_iostream* iostr;

  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);
  RAPTOR_ASSERT_OBJECT_POINTER_RETURN_VALUE(handler, raptor_iostream_handler, NULL);

  raptor_world_open(world);
  
  if(!raptor_iostream_check_handler(handler, 0))
    return NULL;

  iostr = RAPTOR_CALLOC(raptor_iostream*, 1, sizeof(*iostr));
  if(!iostr)
    return NULL;

  iostr->world = world;
  iostr->handler = handler;
  iostr->user_data = (void*)user_data;
  iostr->mode = raptor_iostream_calculate_modes(handler);
  
  if(iostr->handler->init && 
     iostr->handler->init(iostr->user_data)) {
    RAPTOR_FREE(raptor_iostream, iostr);
    return NULL;
  }
  return iostr;
}
Пример #2
0
/**
 * raptor_new_iostream_from_file_handle:
 * @world: raptor world
 * @handle: Input file_handle to open and read from
 *
 * Constructor - create a new iostream reading from a file_handle.
 * 
 * The @handle must already be open for reading.
 * NOTE: This does not fclose the @handle when it is finished.
 *
 * Return value: new #raptor_iostream object or NULL on failure
 **/
raptor_iostream*
raptor_new_iostream_from_file_handle(raptor_world *world, FILE *handle)
{
  raptor_iostream* iostr;
  const raptor_iostream_handler* handler;
  const unsigned int mode = RAPTOR_IOSTREAM_MODE_READ;

  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  if(!handle)
    return NULL;
  
  raptor_world_open(world);
  
  handler = &raptor_iostream_read_file_handle_handler;
  if(!raptor_iostream_check_handler(handler, mode))
    return NULL;

  iostr = RAPTOR_CALLOC(raptor_iostream*, 1, sizeof(*iostr));
  if(!iostr)
    return NULL;

  iostr->world = world;
  iostr->handler = handler;
  iostr->user_data = (void*)handle;
  iostr->mode = mode;

  if(iostr->handler->init && 
     iostr->handler->init(iostr->user_data)) {
    RAPTOR_FREE(raptor_iostream, iostr);
    return NULL;
  }
  return iostr;
}
Пример #3
0
/**
 * raptor_new_sax2:
 * @world: raptor world
 * @locator: raptor locator to use for errors
 * @user_data: pointer context information to pass to SAX handlers
 *
 * Constructor - Create a new SAX2 with error handlers
 *
 * Return value: new #raptor_sax2 object or NULL on failure
 */
raptor_sax2*
raptor_new_sax2(raptor_world *world, raptor_locator *locator,
                void* user_data)
{
  raptor_sax2* sax2;

  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  if(!locator)
    return NULL;
  
  raptor_world_open(world);

  sax2 = RAPTOR_CALLOC(raptor_sax2*, 1, sizeof(*sax2));
  if(!sax2)
    return NULL;

#ifdef RAPTOR_XML_LIBXML
  sax2->magic = RAPTOR_LIBXML_MAGIC;
#endif

  sax2->world = world;
  sax2->locator = locator;
  sax2->user_data = user_data;

  sax2->enabled = 1;

  raptor_object_options_init(&sax2->options, RAPTOR_OPTION_AREA_SAX2);
  
  return sax2;
}
Пример #4
0
/**
 * raptor_new_www:
 * @world: raptor_world object
 * 
 * Constructor - create a new #raptor_www object.
 * 
 * Return value: a new #raptor_www or NULL on failure.
 **/
raptor_www*
raptor_new_www(raptor_world* world)
{
  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  raptor_world_open(world);

  return raptor_new_www_with_connection(world, NULL);
}
Пример #5
0
/**
 * raptor_new_iostream_from_sink:
 * @world: raptor world
 *
 * Create a new read iostream from a sink.
 * 
 * Return value: new #raptor_iostream object or NULL on failure
 **/
raptor_iostream*
raptor_new_iostream_from_sink(raptor_world *world)
{
  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  raptor_world_open(world);
  
  return raptor_new_iostream_from_handler(world, NULL,
                                          &raptor_iostream_sink_handler);
}
Пример #6
0
/**
 * raptor_new_term_from_blank:
 * @world: raptor world
 * @blank: UTF-8 encoded blank node identifier (or NULL)
 *
 * Constructor - create a new blank node statement term from a UTF-8 encoded blank node ID
 *
 * Takes a copy of the passed in @blank
 *
 * If @blank is NULL, creates a new internal identifier and uses it.
 * This will use the handler set with
 * raptor_world_set_generate_bnodeid_parameters()
 *
 * Return value: new term or NULL on failure
*/
raptor_term*
raptor_new_term_from_blank(raptor_world* world, const unsigned char* blank)
{
  size_t length = 0;
  
  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  raptor_world_open(world);

  if (blank)
    length = strlen((const char*)blank);

  return raptor_new_term_from_counted_blank(world, blank, length);
}
Пример #7
0
/**
 * raptor_new_turtle_writer:
 * @world: raptor_world object
 * @base_uri: Base URI for the writer (or NULL)
 * @write_base_uri: non-0 to write '@base' directive to output
 * @nstack: Namespace stack for the writer to start with (or NULL)
 * @iostr: I/O stream to write to
 * 
 * Constructor - Create a new Turtle Writer writing Turtle to a raptor_iostream
 * 
 * Return value: a new #raptor_turtle_writer object or NULL on failure
 **/
raptor_turtle_writer*
raptor_new_turtle_writer(raptor_world* world,
                         raptor_uri* base_uri, int write_base_uri,
                         raptor_namespace_stack *nstack,
                         raptor_iostream* iostr)
{
  raptor_turtle_writer* turtle_writer;

  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  if(!nstack || !iostr)
    return NULL;
  
  raptor_world_open(world);

  turtle_writer = (raptor_turtle_writer*)RAPTOR_CALLOC(raptor_turtle_writer, 1,
                                                       sizeof(*turtle_writer));

  if(!turtle_writer)
    return NULL;

  turtle_writer->world = world;

  turtle_writer->nstack_depth = 0;

  turtle_writer->nstack = nstack;
  if(!turtle_writer->nstack) {
    turtle_writer->nstack = raptor_new_namespaces(world, 1);
    turtle_writer->my_nstack = 1;
  }

  turtle_writer->iostr = iostr;

  turtle_writer->flags = 0;
  turtle_writer->indent = 2;

  turtle_writer->base_uri = NULL;
  /* Ensure any initial base URI is not written relative */
  if(base_uri && write_base_uri)
    raptor_turtle_writer_base(turtle_writer, base_uri);
  turtle_writer->base_uri = base_uri;

  turtle_writer->xsd_boolean_uri = raptor_new_uri(world, (const unsigned char*)"http://www.w3.org/2001/XMLSchema#boolean");
  turtle_writer->xsd_decimal_uri = raptor_new_uri(world, (const unsigned char*)"http://www.w3.org/2001/XMLSchema#decimal");
  turtle_writer->xsd_double_uri = raptor_new_uri(world, (const unsigned char*)"http://www.w3.org/2001/XMLSchema#double");
  turtle_writer->xsd_integer_uri = raptor_new_uri(world, (const unsigned char*)"http://www.w3.org/2001/XMLSchema#integer");
  
  return turtle_writer;
}
Пример #8
0
/**
 * raptor_new_iostream_from_string:
 * @world: raptor world
 * @string: pointer to string
 * @length: length of string
 *
 * Constructor - create a new iostream reading from a string.
 *
 * Return value: new #raptor_iostream object or NULL on failure
 **/
raptor_iostream*
raptor_new_iostream_from_string(raptor_world *world,
                                void *string, size_t length)
{
  raptor_iostream* iostr;
  struct raptor_read_string_iostream_context* con;
  const raptor_iostream_handler* handler;
  const unsigned int mode = RAPTOR_IOSTREAM_MODE_READ;

  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  if(!string)
    return NULL;
  
  raptor_world_open(world);
  
  handler = &raptor_iostream_read_string_handler;
  if(!raptor_iostream_check_handler(handler, mode))
    return NULL;

  iostr = RAPTOR_CALLOC(raptor_iostream*, 1, sizeof(*iostr));
  if(!iostr)
    return NULL;

  con = RAPTOR_CALLOC(struct raptor_read_string_iostream_context*, 1,
                      sizeof(*con));
  if(!con) {
    RAPTOR_FREE(raptor_iostream, iostr);
    return NULL;
  }

  con->string = string;
  con->length = length;

  iostr->world = world;
  iostr->handler = handler;
  iostr->user_data = (void*)con;
  iostr->mode = mode;

  if(iostr->handler->init && iostr->handler->init(iostr->user_data)) {
    raptor_free_iostream(iostr);
    return NULL;
  }
  return iostr;
}
Пример #9
0
/**
 * raptor_new_term_from_counted_literal:
 * @world: raptor world
 * @literal: UTF-8 encoded literal string (or NULL for empty literal)
 * @literal_len: length of literal
 * @datatype: literal datatype URI (or NULL)
 * @language: literal language (or NULL for no language)
 * @language_len: literal language length
 *
 * Constructor - create a new literal statement term from a counted UTF-8 encoded literal string
 *
 * Takes copies of the passed in @literal, @datatype, @language
 *
 * Only one of @language or @datatype may be given.  If both are
 * given, NULL is returned.  If @language is the empty string, it is
 * the equivalent to NULL.
 *
 * Note: The @literal need not be NULL terminated - a NULL will be
 * added to the copied string used.
 *
 * Return value: new term or NULL on failure
 */
raptor_term*
raptor_new_term_from_counted_literal(raptor_world* world,
                                     const unsigned char* literal,
                                     size_t literal_len,
                                     raptor_uri* datatype,
                                     const unsigned char* language,
                                     unsigned char language_len)
{
  raptor_term *t;
  unsigned char* new_literal = NULL;
  unsigned char* new_language = NULL;

  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  raptor_world_open(world);

  if(language && !*language)
    language = NULL;

  if(language && datatype)
    return NULL;
  

  new_literal = RAPTOR_MALLOC(unsigned char*, literal_len + 1);
  if(!new_literal)
    return NULL;

  if(!literal || !*literal)
    literal_len = 0;

  if(literal_len) {
    memcpy(new_literal, literal, literal_len);
    new_literal[literal_len] = '\0';
  } else
    *new_literal = '\0';

  if(language) {
    new_language = RAPTOR_MALLOC(unsigned char*, language_len + 1);
    if(!new_language) {
      RAPTOR_FREE(char*, new_literal);
      return NULL;
    }
    memcpy(new_language, language, language_len);
    new_language[language_len] = '\0';
  } else
Пример #10
0
/**
 * raptor_new_term_from_uri_string:
 * @world: raptor world
 * @uri_string: UTF-8 encoded URI string.
 *
 * Constructor - create a new URI statement term from a UTF-8 encoded Unicode string
 *
 * Return value: new term or NULL on failure
*/
raptor_term*
raptor_new_term_from_uri_string(raptor_world* world, 
                                const unsigned char *uri_string)
{
  raptor_term *t;
  raptor_uri* uri;

  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  uri = raptor_new_uri(world, uri_string);
  if(!uri)
    return NULL;

  t = raptor_new_term_from_uri(world, uri);
  
  raptor_free_uri(uri);
  
  return t;
}
Пример #11
0
/**
 * raptor_new_xml_writer:
 * @world: raptor_world object
 * @nstack: Namespace stack for the writer to start with (or NULL)
 * @iostr: I/O stream to write to
 * 
 * Constructor - Create a new XML Writer writing XML to a raptor_iostream
 * 
 * Return value: a new #raptor_xml_writer object or NULL on failure
 **/
raptor_xml_writer*
raptor_new_xml_writer(raptor_world* world,
                      raptor_namespace_stack *nstack,
                      raptor_iostream* iostr)
{
  raptor_xml_writer* xml_writer;

  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  if(!iostr)
    return NULL;
  
  raptor_world_open(world);

  xml_writer = (raptor_xml_writer*)RAPTOR_CALLOC(raptor_xml_writer, 1,
                                                 sizeof(*xml_writer));
  if(!xml_writer)
    return NULL;

  xml_writer->world = world;

  xml_writer->nstack_depth = 0;

  xml_writer->nstack = nstack;
  if(!xml_writer->nstack) {
    xml_writer->nstack = raptor_new_namespaces(world, 1);
    xml_writer->my_nstack = 1;
  }

  xml_writer->iostr = iostr;

  raptor_object_options_init(&xml_writer->options,
                             RAPTOR_OPTION_AREA_XML_WRITER);
  
  RAPTOR_OPTIONS_SET_NUMERIC(xml_writer, RAPTOR_OPTION_WRITER_INDENT_WIDTH, 2);
  
  RAPTOR_OPTIONS_SET_NUMERIC(xml_writer, RAPTOR_OPTION_WRITER_XML_VERSION, 10);

  /* Write XML declaration */
  RAPTOR_OPTIONS_SET_NUMERIC(xml_writer, RAPTOR_OPTION_WRITER_XML_DECLARATION, 1);
  
  return xml_writer;
}
Пример #12
0
/**
 * raptor_new_iostream_to_filename:
 * @world: raptor world
 * @filename: Output filename to open and write to
 *
 * Constructor - create a new iostream writing to a filename.
 * 
 * Return value: new #raptor_iostream object or NULL on failure
 **/
raptor_iostream*
raptor_new_iostream_to_filename(raptor_world *world, const char *filename)
{
  FILE *handle;
  raptor_iostream* iostr;
  const raptor_iostream_handler* handler;
  const unsigned int mode = RAPTOR_IOSTREAM_MODE_WRITE;

  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  raptor_world_open(world);
  
  if(!filename)
    return NULL;
  
  handler = &raptor_iostream_write_filename_handler;
  if(!raptor_iostream_check_handler(handler, mode))
    return NULL;

  handle = fopen(filename, "wb");
  if(!handle)
    return NULL;
  
  iostr = RAPTOR_CALLOC(raptor_iostream*, 1, sizeof(*iostr));
  if(!iostr) {
    fclose(handle);
    return NULL;
  }

  iostr->world = world;
  iostr->handler = handler;
  iostr->user_data = (void*)handle;
  iostr->mode = mode;

  if(iostr->handler->init && 
     iostr->handler->init(iostr->user_data)) {
    raptor_free_iostream(iostr);
    return NULL;
  }
  return iostr;
}
Пример #13
0
/**
 * raptor_new_term_from_literal:
 * @world: raptor world
 * @literal: UTF-8 encoded literal string (or NULL for empty literal)
 * @datatype: literal datatype URI (or NULL)
 * @language: literal language (or NULL)
 *
 * Constructor - create a new literal statement term
 *
 * Takes copies of the passed in @literal, @datatype, @language
 *
 * Only one of @language or @datatype may be given.  If both are
 * given, NULL is returned.  If @language is the empty string, it is
 * the equivalent to NULL.
 *
 * Return value: new term or NULL on failure
*/
raptor_term*
raptor_new_term_from_literal(raptor_world* world,
                             const unsigned char* literal,
                             raptor_uri* datatype,
                             const unsigned char* language)
{
  size_t literal_len = 0;
  unsigned char language_len = 0;
  
  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  raptor_world_open(world);

  if(literal)
    literal_len = strlen((const char*)literal);

  if(language)
    language_len = strlen((const char*)language);
  
  return raptor_new_term_from_counted_literal(world, literal, literal_len,
                                              datatype, language, language_len);
}
Пример #14
0
/**
 * raptor_new_www_with_connection:
 * @world: raptor_world object
 * @connection: external WWW connection object.
 * 
 * Constructor - create a new #raptor_www object over an existing WWW connection.
 *
 * At present this only works with a libcurl CURL handle object
 * when raptor is compiled with libcurl suppport. Otherwise the
 * @connection is ignored.  This allows such things as setting
 * up special flags on the curl handle before passing into the constructor.
 * 
 * Return value: a new #raptor_www object or NULL on failure.
 **/
raptor_www* 
raptor_new_www_with_connection(raptor_world* world, void *connection)
{
  raptor_www* www;

  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  raptor_world_open(world);

  www = (raptor_www* )RAPTOR_CALLOC(www, 1, sizeof(*www));
  if(!www)
    return NULL;

  www->world = world;  
  www->type = NULL;
  www->free_type = 1; /* default is to free content type */
  www->total_bytes = 0;
  www->failed = 0;
  www->status_code = 0;
  www->write_bytes = NULL;
  www->content_type = NULL;
  www->uri_filter = NULL;
  www->connection_timeout = 10;
  www->cache_control = NULL;

#ifdef RAPTOR_WWW_LIBCURL
  www->curl_handle = (CURL*)connection;
  raptor_www_curl_init(www);
#endif
#ifdef RAPTOR_WWW_LIBXML
  raptor_www_libxml_init(www);
#endif
#ifdef RAPTOR_WWW_LIBFETCH
  raptor_www_libfetch_init(www);
#endif

  return www;
}
Пример #15
0
/**
 * raptor_new_serializer:
 * @world: raptor_world object
 * @name: the serializer name or NULL for default syntax
 *
 * Constructor - create a new raptor_serializer object.
 *
 * Return value: a new #raptor_serializer object or NULL on failure
 */
raptor_serializer*
raptor_new_serializer(raptor_world* world, const char *name)
{
  raptor_serializer_factory* factory;
  raptor_serializer* rdf_serializer;

  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  raptor_world_open(world);

  factory = raptor_get_serializer_factory(world, name);
  if(!factory)
    return NULL;

  rdf_serializer = RAPTOR_CALLOC(raptor_serializer*, 1, sizeof(*rdf_serializer));
  if(!rdf_serializer)
    return NULL;

  rdf_serializer->world = world;
  
  rdf_serializer->context = RAPTOR_CALLOC(void*, 1, factory->context_length);
  if(!rdf_serializer->context) {
    raptor_free_serializer(rdf_serializer);
    return NULL;
  }
  
  rdf_serializer->factory = factory;

  raptor_object_options_init(&rdf_serializer->options,
                             RAPTOR_OPTION_AREA_SERIALIZER);

  if(factory->init(rdf_serializer, name)) {
    raptor_free_serializer(rdf_serializer);
    return NULL;
  }
  
  return rdf_serializer;
}
Пример #16
0
/**
 * raptor_new_term_from_uri:
 * @world: raptor world
 * @uri: uri
 *
 * Constructor - create a new URI statement term
 *
 * Takes a copy (reference) of the passed in @uri
 *
 * Return value: new term or NULL on failure
*/
raptor_term*
raptor_new_term_from_uri(raptor_world* world, raptor_uri* uri)
{
  raptor_term *t;

  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  if(!uri)
    return NULL;
  
  raptor_world_open(world);

  t = (raptor_term*)RAPTOR_CALLOC(raptor_term, 1, sizeof(*t));
  if(!t)
    return NULL;

  t->usage = 1;
  t->world = world;
  t->type = RAPTOR_TERM_TYPE_URI;
  t->value.uri = raptor_uri_copy(uri);

  return t;
}
Пример #17
0
/**
 * raptor_new_term_from_counted_blank:
 * @world: raptor world
 * @blank: UTF-8 encoded blank node identifier (or NULL)
 * @length: length of identifier (or 0)
 *
 * Constructor - create a new blank node statement term from a counted UTF-8 encoded blank node ID
 *
 * Takes a copy of the passed in @blank
 *
 * If @blank is NULL, creates a new internal identifier and uses it.
 * This will use the handler set with
 * raptor_world_set_generate_bnodeid_parameters()
 *
 * Note: The @blank need not be NULL terminated - a NULL will be
 * added to the copied string used.
 *
 * Return value: new term or NULL on failure
*/
raptor_term*
raptor_new_term_from_counted_blank(raptor_world* world,
                                   const unsigned char* blank, size_t length)
{
  raptor_term *t;
  unsigned char* new_id;

  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  raptor_world_open(world);

  if (blank) {
    new_id = (unsigned char*)RAPTOR_MALLOC(cstring, length + 1);
    if(!new_id)
      return NULL;
    memcpy(new_id, blank, length);
    new_id[length] = '\0';
  } else {
    new_id = raptor_world_generate_bnodeid(world);
    length = strlen((const char*)new_id);
  }

  t = (raptor_term*)RAPTOR_CALLOC(raptor_term, 1, sizeof(*t));
  if(!t) {
    RAPTOR_FREE(cstring, new_id);
    return NULL;
  }

  t->usage = 1;
  t->world = world;
  t->type = RAPTOR_TERM_TYPE_BLANK;
  t->value.blank.string = new_id;
  t->value.blank.string_len = length;

  return t;
}
Пример #18
0
/**
 * raptor_new_iostream_to_string:
 * @world: raptor world
 * @string_p: pointer to location to hold string
 * @length_p: pointer to location to hold length of string (or NULL)
 * @malloc_handler: pointer to malloc() to use to make string (or NULL)
 *
 * Constructor - create a new iostream writing to a string.
 *
 * If @malloc_handler is null, raptor will allocate it using it's
 * own memory allocator.  *@string_p is set to NULL on failure (and
 * *@length_p to 0 if @length_p is not NULL).
 * 
 * Return value: new #raptor_iostream object or NULL on failure
 **/
RAPTOR_EXTERN_C
raptor_iostream*
raptor_new_iostream_to_string(raptor_world *world,
                              void **string_p, size_t *length_p,
                              raptor_data_malloc_handler const malloc_handler)
{
  raptor_iostream* iostr;
  struct raptor_write_string_iostream_context* con;
  const raptor_iostream_handler* handler;
  const unsigned int mode = RAPTOR_IOSTREAM_MODE_WRITE;

  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  if(!string_p)
    return NULL;
  
  raptor_world_open(world);
  
  handler = &raptor_iostream_write_string_handler;
  if(!raptor_iostream_check_handler(handler, mode))
    return NULL;

  iostr = RAPTOR_CALLOC(raptor_iostream*, 1, sizeof(*iostr));
  if(!iostr)
    return NULL;

  con = RAPTOR_CALLOC(struct raptor_write_string_iostream_context*, 1,
                      sizeof(*con));
  if(!con) {
    RAPTOR_FREE(raptor_iostream, iostr);
    return NULL;
  }

  con->sb = raptor_new_stringbuffer();
  if(!con->sb) {
    RAPTOR_FREE(raptor_iostream, iostr);
    RAPTOR_FREE(raptor_write_string_iostream_context, con);
    return NULL;
  }

  con->string_p = string_p;
  *string_p = NULL;

  con->length_p = length_p;  
  if(length_p)
    *length_p = 0;

  if(malloc_handler)
    con->malloc_handler = malloc_handler;
  else
    con->malloc_handler = raptor_alloc_memory;

  iostr->world = world;
  iostr->handler = handler;
  iostr->user_data = (void*)con;
  iostr->mode = mode;

  if(iostr->handler->init && iostr->handler->init(iostr->user_data)) {
    raptor_free_iostream(iostr);
    return NULL;
  }
  return iostr;
}
Пример #19
0
/**
 * raptor_new_term_from_counted_literal:
 * @world: raptor world
 * @literal: UTF-8 encoded literal string (or NULL for empty literal)
 * @literal_len: length of literal
 * @datatype: literal datatype URI (or NULL)
 * @language: literal language (or NULL for no language)
 * @language_len: literal language length
 *
 * Constructor - create a new literal statement term from a counted UTF-8 encoded literal string
 *
 * Takes copies of the passed in @literal, @datatype, @language
 *
 * Only one of @language or @datatype may be given.  If both are
 * given, NULL is returned.  If @language is the empty string, it is
 * the equivalent to NULL.
 *
 * Note: The @literal need not be NULL terminated - a NULL will be
 * added to the copied string used.
 *
 * Return value: new term or NULL on failure
 */
raptor_term*
raptor_new_term_from_counted_literal(raptor_world* world,
                                     const unsigned char* literal,
                                     size_t literal_len,
                                     raptor_uri* datatype,
                                     const unsigned char* language,
                                     unsigned char language_len)
{
  raptor_term *t;
  unsigned char* new_literal = NULL;
  unsigned char* new_language = NULL;

  RAPTOR_CHECK_CONSTRUCTOR_WORLD(world);

  raptor_world_open(world);

  if(language && !*language)
    language = NULL;

  if(language && datatype)
    return NULL;
  

  new_literal = (unsigned char*)RAPTOR_MALLOC(cstring, literal_len + 1);
  if(!new_literal)
    return NULL;

  if(!literal || !*literal)
    literal_len = 0;

  if(literal_len) {
    memcpy(new_literal, literal, literal_len);
    new_literal[literal_len] = '\0';
  } else
    *new_literal = '\0';

  if(language) {
    new_language = (unsigned char*)RAPTOR_MALLOC(cstring, language_len + 1);
    if(!new_language) {
      RAPTOR_FREE(cstring, new_literal);
      return NULL;
    }
    memcpy(new_language, language, language_len);
    new_language[language_len] = '\0';
  } else
    language_len = 0;

  if(datatype)
    datatype = raptor_uri_copy(datatype);
  

  t = (raptor_term*)RAPTOR_CALLOC(raptor_term, 1, sizeof(*t));
  if(!t) {
    if(new_literal)
      RAPTOR_FREE(cstring, new_literal);
    if(new_language)
      RAPTOR_FREE(cstring, new_language);
    if(datatype)
      raptor_free_uri(datatype);
    return NULL;
  }
  t->usage = 1;
  t->world = world;
  t->type = RAPTOR_TERM_TYPE_LITERAL;
  t->value.literal.string = new_literal;
  t->value.literal.string_len = literal_len;
  t->value.literal.language = new_language;
  t->value.literal.language_len = language_len;
  t->value.literal.datatype = datatype;

  return t;
}