// fillRuntimeIndexes fills a runtimeIndexes structure will the field // indexes gathered from the remoteTypes recorded in a runtimeValues // structure. func fillRuntimeIndexes(runtime *runtimeValues, out *runtimeIndexes) { outv := reflect.Indirect(reflect.NewValue(out)).(*reflect.StructValue) outt := outv.Type().(*reflect.StructType) runtimev := reflect.Indirect(reflect.NewValue(runtime)).(*reflect.StructValue) // out contains fields corresponding to each runtime type for i := 0; i < outt.NumField(); i++ { // Find the interpreter type for this runtime type name := outt.Field(i).Name et := runtimev.FieldByName(name).Interface().(*remoteType).Type.(*eval.StructType) // Get the field indexes of the interpreter struct type indexes := make(map[string]int, len(et.Elems)) for j, f := range et.Elems { if f.Anonymous { continue } name := f.Name if name[0] >= 'a' && name[0] <= 'z' { name = string(name[0]+'A'-'a') + name[1:] } indexes[name] = j } // Fill this field of out outStructv := outv.Field(i).(*reflect.StructValue) outStructt := outStructv.Type().(*reflect.StructType) for j := 0; j < outStructt.NumField(); j++ { f := outStructv.Field(j).(*reflect.IntValue) name := outStructt.Field(j).Name f.Set(indexes[name]) } } }
func checkFuzzyEqual(a any, b any) (err os.Error) { if !fuzzyEqual(a, b) { err = os.NewError(fmt.Sprint(a, " != ", b, ":", reflect.NewValue(a), "!=", reflect.NewValue(b))) } return }
// Parsuje parametr znajdujacy sie na poczatku frag. Pomija biale znaki przed // parametrem i usuwa za nim (po wywolaniu frag[0] nie jest bialym znakiem). func parse1Param(txt *string, lnum *int) ( par interface{}, err os.Error) { frag := *txt // Pomijamy biale znaki, ktore moga wystapic przed parametrem. err = skipWhite(&frag, lnum) if err != nil { return } if frag[0] == '"' || frag[0] == '\'' { // Parametrem jest tekst. txt_sep := frag[0:1] frag = frag[1:] if len(frag) == 0 { err = ParseErr{*lnum, PARSE_UNEXP_EOF} return } // Parsujemy tekst parametru. par, err = parse1(&frag, lnum, txt_sep) if err != nil { return } } else if uni.IsDigit(int(frag[0])) || str.IndexRune(seps_num, int(frag[0])) != -1 { // Parametrem jest liczba ii := findChar(frag, seps_nnum, lnum) if ii == -1 { err = ParseErr{*lnum, PARSE_UNEXP_EOF} return } var iv int iv, err = strconv.Atoi(frag[0:ii]) if err != nil { var fv float fv, err = strconv.Atof(frag[0:ii]) if err != nil { err = ParseErr{*lnum, PARSE_BAD_FLOINT} return } par = reflect.NewValue(fv) } else { par = reflect.NewValue(iv) } frag = frag[ii:] } else { par, err = parse1VarFun("", &frag, lnum, false) if err != nil { return } } // Pomijamy biale znaki, ktore moga wystapic po parametrze. err = skipWhite(&frag, lnum) *txt = frag return }
func routeHandler(req *Request) *Response { log.Stdout(req.RawURL) path := req.URL.Path ctx := Context{req, newResponse(200, "")} for cr, route := range routes { if !cr.MatchString(path) { continue } match := cr.MatchStrings(path) if len(match) > 0 { if len(match[0]) != len(path) { continue } if req.Method != route.method { continue } ai := 0 handlerType := route.handler.Type().(*reflect.FuncType) expectedIn := handlerType.NumIn() args := make([]reflect.Value, expectedIn) if expectedIn > 0 { a0 := handlerType.In(0) ptyp, ok := a0.(*reflect.PtrType) if ok { typ := ptyp.Elem() if typ == contextType { args[ai] = reflect.NewValue(&ctx) ai += 1 expectedIn -= 1 } } } actualIn := len(match) - 1 if expectedIn != actualIn { log.Stderrf("Incorrect number of arguments for %s\n", path) return newResponse(500, "") } for _, arg := range match[1:] { args[ai] = reflect.NewValue(arg) } ret := route.handler.Call(args)[0].(*reflect.StringValue).Get() var buf bytes.Buffer buf.WriteString(ret) resp := ctx.Response resp.Body = &buf return resp } } return newResponse(404, "") }
/** * Write the command packet to the buffer and send to the server */ func (pkt *packetCommand) write(writer *bufio.Writer) (err os.Error) { // Construct packet header pkt.header = new(packetHeader) pkt.header.length = 1 // Calculate packet length var v reflect.Value for i := 0; i < len(pkt.args); i++ { v = reflect.NewValue(pkt.args[i]) switch v.Type().Name() { default: return os.ErrorString("Unsupported type") case "string": pkt.header.length += uint32(len(v.Interface().(string))) case "uint8": pkt.header.length += 1 case "uint16": pkt.header.length += 2 case "uint32": pkt.header.length += 4 case "uint64": pkt.header.length += 8 } } pkt.header.sequence = 0 err = pkt.header.write(writer) if err != nil { return } // Write command err = writer.WriteByte(byte(pkt.command)) if err != nil { return } // Write params for i := 0; i < len(pkt.args); i++ { v = reflect.NewValue(pkt.args[i]) switch v.Type().Name() { case "string": _, err = writer.WriteString(v.Interface().(string)) case "uint8": err = pkt.writeNumber(writer, uint64(v.Interface().(uint8)), 1) case "uint16": err = pkt.writeNumber(writer, uint64(v.Interface().(uint16)), 2) case "uint32": err = pkt.writeNumber(writer, uint64(v.Interface().(uint32)), 4) case "uint64": err = pkt.writeNumber(writer, uint64(v.Interface().(uint64)), 8) } if err != nil { return } } // Flush err = writer.Flush() return }
// The function run manages sends and receives for a single client. For each // (client Recv) request, this will launch a serveRecv goroutine to deliver // the data for that channel, while (client Send) requests are handled as // data arrives from the client. func (client *expClient) run() { hdr := new(header) hdrValue := reflect.NewValue(hdr) req := new(request) reqValue := reflect.NewValue(req) error := new(error) for { *hdr = header{} if err := client.decode(hdrValue); err != nil { expLog("error decoding client header:", err) break } switch hdr.payloadType { case payRequest: *req = request{} if err := client.decode(reqValue); err != nil { expLog("error decoding client request:", err) break } switch req.dir { case Recv: go client.serveRecv(*hdr, req.count) case Send: // Request to send is clear as a matter of protocol // but not actually used by the implementation. // The actual sends will have payload type payData. // TODO: manage the count? default: error.error = "request: can't handle channel direction" expLog(error.error, req.dir) client.encode(hdr, payError, error) } case payData: client.serveSend(*hdr) case payClosed: client.serveClosed(*hdr) case payAck: client.mu.Lock() if client.ackNum != hdr.seqNum-1 { // Since the sequence number is incremented and the message is sent // in a single instance of locking client.mu, the messages are guaranteed // to be sent in order. Therefore receipt of acknowledgement N means // all messages <=N have been seen by the recipient. We check anyway. expLog("sequence out of order:", client.ackNum, hdr.seqNum) } if client.ackNum < hdr.seqNum { // If there has been an error, don't back up the count. client.ackNum = hdr.seqNum } client.mu.Unlock() default: log.Exit("netchan export: unknown payload type", hdr.payloadType) } } client.exp.delClient(client) }
func TestUnpackArray(t *testing.T) { b := bytes.NewBuffer([]byte{0x90, 0x91, 0x00, 0x92, 0x00, 0x01, 0x93, 0xd1, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x01, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xdc, 0x00, 0x02, 0x00, 0x01, 0xdd, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03}) for _, v := range [](interface{}){[](interface{}){}, [](interface{}){int8(0)}, [](interface{}){int8(0), int8(1)}, [](interface{}){int16(0), int32(1), int64(2)}, [](interface{}){int8(0), int8(1)}, [](interface{}){int8(0), int8(1), int8(2), int8(3)}} { retval, _, e := Unpack(b) if e != nil { t.Error("err != nil") } if !equal(reflect.NewValue(retval.Interface()), reflect.NewValue(v)) { t.Errorf("%s != %s", retval.Interface(), v) } } }
func (j jsonMarshalingPolicy) NewDemarshaler(r io.Reader, p *proxyImpl) Demarshaler { jm := &jsonDemarshaler{Decoder: json.NewDecoder(r), proxy: p} var xb *bool = nil jm.ptrBool = reflect.NewValue(xb).(*reflect.PtrValue) var xi *int = nil jm.ptrInt = reflect.NewValue(xi).(*reflect.PtrValue) var xf *float64 = nil jm.ptrFloat = reflect.NewValue(xf).(*reflect.PtrValue) var xs *string = nil jm.ptrString = reflect.NewValue(xs).(*reflect.PtrValue) return jm }
func main() { flag.Usage = usage flag.Parse() if *showHelp { usage() return } if *showVersion { fmt.Println("doozer", version) return } if flag.NArg() < 1 { fmt.Fprintf(os.Stderr, "%s: missing command\n", os.Args[0]) usage() os.Exit(127) } cmd := flag.Arg(0) c, ok := cmds[cmd] if !ok { fmt.Fprintln(os.Stderr, "Unknown command:", cmd) usage() os.Exit(127) } os.Args = flag.Args() flag.Parse() if *showHelp { help(cmd) return } args := flag.Args() ft := reflect.Typeof(c.f).(*reflect.FuncType) if len(args) != ft.NumIn() { fmt.Fprintf(os.Stderr, "%s: wrong number of arguments\n", cmd) help(cmd) os.Exit(127) } vals := make([]reflect.Value, len(args)) for i, s := range args { vals[i] = reflect.NewValue(s) } fv := reflect.NewValue(c.f).(*reflect.FuncValue) fv.Call(vals) }
func (s Send) send() { // With reflect.ChanValue.Send, we must match the types exactly. So, if // s.Channel is a chan interface{} we convert s.Value to an interface{} // first. c := reflect.NewValue(s.Channel).(*reflect.ChanValue) var v reflect.Value if iface, ok := c.Type().(*reflect.ChanType).Elem().(*reflect.InterfaceType); ok && iface.NumMethod() == 0 { v = newEmptyInterface(s.Value) } else { v = reflect.NewValue(s.Value) } c.Send(v) }
func diff(t *testing.T, prefix string, have, want interface{}) { hv := reflect.NewValue(have).(*reflect.PtrValue).Elem().(*reflect.StructValue) wv := reflect.NewValue(want).(*reflect.PtrValue).Elem().(*reflect.StructValue) if hv.Type() != wv.Type() { t.Errorf("%s: type mismatch %v vs %v", prefix, hv.Type(), wv.Type()) } for i := 0; i < hv.NumField(); i++ { hf := hv.Field(i).Interface() wf := wv.Field(i).Interface() if !reflect.DeepEqual(hf, wf) { t.Errorf("%s: %s = %v want %v", prefix, hv.Type().(*reflect.StructType).Field(i).Name, hf, wf) } } }
func (b *structBuilder) Key(k string) Builder { if b == nil { return nobuilder } switch v := reflect.Indirect(b.val).(type) { case *reflect.StructValue: t := v.Type().(*reflect.StructType) // Case-insensitive field lookup. k = strings.ToLower(k) for i := 0; i < t.NumField(); i++ { if strings.ToLower(t.Field(i).Name) == k { return &structBuilder{val: v.Field(i)} } } case *reflect.MapValue: t := v.Type().(*reflect.MapType) if t.Key() != reflect.Typeof(k) { break } key := reflect.NewValue(k) elem := v.Elem(key) if elem == nil { v.SetElem(key, reflect.MakeZero(t.Elem())) elem = v.Elem(key) } return &structBuilder{val: elem, map_: v, key: key} } return nobuilder }
func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value { m := &clientHelloMsg{} m.vers = uint16(rand.Intn(65536)) m.random = randomBytes(32, rand) m.sessionId = randomBytes(rand.Intn(32), rand) m.cipherSuites = make([]uint16, rand.Intn(63)+1) for i := 0; i < len(m.cipherSuites); i++ { m.cipherSuites[i] = uint16(rand.Int31()) } m.compressionMethods = randomBytes(rand.Intn(63)+1, rand) if rand.Intn(10) > 5 { m.nextProtoNeg = true } if rand.Intn(10) > 5 { m.serverName = randomString(rand.Intn(255), rand) } m.ocspStapling = rand.Intn(10) > 5 m.supportedPoints = randomBytes(rand.Intn(5)+1, rand) m.supportedCurves = make([]uint16, rand.Intn(5)+1) for i, _ := range m.supportedCurves { m.supportedCurves[i] = uint16(rand.Intn(30000)) } return reflect.NewValue(m) }
func (self *Controller) AddHandler(regexp string, fun interface{}) { self.callbacks.Push(&callback{ regexp, reflect.NewValue(fun).(*reflect.FuncValue), reflect.Typeof(fun).(*reflect.FuncType), }) }
/** * Parse params given to Connect() */ func (mysql *MySQL) parseParams(p []interface{}) { mysql.auth = new(MySQLAuth) // Assign default values mysql.auth.port = DefaultPort mysql.auth.socket = DefaultSock // Host / username are required mysql.auth.host = p[0].(string) mysql.auth.username = p[1].(string) // 3rd param should be a password if len(p) > 2 { mysql.auth.password = p[2].(string) } // 4th param should be a database name if len(p) > 3 { mysql.auth.dbname = p[3].(string) } // Reflect 5th param to determine if it is port or socket if len(p) > 4 { v := reflect.NewValue(p[4]) if v.Type().Name() == "int" { mysql.auth.port = v.Interface().(int) } else if v.Type().Name() == "string" { mysql.auth.socket = v.Interface().(string) } } return }
// Evaluate interfaces and pointers looking for a value that can look up the name, via a // struct field, method, or map key, and return the result of the lookup. func (t *Template) lookup(st *state, v reflect.Value, name string) reflect.Value { for v != nil { typ := v.Type() if n := v.Type().NumMethod(); n > 0 { for i := 0; i < n; i++ { m := typ.Method(i) mtyp := m.Type if m.Name == name && mtyp.NumIn() == 1 && mtyp.NumOut() == 1 { if !isExported(name) { t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type()) } return v.Method(i).Call(nil)[0] } } } switch av := v.(type) { case *reflect.PtrValue: v = av.Elem() case *reflect.InterfaceValue: v = av.Elem() case *reflect.StructValue: if !isExported(name) { t.execError(st, t.linenum, "name not exported: %s in type %s", name, st.data.Type()) } return av.FieldByName(name) case *reflect.MapValue: return av.Elem(reflect.NewValue(name)) default: return nil } } return v }
// Returns once all services have signalled that they have started. // Automatically accounts for a variable number of services as contained in the // ServiceContext struct. // // TODO: This implementation is prone to error if the same service sends // MsgTick more than once, fix? func (g *Game) waitOnServiceStart(input chan Msg) { // We can discard the ok value, because svc is always a struct val, _ := (reflect.NewValue(g.svc)).(*reflect.StructValue) svc_num := val.NumField() - 1 // Don't count Game num_left := svc_num for { msg := <-input switch m := msg.(type) { case MsgTick: num_left-- if num_left == 0 { goto done } default: panic("Received message other than MsgTick!") } } done: } // Creates a new player entity for a requesting client func (g *Game) spawnEntity(msg MsgSpawnEntity) { p := msg.Spawn(g.GetUid()) g.AddEntity(p) go p.Run(g.svc) if msg.Reply != nil { desc := NewEntityDesc(p) Send(g, msg.Reply, desc) } }
// Write Optional Params func (pdu *PDUCommon) writeOptional(w *bufio.Writer) (err os.Error) { if len(pdu.Optional) > 0 { for key, val := range pdu.Optional { op := new(pduOptParam) op.tag = uint16(key) op.value = val v := reflect.NewValue(val) switch t := v.(type) { case *reflect.StringValue: op.length = uint16(len(val.(string))) case *reflect.BoolValue: op.length = 1 case *reflect.Uint8Value: op.length = 1 case *reflect.Uint16Value: op.length = 2 case *reflect.Uint32Value: op.length = 4 case *reflect.Uint64Value: op.length = 8 } err = op.write(w) if err != nil { return } } } return }
// getChannels returns all the channels listed in any receive events. func getChannels(events []*Event) ([]interface{}, os.Error) { channels := make([]interface{}, len(events)) j := 0 for _, event := range events { if recv := event.action.getRecv(); recv == nil { continue } c := event.action.getChannel() if _, ok := reflect.NewValue(c).(*reflect.ChanValue); !ok { return nil, SetupError("one of the channel values is not a channel") } duplicate := false for _, other := range channels[0:j] { if c == other { duplicate = true break } } if !duplicate { channels[j] = c j++ } } return channels[0:j], nil }
func setStruct(i interface{}) { switch t := i.(type) { case Person: r := reflect.NewValue(i) name := r.(*reflect.StructValue).FieldByName("name").(*reflect.StringValue).Get() fmt.Printf("Actual name %s\n", name) case *Person: r := reflect.NewValue(i) name := r.(*reflect.PtrValue).Elem().(*reflect.StructValue).FieldByName("name").(*reflect.StringValue).Get() fmt.Printf("Actual name %s\n", name) // now set it r.(*reflect.PtrValue).Elem().(*reflect.StructValue).FieldByName("name").(*reflect.StringValue).Set("Albert Einstein") } }
func decodeBSONData(d *decodeState, kind int, value reflect.Value) { start := d.offset d.skipValue(kind) bd := BSONData{Kind: kind, Data: make([]byte, d.offset-start)} copy(bd.Data, d.data[start:d.offset]) value.SetValue(reflect.NewValue(bd)) }
// Returns a matcher that matches on any array or slice input value // if the given matcher matches every element of that array or slice. // // The returned matcher does not match any non-array-or-slice value. func EachElem(matcher *base.Matcher) *base.Matcher { match := func(actual interface{}) *base.Result { v := reflect.NewValue(actual) var value _ElemAndLen var ok bool value, ok = v.(*reflect.ArrayValue) if !ok { value, ok = v.(*reflect.SliceValue) } if !ok { return base.NewResultf(false, "Was not array or slice: was type %T", actual) } n := value.Len() for i := 0; i < n; i++ { elem := value.Elem(i).Interface() result := matcher.Match(elem) if !result.Matched() { return base.NewResultf(false, "Failed to match element %v of %v: %v", i+1, n, elem). WithCauses(result) } } return base.NewResultf(true, "Matched all of the %v elements", n) } return base.NewMatcherf(match, "EveryElement[%v]", matcher) }
func TestSingletons(t *testing.T) { b := new(bytes.Buffer) enc := NewEncoder(b) dec := NewDecoder(b) for _, test := range singleTests { b.Reset() err := enc.Encode(test.in) if err != nil { t.Errorf("error encoding %v: %s", test.in, err) continue } err = dec.Decode(test.out) switch { case err != nil && test.err == "": t.Errorf("error decoding %v: %s", test.in, err) continue case err == nil && test.err != "": t.Errorf("expected error decoding %v: %s", test.in, test.err) continue case err != nil && test.err != "": if strings.Index(err.String(), test.err) < 0 { t.Errorf("wrong error decoding %v: wanted %s, got %v", test.in, test.err, err) } continue } // Get rid of the pointer in the rhs val := reflect.NewValue(test.out).(*reflect.PtrValue).Elem().Interface() if !reflect.DeepEqual(test.in, val) { t.Errorf("decoding singleton: expected %v got %v", test.in, val) } } }
// Write Optional param func (op *pduOptParam) write(w *bufio.Writer) (err os.Error) { // Create byte array p := make([]byte, 4+op.length) copy(p[0:2], packUint(uint64(op.tag), 2)) copy(p[2:4], packUint(uint64(op.length), 2)) // Determine data type of value v := reflect.NewValue(op.value) switch t := v.(type) { case *reflect.StringValue: copy(p[4:op.length], []byte(op.value.(string))) case *reflect.Uint8Value: p[4] = byte(op.value.(uint8)) case *reflect.Uint16Value: copy(p[4:6], packUint(uint64(op.value.(uint16)), 2)) case *reflect.Uint32Value: copy(p[4:8], packUint(uint64(op.value.(uint32)), 4)) } // Write to buffer _, err = w.Write(p) if err != nil { return } // Flush write buffer err = w.Flush() return }
// The Parser's Unmarshal method is like xml.Unmarshal // except that it can be passed a pointer to the initial start element, // useful when a client reads some raw XML tokens itself // but also defers to Unmarshal for some elements. // Passing a nil start element indicates that Unmarshal should // read the token stream to find the start element. func (p *Parser) Unmarshal(val interface{}, start *StartElement) os.Error { v, ok := reflect.NewValue(val).(*reflect.PtrValue) if !ok { return os.NewError("non-pointer passed to Unmarshal") } return p.unmarshal(v.Elem(), start) }
func UnmarshalFrom(r io.Reader, val interface{}) (err os.Error) { result, _ := DecodeFrom(r) value := reflect.NewValue(val).(*reflect.PtrValue).Elem() switch v := value.(type) { case *reflect.StructValue: slice := reflect.NewValue(result).(*reflect.SliceValue) for i := 0; i < slice.Len(); i++ { e := slice.Elem(i).(*reflect.InterfaceValue).Elem() v.Field(i).SetValue(e) } } return nil }
// ImportNValues imports a channel of the given type and specified direction // and then receives or transmits up to n values on that channel. A value of // n==0 implies an unbounded number of values. The channel to be bound to // the remote site's channel is provided in the call and may be of arbitrary // channel type. // Despite the literal signature, the effective signature is // ImportNValues(name string, chT chan T, dir Dir, pT T) // where T must be a struct, pointer to struct, etc. pT may be more indirect // than the value type of the channel (e.g. chan T, pT *T) but it must be a // pointer. // Example usage: // imp, err := NewImporter("tcp", "netchanserver.mydomain.com:1234") // if err != nil { log.Exit(err) } // ch := make(chan myType) // err := imp.ImportNValues("name", ch, Recv, new(myType), 1) // if err != nil { log.Exit(err) } // fmt.Printf("%+v\n", <-ch) // (TODO: Can we eliminate the need for pT?) func (imp *Importer) ImportNValues(name string, chT interface{}, dir Dir, pT interface{}, n int) os.Error { ch, err := checkChan(chT, dir) if err != nil { return err } // Make sure pT is a pointer (to a pointer...) to a struct. rt := reflect.Typeof(pT) if _, ok := rt.(*reflect.PtrType); !ok { return os.ErrorString("not a pointer:" + rt.String()) } if _, ok := reflect.Indirect(reflect.NewValue(pT)).(*reflect.StructValue); !ok { return os.ErrorString("not a pointer to a struct:" + rt.String()) } imp.chanLock.Lock() defer imp.chanLock.Unlock() _, present := imp.chans[name] if present { return os.ErrorString("channel name already being imported:" + name) } ptr := reflect.MakeZero(reflect.Typeof(pT)).(*reflect.PtrValue) imp.chans[name] = &importChan{ch, dir, ptr, n} // Tell the other side about this channel. req := new(request) req.name = name req.dir = dir req.count = n if err := imp.encode(req, nil); err != nil { log.Stderr("importer request encode:", err) return err } return nil }
func TestUnmarshal(t *testing.T) { var scan scanner for i, tt := range unmarshalTests { in := []byte(tt.in) if err := checkValid(in, &scan); err != nil { t.Errorf("#%d: checkValid: %v", i, err) continue } // v = new(right-type) v := reflect.NewValue(tt.ptr).(*reflect.PtrValue) v.PointTo(reflect.MakeZero(v.Type().(*reflect.PtrType).Elem())) if err := Unmarshal([]byte(in), v.Interface()); err != nil { t.Errorf("#%d: %v", i, err) continue } if !reflect.DeepEqual(v.Elem().Interface(), tt.out) { t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), tt.out) data, _ := Marshal(v.Elem().Interface()) println(string(data)) data, _ = Marshal(tt.out) println(string(data)) return continue } } }
// Eval formats each argument according to the format // f and returns the resulting []byte and os.Error. If // an error occurred, the []byte contains the partially // formatted result. An environment env may be passed // in which is available in custom formatters through // the state parameter. // func (f Format) Eval(env Environment, args ...interface{}) ([]byte, os.Error) { if f == nil { return nil, os.NewError("format is nil") } errors := make(chan os.Error) s := newState(f, env, errors) go func() { for _, v := range args { fld := reflect.NewValue(v) if fld == nil { errors <- os.NewError("nil argument") return } mark := s.save() if !s.eval(s.getFormat(typename(fld.Type())), fld, 0) { // TODO is 0 index correct? s.restore(mark) } } errors <- nil // no errors }() err := <-errors return s.output.Bytes(), err }
func TestRun(t *testing.T) { res := Resolver{"echo": reflect.NewValue(echo).(*reflect.FuncValue)} serv := NewServer(res, true, nil) l, err := net.Listen("tcp", "127.0.0.1:50000") if err != nil { t.Fail() return } serv.Listen(l) go (func() { serv.Run() })() conn, err := net.Dial("tcp", "", "127.0.0.1:50000") if err != nil { t.Fail() return } client := NewSession(conn, true) for _, v := range []string{"world", "test", "hey"} { retval, xerr := client.Send("echo", v) if xerr != nil { t.Error(xerr.String()) return } _retval, ok := retval.(*reflect.StringValue) if !ok { return } if _retval.Get() != "Hello, "+v { t.Error("retval != \"Hello, " + v + "\"") } } }