Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

gtask-stream-parser.c

Go to the documentation of this file.
00001 #include <unistd.h>
00002 #include <string.h>
00003 
00004 #include <gtask/gtask-packet.h>
00005 #include <gtask/gtask-error-packet.h>
00006 #include <gtask/gtask-task-packet.h>
00007 #include <gtask/gtask-watch-packet.h>
00008 #include <gtask/gtask-remove-watch-packet.h>
00009 #include <gtask-query-packet.h>
00010 #include <gtask/gtask-file.h>
00011 
00012 //#include <gtask/gtask-role-packet.h>
00013 
00014 #include <gtask/gtask-stream-parser.h>
00015 
00016 #include <gtask/gtask-internals.h>
00017 
00020 /* @{ */
00021 
00022 static gpointer parent_class;
00023 
00024 static void
00025 gtask_stream_parser_class_init( GTaskStreamParserClass *klass );
00026 
00027 static void
00028 gtask_stream_parser_init( GTaskStreamParser *parser );
00029 
00030 static void
00031 gtask_stream_parser_finalize( GObject *obj );
00032 
00033 static void
00034 gtask_stream_parser_dispose( GObject *obj );
00035 
00036 static gboolean
00037 gtask_stream_parser_init_parser( GTaskStreamParser *parser,
00038                                  char *buff,
00039                                  int len );
00040 
00041 /* the actual SAX parsing callbacks and helpers */
00042 static void
00043 start_document( gpointer data );
00044     
00045 static void
00046 end_document( gpointer data );
00047 
00048 static void
00049 start_element( gpointer data,
00050                const xmlChar *name,
00051                const xmlChar **attrs );
00052 
00053 static  void
00054 end_element( gpointer data, const xmlChar *name );
00055 
00056 static void
00057 get_characters( gpointer data, const xmlChar *chars, int len );
00058 
00059 static void
00060 xml_warning( gpointer data, const char *msg, ... );
00061 
00062 static void
00063 xml_error( gpointer data, const char *msg, ... );
00064 
00065 static void
00066 xml_fatal_error( gpointer data, const char *msg, ... );
00067 
00068 
00069 xmlSAXHandler sax_handler = {
00070     NULL, /* internalSubset */
00071     NULL, /* isStandalone */
00072     NULL, /* hasInternalSubset */
00073     NULL, /* hasExternalSubset */
00074     NULL, /* resolveEntity */
00075     NULL, /* getEntity */
00076     NULL, /* entityDecl */
00077     NULL, /* notationDecl */
00078     NULL, /* attributeDecl */
00079     NULL, /* elementDecl */
00080     NULL, /* unparsedEntityDecl */
00081     NULL, /* setDocumentLocator */
00082     start_document, /* startDocument */
00083     end_document, /* endDocument */
00084     start_element, /* startElement */
00085     end_element, /* endElement */
00086     NULL, /* reference */
00087     get_characters, /* characters */
00088     NULL, /* ignorableWhitespace */
00089     NULL, /* processingInstruction */
00090     NULL, /* comment */
00091     xml_warning, /* xmlParserWarning */
00092     xml_error, /* xmlParserError */
00093     xml_fatal_error, /* xmlParserError */
00094     NULL, /* getParameterEntity */
00095     NULL, /* cdataBlock; */
00096     NULL, /* externalSubset; */
00097     1,
00098     NULL,
00099     NULL, /* startElementNs */
00100     NULL, /* endElementNs */
00101     NULL  /* xmlStructuredErrorFunc */
00102 };
00103 
00104 typedef enum {
00105     DOCUMENT_LEVEL,
00106     STREAM_LEVEL,
00107     PACKET_LEVEL,
00108     PACKET_CONTENTS_LEVEL
00109 } GTaskStreamParserLevel;
00110 
00111 typedef enum {
00112     UNKNOWN,
00113     DOCUMENT_START
00114 } GTaskStreamParserState;
00115 
00116 typedef enum {
00117     NO_PACKET,
00118     ROLE,
00119     ERROR,
00120     WATCH,
00121     REMOVE_WATCH,
00122     TASK,
00123     QUERY
00124 } GTaskStreamParserPacket;
00125 
00126 typedef enum {
00127     NO_PROPERTY,
00128 
00129     PROP_CATEGORY,
00130     PROP_TITLE,
00131 
00132     PROP_PERCENT_COMPLETED,
00133     PROP_ACTIVITY_STATE,
00134 
00135     PROP_STATUS_MESSAGE,
00136     PROP_ERROR_MESSAGE,
00137 
00138     PROP_MIME_TYPE,
00139     PROP_RESULTANT_FILE_URI,
00140     PROP_THUMBNAIL_URI,
00141 
00142     PROP_TIME_LEFT
00143 } GTaskStreamParserProperty;
00144 
00145 struct _GTaskStreamParserPrivate {
00147     //  start parsing for packets
00148     gboolean                  received_header;
00149 
00150     int                       depth;
00151     int                       unknown_depth;
00152 
00153     GTaskStreamParserState    current_state;
00154     GTaskStreamParserState    previous_state;
00155  
00156     GTaskStreamParserError    parser_error;
00157 
00158     GTaskStreamParserPacket   curr_packet_type;
00159     GTaskStreamParserProperty curr_packet_prop;
00160 
00161     // Variables for the SAX Parser
00162 
00164     GTaskPacket      *curr_packet;
00165 
00167     GQueue           *packet_queue;
00168 
00169     xmlParserCtxtPtr  xml_context;
00170 
00171     char              init_buff[4];
00172     int               init_buff_rem;
00173 
00174     char              buff[4096];
00175     int               buff_loc;
00176 
00177     /*
00178     // Variables for the xmlTextReader parser
00179 
00181     xmlTextReaderPtr  xml_reader;
00182 
00184     xmlParserInputBufferPtr xml_buff;
00185     */
00186 
00187     gboolean            stream_eof;
00188     gboolean            dispose_has_run;
00189 };
00190 
00191 GType gtask_stream_parser_get_type( ) {
00192     static GType type = 0;
00193 
00194     if( type == 0 ) {
00195         static const GTypeInfo info = {
00196             sizeof( GTaskStreamParserClass ),
00197             NULL,   /* base_init */
00198             NULL,   /* base_finalize */
00199             (GClassInitFunc )gtask_stream_parser_class_init,   /* class_init */
00200             NULL,   /* class_finalize */
00201             NULL,   /* class_data */
00202             sizeof( GTaskStreamParser ),
00203             0,      /* n_preallocs */
00204             (GInstanceInitFunc) gtask_stream_parser_init
00205         };
00206 
00207         type = g_type_register_static( G_TYPE_OBJECT,
00208                                        "GTaskStreamParser",
00209                                        &info,
00210                                        0 );
00211     }
00212 
00213     return type;
00214 }
00215 
00216 /*
00217  * start of xml parser state machine code
00218  */
00219 
00223 static void
00224 xml_warning( gpointer data, const char *msg, ... ) {
00225     va_list args;
00226 
00227     va_start(args, msg);
00228     g_warning( "xml_warning" );
00229     g_warning( msg, args );
00230     va_end(args);
00231 }
00232 
00233 static void
00234 xml_error( gpointer data, const char *msg, ... ) {
00235     GTaskStreamParser *parser = GTASK_STREAM_PARSER( data );
00236     va_list args;
00237 
00238     va_start(args, msg);
00239     g_error( "xml_error" );
00240     g_error( msg, args );
00241     va_end(args);
00242     parser->private->parser_error = GTASK_STREAM_PARSER_ERROR_SYNTAX_ERROR;
00243 }
00244 
00245 static void
00246 xml_fatal_error( gpointer data, const char *msg, ... ) {
00247     GTaskStreamParser *parser = GTASK_STREAM_PARSER( data );
00248     va_list args;
00249 
00250     va_start(args, msg);
00251     g_error( "xml_fatal_error" );
00252     g_error( msg, args );
00253     va_end(args);
00254 
00255     parser->private->parser_error = GTASK_STREAM_PARSER_ERROR_SYNTAX_ERROR;
00256 }
00257 
00258 static void
00259 start_document( gpointer data ) {
00260     GTaskStreamParser *parser = GTASK_STREAM_PARSER( data );
00261     GTaskStreamParserPrivate *private = parser->private;
00262 
00263 //    g_debug( "start_document" );
00264 
00265     // initialize our parser (again just for kicks)
00266     private->received_header = FALSE;
00267     private->current_state = DOCUMENT_START;
00268     private->previous_state = UNKNOWN;
00269     private->depth = 0;
00270     private->unknown_depth = 0;
00271 
00272     private->parser_error = GTASK_STREAM_PARSER_ERROR_NONE;
00273 }
00274 
00275 static void
00276 end_document( gpointer data ) {
00277     /* nothing to do here really */
00278 }
00279 
00284 static void
00285 start_element( gpointer data,
00286                const xmlChar *name,
00287                const xmlChar **attrs )
00288 {
00289     GTaskStreamParser        *parser = GTASK_STREAM_PARSER( data );
00290     GTaskStreamParserPrivate *private = parser->private;
00291     int               i;
00292 
00293 //    g_debug( "start_element: %d, %s", private->depth, name );
00294 
00295     private->depth++;
00296     private->buff_loc = 0;
00297 
00298     if( private->current_state == UNKNOWN ) {
00299         private->unknown_depth++;
00300 
00301         return;
00302     }
00303 
00304     if( private->depth == STREAM_LEVEL ) {
00305         if( strcmp( name, "gtask-stream" ) != 0 )
00306             private->parser_error = GTASK_STREAM_PARSER_ERROR_SYNTAX_ERROR;
00307         else
00308             private->received_header = TRUE;
00309     } else if( private->depth == PACKET_LEVEL ) {
00312         if( strcmp( name, "task" ) == 0 ) {
00313             const char *app = NULL;
00314             const char *id = NULL;
00315 
00316             GTaskTaskPacket  *packet;
00317             GTaskGenericTask *task = gtask_generic_task_new( );
00318 
00319             for( i = 0; attrs[i]; i++ ) {
00320                 if( strcmp( attrs[i], "application" ) == 0 ) {
00321                     app = attrs[i+1];
00322                 } else if( strcmp( attrs[i], "id" ) == 0 ) {
00323                     id = attrs[i+1];
00324                 }
00325             }
00326 
00327             /* these two elements are required */
00328             if( !app && !id ) {
00329                 private->parser_error = GTASK_STREAM_PARSER_ERROR_SYNTAX_ERROR;
00330                 return;
00331             }
00332 
00333             task = gtask_generic_task_new( );
00334             gtask_generic_task_set_application( task, app );
00335             gtask_generic_task_set_id( task, id );
00336 
00337             private->curr_packet_type = TASK;
00338 
00339             packet = gtask_task_packet_new_with_task( task );
00340             g_object_unref( task );
00341 
00342             packet = gtask_task_packet_new_with_task( task );
00343 
00344             private->curr_packet = GTASK_PACKET( packet );
00345         } else if( strcmp( name, "role" ) == 0 ) {
00346             g_warning( "GTaskRole packets no longer supported" );
00347 //            private->curr_packet_type = ROLE;
00348 //            private->curr_packet = GTASK_PACKET( gtask_role_packet_new( ) );
00349         } else if( strcmp( name, "error" ) == 0 ) {
00350             const char       *type = NULL;
00351 
00352             for( i = 0; attrs[i]; i++ ) {
00353                 if( strcmp( attrs[i], "type" ) == 0 ) {
00354                     type = attrs[i+1];
00355                 }
00356             }
00357 
00363             if( !type ) {
00364                 /* set unknown error type */
00365             }
00366 
00367             private->curr_packet_type = ERROR;
00368             private->curr_packet = GTASK_PACKET( gtask_error_packet_new( ) );
00369         } else if( strcmp( name, "watch" ) == 0 ) {
00370             const char       *id = NULL;
00371             GTaskWatchPacket *packet;
00372             
00373             for( i = 0; attrs[i]; i++ ) {
00374                 if( strcmp( attrs[i], "id" ) == 0 ) {
00375                     id = attrs[i+1];
00376                 }
00377             }
00378 
00379             if( !id ) {
00380                 private->parser_error = GTASK_STREAM_PARSER_ERROR_SYNTAX_ERROR;
00381 
00382                 return;
00383             }
00384 
00385             private->curr_packet_type = WATCH;
00386             packet = gtask_watch_packet_new_with_watch_id( id );
00387 
00388             private->curr_packet = GTASK_PACKET( packet );
00389         } else if( strcmp( name, "remove-watch" ) == 0 ) {
00390             const char             *id = NULL;
00391             GTaskRemoveWatchPacket *packet;
00392 
00393             for( i = 0; attrs[i]; i++ ) {
00394                 if( strcmp( attrs[i], "id" ) == 0 ) {
00395                     id = attrs[i+1];
00396                 }
00397             }
00398 
00399             if( !id ) {
00400                 private->parser_error = GTASK_STREAM_PARSER_ERROR_SYNTAX_ERROR;
00401                 return;
00402             }
00403 
00404             packet = gtask_remove_watch_packet_new_with_watch_id( id );
00405             private->curr_packet_type = REMOVE_WATCH;
00406             private->curr_packet = GTASK_PACKET( packet );
00407         } else if( strcmp( name, "query" ) == 0 ) {
00408             GTaskQueryPacket *packet;
00409 
00410             packet = gtask_query_packet_new( );
00411 
00412             private->curr_packet_type = QUERY;
00413             private->curr_packet = GTASK_PACKET( packet );
00414         } else {
00415             /* skip over unknown elements and their subtrees */
00416             private->curr_packet_type = NO_PACKET;
00417             private->previous_state = private->current_state;
00418             private->current_state = UNKNOWN;
00419         }
00420     } else if( private->depth == PACKET_CONTENTS_LEVEL ) {
00421         switch( private->curr_packet_type ) {
00422             case TASK:
00423                 if( strcmp( name, "category" ) == 0 ) {
00424                     private->curr_packet_prop = PROP_CATEGORY;
00425                 } else if( strcmp( name, "title" ) == 0 ) {
00426                     private->curr_packet_prop = PROP_TITLE;
00427                 } else if( strcmp( name, "percent-completed" ) == 0 ) {
00428                     private->curr_packet_prop = PROP_PERCENT_COMPLETED;
00429                 } else if( strcmp( name, "status-message" ) == 0 ) {
00430                     private->curr_packet_prop = PROP_STATUS_MESSAGE;
00431                 } else if( strcmp( name, "error-message" ) == 0 ) {
00432                     private->curr_packet_prop = PROP_ERROR_MESSAGE;
00433                 } else if( strcmp( name, "thumbnail-uri" ) == 0 ) {
00434                     private->curr_packet_prop = PROP_THUMBNAIL_URI;
00435                 } else if( strcmp( name, "resultant-file-uri" ) == 0 ) {
00436                     private->curr_packet_prop = PROP_RESULTANT_FILE_URI;
00437                 } else if( strcmp( name, "activity-state" ) == 0 ) {
00438                     private->curr_packet_prop = PROP_ACTIVITY_STATE;
00439                 } else if( strcmp( name, "time-left" ) == 0 ) {
00440                     private->curr_packet_prop = PROP_TIME_LEFT;
00441                 } else if( strcmp( name, "file" ) == 0 ) {
00442                     GTaskGenericTask *task = gtask_task_packet_get_task( GTASK_TASK_PACKET( private->curr_packet ) );
00443                     GTaskFile        *file;
00444 
00445                     const char *uri = NULL;
00446                     const char *thumb_uri = NULL;
00447                     const char *mime_type = NULL;
00448                     const char *description = NULL;
00449                     gboolean    completed = FALSE;
00450 
00451                     for( i = 0; attrs[i]; i++ ) {
00452                         if( strcmp( attrs[i], "uri" ) == 0 ) {
00453                             uri = attrs[i+1];
00454                         } else if( strcmp( attrs[i], "thumbnail-uri" ) == 0 ) {
00455                             thumb_uri = attrs[i+1];
00456                         } else if( strcmp( attrs[i], "mime-type" ) == 0 ) {
00457                             mime_type = attrs[i+1];
00458                         } else if( strcmp( attrs[i], "description" ) == 0 ) {
00459                             description = attrs[i+1];
00460                         } else if( strcmp( attrs[i], "completed" ) == 0 ) {
00461                             completed = ( atoi( attrs[i+1] ) > 0 ) ? TRUE : FALSE;
00462                         }
00463                     }
00464 
00465                     file = gtask_file_new_with_properties( uri, mime_type, thumb_uri, description );
00466 
00467                     gtask_file_set_completed( file, completed );
00468 
00469                     gtask_generic_task_add_file( task, file );
00470 
00471                     g_object_unref( file );
00472                 } else {
00473                     private->curr_packet_prop = NO_PROPERTY;
00474                 }
00475                 break;
00476             default:
00477                 break;
00478         }
00479     }
00480 }
00481 
00482 static void
00483 end_element( gpointer data, const xmlChar *name ) {
00484     GTaskStreamParser        *parser = GTASK_STREAM_PARSER( data );
00485     GTaskStreamParserPrivate *private = parser->private;
00486 
00487 //    g_debug( "end_element: %d %s", private->depth, name );
00488 
00489     if( private->current_state == UNKNOWN ) {
00490         if( private->unknown_depth-- == 0 ) {
00491             private->current_state = private->previous_state;
00492         }
00493 
00494         goto DEC_DEPTH;
00495     }
00496 
00497     if( private->depth == STREAM_LEVEL  ) {
00498         /* the only element that can be here is a closing gtask-stream
00499          * since the error handlers would have kicked in if it were anything
00500          * else, so just mark the stream as being closed */
00501 //        g_debug( "received ending gtask-stream, setting stream_eof" );
00502         private->stream_eof = TRUE;
00503     } else if( private->depth == PACKET_LEVEL ) {
00504         GTaskPacket *curr_packet = private->curr_packet;
00505         char        *buff = private->buff;
00506 
00507         /* do nothing if we are not currently constructing a packet */
00508         if( !curr_packet )
00509             goto DEC_DEPTH;
00510 
00511         /* copy of our character data for any of our packets without
00512          * any explicit properties */
00513         switch( private->curr_packet_type ) {
00514             /*
00515             case ROLE:
00516                 gtask_role_packet_set_role_from_name( GTASK_ROLE_PACKET( curr_packet ), buff );
00517                 break;
00518                 */
00519             case ERROR:
00520                 gtask_error_packet_set_error_message( GTASK_ERROR_PACKET( curr_packet ), buff );
00521             default:
00522                 break;
00523         }
00524 
00525         /* place the current packet, if any into the queue */
00526         if( curr_packet ) {
00527 //            g_debug( "adding the current packet to the queue: %s", G_OBJECT_TYPE_NAME( curr_packet ) );
00528             g_queue_push_tail( private->packet_queue, curr_packet );
00529 
00530             private->curr_packet = NULL;
00531         }
00532 
00533         private->curr_packet_type = NO_PACKET;
00534         private->curr_packet_prop = NO_PROPERTY;
00535     } else if( private->depth == PACKET_CONTENTS_LEVEL ) {
00536         GTaskPacket *curr_packet = private->curr_packet;
00537         GTaskGenericTask *task;
00538         char        *buff = private->buff;
00539         float        perc;
00540 
00544         g_strdelimit( buff, "\r\n", ' ' );
00545         g_strstrip( buff );
00546 
00547         switch( private->curr_packet_type ) {
00548             case TASK:
00549                 task = gtask_task_packet_get_task( GTASK_TASK_PACKET( curr_packet ) );
00550 
00551                 switch( private->curr_packet_prop ) {
00552                     case PROP_CATEGORY:
00553                         gtask_generic_task_set_category( task, buff );
00554                         break;
00555                     case PROP_PERCENT_COMPLETED:
00556                         perc = atof( buff );
00557 
00558                         if( perc <  0 )
00559                             perc = -perc;
00560 
00561                         gtask_generic_task_set_percent_done( task, perc );
00562                         break;
00563                     case PROP_TIME_LEFT:
00568                         g_debug( "================> %s : %ld", buff, atol( buff ) );
00569                         if( gtask_generic_task_get_time_left( task ) <= 0 )
00570                             gtask_generic_task_set_time_left( task, atol( buff ) );
00571                         break;
00572                     case PROP_TITLE:
00573                         gtask_generic_task_set_title( task, buff );
00574                         break;
00575                     case PROP_STATUS_MESSAGE:
00576                         gtask_generic_task_set_status_message( task, buff );
00577                         break;
00578                     case PROP_ACTIVITY_STATE:
00579                         gtask_generic_task_set_activity_state_from_string( task,
00580                                                                          buff );
00581                         break;
00582                     case PROP_ERROR_MESSAGE:
00583                         gtask_generic_task_set_error_message( task, buff );
00584                         break;
00585                     case PROP_THUMBNAIL_URI:
00586                         gtask_generic_task_set_thumbnail_uri( task, buff );
00587                         break;
00588                     default:
00589                         break;
00590                 }
00591 
00592                 break;
00593             default:
00594                 break;
00595         }
00596     }
00597 
00598 DEC_DEPTH:
00599     private->depth--;
00600     
00601     // reset the char array to the beginning,
00602     // technically this is incorrect since we need to keep
00603     // a bunch of these to amalgamate junk for each level, but for
00604     // now screw it
00605     parser->private->buff_loc = 0;
00606 }
00607 
00608 static void
00609 get_characters( gpointer data, const xmlChar *chars, int len ) {
00610     GTaskStreamParser *parser = GTASK_STREAM_PARSER( data );
00611     char              *buff = parser->private->buff;
00612     int               *buff_loc = &parser->private->buff_loc;
00613     int                space;
00614 
00615 //    g_debug( "get_characters: length: %d | buffer_location: %d", len, *buff_loc );
00616 
00617     buff[ *buff_loc ] = '\0';
00618 
00619     space = 4096 - *buff_loc - 1 ;
00620 
00621     if( len > space )
00622         len = space;
00623 
00624     strncat( buff + *buff_loc, chars, len );
00625 
00626     *buff_loc += *buff_loc + len;
00627 
00628     buff[ *buff_loc ] = '\0';
00629 }
00630 
00631 
00632 /*
00633  * end of xml parser state machine code
00634  */
00635 
00636 static void
00637 gtask_stream_parser_class_init( GTaskStreamParserClass *klass ) {
00638     GObjectClass *gobject_class = G_OBJECT_CLASS( klass );
00639 
00640     parent_class = g_type_class_peek_parent( klass );
00641 
00642     gobject_class->dispose = gtask_stream_parser_dispose;
00643     gobject_class->finalize = gtask_stream_parser_finalize;
00644 }
00645 
00646 static void
00647 gtask_stream_parser_init( GTaskStreamParser *parser ) {
00648     GTaskStreamParserPrivate *private;
00649 
00650     private = g_new0( GTaskStreamParserPrivate, 1 );
00651 
00652     parser->private = private;
00653 
00654     private->packet_queue = g_new0( GQueue, 1 );
00655 
00656     private->parser_error = GTASK_STREAM_PARSER_ERROR_NONE;
00657     private->stream_eof = FALSE;
00658 
00659     private->received_header = FALSE;
00660 
00661     private->current_state = UNKNOWN;
00662     private->previous_state = UNKNOWN;
00663     private->depth = 0;
00664     private->unknown_depth = 0;
00665     private->buff_loc = 0;
00666 
00667     private->curr_packet_type = NO_PACKET;
00668     private->dispose_has_run = FALSE;
00669 }
00670 
00671 static void
00672 gtask_stream_parser_dispose( GObject *obj ) {
00673     GTaskStreamParser        *parser = GTASK_STREAM_PARSER( obj );
00674     GTaskStreamParserPrivate *private = parser->private;
00675     gpointer                  item = NULL;
00676 
00677     if( private->dispose_has_run )
00678         return;
00679 
00680     while( ( item = g_queue_pop_head( private->packet_queue ) ) ) {
00681         GTaskPacket *packet = GTASK_PACKET( item );
00682 
00683         g_object_unref( packet );
00684     }
00685 
00686     private->dispose_has_run = TRUE;
00687 
00688     if( G_OBJECT_CLASS( parent_class )->dispose )
00689         G_OBJECT_CLASS( parent_class )->dispose( obj );
00690 }
00691 
00692 static void
00693 gtask_stream_parser_finalize( GObject *obj ) {
00694     GTaskStreamParser        *parser = GTASK_STREAM_PARSER( obj );
00695     GTaskStreamParserPrivate *private = parser->private;
00696 
00697     g_queue_free( private->packet_queue );
00698 
00699     // Free our xml-foo
00700     xmlFreeParserCtxt( private->xml_context );
00701 
00702     g_free( parser->private );
00703 
00704     if( G_OBJECT_CLASS( parent_class )->finalize )
00705         G_OBJECT_CLASS( parent_class )->finalize( obj );
00706 }
00707 
00720 GTaskStreamParser *
00721 gtask_stream_parser_new( ) {
00722     return g_object_new( GTASK_STREAM_PARSER_TYPE, NULL );
00723 }
00724 
00740 static gboolean
00741 gtask_stream_parser_init_parser( GTaskStreamParser *parser,
00742                                  char *buff,
00743                                  int len )
00744 {
00745     xmlParserCtxtPtr xml_context;
00746 
00747     if( parser->private->xml_context )
00748         return TRUE;
00749 
00750     //xml_context = xmlCreatePushParserCtxt( &sax_handler, parser, buff, len, NULL );
00751     xml_context = xmlCreatePushParserCtxt( &sax_handler, parser, NULL, 0, "test-stream" );
00752 
00753     if( !xml_context )
00754         return FALSE;
00755 
00756     parser->private->xml_context = xml_context;
00757 
00758     return TRUE;
00759 }
00760 
00771 gboolean
00772 gtask_stream_parser_has_packets( GTaskStreamParser *parser ) {
00773     g_return_val_if_fail( GTASK_IS_STREAM_PARSER( parser ), FALSE );
00774     g_return_val_if_fail( !parser->private->dispose_has_run, FALSE );
00775 
00776     return ( !g_queue_is_empty( parser->private->packet_queue ) );
00777 }
00778 
00788 gboolean
00789 gtask_stream_parser_push_data( GTaskStreamParser *parser,
00790                                char *buff,
00791                                int len )
00792 {
00794     g_return_val_if_fail( GTASK_IS_STREAM_PARSER( parser ), FALSE );
00795     g_return_val_if_fail( !parser->private->dispose_has_run, TRUE );
00796 
00797     g_debug( "IN: gtask_stream_parser_push_data" );
00798 
00799     if( !parser->private->xml_context ) {
00800 //        if( len < 4 ) {
00801 //            g_error( "for the moment the push_data requires art least "
00802 //                     "4 bytes of data for its first call" );
00803 //        }
00804 
00805         g_debug( "pusing first 4 bytes to the parser for init" );
00806         if( !gtask_stream_parser_init_parser( parser, buff, 4 ) ) {
00807             g_error( "Unable to initialize the parser\n" );
00808             g_debug( "LEAVING: gtask_stream_parser_push_data - unable to init parser" );
00809             return FALSE;
00810         }
00811 
00812         /* skip past what was just sent to the parser */
00813 //        buff += 4;
00814 //        len -= 4;
00815     }
00816 
00817     g_debug( "pushing %d bytes of data to the parser: %s", len, buff );
00818     xmlParseChunk( parser->private->xml_context, buff, len, 0 );
00819     g_debug( "done" );
00820 
00823     g_debug( "LEAVING: gtask_stream_parser_push_data" );
00824 
00825     return ( parser->private->parser_error == GTASK_STREAM_PARSER_ERROR_NONE );
00826 }
00827 
00839 GObject *
00840 gtask_stream_parser_get_next_packet( GTaskStreamParser *parser ) {
00841     GTaskStreamParserPrivate *private;
00842     GQueue                   *packet_queue;
00843 
00844     g_return_val_if_fail( GTASK_IS_STREAM_PARSER( parser ), NULL );
00845     g_return_val_if_fail( !parser->private->dispose_has_run, NULL );
00846 
00847     g_debug( "IN: gtask_stream_parser_get_next_packet" );
00848 
00849     private = parser->private;
00850     packet_queue = private->packet_queue;
00851 
00852     if( !g_queue_is_empty( packet_queue ) ) {
00853         g_debug( "LEAVING: gtask_stream_parser_get_next_packet - got packet" );
00854         return G_OBJECT( g_queue_pop_head( packet_queue ) );
00855         //return GTASK_PACKET( g_queue_pop_head( packet_queue ) );
00856     }
00857 
00858     g_debug( "LEAVING: gtask_stream_parser_get_next_packet - no packet" );
00859 
00860     return NULL;
00861 }
00862 
00863 gboolean
00864 gtask_stream_parser_has_error( GTaskStreamParser *parser ) {
00865     g_return_val_if_fail( GTASK_IS_STREAM_PARSER( parser ), TRUE );
00866     g_return_val_if_fail( !parser->private->dispose_has_run, FALSE );
00867 
00868     return ( parser->private->parser_error != GTASK_STREAM_PARSER_ERROR_NONE );
00869 }
00870 
00881 void
00882 gtask_stream_parser_reset_state( GTaskStreamParser *parser ) {
00883     GTaskStreamParserPrivate *private;
00884 
00885     g_return_if_fail( GTASK_IS_STREAM_PARSER( parser ) );
00886 
00887     g_debug( "IN: gtask_stream_parser_reset_state" );
00888 
00889     private = parser->private;
00890 
00891     private->parser_error = GTASK_STREAM_PARSER_ERROR_NONE;
00892     private->stream_eof = FALSE;
00893 
00894     private->received_header = FALSE;
00895 
00896     private->current_state = UNKNOWN;
00897     private->previous_state = UNKNOWN;
00898     private->depth = 0;
00899     private->unknown_depth = 0;
00900     private->buff_loc = 0;
00901 
00902     private->curr_packet_type = NO_PACKET;
00903 
00904     g_debug( "LEAVING: gtask_stream_parser_reset_state" );
00905 }
00906 
00907 /* @} */

Generated on Mon Feb 2 21:26:14 2004 for libgtask by doxygen 1.3.4