2 #include <stdio.h> /* for FILE etc */
3 #include <stdlib.h> /* for malloc */
4 #include <ctype.h> /* for isprint */
7 #include <string.h> /* for making strcasestr happy */
9 #include "pnd_container.h"
12 #include "pnd_pndfiles.h"
14 unsigned char pnd_pnd_seek_pxml ( FILE *f ) {
16 char *match; // match within buffer
17 unsigned int len; // length of file (not suporting 'big files' 2GB..)
18 unsigned int pos; // current tape head
19 unsigned int readable; // amount to read (for small files/chunks)
21 b = malloc ( PND_PXML_WINDOW_SIZE + 1 );
27 memset ( b, '\0', PND_PXML_WINDOW_SIZE + 1 );
29 // determine length of file
30 fseek ( f, 0, SEEK_END );
32 fseek ( f, 0, SEEK_SET );
34 /* ready to scan through the file, backwards
38 if ( len <= PND_PXML_WINDOW_SIZE ) {
42 pos = len - PND_PXML_WINDOW_SIZE;
43 readable = PND_PXML_WINDOW_SIZE;
48 //printf ( "find pxml; pos %u readable %u\n", pos, readable );
50 // seek into this blocks position
51 fseek ( f, pos, SEEK_SET );
54 fread ( b, 1, readable, f );
56 // find the head tag here? now, there are serious heavy duty algorithyms for locating
57 // strings within an arbitrary buffer. Thats needs to be done. This is the worst
58 // performing brute force strategy here.
59 if ( ( match = pnd_match_binbuf ( b, readable, PXML_TAGHEAD ) ) ) {
60 fseek ( f, pos + ( match - b ), SEEK_SET );
61 //printf ( " match found at %u\n", pos + ( match - b ) );
66 // no match, so we need to back up another chunk; if we can't
67 // back up that much, we're on our last check. if we can't back
68 // up at all, we've already been here and time to fail
71 } else if ( pos > PND_PXML_WINDOW_FRACTIONAL ) {
72 pos -= PND_PXML_WINDOW_FRACTIONAL;
73 readable = PND_PXML_WINDOW_SIZE;
75 readable = PND_PXML_WINDOW_SIZE - pos;
76 memset ( b + pos, '\0', PND_PXML_WINDOW_SIZE - pos );
82 // exeunt, with alarums
87 unsigned char pnd_pnd_accrue_pxml ( FILE *f, char *target, unsigned int maxlen ) {
88 char inbuf [ 1024 ]; // TBD: love all these assumptions? noob!
89 char *insert = target;
92 while ( fgets ( inbuf, 1023, f ) ) {
94 // copy inbuf onto end of target
96 strncpy ( insert, inbuf, maxlen );
97 // reduce counter for max size so we can avoid buffer overruns
99 maxlen -= l; // reduce
100 insert += l; // increment
102 strncat ( target, inbuf, maxlen );
105 if ( strcasestr ( inbuf, PXML_TAGFOOT ) ) {
114 char *pnd_match_binbuf ( char *haystack, unsigned int maxlen, char *needle ) {
115 char *end = haystack + maxlen - strlen ( needle );
116 unsigned int needlelen = strlen ( needle );
118 while ( haystack < end ) {
120 if ( isprint(*haystack) ) {
122 if ( strncasecmp ( haystack, needle, needlelen ) == 0 ) {
123 //printf ( "haystack %s\n", haystack );