changeset 2:2b212e5a0009

add redit_client.pl and fix redit-client-sm.el
author shinobu
date Tue, 08 Aug 2006 07:49:12 +0900
parents a897604a9280
children 52cb18a3c1e2
files redit-client-sm.el redit_client.pl
diffstat 2 files changed, 238 insertions(+), 104 deletions(-) [+]
line wrap: on
line diff
--- a/redit-client-sm.el	Mon Nov 28 18:38:29 2005 +0900
+++ b/redit-client-sm.el	Tue Aug 08 07:49:12 2006 +0900
@@ -1,7 +1,7 @@
 ;	$Id$
 ;  (defcustom redit-client-program "/usr/home/masasi/work/redit/reditclient"
 ;(defcustom redit-client-program "/usr/home/shinobu/redit/demo/reditclient"
- (defcustom redit-client-program "/home/dot/work/rep/emacs/edit/reditclient" 
+ (defcustom redit-client-program "/Users/dot/work/REP_project/emacs/redit_client.pl"
   "The program to use as the remote-edit client."
   :group 'redit
   :type 'string)
@@ -26,6 +26,9 @@
 (defvar redit-client-editor-id "0"
   "Remote-edit client's editor-id.")
 
+(defvar redit-client-session-id 0
+  "Remote-edit client's session-id.")
+
 ; editor local sequence number
 (defvar redit-client-seqno 0
     "Remote-edit client's editor-id.")
@@ -60,13 +63,20 @@
 (defvar redit-replace-command       "13")
 
 ;; REP Session
-(defvar redit-join-command          "41")
-(defvar redit-get-command           "43")
-(defvar redit-put-command           "45")
-(defvar redit-select-command        "47")
-(defvar redit-register-command      "49")
-(defvar redit-deregister-command    "51")
-(defvar redit-quit-command          "53")
+(defvar redit-join-command           "41")
+(defvar redit-join-ack-command       "42")
+(defvar redit-get-command            "43")
+(defvar redit-get-ack-command        "44")
+(defvar redit-put-command            "45")
+(defvar redit-put-ack-command        "46")
+(defvar redit-select-command         "47")
+(defvar redit-select-ack-command     "48")
+(defvar redit-register-command       "49")
+(defvar redit-register-ack-command   "50")
+(defvar redit-deregister-command     "51")
+(defvar redit-deregister-ack-command "52")
+(defvar redit-quit-command           "53")
+(defvar redit-quit-ack-command       "54")
 
 (defun redit-client-start (host)
   "Allow this Emacs process to be a remote-edit client for client processes."
@@ -117,13 +127,13 @@
 	(set-process-coding-system redit-client-process
 				   'raw-text 'raw-text)
 	(process-kill-without-query redit-client-process)
-	(make-local-hook 'before-change-functions)
-	(make-local-hook 'after-change-functions)
+	; (make-local-hook 'before-change-functions)
+	; (make-local-hook 'after-change-functions)
     ; FIXME
     ; concat my hostname this command?
     (process-send-string 
         redit-client-process
-        (concat (format "%10d%10d%10d%10d%10d" (string-to-number redit-join-command) 0 (gen-seqno) 0 0))))
+        (concat (format "%10d%10d%10d%10d%10d%10d" (string-to-number redit-join-command) 0 0 (gen-seqno) 0 0) "\n")))
     (error "redit-client connection refused.")))
 
  ; (redit-get-command)
@@ -140,17 +150,29 @@
   "select session"
   (interactive "P")
   (if (setq session-name (read-string "session name:")) 
-    (process-send-string 
-        redit-client-process
-        (concat (format "%10d%10d%10d%10d%10d" (string-to-number redit-select-command) (string-to-number redit-client-editor-id) (gen-seqno) 0 0)
-        session-name))
+    (progn 
+        (setq redit-client-session-id (string-to-number session-name))
+        (process-send-string 
+            redit-client-process
+            (concat (format "%10d%10d%10d%10d%10d%10d" (string-to-number redit-select-command) redit-client-session-id redit-client-editor-id (gen-seqno) 0 0) session-name "\n"))
+    )
     (error "invalid session name.")
     )
   )
 
- (defun redit-put-command ()
-  "put"
-  (interactive)
+ ;(defun redit-put-command ()
+ ; "put"
+ ; (interactive)
+ ; )
+ (defun redit-put-command (session-name)
+  "put session"
+  (interactive "P")
+  (if (setq session-name (read-string "put session name:")) 
+    (process-send-string 
+        redit-client-process
+        (concat (format "%10d%10d%10d%10d%10d%10d" (string-to-number redit-put-command) redit-client-session-id redit-client-editor-id (gen-seqno) 0 0) session-name "\n"))
+    (error "invalid session name.")
+    )
   )
 
  (defun redit-register-command (session-name)
@@ -159,9 +181,7 @@
   (if (setq session-name (read-string "session name:")) 
     (process-send-string 
         redit-client-process
-        ; FIXME "%10d%10d%10d%10d%10d" ?
-        (concat (format "%10d%10d%10d%10d%10d" (string-to-number redit-register-command) (string-to-number redit-client-editor-id) (gen-seqno) 0 0)
-        session-name))
+        (concat (format "%10d%10d%10d%10d%10d%10d" (string-to-number redit-register-command) redit-client-session-id redit-client-editor-id (gen-seqno) 0 0) session-name "\n"))
     (error "invalid session name.")
     )
   )
@@ -198,7 +218,7 @@
 	(progn
 	  (process-send-string
 	   redit-client-process
-		   (format "%10d%10d%10d%10d%10d" (string-to-number redit-read-command) (string-to-number redit-client-editor-id) (gen-seqno) linenum 0))
+		   (format "%10d%10d%10d%10d%10d%10d\n" (string-to-number redit-read-command) redit-client-session-id redit-client-editor-id (gen-seqno) linenum 0))
 	  (while (eq nil
 		     (accept-process-output redit-client-process)))))
     (error "redit-client is not running.")))
