@@ -548,19 +548,21 @@ channel_collapse(int idx)
548548}
549549
550550/*
551- * Use the read buffer of channel "ch_idx" and parse JSON messages that are
551+ * Use the read buffer of channel "ch_idx" and parse a JSON messages that is
552552 * complete. The messages are added to the queue.
553+ * Return TRUE if there is more to read.
553554 */
554- void
555- channel_read_json (int ch_idx )
555+ static int
556+ channel_parse_json (int ch_idx )
556557{
557558 js_read_T reader ;
558559 typval_T listtv ;
559560 jsonq_T * item ;
560561 jsonq_T * head = & channels [ch_idx ].ch_json_head ;
562+ int ret ;
561563
562564 if (channel_peek (ch_idx ) == NULL )
563- return ;
565+ return FALSE ;
564566
565567 /* TODO: make reader work properly */
566568 /* reader.js_buf = channel_peek(ch_idx); */
@@ -569,36 +571,52 @@ channel_read_json(int ch_idx)
569571 reader .js_fill = NULL ;
570572 /* reader.js_fill = channel_fill; */
571573 reader .js_cookie = & ch_idx ;
572- if (json_decode (& reader , & listtv ) == OK )
574+ ret = json_decode (& reader , & listtv );
575+ if (ret == OK )
573576 {
574- item = (jsonq_T * )alloc ((unsigned )sizeof (jsonq_T ));
575- if (item == NULL )
577+ if (listtv .v_type != VAR_LIST )
578+ {
579+ /* TODO: give error */
576580 clear_tv (& listtv );
581+ }
577582 else
578583 {
579- item -> value = alloc_tv ();
580- if (item -> value == NULL )
581- {
582- vim_free (item );
584+ item = (jsonq_T * )alloc ((unsigned )sizeof (jsonq_T ));
585+ if (item == NULL )
583586 clear_tv (& listtv );
584- }
585587 else
586588 {
587- * item -> value = listtv ;
588- item -> prev = head -> prev ;
589- head -> prev = item ;
590- item -> next = head ;
591- item -> prev -> next = item ;
589+ item -> value = alloc_tv ();
590+ if (item -> value == NULL )
591+ {
592+ vim_free (item );
593+ clear_tv (& listtv );
594+ }
595+ else
596+ {
597+ * item -> value = listtv ;
598+ item -> prev = head -> prev ;
599+ head -> prev = item ;
600+ item -> next = head ;
601+ item -> prev -> next = item ;
602+ }
592603 }
593604 }
594605 }
595606
596607 /* Put the unread part back into the channel.
597608 * TODO: insert in front */
598609 if (reader .js_buf [reader .js_used ] != NUL )
610+ {
599611 channel_save (ch_idx , reader .js_buf + reader .js_used ,
600612 (int )(reader .js_end - reader .js_buf ) - reader .js_used );
613+ ret = TRUE;
614+ }
615+ else
616+ ret = FALSE;
617+
601618 vim_free (reader .js_buf );
619+ return ret ;
602620}
603621
604622/*
@@ -632,7 +650,8 @@ channel_get_json(int ch_idx, int id, typval_T **rettv)
632650 typval_T * tv = & l -> lv_first -> li_tv ;
633651
634652 if ((id > 0 && tv -> v_type == VAR_NUMBER && tv -> vval .v_number == id )
635- || id <= 0 )
653+ || (id <= 0
654+ && (tv -> v_type != VAR_NUMBER || tv -> vval .v_number < 0 )))
636655 {
637656 * rettv = item -> value ;
638657 remove_json_node (item );
@@ -742,23 +761,19 @@ may_invoke_callback(int idx)
742761 int seq_nr = -1 ;
743762 int json_mode = channels [idx ].ch_json_mode ;
744763
745- if (channel_peek (idx ) == NULL )
746- return FALSE;
747764 if (channels [idx ].ch_close_cb != NULL )
748765 /* this channel is handled elsewhere (netbeans) */
749766 return FALSE;
750767
751768 if (json_mode )
752769 {
753- /* Get any json message. Return if there isn't one. */
754- channel_read_json (idx );
770+ /* Get any json message in the queue. */
755771 if (channel_get_json (idx , -1 , & listtv ) == FAIL )
756- return FALSE;
757- if (listtv -> v_type != VAR_LIST )
758772 {
759- /* TODO: give error */
760- clear_tv (listtv );
761- return FALSE;
773+ /* Parse readahead, return when there is still no message. */
774+ channel_parse_json (idx );
775+ if (channel_get_json (idx , -1 , & listtv ) == FAIL )
776+ return FALSE;
762777 }
763778
764779 list = listtv -> vval .v_list ;
@@ -792,6 +807,11 @@ may_invoke_callback(int idx)
792807 }
793808 seq_nr = typetv -> vval .v_number ;
794809 }
810+ else if (channel_peek (idx ) == NULL )
811+ {
812+ /* nothing to read on raw channel */
813+ return FALSE;
814+ }
795815 else
796816 {
797817 /* For a raw channel we don't know where the message ends, just get
@@ -1105,19 +1125,29 @@ channel_read_block(int idx)
11051125 int
11061126channel_read_json_block (int ch_idx , int id , typval_T * * rettv )
11071127{
1128+ int more ;
1129+
11081130 for (;;)
11091131 {
1110- channel_read_json (ch_idx );
1132+ more = channel_parse_json (ch_idx );
11111133
11121134 /* search for messsage "id" */
11131135 if (channel_get_json (ch_idx , id , rettv ) == OK )
11141136 return OK ;
11151137
1116- /* Wait for up to 2 seconds.
1117- * TODO: use timeout set on the channel. */
1118- if (channel_wait (channels [ch_idx ].ch_fd , 2000 ) == FAIL )
1119- break ;
1120- channel_read (ch_idx );
1138+ if (!more )
1139+ {
1140+ /* Handle any other messages in the queue. If done some more
1141+ * messages may have arrived. */
1142+ if (channel_parse_messages ())
1143+ continue ;
1144+
1145+ /* Wait for up to 2 seconds.
1146+ * TODO: use timeout set on the channel. */
1147+ if (channel_wait (channels [ch_idx ].ch_fd , 2000 ) == FAIL )
1148+ break ;
1149+ channel_read (ch_idx );
1150+ }
11211151 }
11221152 return FAIL ;
11231153}
@@ -1271,16 +1301,23 @@ channel_select_check(int ret_in, void *rfds_in)
12711301# endif /* !FEAT_GUI_W32 && HAVE_SELECT */
12721302
12731303/*
1274- * Invoked from the main loop when it's save to execute received commands.
1304+ * Execute queued up commands.
1305+ * Invoked from the main loop when it's safe to execute received commands.
1306+ * Return TRUE when something was done.
12751307 */
1276- void
1308+ int
12771309channel_parse_messages (void )
12781310{
12791311 int i ;
1312+ int ret = FALSE;
12801313
12811314 for (i = 0 ; i < channel_count ; ++ i )
12821315 while (may_invoke_callback (i ) == OK )
1283- ;
1316+ {
1317+ i = 0 ; /* start over */
1318+ ret = TRUE;
1319+ }
1320+ return ret ;
12841321}
12851322
12861323#endif /* FEAT_CHANNEL */
0 commit comments