@@ -523,19 +523,21 @@ channel_collapse(int idx)
523523}
524524
525525/*
526- * Use the read buffer of channel "ch_idx" and parse JSON messages that are
526+ * Use the read buffer of channel "ch_idx" and parse a JSON messages that is
527527 * complete. The messages are added to the queue.
528+ * Return TRUE if there is more to read.
528529 */
529- void
530- channel_read_json (int ch_idx )
530+ static int
531+ channel_parse_json (int ch_idx )
531532{
532533 js_read_T reader ;
533534 typval_T listtv ;
534535 jsonq_T * item ;
535536 jsonq_T * head = & channels [ch_idx ].ch_json_head ;
537+ int ret ;
536538
537539 if (channel_peek (ch_idx ) == NULL )
538- return ;
540+ return FALSE ;
539541
540542 /* TODO: make reader work properly */
541543 /* reader.js_buf = channel_peek(ch_idx); */
@@ -544,36 +546,52 @@ channel_read_json(int ch_idx)
544546 reader .js_fill = NULL ;
545547 /* reader.js_fill = channel_fill; */
546548 reader .js_cookie = & ch_idx ;
547- if (json_decode (& reader , & listtv ) == OK )
549+ ret = json_decode (& reader , & listtv );
550+ if (ret == OK )
548551 {
549- item = (jsonq_T * )alloc ((unsigned )sizeof (jsonq_T ));
550- if (item == NULL )
552+ if (listtv .v_type != VAR_LIST )
553+ {
554+ /* TODO: give error */
551555 clear_tv (& listtv );
556+ }
552557 else
553558 {
554- item -> value = alloc_tv ();
555- if (item -> value == NULL )
556- {
557- vim_free (item );
559+ item = (jsonq_T * )alloc ((unsigned )sizeof (jsonq_T ));
560+ if (item == NULL )
558561 clear_tv (& listtv );
559- }
560562 else
561563 {
562- * item -> value = listtv ;
563- item -> prev = head -> prev ;
564- head -> prev = item ;
565- item -> next = head ;
566- item -> prev -> next = item ;
564+ item -> value = alloc_tv ();
565+ if (item -> value == NULL )
566+ {
567+ vim_free (item );
568+ clear_tv (& listtv );
569+ }
570+ else
571+ {
572+ * item -> value = listtv ;
573+ item -> prev = head -> prev ;
574+ head -> prev = item ;
575+ item -> next = head ;
576+ item -> prev -> next = item ;
577+ }
567578 }
568579 }
569580 }
570581
571582 /* Put the unread part back into the channel.
572583 * TODO: insert in front */
573584 if (reader .js_buf [reader .js_used ] != NUL )
585+ {
574586 channel_save (ch_idx , reader .js_buf + reader .js_used ,
575587 (int )(reader .js_end - reader .js_buf ) - reader .js_used );
588+ ret = TRUE;
589+ }
590+ else
591+ ret = FALSE;
592+
576593 vim_free (reader .js_buf );
594+ return ret ;
577595}
578596
579597/*
@@ -607,7 +625,8 @@ channel_get_json(int ch_idx, int id, typval_T **rettv)
607625 typval_T * tv = & l -> lv_first -> li_tv ;
608626
609627 if ((id > 0 && tv -> v_type == VAR_NUMBER && tv -> vval .v_number == id )
610- || id <= 0 )
628+ || (id <= 0
629+ && (tv -> v_type != VAR_NUMBER || tv -> vval .v_number < 0 )))
611630 {
612631 * rettv = item -> value ;
613632 remove_json_node (item );
@@ -717,23 +736,19 @@ may_invoke_callback(int idx)
717736 int seq_nr = -1 ;
718737 int json_mode = channels [idx ].ch_json_mode ;
719738
720- if (channel_peek (idx ) == NULL )
721- return FALSE;
722739 if (channels [idx ].ch_close_cb != NULL )
723740 /* this channel is handled elsewhere (netbeans) */
724741 return FALSE;
725742
726743 if (json_mode )
727744 {
728- /* Get any json message. Return if there isn't one. */
729- channel_read_json (idx );
745+ /* Get any json message in the queue. */
730746 if (channel_get_json (idx , -1 , & listtv ) == FAIL )
731- return FALSE;
732- if (listtv -> v_type != VAR_LIST )
733747 {
734- /* TODO: give error */
735- clear_tv (listtv );
736- return FALSE;
748+ /* Parse readahead, return when there is still no message. */
749+ channel_parse_json (idx );
750+ if (channel_get_json (idx , -1 , & listtv ) == FAIL )
751+ return FALSE;
737752 }
738753
739754 list = listtv -> vval .v_list ;
@@ -767,6 +782,11 @@ may_invoke_callback(int idx)
767782 }
768783 seq_nr = typetv -> vval .v_number ;
769784 }
785+ else if (channel_peek (idx ) == NULL )
786+ {
787+ /* nothing to read on raw channel */
788+ return FALSE;
789+ }
770790 else
771791 {
772792 /* For a raw channel we don't know where the message ends, just get
@@ -1080,19 +1100,29 @@ channel_read_block(int idx)
10801100 int
10811101channel_read_json_block (int ch_idx , int id , typval_T * * rettv )
10821102{
1103+ int more ;
1104+
10831105 for (;;)
10841106 {
1085- channel_read_json (ch_idx );
1107+ more = channel_parse_json (ch_idx );
10861108
10871109 /* search for messsage "id" */
10881110 if (channel_get_json (ch_idx , id , rettv ) == OK )
10891111 return OK ;
10901112
1091- /* Wait for up to 2 seconds.
1092- * TODO: use timeout set on the channel. */
1093- if (channel_wait (channels [ch_idx ].ch_fd , 2000 ) == FAIL )
1094- break ;
1095- channel_read (ch_idx );
1113+ if (!more )
1114+ {
1115+ /* Handle any other messages in the queue. If done some more
1116+ * messages may have arrived. */
1117+ if (channel_parse_messages ())
1118+ continue ;
1119+
1120+ /* Wait for up to 2 seconds.
1121+ * TODO: use timeout set on the channel. */
1122+ if (channel_wait (channels [ch_idx ].ch_fd , 2000 ) == FAIL )
1123+ break ;
1124+ channel_read (ch_idx );
1125+ }
10961126 }
10971127 return FAIL ;
10981128}
@@ -1246,16 +1276,23 @@ channel_select_check(int ret_in, void *rfds_in)
12461276# endif /* !FEAT_GUI_W32 && HAVE_SELECT */
12471277
12481278/*
1249- * Invoked from the main loop when it's save to execute received commands.
1279+ * Execute queued up commands.
1280+ * Invoked from the main loop when it's safe to execute received commands.
1281+ * Return TRUE when something was done.
12501282 */
1251- void
1283+ int
12521284channel_parse_messages (void )
12531285{
12541286 int i ;
1287+ int ret = FALSE;
12551288
12561289 for (i = 0 ; i < channel_count ; ++ i )
12571290 while (may_invoke_callback (i ) == OK )
1258- ;
1291+ {
1292+ i = 0 ; /* start over */
1293+ ret = TRUE;
1294+ }
1295+ return ret ;
12591296}
12601297
12611298#endif /* FEAT_CHANNEL */
0 commit comments