@@ -220,12 +240,13 @@
 	  ;の文字列を送る
 		  (process-send-string 
 		   redit-client-process
-		   (concat (format "%10d%10d%10d%10d%10d" (string-to-number redit-write-command) (string-to-number redit-client-editor-id) (gen-seqno) linenum length)
+		   (concat (format "%10d%10d%10d%10d%10d%10d" (string-to-number redit-write-command) redit-client-session-id redit-client-editor-id (gen-seqno) linenum length)
 				   (buffer-substring beginp endp)
 				   (if (eq isnewline t)
-					   "\n")))
-		  (while (eq nil
-					 (accept-process-output redit-client-process 1)))))
+					   "\n") "\n"))
+		  ;(while (eq nil
+		  ;			 (accept-process-output redit-client-process 1)))))
+          ))
     (error "redit-client is not running.")))
 
 ; linenum で指定した行の削除命令を redit-client-process に送信する
@@ -235,9 +256,10 @@
 	; write lines on server buffer
 	(process-send-string
 	 redit-client-process
-	 (concat (format "%10d%10d%10d%10d%10d" (string-to-number redit-delete-line-command) (string-to-number redit-client-editor-id) (gen-seqno) linenum 0)))
-	(while (eq nil
-		   (accept-process-output redit-client-process 1))))
+	 (concat (format "%10d%10d%10d%10d%10d%10d" (string-to-number redit-delete-line-command) redit-client-session-id redit-client-editor-id (gen-seqno) linenum 0) "\n"))
+	;(while (eq nil
+	;	   (accept-process-output redit-client-process 1))))
+    )
     (error "redit-client is not running.")))
 
 ; redit-client-process へcloseコマンドを送る
