implemented response reading
1 files changed, 38 insertions(+), 35 deletions(-)

M hackurist.go
M hackurist.go +38 -35
@@ 19,29 19,19 @@ const (
 	requestRunCommand headerId = 1  // n/a
 	requestQuit       headerId = -4 // RPC_REQUEST_QUIT
 
-	responseResult headerId = iota - 1 // RPC_REPLY_RESULT
-	responseFail                       // RPC_REPLY_FAIL
-	responseText                       // RPC_REPLY_TEXT
+	responseResult headerId = -1 // RPC_REPLY_RESULT
+	responseFail   headerId = -2 // RPC_REPLY_FAIL
+	responseText   headerId = -3 // RPC_REPLY_TEXT
 )
 
-const (
-	linkFailure    int32 = iota - 3 // CR_LINK_FAILURE
-	needsConsole                    // CR_NEEDS_CONSOLE
-	notImplemented                  // CR_NOT_IMPLEMENTED
-	ok                              // CR_OK
-	failure                         // CR_FAILURE
-	wrongeUsage                     // CR_WRONG_USAGE
-	notFound                        // CR_NOT_FOUND
-)
-
-var serverErrors = map[int32]error{
-	linkFailure:    errors.New("rpc call failed due to I/O or protocol error"),
-	needsConsole:   errors.New("attempt to call interactive command without console"),
-	notImplemented: errors.New("command not implemented or plugin not loaded"),
-	ok:             nil,
-	failure:        errors.New("failure"),
-	wrongeUsage:    errors.New("wrong arguments or ui state"),
-	notFound:       errors.New("target object not found"),
+var serverErrors = map[dfproto.CoreErrorNotification_ErrorCode]error{
+	dfproto.CoreErrorNotification_CR_LINK_FAILURE:    errors.New("rpc call failed due to I/O or protocol error"),
+	dfproto.CoreErrorNotification_CR_WOULD_BREAK:     errors.New("attempt to call interactive command without console"),
+	dfproto.CoreErrorNotification_CR_NOT_IMPLEMENTED: errors.New("command not implemented or plugin not loaded"),
+	dfproto.CoreErrorNotification_CR_OK:              nil,
+	dfproto.CoreErrorNotification_CR_FAILURE:         errors.New("failure"),
+	dfproto.CoreErrorNotification_CR_WRONG_USAGE:     errors.New("wrong arguments or ui state"),
+	dfproto.CoreErrorNotification_CR_NOT_FOUND:       errors.New("target object not found"),
 }
 
 type Conn struct {

          
@@ 95,6 85,8 @@ func (c Conn) ShakeHands() error {
 	return nil
 }
 
+const sizeHeader = 8
+
 // id is:
 // RequestQuit: quitting
 // when running a cmd. then id is

          
@@ 104,11 96,8 @@ func (c Conn) ShakeHands() error {
 // CoreSuspend: 2
 //    CoreResume: 3
 // RunLua: 4
+// marshaled: xx00yyyy, where x=id and y=size
 // size is ignored when id = RequestQuit
-//
-// so ist xx00yyyy, where x=id and y=size
-const sizeHeader = 8
-
 type header struct {
 	id   headerId
 	size int32

          
@@ 162,8 151,8 @@ func (c Conn) RunCommand(cmd string, arg
 	for {
 		header, err := c.readHeader()
 		if header.id == responseFail {
-			// todo: checkif serverErrors[id] is set?
-			return response, serverErrors[header.size]
+			// todo: check if serverErrors[id] is set?
+			return response, serverErrors[dfproto.CoreErrorNotification_ErrorCode(header.size)]
 		}
 		buf, err := c.read(int(header.size))
 		if err != nil && err != io.EOF {

          
@@ 172,14 161,28 @@ func (c Conn) RunCommand(cmd string, arg
 		if err == io.EOF {
 			break
 		}
-		// jedes mal header + CoreTextNotification! (besitzt CoreTextFragment)
-		// todo: abfrage ob text oder result
-		protobuf := new(dfproto.CoreTextNotification)
-		if err = proto.Unmarshal(buf, protobuf); err != nil {
-			return response, fmt.Errorf("RunCommand: %s", err)
-		}
-		for _, fragment := range protobuf.GetFragments() {
-			response = append(response, []byte(fragment.GetText())...)
+		// jeach time header + CoreTextNotification
+		// imrove: don't distinguish between result and text
+		switch header.id {
+		case responseFail:
+			errorCode := dfproto.CoreErrorNotification_ErrorCode(header.size)
+			if errorCode == dfproto.CoreErrorNotification_CR_OK {
+				errorCode = dfproto.CoreErrorNotification_CR_FAILURE
+			}
+			return response, serverErrors[errorCode]
+		case responseText:
+			protobuf := new(dfproto.CoreTextNotification)
+			if err = proto.Unmarshal(buf, protobuf); err != nil {
+				return response, fmt.Errorf("RunCommand: %s", err)
+			}
+			for _, fragment := range protobuf.GetFragments() {
+				response = append(response, []byte(fragment.GetText())...)
+			}
+		case responseResult:
+		// responseResult has a zero bytes msg attached
+		// todo: still marshall it
+		default:
+			return response, serverErrors[dfproto.CoreErrorNotification_CR_FAILURE]
 		}
 	}
 	return response, nil