Source Code (Use browser search to find items of interest.)

Class Index

kdelibs'BookmarkTokenizer (./kdelibs/kfile/booktoken.h:73)

class BookmarkTokenizer
{
public:
    BookmarkTokenizer();
    ~BookmarkTokenizer();

    void begin();
    void write( const QString& );
    void end();

    char* nextToken();
    bool hasMoreTokens();

    void first()
	{ curr = head; }

protected:
    void reset();
    void appendToken( const char *t, int len )
    {
	if ( len < 1 )
	    return;

	BMToken *tok = new BMToken( t, len );

	if ( head )
	{
	    tail->setNext( tok );
	    tail = tok;
	}
	else
	{
	    head = tail = tok;
	}

	if ( !curr )
	    curr = tok;
    }
    
protected:
    char *buffer;
    char *dest;

    BMToken *head;
    BMToken *tail;

    BMToken *curr;
    
    // the size of buffer
    int size;
    
    // are we in a html tag
    bool tag;

    // are we in quotes within a html tag
    bool tquote;
    
    // To avoid multiple spaces
    bool space;

    // Discard line breaks immediately after tags
    bool discardCR;
    
    // Area we in a <!-- comment --> block
    bool comment;
};

//-----------------------------------------------------------------------------

kdelibs'BookmarkTokenizer::BookmarkTokenizer() (./kdelibs/kfile/booktoken.cpp:42)

BookmarkTokenizer::BookmarkTokenizer()
{
    head = tail = curr = 0;
    buffer = 0;
}


kdelibs'BookmarkTokenizer::reset() (./kdelibs/kfile/booktoken.cpp:48)

void BookmarkTokenizer::reset()
{
    while ( head )
    {
	curr = head->next();
	delete head;
	head = curr;
    }

    head = tail = curr = 0;

    if ( buffer )
	delete [] buffer;
    buffer = 0;
}


kdelibs'BookmarkTokenizer::begin() (./kdelibs/kfile/booktoken.cpp:64)

void BookmarkTokenizer::begin()
{
    reset();
    size = 1000;
    buffer = new char[ 1024 ];
    dest = buffer;
    tag = false;
    space = false;
    discardCR = false;
    comment = false;
    tquote = false;
}


kdelibs'BookmarkTokenizer::write() (./kdelibs/kfile/booktoken.cpp:77)