@@ -248,7 +270,7 @@
     (redit-client-write-line line nil)
     (process-send-string
      redit-client-process
-     (concat (format "%10d%10d%10d%10d%10d" (string-to-number redit-close-command) (string-to-number redit-client-editor-id) (gen-seqno) linenum 0)))))
+     (concat (format "%10d%10d%10d%10d%10d%10d" (string-to-number redit-close-command) redit-client-session-id redit-client-editor-id (gen-seqno) linenum 0) "\n"))))
 
 ; redit-client-process を終了させる
 (defun redit-client-kill ()
@@ -269,83 +291,79 @@
 	       'redit-client-before-change-function t)
   (remove-hook 'after-change-functions
 	       'redit-client-after-change-function t)
-  (message string) ;; add
-  (let ((command (string-to-number (rep-get-command-from-pkt string))))
+  ; (message string) ;; add
+  (let ((command (rep-get-command-from-pkt string)))
     ;command がどの命令かを判断し、対応した処理をする。case みたい
     (cond 
      ; FIXME
-     ((string-equal command (string-to-number redit-open-ack))
-      (if (not redit-client-editor-id)
-	  (redit-client-exec-open-ack string)))
+     ((if (= command (string-to-number redit-open-ack))
+      (if (/= redit-client-editor-id)
+	  (redit-client-exec-open-ack string))))
 
-     ((string-equal command (string-to-number  redit-read-ack))
-      (if (= redit-client-editor-id
-	     (string-to-number (rep-get-editor-id-from-pkt string)))
-	  (redit-client-exec-read-ack string)))
+     ((if (= command (string-to-number  redit-read-ack))
+      (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string))
+	  (redit-client-exec-read-ack string))))
 
-     ((string-equal command (string-to-number redit-write-still-ack))
-      (if (= redit-client-editor-id
-	     (string-to-number (rep-get-editor-id-from-pkt string)))
-	  (redit-client-exec-write-still-ack string)))
+     ((if (= command (string-to-number redit-write-still-ack))
+      (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string))
+	  (redit-client-exec-write-still-ack string))))
 
-     ((string-equal command (string-to-number redit-delete-line-ack))
-      (if (= redit-client-editor-id
-	     (string-to-number (rep-get-editor-id-from-pkt string)))
-	  (redit-client-exec-delete-line-ack string)))
+     ((if (= command (string-to-number redit-delete-line-ack))
+      (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string))
+	  (redit-client-exec-delete-line-ack string))))
 
-     ((string-equal command (string-to-number redit-close-ack))
-      (if (= redit-client-editor-id
-	     (string-to-number (rep-get-editor-id-from-pkt string)))
-	  (redit-client-exec-close-ack string)))
+     ((if (= command (string-to-number redit-close-ack))
+      (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string))
+	  (redit-client-exec-close-ack string))))
 
-     ((string-equal command (string-to-number redit-write-command))
-      (if (= redit-client-editor-id
-	     (string-to-number (rep-get-editor-id-from-pkt string)))
-	  (redit-client-exec-write-line string)))
+     ((if (= command (string-to-number redit-write-command))
+      (if (/= redit-client-editor-id (rep-get-editor-id-from-pkt string))
+	  (redit-client-exec-write-line string))))
 
      ; from Session Manager
