1 /*
2 ##############################################################################
3 # 	Copyright (c) 2000-2006 All rights reserved
4 # 	Alberto Reggiori <areggiori@webweaving.org>
5 #	Dirk-Willem van Gulik <dirkx@webweaving.org>
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 #
11 # 1. Redistributions of source code must retain the above copyright
12 #    notice, this list of conditions and the following disclaimer.
13 #
14 # 2. Redistributions in binary form must reproduce the above copyright
15 #    notice, this list of conditions and the following disclaimer in
16 #    the documentation and/or other materials provided with the
17 #    distribution.
18 #
19 # 3. The end-user documentation included with the redistribution,
20 #    if any, must include the following acknowledgment:
21 #       "This product includes software developed by
22 #        Alberto Reggiori <areggiori@webweaving.org> and
23 #        Dirk-Willem van Gulik <dirkx@webweaving.org>."
24 #    Alternately, this acknowledgment may appear in the software itself,
25 #    if and wherever such third-party acknowledgments normally appear.
26 #
27 # 4. All advertising materials mentioning features or use of this software
28 #    must display the following acknowledgement:
29 #    This product includes software developed by the University of
30 #    California, Berkeley and its contributors.
31 #
32 # 5. Neither the name of the University nor the names of its contributors
33 #    may be used to endorse or promote products derived from this software
34 #    without specific prior written permission.
35 #
36 # 6. Products derived from this software may not be called "RDFStore"
37 #    nor may "RDFStore" appear in their names without prior written
38 #    permission.
39 #
40 # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
41 # ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44 # FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 # OF THE POSSIBILITY OF SUCH DAMAGE.
52 #
53 # ====================================================================
54 #
55 # This software consists of work developed by Alberto Reggiori and
56 # Dirk-Willem van Gulik. The RDF specific part is based based on public
57 # domain software written at the Stanford University Database Group by
58 # Sergey Melnik. For more information on the RDF API Draft work,
59 # please see <http://www-db.stanford.edu/~melnik/rdf/api.html>
60 # The DBMS TCP/IP server part is based on software originally written
61 # by Dirk-Willem van Gulik for Web Weaving Internet Engineering m/v Enschede,
62 # The Netherlands.
63 #
64 ##############################################################################
65 #
66 # $Id: rdfstore_iterator.c,v 1.16 2006/06/19 10:10:21 areggiori Exp $
67 #
68 */
69 
70 #if !defined(WIN32)
71 #include <sys/param.h>
72 #endif
73 
74 #include <sys/types.h>
75 #include <stdio.h>
76 #include <stdlib.h>
77 #include <errno.h>
78 #include <strings.h>
79 #include <fcntl.h>
80 
81 #include <time.h>
82 #include <sys/stat.h>
83 
84 #include "rdfstore_log.h"
85 #include "rdfstore.h"
86 #include "rdfstore_iterator.h"
87 #include "rdfstore_serializer.h"
88 #include "rdfstore_digest.h"
89 #include "rdfstore_bits.h"
90 #include "rdfstore_utf8.h"
91 
92 /*
93 #define RDFSTORE_DEBUG
94 */
95 
96 RDF_Statement   *
97 rdfstore_iterator_fetch_statement (
98 rdfstore_iterator       * me
99 );
100 
rdfstore_iterator_close(rdfstore_iterator * me)101 int rdfstore_iterator_close (
102 rdfstore_iterator * me
103 ) {
104 	if (	( me != NULL ) &&
105 		( me->store != NULL ) &&
106 		( me->store->cursor != NULL ) &&
107 		( me != me->store->cursor ) ) { /* do not touch internal cursors - still needed????!!??! */
108                 me->store->attached--; /* detach myself from the storage */
109 
110 		/* dispose the storage (if possible) */
111 		if ( me->store->tobeclosed ) {
112 #ifdef RDFSTORE_DEBUG
113                         printf(">>>>>>>>>>>>>>>>>>>>%p GOING TO CLOSE\n",me->store);
114 #endif
115                         rdfstore_disconnect( me->store );
116                         };
117 
118 		RDFSTORE_FREE( me );
119 		me = NULL;
120 
121 		return 1;
122 	} else {
123 		return 0;
124 	};
125 };
126 
rdfstore_iterator_hasnext(rdfstore_iterator * me)127 int rdfstore_iterator_hasnext (
128 rdfstore_iterator       * me
129 ) {
130 if ( me == NULL )
131 	return 0;
132 #ifdef RDFSTORE_DEBUG
133 printf("HASNEXT %d < %d\n",me->st_counter, me->size);
134 #endif
135 if ( me->st_counter < me->size ) {
136 	return 1;
137 } else {
138 	return 0;
139 	};
140 };
141 
142 RDF_Statement   *
rdfstore_iterator_next(rdfstore_iterator * me)143 rdfstore_iterator_next (
144 rdfstore_iterator       * me
145 ) {
146 	RDF_Statement   * s=NULL;
147 
148 	if ( me == NULL )
149 		return NULL;
150 
151 	/* advance to the next item */
152 	me->st_counter++;
153 
154 	/* get the next one if any */
155 	me->pos++;
156 	if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
157 		return NULL;
158 
159 #ifdef RDFSTORE_DEBUG
160 printf("rdfstore_iterator_next( st_counter=%d pos=%d )\n",me->st_counter,me->pos);
161 #endif
162 
163 	s =  rdfstore_iterator_fetch_statement ( me );
164 
165 #ifdef RDFSTORE_DEBUG
166 	if (s != NULL ){
167 		fprintf(stderr,"\tS='%s'\n",s->subject->value.resource.identifier);
168                 fprintf(stderr,"\tP='%s'\n",s->predicate->value.resource.identifier);
169                 if ( s->object->type != 1 ) {
170                 	fprintf(stderr,"\tO='%s'\n",s->object->value.resource.identifier);
171                 } else {
172                 	fprintf(stderr,"\tOLIT='%s'\n",s->object->value.literal.string);
173                 	};
174                 if ( s->context != NULL )
175                 	fprintf(stderr,"\tC='%s'\n",s->context->value.resource.identifier);
176                 if ( s->node != NULL )
177 			fprintf(stderr,"\tSRES='%s'\n",s->node->value.resource.identifier);
178 		};
179 #endif
180 
181 	return s;
182 	};
183 
184 RDF_Node   *
rdfstore_iterator_next_subject(rdfstore_iterator * me)185 rdfstore_iterator_next_subject (
186         rdfstore_iterator       * me
187         ) {
188 	RDF_Statement   * s=NULL;
189 	RDF_Node    * r=NULL;
190 
191 	if ( me == NULL )
192 		return NULL;
193 	/* advance to the next item */
194 	me->st_counter++;
195 
196 	/* get the next one if any */
197 	me->pos++;
198 	if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
199                 return NULL;
200 
201 	s =  rdfstore_iterator_fetch_statement ( me );
202 
203 	if ( s != NULL ) {
204         	r = s->subject;
205 
206         	RDFSTORE_FREE( s->predicate->value.resource.identifier );
207         	RDFSTORE_FREE( s->predicate );
208         	if ( s->object->type == 1 ) {
209 			if ( s->object->value.literal.dataType != NULL )
210 				RDFSTORE_FREE( s->object->value.literal.dataType );
211         		RDFSTORE_FREE( s->object->value.literal.string );
212         	} else {
213         		RDFSTORE_FREE( s->object->value.resource.identifier );
214         		};
215         	RDFSTORE_FREE( s->object );
216 		if ( s->context != NULL ) {
217         		RDFSTORE_FREE( s->context->value.resource.identifier );
218         		RDFSTORE_FREE( s->context );
219 			};
220 		if ( s->node != NULL ) {
221         		RDFSTORE_FREE( s->node->value.resource.identifier );
222         		RDFSTORE_FREE( s->node );
223 			};
224         	RDFSTORE_FREE( s );
225 		};
226 
227 	return r;
228 	};
229 
230 RDF_Node   *
rdfstore_iterator_next_predicate(rdfstore_iterator * me)231 rdfstore_iterator_next_predicate (
232         rdfstore_iterator       * me
233         ) {
234 	RDF_Statement   * s=NULL;
235         RDF_Node    * r=NULL;
236 
237 	if ( me == NULL )
238 		return NULL;
239 
240 	/* advance to the next item */
241 	me->st_counter++;
242 
243 	/* get the next one if any */
244 	me->pos++;
245 	if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
246                 return NULL;
247 
248 	s =  rdfstore_iterator_fetch_statement ( me );
249 
250 	if ( s != NULL ) {
251 		RDFSTORE_FREE( s->subject->value.resource.identifier );
252         	RDFSTORE_FREE( s->subject );
253 
254         	r = s->predicate;
255 
256         	if ( s->object->type == 1 ) {
257 			if ( s->object->value.literal.dataType != NULL )
258                         	RDFSTORE_FREE( s->object->value.literal.dataType );
259                 	RDFSTORE_FREE( s->object->value.literal.string );
260         	} else {
261                 	RDFSTORE_FREE( s->object->value.resource.identifier );
262                 	};
263         	RDFSTORE_FREE( s->object );
264         	if ( s->context != NULL ) {
265                 	RDFSTORE_FREE( s->context->value.resource.identifier );
266                 	RDFSTORE_FREE( s->context );
267                 	};
268 		if ( s->node != NULL ) {
269                 	RDFSTORE_FREE( s->node->value.resource.identifier );
270                 	RDFSTORE_FREE( s->node );
271                 	};
272         	RDFSTORE_FREE( s );
273 		};
274 
275         return r;
276 	};
277 
278 RDF_Node   *
rdfstore_iterator_next_object(rdfstore_iterator * me)279 rdfstore_iterator_next_object (
280         rdfstore_iterator       * me
281         ) {
282 	RDF_Statement   * s=NULL;
283         RDF_Node    * p=NULL;
284 
285 	if ( me == NULL )
286 		return NULL;
287 
288 	/* advance to the next item */
289 	me->st_counter++;
290 
291 	/* get the next one if any */
292 	me->pos++;
293 	if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
294                 return NULL;
295 
296 	s =  rdfstore_iterator_fetch_statement ( me );
297 
298 	if ( s != NULL ) {
299 		RDFSTORE_FREE( s->subject->value.resource.identifier );
300         	RDFSTORE_FREE( s->subject );
301 		RDFSTORE_FREE( s->predicate->value.resource.identifier );
302         	RDFSTORE_FREE( s->predicate );
303 
304         	p = s->object;
305 
306         	if ( s->context != NULL ) {
307                 	RDFSTORE_FREE( s->context->value.resource.identifier );
308                 	RDFSTORE_FREE( s->context );
309                 	};
310 		if ( s->node != NULL ) {
311                 	RDFSTORE_FREE( s->node->value.resource.identifier );
312                 	RDFSTORE_FREE( s->node );
313                 	};
314         	RDFSTORE_FREE( s );
315 		};
316 
317         return p;
318 	};
319 
320 RDF_Node   *
rdfstore_iterator_next_context(rdfstore_iterator * me)321 rdfstore_iterator_next_context (
322         rdfstore_iterator       * me
323         ) {
324 	RDF_Statement   * s=NULL;
325         RDF_Node    * r=NULL;
326 
327 	if ( me == NULL )
328 		return NULL;
329 
330 	/* advance to the next item */
331 	me->st_counter++;
332 
333 	/* get the next one if any */
334 	me->pos++;
335 	if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
336                 return NULL;
337 
338 	s =  rdfstore_iterator_fetch_statement ( me );
339 
340 	if ( s != NULL ) {
341 		RDFSTORE_FREE( s->subject->value.resource.identifier );
342         	RDFSTORE_FREE( s->subject );
343 		RDFSTORE_FREE( s->predicate->value.resource.identifier );
344         	RDFSTORE_FREE( s->predicate );
345         	if ( s->object->type == 1 ) {
346 			if ( s->object->value.literal.dataType != NULL )
347                         	RDFSTORE_FREE( s->object->value.literal.dataType );
348                 	RDFSTORE_FREE( s->object->value.literal.string );
349         	} else {
350                 	RDFSTORE_FREE( s->object->value.resource.identifier );
351                 	};
352         	RDFSTORE_FREE( s->object );
353 
354         	r = s->context;
355 
356 		if ( s->node != NULL ) {
357                 	RDFSTORE_FREE( s->node->value.resource.identifier );
358                 	RDFSTORE_FREE( s->node );
359                 	};
360         	RDFSTORE_FREE( s );
361 		};
362 
363         return r;
364 	};
365 
366 RDF_Statement   *
rdfstore_iterator_current(rdfstore_iterator * me)367 rdfstore_iterator_current (
368         rdfstore_iterator       * me
369         ) {
370 	if ( me == NULL )
371 		return NULL;
372 	return rdfstore_iterator_fetch_statement ( me );
373 	};
374 
375 RDF_Node   *
rdfstore_iterator_current_subject(rdfstore_iterator * me)376 rdfstore_iterator_current_subject (
377         rdfstore_iterator       * me
378         ) {
379 	RDF_Statement   * s=NULL;
380         RDF_Node    * r=NULL;
381 
382 	if ( me == NULL )
383 		return NULL;
384 
385 	s =  rdfstore_iterator_fetch_statement ( me );
386 
387 	if ( s != NULL ) {
388         	r = s->subject;
389 
390 		RDFSTORE_FREE( s->predicate->value.resource.identifier );
391         	RDFSTORE_FREE( s->predicate );
392         	if ( s->object->type == 1 ) {
393 			if ( s->object->value.literal.dataType != NULL )
394                         	RDFSTORE_FREE( s->object->value.literal.dataType );
395                 	RDFSTORE_FREE( s->object->value.literal.string );
396         	} else {
397                 	RDFSTORE_FREE( s->object->value.resource.identifier );
398                 	};
399         	RDFSTORE_FREE( s->object );
400         	if ( s->context != NULL ) {
401                 	RDFSTORE_FREE( s->context->value.resource.identifier );
402                 	RDFSTORE_FREE( s->context );
403                 	};
404 		if ( s->node != NULL ) {
405                 	RDFSTORE_FREE( s->node->value.resource.identifier );
406                 	RDFSTORE_FREE( s->node );
407                 	};
408         	RDFSTORE_FREE( s );
409 		};
410 
411         return r;
412 	};
413 
414 RDF_Node   *
rdfstore_iterator_current_predicate(rdfstore_iterator * me)415 rdfstore_iterator_current_predicate (
416         rdfstore_iterator       * me
417         ) {
418 	RDF_Statement   * s=NULL;
419         RDF_Node    * r=NULL;
420 
421 	if ( me == NULL )
422 		return NULL;
423 
424 	s =  rdfstore_iterator_fetch_statement ( me );
425 
426 	if ( s != NULL ) {
427 		RDFSTORE_FREE( s->subject->value.resource.identifier );
428         	RDFSTORE_FREE( s->subject );
429 
430         	r = s->predicate;
431 
432         	if ( s->object->type == 1 ) {
433 			if ( s->object->value.literal.dataType != NULL )
434                         	RDFSTORE_FREE( s->object->value.literal.dataType );
435                 	RDFSTORE_FREE( s->object->value.literal.string );
436         	} else {
437                 	RDFSTORE_FREE( s->object->value.resource.identifier );
438                 	};
439         	RDFSTORE_FREE( s->object );
440         	if ( s->context != NULL ) {
441                 	RDFSTORE_FREE( s->context->value.resource.identifier );
442                 	RDFSTORE_FREE( s->context );
443                 	};
444 		if ( s->node != NULL ) {
445                 	RDFSTORE_FREE( s->node->value.resource.identifier );
446                 	RDFSTORE_FREE( s->node );
447                 	};
448         	RDFSTORE_FREE( s );
449 		};
450 
451         return r;
452 	};
453 
454 RDF_Node   *
rdfstore_iterator_current_object(rdfstore_iterator * me)455 rdfstore_iterator_current_object (
456         rdfstore_iterator       * me
457         ) {
458 	RDF_Statement   * s=NULL;
459         RDF_Node    * p=NULL;
460 
461 	if ( me == NULL )
462 		return NULL;
463 
464 	s =  rdfstore_iterator_fetch_statement ( me );
465 
466 	if ( s != NULL ) {
467 		RDFSTORE_FREE( s->subject->value.resource.identifier );
468         	RDFSTORE_FREE( s->subject );
469         	RDFSTORE_FREE( s->predicate->value.resource.identifier );
470         	RDFSTORE_FREE( s->predicate );
471 
472         	p = s->object;
473 
474         	if ( s->context != NULL ) {
475                 	RDFSTORE_FREE( s->context->value.resource.identifier );
476                 	RDFSTORE_FREE( s->context );
477                 	};
478 		if ( s->node != NULL ) {
479                 	RDFSTORE_FREE( s->node->value.resource.identifier );
480                 	RDFSTORE_FREE( s->node );
481                 	};
482         	RDFSTORE_FREE( s );
483 		};
484 
485         return p;
486 	};
487 
488 RDF_Node   *
rdfstore_iterator_current_context(rdfstore_iterator * me)489 rdfstore_iterator_current_context (
490         rdfstore_iterator       * me
491         ) {
492 	RDF_Statement   * s=NULL;
493         RDF_Node    * r=NULL;
494 
495 	if ( me == NULL )
496 		return NULL;
497 
498 	s =  rdfstore_iterator_fetch_statement ( me );
499 
500 	if ( s != NULL ) {
501 		RDFSTORE_FREE( s->subject->value.resource.identifier );
502         	RDFSTORE_FREE( s->subject );
503 		RDFSTORE_FREE( s->predicate->value.resource.identifier );
504         	RDFSTORE_FREE( s->predicate );
505         	if ( s->object->type == 1 ) {
506 			if ( s->object->value.literal.dataType != NULL )
507                         	RDFSTORE_FREE( s->object->value.literal.dataType );
508                 	RDFSTORE_FREE( s->object->value.literal.string );
509         	} else {
510                 	RDFSTORE_FREE( s->object->value.resource.identifier );
511                 	};
512         	RDFSTORE_FREE( s->object );
513 
514         	r = s->context;
515 
516 		if ( s->node != NULL ) {
517                 	RDFSTORE_FREE( s->node->value.resource.identifier );
518                 	RDFSTORE_FREE( s->node );
519                 	};
520         	RDFSTORE_FREE( s );
521 		};
522 
523         return r;
524 	};
525 
526 /* the following 4 methods reset the iterator and return the first item in the list */
527 RDF_Statement   *
rdfstore_iterator_first(rdfstore_iterator * me)528 rdfstore_iterator_first (
529         rdfstore_iterator       * me
530         ) {
531 	RDF_Statement   * s=NULL;
532 	if ( me == NULL )
533 		return NULL;
534 
535 	/* reset iterator */
536 	me->st_counter = 0;
537 
538 	/* get the first one if any */
539 	me->pos = 0;
540 	if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
541 		return NULL;
542 
543 #ifdef RDFSTORE_DEBUG
544 printf("rdfstore_iterator_first( st_counter=%d pos=%d )\n",me->st_counter,me->pos);
545 #endif
546 
547 	s = rdfstore_iterator_current ( me );
548 
549 #ifdef RDFSTORE_DEBUG
550 	if (s != NULL ){
551 		fprintf(stderr,"\tS='%s'\n",s->subject->value.resource.identifier);
552                 fprintf(stderr,"\tP='%s'\n",s->predicate->value.resource.identifier);
553                 if ( s->object->type != 1 ) {
554                 	fprintf(stderr,"\tO='%s'\n",s->object->value.resource.identifier);
555                 } else {
556                 	fprintf(stderr,"\tOLIT='%s'\n",s->object->value.literal.string);
557                 	};
558                 if ( s->context != NULL )
559                 	fprintf(stderr,"\tC='%s'\n",s->context->value.resource.identifier);
560                 if ( s->node != NULL )
561 			fprintf(stderr,"\tSRES='%s'\n",s->node->value.resource.identifier);
562 		};
563 #endif
564 
565 	return s;
566 	};
567 
568 RDF_Node   *
rdfstore_iterator_first_subject(rdfstore_iterator * me)569 rdfstore_iterator_first_subject (
570         rdfstore_iterator       * me
571         ) {
572 	if ( me == NULL )
573 		return NULL;
574 
575 	/* reset iterator */
576 	me->st_counter = 0;
577 
578 	/* get the first one if any */
579 	me->pos = 0;
580 	if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
581 		return NULL;
582 
583 	return rdfstore_iterator_current_subject ( me );
584 	};
585 
586 RDF_Node   *
rdfstore_iterator_first_predicate(rdfstore_iterator * me)587 rdfstore_iterator_first_predicate (
588         rdfstore_iterator       * me
589         ) {
590 	if ( me == NULL )
591 		return NULL;
592 
593 	/* reset iterator */
594 	me->st_counter = 0;
595 
596 	/* get the first one if any */
597 	me->pos = 0;
598 	if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
599 		return NULL;
600 
601 	return rdfstore_iterator_current_predicate ( me );
602 	};
603 
604 RDF_Node   *
rdfstore_iterator_first_object(rdfstore_iterator * me)605 rdfstore_iterator_first_object (
606         rdfstore_iterator       * me
607         ) {
608 	if ( me == NULL )
609 		return NULL;
610 
611 	/* reset iterator */
612 	me->st_counter = 0;
613 
614 	/* get the first one if any */
615 	me->pos = 0;
616 	if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
617 		return NULL;
618 
619 	return rdfstore_iterator_current_object ( me );
620 	};
621 
622 RDF_Node   *
rdfstore_iterator_first_context(rdfstore_iterator * me)623 rdfstore_iterator_first_context (
624         rdfstore_iterator       * me
625         ) {
626 	if ( me == NULL )
627 		return NULL;
628 
629 	/* reset iterator */
630 	me->st_counter = 0;
631 
632 	/* get the first one if any */
633 	me->pos = 0;
634 	if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) )
635 		return NULL;
636 
637 	return rdfstore_iterator_current_context ( me );
638 	};
639 
640 /* return items one by one till the end; then reset and return undef i.e. while( s = rdfstore_iterator_each(me) ) { ..... }; */
641 RDF_Statement   *
rdfstore_iterator_each(rdfstore_iterator * me)642 rdfstore_iterator_each (
643 rdfstore_iterator       * me
644 ) {
645 	RDF_Statement   * s=NULL;
646 
647 	if ( me == NULL )
648 		return NULL;
649 
650 	if (! rdfstore_iterator_hasnext( me ) ) {
651 		/* reset and return undef */
652 		me->st_counter = 0;
653 		me->pos = 0;
654 		return NULL;
655 		};
656 
657 	/* set pos to the current one */
658 	if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) ) {
659 		/* reset and return undef */
660 		me->st_counter = 0;
661 		me->pos = 0;
662 		return NULL; /* but this is an error not end of iteration! */
663 		};
664 
665 #ifdef RDFSTORE_DEBUG
666 printf("rdfstore_iterator_each( st_counter=%d pos=%d )\n",me->st_counter,me->pos);
667 #endif
668 
669 	s =  rdfstore_iterator_fetch_statement ( me );
670 
671 	if ( s == NULL ) {
672 		/* reset and return undef */
673 		me->st_counter = 0;
674 		me->pos = 0;
675 		return NULL; /* but this is an error not end of iteration! */
676 		};
677 
678 	/* hop to the next one if any */
679 	me->st_counter++;
680 	me->pos++;
681 
682 #ifdef RDFSTORE_DEBUG
683 	if (s != NULL ){
684 		fprintf(stderr,"\tS='%s'\n",s->subject->value.resource.identifier);
685                 fprintf(stderr,"\tP='%s'\n",s->predicate->value.resource.identifier);
686                 if ( s->object->type != 1 ) {
687                 	fprintf(stderr,"\tO='%s'\n",s->object->value.resource.identifier);
688                 } else {
689                 	fprintf(stderr,"\tOLIT='%s'\n",s->object->value.literal.string);
690                 	};
691                 if ( s->context != NULL )
692                 	fprintf(stderr,"\tC='%s'\n",s->context->value.resource.identifier);
693                 if ( s->node != NULL )
694 			fprintf(stderr,"\tSRES='%s'\n",s->node->value.resource.identifier);
695 		};
696 #endif
697 
698 	return s;
699 	};
700 
701 RDF_Node   *
rdfstore_iterator_each_subject(rdfstore_iterator * me)702 rdfstore_iterator_each_subject (
703         rdfstore_iterator       * me
704         ) {
705 	RDF_Statement   * s=NULL;
706         RDF_Node    * r=NULL;
707 
708 	if ( me == NULL )
709 		return NULL;
710 
711 	if (! rdfstore_iterator_hasnext( me ) ) {
712                 /* reset and return undef */
713                 me->st_counter = 0;
714                 me->pos = 0;
715                 return NULL;
716                 };
717 
718         /* set pos to the current one */
719         if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) ) {
720                 /* reset and return undef */
721                 me->st_counter = 0;
722                 me->pos = 0;
723                 return NULL; /* but this is an error not end of iteration! */
724                 };
725 
726 	s =  rdfstore_iterator_fetch_statement ( me );
727 
728 	if ( s != NULL ) {
729         	r = s->subject;
730 
731 		RDFSTORE_FREE( s->predicate->value.resource.identifier );
732         	RDFSTORE_FREE( s->predicate );
733         	if ( s->object->type == 1 ) {
734 			if ( s->object->value.literal.dataType != NULL )
735                         	RDFSTORE_FREE( s->object->value.literal.dataType );
736                 	RDFSTORE_FREE( s->object->value.literal.string );
737         	} else {
738                 	RDFSTORE_FREE( s->object->value.resource.identifier );
739                 	};
740         	RDFSTORE_FREE( s->object );
741         	if ( s->context != NULL ) {
742                 	RDFSTORE_FREE( s->context->value.resource.identifier );
743                 	RDFSTORE_FREE( s->context );
744                 	};
745 		if ( s->node != NULL ) {
746                 	RDFSTORE_FREE( s->node->value.resource.identifier );
747                 	RDFSTORE_FREE( s->node );
748                 	};
749         	RDFSTORE_FREE( s );
750 		};
751 
752         if ( r == NULL ) {
753                 /* reset and return undef */
754                 me->st_counter = 0;
755                 me->pos = 0;
756                 return NULL; /* but this is an error not end of iteration! */
757                 };
758 
759         /* hop to the next one if any */
760         me->st_counter++;
761         me->pos++;
762 
763 	return r;
764 	};
765 
766 RDF_Node   *
rdfstore_iterator_each_predicate(rdfstore_iterator * me)767 rdfstore_iterator_each_predicate (
768         rdfstore_iterator       * me
769         ) {
770 	RDF_Statement   * s=NULL;
771         RDF_Node    * r=NULL;
772 
773         if ( me == NULL )
774                 return NULL;
775 
776         if (! rdfstore_iterator_hasnext( me ) ) {
777                 /* reset and return undef */
778                 me->st_counter = 0;
779                 me->pos = 0;
780                 return NULL;
781                 };
782 
783         /* set pos to the current one */
784         if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) ) {
785                 /* reset and return undef */
786                 me->st_counter = 0;
787                 me->pos = 0;
788                 return NULL; /* but this is an error not end of iteration! */
789                 };
790 
791 	s =  rdfstore_iterator_fetch_statement ( me );
792 
793 	if ( s != NULL ) {
794 		RDFSTORE_FREE( s->subject->value.resource.identifier );
795         	RDFSTORE_FREE( s->subject );
796 
797         	r = s->predicate;
798 
799         	if ( s->object->type == 1 ) {
800 			if ( s->object->value.literal.dataType != NULL )
801                         	RDFSTORE_FREE( s->object->value.literal.dataType );
802                 	RDFSTORE_FREE( s->object->value.literal.string );
803         	} else {
804                 	RDFSTORE_FREE( s->object->value.resource.identifier );
805                 	};
806         	RDFSTORE_FREE( s->object );
807         	if ( s->context != NULL ) {
808                 	RDFSTORE_FREE( s->context->value.resource.identifier );
809                 	RDFSTORE_FREE( s->context );
810                 	};
811 		if ( s->node != NULL ) {
812                 	RDFSTORE_FREE( s->node->value.resource.identifier );
813                 	RDFSTORE_FREE( s->node );
814                 	};
815         	RDFSTORE_FREE( s );
816 		};
817 
818         if ( r == NULL ) {
819                 /* reset and return undef */
820                 me->st_counter = 0;
821                 me->pos = 0;
822                 return NULL; /* but this is an error not end of iteration! */
823                 };
824 
825         /* hop to the next one if any */
826         me->st_counter++;
827         me->pos++;
828 
829         return r;
830 	};
831 
832 RDF_Node   *
rdfstore_iterator_each_object(rdfstore_iterator * me)833 rdfstore_iterator_each_object (
834         rdfstore_iterator       * me
835         ) {
836 	RDF_Statement   * s=NULL;
837         RDF_Node    * p=NULL;
838 
839         if ( me == NULL )
840                 return NULL;
841 
842         if (! rdfstore_iterator_hasnext( me ) ) {
843                 /* reset and return undef */
844                 me->st_counter = 0;
845                 me->pos = 0;
846                 return NULL;
847                 };
848 
849         /* set pos to the current one */
850         if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) ) {
851                 /* reset and return undef */
852                 me->st_counter = 0;
853                 me->pos = 0;
854                 return NULL; /* but this is an error not end of iteration! */
855                 };
856 
857 	s =  rdfstore_iterator_fetch_statement ( me );
858 
859 	if ( s != NULL ) {
860 		RDFSTORE_FREE( s->subject->value.resource.identifier );
861         	RDFSTORE_FREE( s->subject );
862         	RDFSTORE_FREE( s->predicate->value.resource.identifier );
863         	RDFSTORE_FREE( s->predicate );
864 
865         	p = s->object;
866 
867         	if ( s->context != NULL ) {
868                 	RDFSTORE_FREE( s->context->value.resource.identifier );
869                 	RDFSTORE_FREE( s->context );
870                 	};
871 		if ( s->node != NULL ) {
872                 	RDFSTORE_FREE( s->node->value.resource.identifier );
873                 	RDFSTORE_FREE( s->node );
874                 	};
875         	RDFSTORE_FREE( s );
876 		};
877 
878         if ( p == NULL ) {
879                 /* reset and return undef */
880                 me->st_counter = 0;
881                 me->pos = 0;
882                 return NULL; /* but this is an error not end of iteration! */
883                 };
884 
885         /* hop to the next one if any */
886         me->st_counter++;
887         me->pos++;
888 
889         return p;
890 	};
891 
892 RDF_Node   *
rdfstore_iterator_each_context(rdfstore_iterator * me)893 rdfstore_iterator_each_context (
894         rdfstore_iterator       * me
895         ) {
896 	RDF_Statement   * s=NULL;
897         RDF_Node    * r=NULL;
898 
899 	if ( me == NULL )
900 		return NULL;
901 
902 	if (! rdfstore_iterator_hasnext( me ) ) {
903                 /* reset and return undef */
904                 me->st_counter = 0;
905                 me->pos = 0;
906                 return NULL;
907                 };
908 
909         /* set pos to the current one */
910         if ( (me->pos = rdfstore_bits_getfirstsetafter(me->ids_size, me->ids, me->pos)) >= 8*(me->ids_size) ) {
911                 /* reset and return undef */
912                 me->st_counter = 0;
913                 me->pos = 0;
914                 return NULL; /* but this is an error not end of iteration! */
915                 };
916 
917 	s =  rdfstore_iterator_fetch_statement ( me );
918 
919 	if ( s != NULL ) {
920 		RDFSTORE_FREE( s->subject->value.resource.identifier );
921         	RDFSTORE_FREE( s->subject );
922         	RDFSTORE_FREE( s->predicate->value.resource.identifier );
923         	RDFSTORE_FREE( s->predicate );
924         	if ( s->object->type == 1 ) {
925 			if ( s->object->value.literal.dataType != NULL )
926                         	RDFSTORE_FREE( s->object->value.literal.dataType );
927                 	RDFSTORE_FREE( s->object->value.literal.string );
928         	} else {
929                 	RDFSTORE_FREE( s->object->value.resource.identifier );
930                 	};
931         	RDFSTORE_FREE( s->object );
932 
933         	r = s->context;
934 
935 		if ( s->node != NULL ) {
936                 	RDFSTORE_FREE( s->node->value.resource.identifier );
937                 	RDFSTORE_FREE( s->node );
938                 	};
939         	RDFSTORE_FREE( s );
940 		};
941 
942         if ( r == NULL ) {
943                 /* reset and return undef */
944                 me->st_counter = 0;
945                 me->pos = 0;
946                 return NULL; /* but this is an error not end of iteration! */
947                 };
948 
949         /* hop to the next one if any */
950         me->st_counter++;
951         me->pos++;
952 
953 	return r;
954 	};
955 
rdfstore_iterator_remove(rdfstore_iterator * me)956 int rdfstore_iterator_remove (
957         rdfstore_iterator       * me
958         ) {
959 
960 #ifdef RDFSTORE_DEBUG
961 	{
962 	int i=0;
963         printf("iterator remove ACTUAL (BEFORE remove):\n");
964         for ( i=0; i<me->ids_size; i++) {
965 		printf("%02X",me->ids[i]);
966        		};
967 	printf("' (%d)\n",me->ids_size);
968 	}
969 #endif
970 
971 	/* zap current pos - we do not check whether is zero already or not....yet :) */
972 	if( ! rdfstore_bits_setmask(& me->ids_size, me->ids, me->pos, 1, 0, sizeof(me->ids)) )
973 		return 0;
974 
975 #ifdef RDFSTORE_DEBUG
976 	{
977 	int i=0;
978         printf("iterator remove ACTUAL (AFTER remove):\n");
979         for ( i=0; i<me->ids_size; i++) {
980 		printf("%02X",me->ids[i]);
981        		};
982 	printf("' (%d)\n",me->ids_size);
983 	}
984 #endif
985 
986 	me->size--;
987 	me->ids_size = rdfstore_bits_shorten( me->ids_size, me->ids );
988 
989 	return 1;
990 	};
991 
992 int
rdfstore_iterator_contains(rdfstore_iterator * me,RDF_Statement * statement,RDF_Node * given_context)993 rdfstore_iterator_contains (
994         rdfstore_iterator       * me,
995         RDF_Statement           * statement,
996         RDF_Node            * given_context
997         ) {
998         RDF_Node * context = NULL;
999         unsigned char outbuf[256];
1000         DBT key, data;
1001         unsigned int pos=0,err=0;
1002         unsigned int st_id=0;
1003 	int hc=0;
1004 
1005 	if (    ( statement             == NULL ) ||
1006         	( statement->subject    == NULL ) ||
1007         	( statement->predicate  == NULL ) ||
1008         	( statement->subject->value.resource.identifier   == NULL ) ||
1009         	( statement->predicate->value.resource.identifier   == NULL ) ||
1010         	( statement->object     == NULL ) ||
1011         	(       ( statement->object->type != 1 ) &&
1012                 	( statement->object->value.resource.identifier   == NULL ) ) ||
1013         	(       ( given_context != NULL ) &&
1014                 	( given_context->value.resource.identifier   == NULL ) ) ||
1015         	(       ( statement->node != NULL ) &&
1016                 	( statement->node->value.resource.identifier   == NULL ) ) )
1017         	return -1;
1018 
1019         if (given_context == NULL) {
1020 		if (statement->context != NULL)
1021                         context = statement->context;
1022                 /* we do not use the default context of the store because an iterator could contain different contexts and it would mess everything up */
1023         } else {
1024                 /* use given context instead */
1025                 context = given_context;
1026                 };
1027 
1028 	/* compute statement hashcode */
1029 	hc = rdfstore_digest_get_statement_hashCode( statement, context );
1030 
1031 	/* cache the hashcode if the statement has a "proper" identity */
1032 	if ( given_context == NULL )
1033 		statement->hashcode = hc;
1034 
1035 	memset(&key, 0, sizeof(key));
1036 	memset(&data, 0, sizeof(data));
1037 
1038 #ifdef RDFSTORE_DEBUG
1039 {
1040 char * buff;
1041 fprintf(stderr,"ITERATOR CONTAINS:\n");
1042 fprintf(stderr,"\tS='%s'\n",statement->subject->value.resource.identifier);
1043 fprintf(stderr,"\tP='%s'\n",statement->predicate->value.resource.identifier);
1044 if ( statement->object->type != 1 ) {
1045         fprintf(stderr,"\tO='%s'\n",statement->object->value.resource.identifier);
1046 } else {
1047         fprintf(stderr,"\tOLIT='%s'\n",statement->object->value.literal.string);
1048         };
1049 if ( context != NULL ) {
1050         fprintf(stderr,"\tC='%s'\n",context->value.resource.identifier);
1051         };
1052 if ( statement->node != NULL )
1053 	fprintf(stderr,"\tSRES='%s'\n",statement->node->value.resource.identifier);
1054 if( (buff=rdfstore_ntriples_statement( statement, context )) != NULL ) {
1055         fprintf(stderr," N-triples: %s\n", buff );
1056         RDFSTORE_FREE( buff );
1057         };
1058 };
1059 #endif
1060 
1061         /* look for the statement internal identifier */
1062         bzero(outbuf,sizeof(int));
1063         packInt( hc, outbuf );
1064         key.data = outbuf;
1065         key.size = sizeof(int);
1066         err = rdfstore_flat_store_fetch( me->store->statements, key, &data );
1067         if(err!=0) {
1068                 if (err!=FLAT_STORE_E_NOTFOUND) {
1069                         perror("rdfstore_iterator_contains");
1070                         fprintf(stderr,"Could not fetch key '%s' in statements for store '%s': %s\n",(char *)key.data,(me->store->name != NULL) ? me->store->name : "(in-memory)", rdfstore_flat_store_get_error( me->store->statements ) );
1071                         return -1;
1072                 } else {
1073                         return 0;
1074                         };
1075         } else {
1076                 unpackInt( data.data, &st_id);
1077                 RDFSTORE_FREE( data.data );
1078                 pos = st_id;
1079                 return (        ( rdfstore_bits_isanyset(&me->ids_size,me->ids,&pos,1) != 0 ) && /* are we sure that rdfstore_bits_isanyset() work here??!?! */
1080                                 ( pos == st_id ) ) ? 1 : 0;
1081                 };
1082 	};
1083 
1084 rdfstore_iterator *
rdfstore_iterator_intersect(rdfstore_iterator * me,rdfstore_iterator * you)1085 rdfstore_iterator_intersect (
1086         rdfstore_iterator       * me,
1087         rdfstore_iterator       * you
1088         ) {
1089 	rdfstore_iterator * results;
1090 
1091 	if (	( me == NULL ) ||
1092 		( you == NULL ) )
1093 		return NULL;
1094 
1095 	if ( me->store != you->store ) {
1096                	perror("rdfstore_iterator_intersect");
1097                	fprintf(stderr,"Cannot intersect cursors from different stores\n");
1098 		return NULL;
1099 		};
1100 
1101         results = NULL;
1102         results = (rdfstore_iterator *) RDFSTORE_MALLOC( sizeof(rdfstore_iterator) );
1103         if ( results == NULL ) {
1104                	perror("rdfstore_iterator_intersect");
1105                	fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1106                	return NULL;
1107                	};
1108         results->store = me->store;
1109 	me->store->attached++;
1110         results->remove_holes = 0;
1111         results->st_counter = 0;
1112 
1113 #ifdef RDFSTORE_DEBUG
1114 	{
1115 	int j;
1116 	printf("rdfstore_iterator_intersect (ME bits only) '");
1117         for ( j=0; j<me->ids_size; j++) {
1118         	printf("%02X",me->ids[j]);
1119        		};
1120         printf("'\n");
1121 	}
1122 	{
1123 	int j;
1124 	printf("rdfstore_iterator_intersect (YOU bits only) '");
1125         for ( j=0; j<you->ids_size; j++) {
1126         	printf("%02X",you->ids[j]);
1127        		};
1128         printf("'\n");
1129 	}
1130 #endif
1131 
1132 	/* A & B */
1133 	results->ids_size = rdfstore_bits_and( me->ids_size, me->ids, you->ids_size, you->ids, results->ids );
1134 	results->ids_size = rdfstore_bits_shorten( results->ids_size, results->ids);
1135 
1136 #ifdef RDFSTORE_DEBUG
1137 	{
1138 	int j;
1139 	printf("rdfstore_iterator_intersect (RESULTS bits only) '");
1140         for ( j=0; j<results->ids_size; j++) {
1141         	printf("%02X",results->ids[j]);
1142        		};
1143         printf("'\n");
1144 	}
1145 #endif
1146 
1147 	results->size = 0;
1148         results->pos = 0;
1149 	while ( (results->pos = rdfstore_bits_getfirstsetafter(results->ids_size, results->ids, results->pos)) < 8*(results->ids_size) ) {
1150 		results->pos++;
1151 		results->size++;
1152 		};
1153         results->pos = 0;
1154 
1155 	return results;
1156 	};
1157 
1158 rdfstore_iterator *
rdfstore_iterator_unite(rdfstore_iterator * me,rdfstore_iterator * you)1159 rdfstore_iterator_unite (
1160         rdfstore_iterator       * me,
1161         rdfstore_iterator       * you
1162         ) {
1163 	rdfstore_iterator * results;
1164 
1165 	if (	( me == NULL ) ||
1166 		( you == NULL ) )
1167 		return NULL;
1168 
1169 	if ( me->store != you->store ) {
1170                	perror("rdfstore_iterator_unite");
1171                	fprintf(stderr,"Cannot unite cursors from different stores\n");
1172 		return NULL;
1173 		};
1174 
1175         results = NULL;
1176         results = (rdfstore_iterator *) RDFSTORE_MALLOC( sizeof(rdfstore_iterator) );
1177         if ( results == NULL ) {
1178                	perror("rdfstore_iterator_unite");
1179                	fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1180                	return NULL;
1181                	};
1182         results->store = me->store;
1183 	me->store->attached++;
1184         results->remove_holes = 0;
1185         results->st_counter = 0;
1186 
1187 #ifdef RDFSTORE_DEBUG
1188 	{
1189 	int j;
1190 	printf("rdfstore_iterator_unite (ME bits only) '");
1191         for ( j=0; j<me->ids_size; j++) {
1192         	printf("%02X",me->ids[j]);
1193        		};
1194         printf("'\n");
1195 	}
1196 	{
1197 	int j;
1198 	printf("rdfstore_iterator_unite (YOU bits only) '");
1199         for ( j=0; j<you->ids_size; j++) {
1200         	printf("%02X",you->ids[j]);
1201        		};
1202         printf("'\n");
1203 	}
1204 #endif
1205 
1206 	/* A | B */
1207 	results->ids_size = rdfstore_bits_or( me->ids_size, me->ids, you->ids_size, you->ids, results->ids );
1208 	results->ids_size = rdfstore_bits_shorten( results->ids_size, results->ids);
1209 
1210 #ifdef RDFSTORE_DEBUG
1211 	{
1212 	int j;
1213 	printf("rdfstore_iterator_unite (RESULTS bits only) '");
1214         for ( j=0; j<results->ids_size; j++) {
1215         	printf("%02X",results->ids[j]);
1216        		};
1217         printf("'\n");
1218 	}
1219 #endif
1220 
1221 	results->size = 0;
1222         results->pos = 0;
1223 	while ( (results->pos = rdfstore_bits_getfirstsetafter(results->ids_size, results->ids, results->pos)) < 8*(results->ids_size) ) {
1224 		results->pos++;
1225 		results->size++;
1226 		};
1227         results->pos = 0;
1228 
1229 	return results;
1230 	};
1231 
1232 rdfstore_iterator *
rdfstore_iterator_subtract(rdfstore_iterator * me,rdfstore_iterator * you)1233 rdfstore_iterator_subtract (
1234         rdfstore_iterator       * me,
1235         rdfstore_iterator       * you
1236         ) {
1237 	rdfstore_iterator * results;
1238 	register int i=0;
1239 	unsigned char not[RDFSTORE_MAXRECORDS_BYTES_SIZE];
1240 
1241 	if (	( me == NULL ) ||
1242 		( you == NULL ) )
1243 		return NULL;
1244 
1245 	if ( me->store != you->store ) {
1246                	perror("rdfstore_iterator_subtract");
1247                	fprintf(stderr,"Cannot subtract cursors from different stores\n");
1248 		return NULL;
1249 		};
1250 
1251         results = NULL;
1252         results = (rdfstore_iterator *) RDFSTORE_MALLOC( sizeof(rdfstore_iterator) );
1253         if ( results == NULL ) {
1254                	perror("rdfstore_iterator_subtract");
1255                	fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1256                	return NULL;
1257                	};
1258         results->store = me->store;
1259 	me->store->attached++;
1260         results->remove_holes = 0;
1261         results->st_counter = 0;
1262 
1263 #ifdef RDFSTORE_DEBUG
1264 	{
1265 	int j;
1266 	printf("rdfstore_iterator_subtract (ME bits only) '");
1267         for ( j=0; j<me->ids_size; j++) {
1268         	printf("%02X",me->ids[j]);
1269        		};
1270         printf("'\n");
1271 	}
1272 	{
1273 	int j;
1274 	printf("rdfstore_iterator_subtract (YOU bits only) '");
1275         for ( j=0; j<you->ids_size; j++) {
1276         	printf("%02X",you->ids[j]);
1277        		};
1278         printf("'\n");
1279 	}
1280 #endif
1281 
1282 	/* A & (~B) */
1283 	for (	i=0;
1284 		i<you->ids_size;
1285 		i++ ) {
1286 		not[i] = ( ~ you->ids[i] );
1287 		};
1288 #ifdef RDFSTORE_DEBUG
1289 	{
1290 	int j;
1291 	printf("rdfstore_iterator_subtract ( *NOT* YOU bits only) '");
1292         for ( j=0; j<you->ids_size; j++) {
1293         	printf("%02X",not[j]);
1294        		};
1295         printf("'\n");
1296 	}
1297 #endif
1298 
1299 	results->ids_size = rdfstore_bits_and( me->ids_size, me->ids, you->ids_size, not, results->ids );
1300 	results->ids_size = rdfstore_bits_shorten( results->ids_size, results->ids);
1301 
1302 #ifdef RDFSTORE_DEBUG
1303 	{
1304 	int j;
1305 	printf("rdfstore_iterator_subtract (RESULTS bits only) '");
1306         for ( j=0; j<results->ids_size; j++) {
1307         	printf("%02X",results->ids[j]);
1308        		};
1309         printf("'\n");
1310 	}
1311 #endif
1312 
1313 	results->size = 0;
1314         results->pos = 0;
1315 	while ( (results->pos = rdfstore_bits_getfirstsetafter(results->ids_size, results->ids, results->pos)) < 8*(results->ids_size) ) {
1316 		results->pos++;
1317 		results->size++;
1318 		};
1319         results->pos = 0;
1320 
1321 	return results;
1322 	};
1323 
1324 rdfstore_iterator *
rdfstore_iterator_complement(rdfstore_iterator * me)1325 rdfstore_iterator_complement (
1326         rdfstore_iterator       * me
1327         ) {
1328 	rdfstore_iterator * results;
1329 	rdfstore_iterator * results1;
1330 	rdfstore_iterator * results2;
1331 
1332 	if ( me == NULL )
1333 		return NULL;
1334 
1335         results = NULL;
1336         results = (rdfstore_iterator *) RDFSTORE_MALLOC( sizeof(rdfstore_iterator) );
1337         if ( results == NULL ) {
1338                	perror("rdfstore_iterator_complement");
1339                	fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1340                	return NULL;
1341                	};
1342         results->store = me->store;
1343 	me->store->attached++;
1344         results->remove_holes = 0;
1345         results->st_counter = 0;
1346 
1347 #ifdef RDFSTORE_DEBUG
1348 	{
1349 	int j;
1350 	printf("rdfstore_iterator_complement (ME bits only) '");
1351         for ( j=0; j<me->ids_size; j++) {
1352         	printf("%02X",me->ids[j]);
1353        		};
1354         printf("'\n");
1355 	}
1356 #endif
1357 
1358 	results->ids_size = rdfstore_bits_not( me->ids_size, me->ids, results->ids );
1359 	results->ids_size = rdfstore_bits_shorten( results->ids_size, results->ids);
1360 
1361 #ifdef RDFSTORE_DEBUG
1362 	{
1363 	int j;
1364 	printf("rdfstore_iterator_complement (RESULTS bits only) '");
1365         for ( j=0; j<results->ids_size; j++) {
1366         	printf("%02X",results->ids[j]);
1367        		};
1368         printf("'\n");
1369 	}
1370 #endif
1371 
1372 	results->size = 0;
1373         results->pos = 0;
1374 	while ( (results->pos = rdfstore_bits_getfirstsetafter(results->ids_size, results->ids, results->pos)) < 8*(results->ids_size) ) {
1375 		results->pos++;
1376 		results->size++;
1377 		};
1378         results->pos = 0;
1379 
1380 	results1 = rdfstore_elements ( me->store );
1381 
1382         if ( results1 == NULL ) {
1383                	perror("rdfstore_iterator_complement");
1384                	fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1385 		rdfstore_iterator_close( results );
1386                	return NULL;
1387                	};
1388 
1389 	/* make sure that result set is sane */
1390 	results2 = rdfstore_iterator_intersect(	results, results1 );
1391 
1392 	rdfstore_iterator_close( results1 );
1393 	rdfstore_iterator_close( results );
1394 
1395         if ( results2 == NULL ) {
1396                	perror("rdfstore_iterator_complement");
1397                	fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1398                	return NULL;
1399                	};
1400 
1401 	return results2;
1402 	};
1403 
1404 /* it returns a one when A is set and B is not set. But NOT the other way round. */
1405 rdfstore_iterator *
rdfstore_iterator_exor(rdfstore_iterator * me,rdfstore_iterator * you)1406 rdfstore_iterator_exor (
1407         rdfstore_iterator       * me,
1408         rdfstore_iterator       * you
1409         ) {
1410 	rdfstore_iterator * results;
1411 
1412 	if (	( me == NULL ) ||
1413 		( you == NULL ) )
1414 		return NULL;
1415 
1416 	if ( me->store != you->store ) {
1417                	perror("rdfstore_iterator_exor");
1418                	fprintf(stderr,"Cannot carry out exor of cursors from different stores\n");
1419 		return NULL;
1420 		};
1421 
1422         results = NULL;
1423         results = (rdfstore_iterator *) RDFSTORE_MALLOC( sizeof(rdfstore_iterator) );
1424         if ( results == NULL ) {
1425                	perror("rdfstore_iterator_exor");
1426                	fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1427                	return NULL;
1428                	};
1429         results->store = me->store;
1430 	me->store->attached++;
1431         results->remove_holes = 0;
1432         results->st_counter = 0;
1433 
1434 #ifdef RDFSTORE_DEBUG
1435 	{
1436 	int j;
1437 	printf("rdfstore_iterator_exor (ME bits only) '");
1438         for ( j=0; j<me->ids_size; j++) {
1439         	printf("%02X",me->ids[j]);
1440        		};
1441         printf("'\n");
1442 	}
1443 	{
1444 	int j;
1445 	printf("rdfstore_iterator_exor (YOU bits only) '");
1446         for ( j=0; j<you->ids_size; j++) {
1447         	printf("%02X",you->ids[j]);
1448        		};
1449         printf("'\n");
1450 	}
1451 #endif
1452 
1453 	/* (A | B) ^ B aka Exor */
1454 	results->ids_size = rdfstore_bits_exor( me->ids_size, me->ids, you->ids_size, you->ids, results->ids );
1455 	results->ids_size = rdfstore_bits_shorten( results->ids_size, results->ids);
1456 
1457 #ifdef RDFSTORE_DEBUG
1458 	{
1459 	int j;
1460 	printf("rdfstore_iterator_exor (RESULTS bits only) '");
1461         for ( j=0; j<results->ids_size; j++) {
1462         	printf("%02X",results->ids[j]);
1463        		};
1464         printf("'\n");
1465 	}
1466 #endif
1467 
1468 	results->size = 0;
1469         results->pos = 0;
1470 	while ( (results->pos = rdfstore_bits_getfirstsetafter(results->ids_size, results->ids, results->pos)) < 8*(results->ids_size) ) {
1471 		results->pos++;
1472 		results->size++;
1473 		};
1474         results->pos = 0;
1475 
1476 	return results;
1477 	};
1478 
1479 rdfstore_iterator *
rdfstore_iterator_duplicate(rdfstore_iterator * me)1480 rdfstore_iterator_duplicate (
1481         rdfstore_iterator       * me
1482         ) {
1483 	rdfstore_iterator * results;
1484 
1485         results = NULL;
1486         results = (rdfstore_iterator *) RDFSTORE_MALLOC( sizeof(rdfstore_iterator) );
1487         if ( results == NULL ) {
1488                	perror("rdfstore_iterator_duplicate");
1489                	fprintf(stderr,"Cannot create internal results cursor/iterator for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1490                	return NULL;
1491                	};
1492         results->store = me->store;
1493         results->store->attached++; /* one more attached I guess */
1494         /*bzero(results->ids,sizeof(results->ids)); */
1495         bcopy(me->ids,results->ids,sizeof(unsigned char)*me->ids_size);
1496         results->ids_size = me->ids_size;
1497         results->remove_holes = me->remove_holes;
1498         results->pos = me->pos;
1499         results->st_counter = me->st_counter;
1500 	results->size = me->size;
1501 
1502 	return results;
1503 	};
1504 
rdfstore_iterator_size(rdfstore_iterator * me)1505 unsigned int rdfstore_iterator_size (
1506         rdfstore_iterator       * me
1507         ) {
1508 
1509 	if ( me == NULL )
1510 		return -1;
1511 
1512 	return me->size;
1513 	};
1514 
1515 /* return a statement given its ID; the statement structure needs to be disposed by the caller */
1516 RDF_Statement   *
rdfstore_iterator_fetch_statement(rdfstore_iterator * me)1517 rdfstore_iterator_fetch_statement (
1518         rdfstore_iterator	* me
1519         ) {
1520 	DBT key, data;
1521 	unsigned char outbuf[256];
1522 	RDF_Statement * statement;
1523 	unsigned int st_id;
1524 	int length=0;
1525 	char * p;
1526 	char mask=0;
1527 	int err=0;
1528 
1529 	if ( me == NULL )
1530 		return NULL;
1531 
1532 	if ( me->size <= 0 )
1533 		return NULL;
1534 
1535         memset(&key, 0, sizeof(key));
1536         memset(&data, 0, sizeof(data));
1537 
1538 	st_id = (unsigned int)me->pos; /* this is set by other iterator methods such as first() and next() */
1539 
1540 #ifdef RDFSTORE_DEBUG
1541 	printf(">>>>>>>>>>>>>>>>>> rdfstore_iterator_fetch_statement: st_id=%d\n",st_id);
1542 #endif
1543 
1544 	/* create memory structures */
1545 	statement = (RDF_Statement *) RDFSTORE_MALLOC(sizeof(RDF_Statement));
1546 	if ( statement == NULL ) {
1547 		perror("rdfstore_iterator_fetch_statement");
1548                 fprintf(stderr,"Could not even create statement for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1549 
1550 		return NULL;
1551 		};
1552 	statement->node = NULL;
1553 	statement->hashcode = 0;
1554 	statement->isreified = 0; /* expensive to check this in the database ?!??? */
1555         statement->subject = (RDF_Node *) RDFSTORE_MALLOC(sizeof(RDF_Node));
1556 	if ( statement->subject == NULL ) {
1557 		perror("rdfstore_iterator_fetch_statement");
1558                 fprintf(stderr,"Could not even create statement subject for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1559 
1560 		RDFSTORE_FREE(statement);
1561 
1562 		return NULL;
1563 		};
1564         statement->subject->hashcode=0;
1565         statement->predicate = (RDF_Node *) RDFSTORE_MALLOC(sizeof(RDF_Node));
1566 	if ( statement->predicate == NULL ) {
1567 		perror("rdfstore_iterator_fetch_statement");
1568                 fprintf(stderr,"Could not even create statement predicate for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1569 
1570 		RDFSTORE_FREE(statement->subject);
1571 		RDFSTORE_FREE(statement);
1572 
1573 		return NULL;
1574 		};
1575         statement->predicate->hashcode=0;
1576         statement->object = (RDF_Node *) RDFSTORE_MALLOC(sizeof(RDF_Node));
1577 	if ( statement->object == NULL ) {
1578 		perror("rdfstore_iterator_fetch_statement");
1579                 fprintf(stderr,"Could not even create statement object property for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1580 
1581 		RDFSTORE_FREE(statement->subject);
1582 		RDFSTORE_FREE(statement->predicate);
1583 		RDFSTORE_FREE(statement);
1584 
1585 		return NULL;
1586 		};
1587         statement->object->hashcode=0;
1588 
1589 	/* here are all the DB operations needed to fetch a statement */
1590 
1591 	/* fetch statement */
1592 	bzero(outbuf,sizeof(int));
1593 	packInt( st_id, outbuf );
1594 	key.data = outbuf;
1595 	key.size = sizeof(int);
1596         err = rdfstore_flat_store_fetch ( me->store->nodes, key, &data );
1597         if ( err == 0 ) {
1598 		length = ( sizeof(int) * 7 ) + 1; /* see doc/SWADe-rdfstore.html about how info is stored */
1599 
1600 #ifdef RDFSTORE_DEBUG
1601                 fprintf(stderr,"GOT statement '%s' %d\n",(char *)data.data+length);
1602 #endif
1603 
1604 		/* sort out various components */
1605 		p = data.data + length;
1606 		mask = *(p-1);
1607 
1608 		/* subject */
1609 		length=0;
1610 		unpackInt( data.data, &length );
1611 		statement->subject->value.resource.identifier = NULL;
1612         	statement->subject->value.resource.identifier = (char *) RDFSTORE_MALLOC( sizeof(char)*(length + 1) );
1613         	if ( statement->subject->value.resource.identifier == NULL ) {
1614 			perror("rdfstore_iterator_fetch_statement");
1615                 	fprintf(stderr,"Could not even fetch statement subject for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1616 			RDFSTORE_FREE( data.data );
1617 			RDFSTORE_FREE( statement->subject );
1618 			RDFSTORE_FREE( statement->predicate );
1619 			RDFSTORE_FREE( statement->object );
1620 			RDFSTORE_FREE( statement );
1621 
1622                 	return NULL;
1623                 	};
1624 		statement->subject->type= (mask & 2) ? 2 : 0;
1625 		memcpy(statement->subject->value.resource.identifier,p,length);
1626 		memcpy(statement->subject->value.resource.identifier+length,"\0",1);
1627 		statement->subject->value.resource.identifier_len = length;
1628 		p+=length;
1629 
1630 		/* predicate */
1631 		length=0;
1632 		unpackInt( data.data+(sizeof(int)), &length );
1633 		statement->predicate->value.resource.identifier=NULL;
1634         	statement->predicate->value.resource.identifier = (char *) RDFSTORE_MALLOC( sizeof(char)*(length + 1) );
1635         	if ( statement->predicate->value.resource.identifier == NULL ) {
1636 			perror("rdfstore_iterator_fetch_statement");
1637                 	fprintf(stderr,"Could not even fetch statement predicate for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1638 			RDFSTORE_FREE( data.data );
1639                 	RDFSTORE_FREE( statement->subject->value.resource.identifier );
1640 			RDFSTORE_FREE( statement->subject );
1641 			RDFSTORE_FREE( statement->predicate );
1642 			RDFSTORE_FREE( statement->object );
1643 			RDFSTORE_FREE( statement );
1644 
1645                 	return NULL;
1646                 	};
1647 		statement->predicate->type= (mask & 4) ? 2 : 0;
1648 		memcpy(statement->predicate->value.resource.identifier,p,length);
1649 		memcpy(statement->predicate->value.resource.identifier+length,"\0",1);
1650 		statement->predicate->value.resource.identifier_len = length;
1651 		p+=length;
1652 
1653 		/* object */
1654 		length=0;
1655 		unpackInt( data.data+(sizeof(int)*2), &length );
1656 		if ( mask & 1 ) {
1657 			/* object literal value */
1658 			statement->object->value.literal.string = NULL;
1659         		statement->object->value.literal.string = (char *) RDFSTORE_MALLOC( sizeof(char)*(length + 1) );
1660         		if ( statement->object->value.literal.string == NULL ) {
1661 				perror("rdfstore_iterator_fetch_statement");
1662                 		fprintf(stderr,"Could not even fetch statement object literal for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1663 				RDFSTORE_FREE( data.data );
1664 		               	RDFSTORE_FREE( statement->subject->value.resource.identifier );
1665 				RDFSTORE_FREE( statement->subject );
1666 		               	RDFSTORE_FREE( statement->predicate->value.resource.identifier );
1667 				RDFSTORE_FREE( statement->predicate );
1668 				RDFSTORE_FREE( statement->object );
1669 				RDFSTORE_FREE( statement );
1670 
1671 				return NULL;
1672 				};
1673 			statement->object->type = 1; /* literal */
1674 			memcpy(statement->object->value.literal.string,p,length);
1675 			memcpy(statement->object->value.literal.string+length,"\0",1);
1676 			statement->object->value.literal.string_len = length;
1677 			p+=length;
1678 
1679 			/* object xml:lang */
1680 			length=0;
1681 			unpackInt( data.data+(sizeof(int)*3), &length );
1682 			if ( length ) {
1683 				memcpy(statement->object->value.literal.lang,p,length);
1684 				memcpy(statement->object->value.literal.lang+length,"\0",1);
1685 				p+=length;
1686 			} else {
1687 				memcpy(statement->object->value.literal.lang,"\0",1); /* or =NULL ??? */
1688 				};
1689 
1690 			/* object rdf:dataType */
1691 			length=0;
1692 			unpackInt( data.data+(sizeof(int)*4), &length );
1693 			statement->object->value.literal.dataType = NULL;
1694 			if ( length ) {
1695         			statement->object->value.literal.dataType = (char *) RDFSTORE_MALLOC( sizeof(char)*(length + 1) );
1696         			if ( statement->object->value.literal.dataType == NULL ) {
1697 					perror("rdfstore_iterator_fetch_statement");
1698                 			fprintf(stderr,"Could not even fetch statement object literal rdf:dataType for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1699 					RDFSTORE_FREE( data.data );
1700 		               		RDFSTORE_FREE( statement->subject->value.resource.identifier );
1701 					RDFSTORE_FREE( statement->subject );
1702 		               		RDFSTORE_FREE( statement->predicate->value.resource.identifier );
1703 					RDFSTORE_FREE( statement->predicate );
1704 		               		RDFSTORE_FREE( statement->object->value.literal.string );
1705 					RDFSTORE_FREE( statement->object );
1706 					RDFSTORE_FREE( statement );
1707 
1708 					return NULL;
1709 					};
1710 				statement->object->value.literal.parseType= ( strncmp(p,RDFSTORE_RDF_PARSETYPE_LITERAL,length) == 0 ) ? 1 : 0;
1711 				memcpy(statement->object->value.literal.dataType,p,length);
1712 				memcpy(statement->object->value.literal.dataType+length,"\0",1);
1713 				p+=length;
1714 			} else {
1715 				statement->object->value.literal.parseType = 0;
1716 				};
1717 		} else {
1718 			statement->object->value.resource.identifier=NULL;
1719         		statement->object->value.resource.identifier = (char *) RDFSTORE_MALLOC( sizeof(char)*(length + 1) );
1720         		if ( statement->object->value.resource.identifier == NULL ) {
1721 				perror("rdfstore_iterator_fetch_statement");
1722                 		fprintf(stderr,"Could not even fetch statement object for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1723 				RDFSTORE_FREE( data.data );
1724                 		RDFSTORE_FREE( statement->subject->value.resource.identifier );
1725 				RDFSTORE_FREE( statement->subject );
1726                 		RDFSTORE_FREE( statement->predicate->value.resource.identifier );
1727 				RDFSTORE_FREE( statement->predicate );
1728 				RDFSTORE_FREE( statement->object );
1729 				RDFSTORE_FREE( statement );
1730 
1731                 		return NULL;
1732                 		};
1733 			statement->object->type= (mask & 8) ? 2 : 0;
1734 			memcpy(statement->object->value.resource.identifier,p,length);
1735 			memcpy(statement->object->value.resource.identifier+length,"\0",1);
1736 			statement->object->value.resource.identifier_len = length;
1737 			p+=length;
1738 			};
1739 
1740 		/* context */
1741 		length=0;
1742 		unpackInt( data.data+(sizeof(int)*5), &length );
1743 		statement->context = NULL;
1744 		if ( length ) {
1745         		statement->context = (RDF_Node *) RDFSTORE_MALLOC(sizeof(RDF_Node));
1746 			if ( statement->context == NULL ) {
1747 				perror("rdfstore_iterator_fetch_statement");
1748                 		fprintf(stderr,"Could not even create statement context for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1749 				RDFSTORE_FREE( data.data );
1750 		               	RDFSTORE_FREE( statement->subject->value.resource.identifier );
1751 				RDFSTORE_FREE( statement->subject );
1752 		               	RDFSTORE_FREE( statement->predicate->value.resource.identifier );
1753 				RDFSTORE_FREE( statement->predicate );
1754 				if ( statement->object->type != 1 ) {
1755 		               		RDFSTORE_FREE( statement->object->value.resource.identifier );
1756 				} else {
1757 		               		RDFSTORE_FREE( statement->object->value.literal.string );
1758 					if ( statement->object->value.literal.dataType != NULL )
1759 						RDFSTORE_FREE( statement->object->value.literal.dataType );
1760 					};
1761 				RDFSTORE_FREE( statement->object );
1762 				RDFSTORE_FREE( statement );
1763 
1764 				return NULL;
1765 				};
1766         		statement->context->hashcode=0;
1767 
1768 			statement->context->value.resource.identifier=NULL;
1769 	        	statement->context->value.resource.identifier = (char *) RDFSTORE_MALLOC( sizeof(char)*(length + 1) );
1770 	        	if ( statement->context->value.resource.identifier == NULL ) {
1771 				perror("rdfstore_iterator_fetch_statement");
1772 	                	fprintf(stderr,"Could not even fetch statement context for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1773 
1774 				RDFSTORE_FREE( data.data );
1775 		               	RDFSTORE_FREE( statement->subject->value.resource.identifier );
1776 				RDFSTORE_FREE( statement->subject );
1777 		               	RDFSTORE_FREE( statement->predicate->value.resource.identifier );
1778 				RDFSTORE_FREE( statement->predicate );
1779 				if ( statement->object->type != 1 ) {
1780 		               		RDFSTORE_FREE( statement->object->value.resource.identifier );
1781 				} else {
1782 		               		RDFSTORE_FREE( statement->object->value.literal.string );
1783 					if ( statement->object->value.literal.dataType != NULL )
1784 						RDFSTORE_FREE( statement->object->value.literal.dataType );
1785 					};
1786 				RDFSTORE_FREE( statement->object );
1787 				RDFSTORE_FREE( statement->context );
1788 				RDFSTORE_FREE( statement );
1789 
1790 	                	return NULL;
1791 	                	};
1792 			statement->context->type= (mask & 16) ? 2 : 0;
1793 			memcpy(statement->context->value.resource.identifier,p,length);
1794 			memcpy(statement->context->value.resource.identifier+length,"\0",1);
1795 			statement->context->value.resource.identifier_len = length;
1796 			p+=length;
1797 			};
1798 
1799 		/* statement as resource stuff */
1800 		length=0;
1801 		unpackInt( data.data+(sizeof(int)*6), &length );
1802 		statement->node = NULL;
1803 		if ( length ) {
1804         		statement->node = (RDF_Node *) RDFSTORE_MALLOC(sizeof(RDF_Node));
1805 			if ( statement->node == NULL ) {
1806 				perror("rdfstore_iterator_fetch_statement");
1807                 		fprintf(stderr,"Could not even create statement as resource for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1808 				RDFSTORE_FREE( data.data );
1809 		               	RDFSTORE_FREE( statement->subject->value.resource.identifier );
1810 				RDFSTORE_FREE( statement->subject );
1811 		               	RDFSTORE_FREE( statement->predicate->value.resource.identifier );
1812 				RDFSTORE_FREE( statement->predicate );
1813 				if ( statement->object->type != 1 ) {
1814 		               		RDFSTORE_FREE( statement->object->value.resource.identifier );
1815 				} else {
1816 		               		RDFSTORE_FREE( statement->object->value.literal.string );
1817 					if ( statement->object->value.literal.dataType != NULL )
1818 						RDFSTORE_FREE( statement->object->value.literal.dataType );
1819 					};
1820 				RDFSTORE_FREE( statement->object );
1821 				if ( statement->context != NULL ) {
1822 		               		RDFSTORE_FREE( statement->context->value.resource.identifier );
1823 					RDFSTORE_FREE( statement->context );
1824 					};
1825 				RDFSTORE_FREE( statement );
1826 
1827 				return NULL;
1828 				};
1829         		statement->node->hashcode=0;
1830 
1831 			statement->node->value.resource.identifier=NULL;
1832 	        	statement->node->value.resource.identifier = (char *) RDFSTORE_MALLOC( sizeof(char)*(length + 1) );
1833 	        	if ( statement->node->value.resource.identifier == NULL ) {
1834 				perror("rdfstore_iterator_fetch_statement");
1835 	                	fprintf(stderr,"Could not even fetch statement as resource for store '%s'\n",(me->store->name != NULL) ? me->store->name : "(in-memory)" );
1836 
1837 				RDFSTORE_FREE( data.data );
1838 		               	RDFSTORE_FREE( statement->subject->value.resource.identifier );
1839 				RDFSTORE_FREE( statement->subject );
1840 		               	RDFSTORE_FREE( statement->predicate->value.resource.identifier );
1841 				RDFSTORE_FREE( statement->predicate );
1842 				if ( statement->object->type != 1 ) {
1843 		               		RDFSTORE_FREE( statement->object->value.resource.identifier );
1844 				} else {
1845 		               		RDFSTORE_FREE( statement->object->value.literal.string );
1846 					if ( statement->object->value.literal.dataType != NULL )
1847 						RDFSTORE_FREE( statement->object->value.literal.dataType );
1848 					};
1849 				RDFSTORE_FREE( statement->object );
1850 				if ( statement->context != NULL ) {
1851 		               		RDFSTORE_FREE( statement->context->value.resource.identifier );
1852 					RDFSTORE_FREE( statement->context );
1853 					};
1854 				RDFSTORE_FREE( statement->node );
1855 				RDFSTORE_FREE( statement );
1856 
1857 	                	return NULL;
1858 	                	};
1859 			statement->node->type = 0; /* see http://www.w3.org/TR/rdf-syntax-grammar/#section-Syntax-reifying why */
1860 			memcpy(statement->node->value.resource.identifier,p,length);
1861 			memcpy(statement->node->value.resource.identifier+length,"\0",1);
1862 			statement->node->value.resource.identifier_len = length;
1863 			p+=length;
1864 			};
1865 
1866 		RDFSTORE_FREE( data.data );
1867          } else {
1868 		perror("rdfstore_iterator_fetch_statement");
1869                 fprintf(stderr,"Could not even fetch statement '%d' (key is %d bytes) for store '%s': %s\n",st_id, (int)key.size, (me->store->name != NULL) ? me->store->name : "(in-memory)", rdfstore_flat_store_get_error( me->store->nodes ) );
1870 
1871 		RDFSTORE_FREE(statement->subject);
1872 		RDFSTORE_FREE(statement->predicate);
1873 		RDFSTORE_FREE(statement->object);
1874 		RDFSTORE_FREE(statement);
1875 
1876                 return NULL;
1877 		};
1878 
1879 #ifdef RDFSTORE_DEBUG
1880 	if (statement != NULL ) {
1881 		fprintf(stderr,"\tS='%s'\n",statement->subject->value.resource.identifier);
1882 		fprintf(stderr,"\tP='%s'\n",statement->predicate->value.resource.identifier);
1883                 if ( statement->object->type != 1 ) {
1884 			fprintf(stderr,"\tO='%s'\n",statement->object->value.resource.identifier);
1885                 } else {
1886                 	fprintf(stderr,"\tOLIT='%s'\n",statement->object->value.literal.string);
1887                         };
1888                 if ( statement->context != NULL )
1889 			fprintf(stderr,"\tC='%s'\n",statement->context->value.resource.identifier);
1890                 if ( statement->node != NULL )
1891 			fprintf(stderr,"\tSRES='%s'\n",statement->node->value.resource.identifier);
1892 		};
1893 #endif
1894 
1895 	return statement;
1896 	};
1897