void BookmarkTokenizer::write( const QString& str )
{
    KCharsets *charsets=KGlobal::charsets();
    
    if ( str.isNull() )
	return;
    
    const char *src = str.ascii();

    while ( *src != 0 )
    {
	// do we need to enlarge the buffer?
	if ( dest - buffer > size )
	{
	    char *newbuf = new char [ size + 1024 ];
	    memcpy( newbuf, buffer, dest - buffer + 1 );
	    dest = newbuf + ( dest - buffer );
	    delete [] buffer;
	    buffer = newbuf;
	    size += 1024;
	}
	if ( comment )
	{
	    if ( !strncmp( src, "->", 2 ) )
	    {
		src += 2;
		comment = false;
	    }
	    else
		src++;
	}
	else if ( *src == '&' ) 
	{
	    space = false;

	    // Is the string long enough?
	    if ( *(src+1) != '\0' && *(src+2) != '\0' )
	    {
		// Special character by number?
		if ( *(src + 1) == '#' )
		{
		    char *endptr;
		    int z = (int) strtol( src+2, &endptr, 10 );
		    // parse only ascii characters unless in quotes
		    if (z<128 || tquote){
			*dest++ = z;
		    }
		    else{
		      *dest=0;
		      // add currend token
		      appendToken(buffer,dest-buffer);
		      
		      // add token with the amp-sequence for further conversion
		      memcpy(buffer,src,endptr-src);
		      buffer[endptr-src]=0;
		      appendToken(buffer,endptr-src);
		      
		      dest=buffer;
		    }
		    src = endptr;
		    // Skip a trailing ';' ?
		    if ( *src == ';' )
		        src++;
		}
		// Special character ?
		else if ( isalpha( *(src + 1) ) )
		{
		     if (!tag){
		       // add currend token
		       *dest=0;
		       appendToken(buffer,dest-buffer);
		       dest=buffer;
		    
		       const char *endptr=src+1;
		       while(*endptr && isalpha(*endptr)) endptr++;
		       if (*endptr==';') endptr++;
		       // add token with the amp-sequence for further conversion
		       memcpy(buffer,src,endptr-src);
		       buffer[endptr-src]=0;
		       appendToken(buffer,endptr-src);
		       src=endptr;
		       *dest=0;
		     }
		     else{
		       // There is no need for font switching 
		       // when we are in tag quotes, so amp-sequences can be 
		       // translated here. I hope noone uses non iso-8859-1
		       // characters here.
		       int len=0;
		       const QChar res=charsets->fromEntity(QString::fromLatin1(src), len);
		       if ( len > 0 )
		       {
			   // we should check it's ascii...
			   *dest++ = (res.unicode() & 0xFF);
			   src+=len;
		       }
		       else
		       {
			   *dest++ = *src++;
		       }
		     }  
		}
		else
		    *dest++ = *src++;
	    }
	    else
		*dest++ = *src++;
	}
	else if ( *src == '<' && !tquote )
	{
	    src++;
	    if ( strncmp( src, "!-", 2 ) == 0 )
	    {
		src += 2;
		comment = true;
		continue;
	    }

	    space = true;      // skip leading spaces
	    discardCR = true;  // skip leading CR
	    tquote = false;

	    if ( dest > buffer )
	    {
		*dest = 0;
		appendToken( buffer, dest-buffer );
		dest = buffer;
	    }
	    *dest = TAG_ESCAPE;
	    dest++;
	    *dest = '<';
	    dest++;
	    tag = true;
	}
	else if ( *src == '>' && tag && !tquote )
	{
	    space = false;
	    discardCR = false;

	    *dest = '>';
	    *(dest+1) = 0;

	    // make the tag lower case
	    char *ptr = buffer+2;
	    while ( *ptr && *ptr != ' ' )
	    {
		*ptr = tolower( *ptr );
		ptr++;
	    }

	    appendToken( buffer, dest-buffer+1 );
	    dest = buffer;

	    tag = false;
	    src++;
	}
	else if ( *src == '\n' )
	{
	    if ( !discardCR )
	    {
		if ( tag )
		{
		    if ( !space )
		    {
			*dest = ' ';
			dest++;
			space = true;
		    }
		}
		else if ( !space )
		{
		    *dest = 0;
		    appendToken( buffer, dest-buffer );
		    dest = buffer;

		    *dest = ' ';
		    *(dest+1) = 0;
		    appendToken( buffer, 1 );
		    dest = buffer;

		    space = true;
		}
	    }
	    src++;
	}
	else if ( *src == ' ' )
	{
	    if ( tag )
	    {
		if ( !space )
		{
		    *dest = ' ';
		    dest++;
		    space = true;
		}
	    }
	    else if ( !space )
	    {
		*dest = 0;
		appendToken( buffer, dest-buffer );
		dest = buffer;

		*dest = ' ';
		*(dest+1) = 0;
		appendToken( buffer, 1 );
		dest = buffer;

		space = true;
	    }
	    src++;
	}
	else if ( *src == '\t' )
	{
	    if ( tag )
	    {
		if ( !space )
		{
		    *dest = ' ';
		    dest++;
		    space = true;
		}
	    }
	    else if ( !space )
	    {
		*dest = 0;
		appendToken( buffer, dest-buffer );
		dest = buffer;

		*dest = ' ';
		*(dest+1) = 0;
		appendToken( buffer, 1 );
		dest = buffer;

		space = true;
	    }
	    src++;
	}
	else if ( *src == 13 )
	{
	    // discard
	    src++;
	}
	else if ( *src == '\"' || *src == '\'')
	{ // we treat " & ' the same in tags
	    if ( tag )
	    {
		src++;
		if ( *(dest-1) == '=' )
		{
		    tquote = true;
		    *dest = '\"';
		    dest++;
		    space = false;
		    discardCR = false;
		}
		else if ( tquote )
		{
		    tquote = false;
		    *dest = '\"';
		    dest++;
		    *dest = ' ';
		    dest++;
		    space = true;
		    discardCR = true;
		}
		else
		    continue;  // stray '\"'
	    }
	    else
	    {
		space = false;
		discardCR = false;

		*dest = *src++;
		dest++;
	    }
	}
	else if ( *src == '=' )
	{
	    src++;

	    if ( tag )
	    {
		if ( tquote )
		{
		    space = false;
		    discardCR = false;
		    *dest = '=';
		    dest++;
		}
		else
		{
		    // discard space before '='
		    if ( *(dest-1) == ' ' )
			dest--;

		    *dest = '=';
		    dest++;
		    space = true;
		    discardCR = true;
		}
	    }
	    else
	    {
		space = false;
		discardCR = false;

		*dest = '=';
		dest++;
	    }
	}
	else
	{
	    space = false;
	    discardCR = false;

	    *dest = *src++;
	    dest++;
	}
    }
}


kdelibs'BookmarkTokenizer::end() (./kdelibs/kfile/booktoken.cpp:399)

void BookmarkTokenizer::end()
{
    if ( buffer == 0 )
	return;

    if ( dest > buffer )
    {
	*dest = 0;
	appendToken( buffer, dest-buffer );
    }

    delete [] buffer;
    buffer = 0;
}


kdelibs'BookmarkTokenizer::nextToken() (./kdelibs/kfile/booktoken.cpp:414)

char* BookmarkTokenizer::nextToken()
{
    char *t = curr->token();
    curr = curr->next();

    return t;
}


kdelibs'BookmarkTokenizer::hasMoreTokens() (./kdelibs/kfile/booktoken.cpp:422)

bool BookmarkTokenizer::hasMoreTokens()
{
    return ( curr != 0 );
}


kdelibs'BookmarkTokenizer::~BookmarkTokenizer() (./kdelibs/kfile/booktoken.cpp:427)

BookmarkTokenizer::~BookmarkTokenizer()
{
    reset();
}

//-----------------------------------------------------------------------------