-     ; join(editor id)
-     ; editor idを保存する
-     ((string-equal command (string-to-number redit-join-command))
-      (if (= redit-client-editor-id
-	     (string-to-number (rep-get-command-from-pkt string)))
+
+     ; join ack (editor id)
+     ; editor id を保存する
+     ((if (= command (string-to-number redit-join-ack-command))
 	  (redit-client-exec-join string)))
-     ; get
-     ((string-equal command (string-to-number redit-get-command))
-      (if (= redit-client-editor-id
-	     (string-to-number (rep-get-editor-id-from-pkt string)))
-	  (redit-client-exec-get string)))
-     ; put
-     ((string-equal command (string-to-number redit-put-command))
-      (if (= redit-client-editor-id
-	     (string-to-number (rep-get-editor-id-from-pkt string)))
+
+     ; put ack (editor id)
+     ; session id を保存する
+     ((if (= command (string-to-number redit-put-ack-command))
 	  (redit-client-exec-put string)))
-     ; select
-     ((string-equal command (string-to-number redit-select-command))
-      (if (= redit-client-editor-id
-	     (string-to-number (rep-get-editor-id-from-pkt string)))
-	  (redit-client-exec-select string)))
+
+     ; select ack
+     ; TODO : start editing
+     ((if (= command (string-to-number redit-select-ack-command))
+        (progn 
+            (add-hook 'before-change-functions
+	                  'redit-client-before-change-function t t)
+            (add-hook 'after-change-functions
+	                  'redit-client-after-change-function t t))))
+
+     ; get
+     ((if (= command (string-to-number redit-get-command))
+      (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string))
+	  (redit-client-exec-get string))))
      ; register
-     ((string-equal command (string-to-number redit-register-command))
-      (if (= redit-client-editor-id
-	     (string-to-number (rep-get-editor-id-from-pkt string)))
-	  (redit-client-exec-register string)))
+     ((if (= command (string-to-number redit-register-command))
+      (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string))
+	  (redit-client-exec-register string))))
      ; deregister
-     ((string-equal command (string-to-number redit-deregister-command))
-      (if (= redit-client-editor-id
-	     (string-to-number (rep-get-editor-id-from-pkt string)))
-	  (redit-client-exec-deregister string)))
+     ((if (= command (string-to-number redit-deregister-command))
+      (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string))
+	  (redit-client-exec-deregister string))))
 
      ; delete line
-     ((string-equal command (string-to-number redit-delete-line-command))
-      (if (= redit-client-editor-id
-	     (string-to-number (rep-get-editor-id-from-pkt string)))
-	  (redit-server-exec-delete-line string)))
+     ((if (= command (string-to-number redit-delete-line-command))
+      (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string))
+	  (redit-server-exec-delete-line string))))
      ((string-equal string ""))))
