Commits

Miki Tebeka committed 1844226

Compiles (and fails)

  • Participants
  • Parent commits 863171a
  • Branches simple-type-parsing

Comments (0)

Files changed (1)

 type serverReply struct {
 	SessionId *string
 	Status    int
+	Value interface{}
 }
 
-type statusReply struct {
-	Value Status
-}
-type stringReply struct {
-	Value *string
-}
-type stringsReply struct {
-	Value []string
-}
-type boolReply struct {
-	Value bool
-}
-type element struct {
+/* Element as returned by JSON protocol */
+type jsonElement struct {
 	ELEMENT string
 }
-type elementReply struct {
-	Value element
-}
-type elementsReply struct {
-	Value []element
-}
-type cookiesReply struct {
-	Value []Cookie
-}
-type locationReply struct {
-	Value Point
-}
-type sizeReply struct {
-	Value Size
-}
-type anyReply struct {
-	Value interface{}
-}
 
 func isMimeType(response *http.Response, mtype string) bool {
 	if ctype, ok := response.Header["Content-Type"]; ok {
 }
 
 
-func (wd *remoteWD) execute(method, url string, data []byte) ([]byte, os.Error) {
+func (wd *remoteWD) execute(method, url string, data []byte) (interface{}, os.Error) {
 	request, err := newRequest(method, url, data)
 	if err != nil {
 		return nil, err
 
 	cleanNils(buf)
 
-	reply := new(serverReply)
 	if isMimeType(response, JSON_TYPE) {
+		reply := new(serverReply)
 		err := json.Unmarshal(buf, reply)
 		if err != nil {
 			return nil, err
 
 			return nil, os.NewError(message)
 		}
-		return buf, err
+		return reply.Value, err
 	}
 
 	ctype, ok := response.Header["Content-Type"]
 		return nil, err
 	}
 
-	status := new(statusReply)
-	err = json.Unmarshal(reply, status)
+	/* It's faster to let the json module fill the status structure than rolling
+	   it out by hand .
+	*/
+	status := new(Status)
+	data, _ := json.Marshal(reply)
+	err = json.Unmarshal(data, status)
 	if err != nil {
 		return nil, err
 	}
-
-	return &status.Value, nil
+	return status, nil
 }
 
 func (wd *remoteWD) NewSession() (string, os.Error) {
 		return "", err
 	}
 
-	reply := new(serverReply)
-	json.Unmarshal(response, reply)
+	id, ok := response.(string)
+	if !ok {
+		return "", os.NewError("Bad reply type")
+	}
 
-	wd.id = *reply.SessionId
-
-	return wd.id, nil
+	wd.id = id
+	return id, nil
 }
 
 func (wd *remoteWD) Quit() os.Error {
 		return "", err
 	}
 
-	reply := new(stringReply)
-	err = json.Unmarshal(response, reply)
-	if err != nil {
-		return "", err
+	// null replies are OK
+	if response == nil {
+		return "", nil
 	}
 
-	return *reply.Value, nil
+	value, ok := response.(string)
+	if !ok {
+		return "", os.NewError("Bad return type")
+	}
+
+	return value, nil
 }
 
 func (wd *remoteWD) CurrentWindowHandle() (string, os.Error) {
 	if err != nil {
 		return nil, err
 	}
-	reply := new(stringsReply)
-	json.Unmarshal(response, reply)
 
-	return reply.Value, nil
+	ihandles, ok := response.([]interface{})
+	if !ok {
+		return nil, os.NewError("Bad return type")
+	}
+	handles := make([]string, len(ihandles))
+	for i, v := range(ihandles) {
+		handles[i], _ = v.(string)
+	}
+
+	return handles, nil
 }
 
 func (wd *remoteWD) CurrentURL() (string, os.Error) {
-	url := wd.requestURL("/session/%s/url", wd.id)
-	response, err := wd.execute("GET", url, nil)
-	if err != nil {
-		return "", err
-	}
-	reply := new(stringReply)
-	json.Unmarshal(response, reply)
+	return wd.stringCommand("/session/%s/url")
+}
 
-	return *reply.Value, nil
+func (wd *remoteWD) voidCommand(urlTemplate string, data []byte) os.Error {
+	url := wd.requestURL(urlTemplate, wd.id)
+	_, err := wd.execute("POST", url, data)
+	return err
 
 }
 
 func (wd *remoteWD) Get(url string) os.Error {
-	requestURL := wd.requestURL("/session/%s/url", wd.id)
 	params := map[string]string{
 		"url": url,
 	}
 	if err != nil {
 		return err
 	}
-	_, err = wd.execute("POST", requestURL, data)
-
-	return err
+	return wd.voidCommand("/session/%s/url", data)
 }
 
-func (wd *remoteWD) voidCommand(urlTemplate string) os.Error {
-	url := wd.requestURL(urlTemplate, wd.id)
-	_, err := wd.execute("POST", url, nil)
-	return err
-
-}
 
 func (wd *remoteWD) Forward() os.Error {
-	return wd.voidCommand("/session/%s/forward")
+	return wd.voidCommand("/session/%s/forward", nil)
 }
 
 func (wd *remoteWD) Back() os.Error {
-	return wd.voidCommand("/session/%s/back")
+	return wd.voidCommand("/session/%s/back", nil)
 }
 
 func (wd *remoteWD) Refresh() os.Error {
-	return wd.voidCommand("/session/%s/refresh")
+	return wd.voidCommand("/session/%s/refresh", nil)
 }
 
 func (wd *remoteWD) Title() (string, os.Error) {
 	return wd.stringCommand("/session/%s/source")
 }
 
-func (wd *remoteWD) find(by, value, suffix, url string) ([]byte, os.Error) {
+func (wd *remoteWD) find(by, value, suffix, url string) (interface{}, os.Error) {
 	params := map[string]string{
 		"using": by,
 		"value": value,
 	return wd.execute("POST", url, data)
 }
 
-func decodeElement(wd *remoteWD, data []byte) (WebElement, os.Error) {
-	reply := new(elementReply)
-	err := json.Unmarshal(data, reply)
-	if err != nil {
-		return nil, err
+func decodeElement(wd *remoteWD, data interface{}) (WebElement, os.Error) {
+	imap, ok := data.(map[string]interface{})
+	if !ok {
+		return nil, os.NewError("Bad return type")
 	}
 
-	elem := &remoteWE{wd, reply.Value.ELEMENT}
+	id, ok := imap["ELEMENT"].(string)
+	if !ok {
+		return nil, os.NewError("Bad id type")
+	}
+
+	elem := &remoteWE{wd, id}
 	return elem, nil
 }
 
 	return decodeElement(wd, response)
 }
 
-func decodeElements(wd *remoteWD, data []byte) ([]WebElement, os.Error) {
-	reply := new(elementsReply)
-	err := json.Unmarshal(data, reply)
+func decodeElements(wd *remoteWD, data interface{}) ([]WebElement, os.Error) {
+	buf, err := json.Marshal(data)
 	if err != nil {
 		return nil, err
 	}
-
-	elems := make([]WebElement, len(reply.Value))
-	for i, elem := range reply.Value {
-		elems[i] = &remoteWE{wd, elem.ELEMENT}
+	jelems := new([]jsonElement)
+	err = json.Unmarshal(buf, jelems)
+	if err != nil {
+		return nil, os.NewError("Bad return type")
 	}
-
+	elems := make([]WebElement, len(*jelems))
+	for i, e := range(*jelems) {
+		elems[i] = &remoteWE{wd, e.ELEMENT}
+	}
 	return elems, nil
 }
 
 func (wd *remoteWD) ActiveElement() (WebElement, os.Error) {
 	url := wd.requestURL("/session/%s/element/active", wd.id)
 	response, err := wd.execute("GET", url, nil)
-
-	reply := new(elementReply)
-	err = json.Unmarshal(response, reply)
 	if err != nil {
 		return nil, err
 	}
 
-	elem := &remoteWE{wd, reply.Value.ELEMENT}
-	return elem, nil
+	return decodeElement(wd, response)
 }
 
 func (wd *remoteWD) GetCookies() ([]Cookie, os.Error) {
 		return nil, err
 	}
 
-	reply := new(cookiesReply)
-	err = json.Unmarshal(data, reply)
+	/* Let json do the hard work of decoding. */
+	items, _ := json.Marshal(data)
+	cookies := new([]Cookie)
+	err = json.Unmarshal(items, cookies)
 	if err != nil {
 		return nil, err
 	}
 
-	return reply.Value, nil
+	return *cookies, nil
 }
 
 func (wd *remoteWD) AddCookie(cookie *Cookie) os.Error {
 }
 
 func (wd *remoteWD) DoubleClick() os.Error {
-	return wd.voidCommand("/session/%s/doubleclick")
+	return wd.voidCommand("/session/%s/doubleclick", nil)
 }
 
 func (wd *remoteWD) ButtonDown() os.Error {
-	return wd.voidCommand("/session/%s/buttondown")
+	return wd.voidCommand("/session/%s/buttondown", nil)
 }
 
 func (wd *remoteWD) ButtonUp() os.Error {
-	return wd.voidCommand("/session/%s/buttonup")
+	return wd.voidCommand("/session/%s/buttonup", nil)
 }
 
 func (wd *remoteWD) SendModifier(modifier string, isDown bool) os.Error {
 }
 
 func (wd *remoteWD) DismissAlert() os.Error {
-	return wd.voidCommand("/session/%s/dismiss_alert")
+	return wd.voidCommand("/session/%s/dismiss_alert", nil)
 }
 
 
 func (wd *remoteWD) AcceptAlert() os.Error {
-	return wd.voidCommand("/session/%s/accept_alert")
+	return wd.voidCommand("/session/%s/accept_alert", nil)
 }
 
 
 		return nil, err
 	}
 
-	reply := new(anyReply)
-	err = json.Unmarshal(response, reply)
-	if err != nil {
-		return nil, err
-	}
-
-	return reply.Value, nil
+	return response, nil
 }
 
 func (wd *remoteWD) ExecuteScript(script string, args []interface{}) (interface{}, os.Error) {
 
 func (elem *remoteWE) Click() os.Error {
 	urlTemplate := fmt.Sprintf("/session/%%s/element/%s/click", elem.id)
-	return elem.parent.voidCommand(urlTemplate)
+	return elem.parent.voidCommand(urlTemplate, nil)
 }
 
 func (elem *remoteWE) SendKeys(keys string) os.Error {
 
 func (elem *remoteWE) Submit() os.Error {
 	urlTemplate := fmt.Sprintf("/session/%%s/element/%s/submit", elem.id)
-	return elem.parent.voidCommand(urlTemplate)
+	return elem.parent.voidCommand(urlTemplate, nil)
 }
 
 func (elem *remoteWE) Clear() os.Error {
 	urlTemplate := fmt.Sprintf("/session/%%s/element/%s/clear", elem.id)
-	return elem.parent.voidCommand(urlTemplate)
+	return elem.parent.voidCommand(urlTemplate, nil)
 }
 
 func (elem *remoteWE) MoveTo(xOffset, yOffset int) os.Error {
 		return false, err
 	}
 
-	reply := new(boolReply)
-	err = json.Unmarshal(response, reply)
-	if err != nil {
-		return false, err
+	value, ok := response.(bool)
+	if !ok {
+		return false, os.NewError("Bad return type")
 	}
-
-	return reply.Value, nil
+	return value, nil
 }
 
 // Porperties
 }
 
 func (elem *remoteWE) GetAttribute(name string) (string, os.Error) {
-	wd := elem.parent
-	url := wd.requestURL("/session/%s/element/%s/attribute/%s", wd.id, elem.id, name)
-	response, err := wd.execute("GET", url, nil)
-	if err != nil {
-		return "", err
-	}
-	reply := new(stringReply)
-	err = json.Unmarshal(response, reply)
-	if err != nil {
-		return "", err
-	}
-
-	return *reply.Value, nil
+	urlTemplate := fmt.Sprintf("/session/%%s/element/%s/attribute/%s", elem.id, name)
+	return elem.parent.stringCommand(urlTemplate)
 }
 
 func (elem *remoteWE) location(suffix string) (*Point, os.Error) {
 	if err != nil {
 		return nil, err
 	}
-	reply := new(locationReply)
-	err = json.Unmarshal(response, reply)
+
+	data, err := json.Marshal(response)
 	if err != nil {
 		return nil, err
 	}
 
-	return &reply.Value, nil
+	point := new(Point)
+	err = json.Unmarshal(data, point)
+	if err != nil {
+		return nil, err
+	}
+
+	return point, nil
 }
 
 func (elem *remoteWE) Location() (*Point, os.Error) {
 	if err != nil {
 		return nil, err
 	}
-	reply := new(sizeReply)
-	err = json.Unmarshal(response, reply)
+
+	data, err := json.Marshal(response)
 	if err != nil {
 		return nil, err
 	}
+	value := new(Size)
+	err = json.Unmarshal(data, value)
+	if err != nil {
+		return nil, os.NewError("Bad return type")
+	}
 
-	return &reply.Value, nil
+	return value, nil
 }
 
 func (elem *remoteWE) CSSProperty(name string) (string, os.Error) {