-  (add-hook 'before-change-functions
-	    'redit-client-before-change-function t t)
-  (add-hook 'after-change-functions
-	    'redit-client-after-change-function t t))
+     ;(add-hook 'before-change-functions
+	 ;           'redit-client-before-change-function t t)
+     ;(add-hook 'after-change-functions
+	 ;           'redit-client-after-change-function t t)
+     )
 
 ; window-scroll-functions に hook される。
 ; window がスクロールする度に呼ばれる
@@ -401,6 +419,7 @@
 ; begin と end には変更前の変更部分の始まりと終わりの point が入る
 (defun redit-client-before-change-function (begin end)
   ; check delete
+  ; (message "call redit-client-before-change-function")
   (let ((beginl (real-count-lines begin)) ; begin の行番号
 	(endl (real-count-lines end))     ; end の行番号
 	(currline)) ; currline = nil
@@ -420,6 +439,7 @@
 ; begin と end には変更後の変更部分の始まりと終わりの point が入る
 (defun redit-client-after-change-function (begin end length)
   ; check insert
+  ; (message "call redit-client-after-change-function")
   (let ((beginl (real-count-lines begin))
 	(endl (real-count-lines end))
 	(currline))
@@ -435,7 +455,7 @@
 ; 引き数で与えられた string (line_num + text_data) から
 ; 指定された行を削除し、そこに text_data を挿入する
 (defun redit-client-exec-write-line (string)
-  (let ((linenum (string-to-number (rep-get-line-number-from-pkt string))) ; 行番号
+  (let ((linenum (rep-get-line-number-from-pkt string)) ; 行番号
 	(text (rep-get-text-from-pkt string)))  ; テキストデータ
     (if (< (real-count-lines (point-max)) linenum)
 	(progn
@@ -448,7 +468,7 @@
 
 ; 引き数 string (line_num + text_data) で指定された行を削除する
 (defun redit-client-exec-delete-line (string)
-  (let ((linenum (string-to-number (rep-get-line-number-from-pkt string))))
+  (let ((linenum (rep-get-line-number-from-pkt string)))
     (goto-line linenum)
     ; 行頭から末尾までのテキストを削除
     (delete-region (progn (beginning-of-line) (point))
@@ -462,8 +482,8 @@
 ; 引き数 string (buf_num + line_num + text_data) 
 (defun redit-client-exec-open-ack (string)
   (save-excursion
-    (let ((bufnum (string-to-number (rep-get-editor-id-from-pkt string)))
-	  (linenum (string-to-number (rep-get-line-number-from-pkt string))))
+    (let ((bufnum (rep-get-editor-id-from-pkt string))
+	  (linenum (rep-get-line-number-from-pkt string)))
       (make-variable-buffer-local 'redit-client-buffer-name)
       (make-variable-buffer-local 'redit-client-editor-id)
       (setq redit-client-buffer-name
@@ -494,7 +514,7 @@
 ; text_data を挿入する
 (defun redit-client-exec-read-ack (string)
   (save-excursion
-    (let ((lines (string-to-number (rep-get-line-number-from-pkt string))))
+    (let ((lines (rep-get-line-number-from-pkt string)))
       ; redit-client-buffer をカレントバッファにする
       (set-buffer redit-client-buffer)
       (goto-line lines)
@@ -507,13 +527,13 @@
 (defun redit-client-exec-write-still-ack (string)
   (save-excursion
     (set-buffer redit-client-buffer)
-    (let ((linenum (string-to-number (rep-get-line-number-from-pkt string ))))
+    (let ((linenum (rep-get-line-number-from-pkt string )))
       (setq redit-client-line-max-in-server linenum))))
 
 (defun redit-client-exec-delete-line-ack (string)
   (save-excursion
     (set-buffer redit-client-buffer)
-    (let ((linenum (string-to-number (rep-get-line-number-from-pkt string))))
+    (let ((linenum (rep-get-line-number-from-pkt string)))
       (setq redit-client-line-max-in-server linenum))))
 
 ; プロセスとバッファ、ローカル変数を削除する
@@ -524,12 +544,15 @@
       (kill-buffer redit-client-buffer))
   (kill-all-local-variables))
 
-; 引き数で与えられた string から Session IDを取得する
+; 引き数で与えられた string から Editor IDを取得する
 (defun redit-client-exec-join (string)
   (setq redit-client-editor-id (rep-get-editor-id-from-pkt string))
-  ; FIXME : open another buffer?
   (insert (rep-get-text-from-pkt string)))
 
+; 引き数で与えられた string から Session IDを取得する
+(defun redit-client-exec-put (string)
+  (setq redit-client-session-id (rep-get-session-id-from-pkt string)))
+
 ; プロセスの状態を見て、対応したメッセージを表示
 (defun redit-client-sentinel (proc msg)
   (cond ((eq (process-status proc) 'exit)
@@ -543,13 +566,15 @@
 
 (defun rep-get-command-from-pkt (pkt)
     (string-to-number (substring pkt 0 10)))
-(defun rep-get-editor-id-from-pkt (pkt)
+(defun rep-get-session-id-from-pkt (pkt)
     (string-to-number (substring pkt 10 20)))
+(defun rep-get-editor-id-from-pkt (pkt)
+    (string-to-number (substring pkt 20 30)))
 (defun rep-get-sequence-id-from-pkt (pkt)
-    (string-to-number (substring pkt 20 30)))
+    (string-to-number (substring pkt 30 40)))
 (defun rep-get-line-number-from-pkt (pkt)
-    (string-to-number (substring pkt 30 40)))
+    (string-to-number (substring pkt 40 50)))
 (defun rep-get-text-size-from-pkt (pkt)
-    (string-to-number (substring pkt 40 50)))
+    (string-to-number (substring pkt 50 60)))
 (defun rep-get-text-from-pkt (pkt)
-    (substring pkt 50))
+    (substring pkt 60))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/redit_client.pl	Tue Aug 08 07:49:12 2006 +0900
@@ -0,0 +1,109 @@
+#!/usr/bin/perl
+
+#use strict;
+
+use IO::Select;
+use IO::Socket;
+use Rep;
+
+if($ARGV[0] eq "") {
+    print "Usage: $0 SERVER_NAME\n";
+    exit;
+}
+
+# Rep.pm に移動する
+sub HEADER_TOKEN_SIZ {10};
+sub EMACS_HEADER_SIZ {60};
+sub HEADER_CMD_POS {0};
+sub HEADER_SID_POS {1};
+sub HEADER_EID_POS {2};
+sub HEADER_SEQNO_POS {3};
+sub HEADER_LINENO_POS {4};
+sub HEADER_TEXTSIZ_POS {5};
+
+my $peer_addr = $ARGV[0];
+my $peer_port = "8080";
+my $TIMEOUT = 0;
+
+# connect to the session manager
+$sock = new IO::Socket::INET(PeerAddr => $peer_addr,
+                             PeerPort => $peer_port,
+                             Proto    => 'tcp') or die("Cannot open socket : $!\n");
+
+my $myeid;
+my $mysid;
+my $ack;
+my $packet;
+
+my $sm_selector = new IO::Select($sock) or die "Cannot select socket : $!\n";
+my $stdin_selector = new IO::Select(\*STDIN) or die "Cannot select stdin : $!\n";
+
+while(1){
+    # message from remote editor client (STDIN)
+    if ($stdin_selector->can_read($TIMEOUT)) {
+        my $buffer = <STDIN>;
+        # TODO : 
+        my $packet = &make_packet_from_emacs($buffer);
+        $sock->write($packet,length($packet));
+        &debug_msg("send message is : ||" .  $buffer . "||\n");
+    }
+
+    # message from session manager
+    if ($sm_selector->can_read($TIMEOUT)) {
+        my $sm_message = &read_and_unpack($sock);
+
+        if($sm_message->{'cmd'} == SMCMD_JOIN_ACK){
+            $myeid = $sm_message->{'eid'};
+            &debug_msg("mysid is : " .  $mysid . "\n");
+        }
+
+        if($sm_message->{'cmd'} == SMCMD_PUT_ACK){
+            $mysid = $sm_message->{'sid'};
+            &debug_msg("mysid is : " .  $mysid . "\n");
+        }
+
+        if($sm_message->{'eid'} != $myeid or $sm_message->{'cmd'} == SMCMD_JOIN_ACK or $sm_message->{'cmd'} == SMCMD_PUT_ACK or $sm_message->{'cmd'} == SMCMD_SELECT_ACK){
+            my $output = sprintf("%10d%10d%10d%10d%10d%10d" . $sm_message->{'text'},
+                                                $sm_message->{'cmd'},
+                                                $sm_message->{'sid'},
+                                                $sm_message->{'eid'},
+                                                $sm_message->{'seqno'},
+                                                $sm_message->{'lineno'},
+                                                $sm_message->{'textsiz'}
+                );
+            syswrite(STDOUT,$output,length($output));
+            &debug_msg("recv message is : ||" .  $output . "||\n");
+        } else {
+            &debug_msg("chop cmd : " .  $sm_message->{'cmd'} . "\n");
+            &debug_msg("chop eid : " .  $sm_message->{'eid'} . "\n");
+        }
+    }
+
+}
+
+sub make_packet_from_emacs {
+    # FIXME
+    my $buffer = shift;
+    return &make_packet(
+        &get_header_token($buffer, HEADER_CMD_POS),
+        &get_header_token($buffer, HEADER_SID_POS),
+        &get_header_token($buffer, HEADER_EID_POS),
+        &get_header_token($buffer, HEADER_SEQNO_POS),
+        &get_header_token($buffer, HEADER_LINENO_POS),
+        substr($buffer,&EMACS_HEADER_SIZ)
+    );
+}
+
+sub get_header_token {
+    my $buffer = shift;
+    my $pos = shift;
+
+    return int(substr($buffer, &HEADER_TOKEN_SIZ * $pos, &HEADER_TOKEN_SIZ));
+}
+
+sub debug_msg {
+    my $msg = shift;
+    open(DEBUG,">> debug.txt");
+    print DEBUG "eid $myeid : " . $msg;
+    close(DEBUG);
+}