func (cnn *serverConn) handle(chpv reflect.Value, name []byte) { handler := func(ws *websocket.Conn) { // send go func() { for { if v, ok := chpv.Recv(); ok { cnn.codec.Send(ws, v) } else { panic(Closed) } } }() // recieve for { v := reflect.New(chpv.Type().Elem()) cnn.codec.Receive(ws, v.Interface()) chpv.Send(reflect.Indirect(v)) } } encodedName := base64.URLEncoding.EncodeToString(name) if _, ok := cnn.channels[encodedName]; !ok { cnn.channels[encodedName] = true pattern := fmt.Sprintf("/%s", encodedName) cnn.handlers.Handle(pattern, websocket.Handler(handler)) } }
// Publish all values that arrive on the channel until it is closed or we // encounter an error. func chPublish(c *EncodedConn, chVal reflect.Value, subject string) { for { val, ok := chVal.Recv() if !ok { // Channel has most likely been closed. return } if e := c.Publish(subject, val.Interface()); e != nil { // Do this under lock. c.Conn.mu.Lock() defer c.Conn.mu.Unlock() if c.Conn.Opts.AsyncErrorCB != nil { // FIXME(dlc) - Not sure this is the right thing to do. // FIXME(ivan) - If the connection is not yet closed, try to schedule the callback if c.Conn.isClosed() { go c.Conn.Opts.AsyncErrorCB(c.Conn, nil, e) } else { c.Conn.ach <- func() { c.Conn.Opts.AsyncErrorCB(c.Conn, nil, e) } } } return } } }
func applyToChan(obj reflect.Value, head P, mid string, tail P, ctx *Context) error { if dir := obj.Type().ChanDir(); dir != reflect.RecvDir && dir != reflect.BothDir { return fmt.Errorf("invalid channel direction '%s' at '%s'", dir, head) } switch mid { case "1": result, ok := obj.Recv() if !ok { return ErrMissing } return apply(result, append(head, mid), tail, ctx) case "*": for !ctx.stop { result, ok := obj.Recv() if !ok { return nil } if err := apply(result, append(head, mid), tail, ctx); err != nil && err != ErrMissing { return err } } return nil default: return fmt.Errorf("invalid channel component '%s' at '%s'", mid, head) } }
func iterateChan(valueOfIter reflect.Value, out chan Pair) { i := 0 for v, ok := valueOfIter.Recv(); ok; v, ok = valueOfIter.Recv() { out <- Pair{i, v.Interface()} i++ } }
func pMapChanInt(inChan reflect.Value, f interface{}, outChan reflect.Value) { fVal := reflect.ValueOf(f) val, ok := inChan.Recv() for ok { results := fVal.Call([]reflect.Value{val}) outChan.Send(results[0]) val, ok = inChan.Recv() } outChan.Close() }
func (t *Transport) fromChan(cid uint64, cval reflect.Value) error { // Type check! woo if cval.Kind() != reflect.Chan { return fmt.Errorf("fatchan: cannot connect a %s - must be a channel", cval.Type()) } if cval.Type().ChanDir()&reflect.RecvDir == 0 { return fmt.Errorf("fatchan: cannot connect a %s - send-only channel", cval.Type()) } sid := t.sid go func() { buf := new(bytes.Buffer) for { // Keep reusing the same buffer buf.Reset() // Wait for an object from the channel v, ok := cval.Recv() if !ok { // send close message t.writeBuf(cid, buf) return } // Encode the object if err := t.encodeValue(buf, v); err != nil { t.err(sid, cid, err) continue } // Send the encoding if err := t.writeBuf(cid, buf); err != nil { t.err(sid, cid, err) break } } // Drain the channel to close for { v, ok := cval.Recv() if !ok { break } t.err(sid, cid, fmt.Errorf("discarding %+v - channel closed due to error", v)) } // Send EOF t.err(sid, cid, io.EOF) }() return nil }
// Publish all values that arrive on the channel until it is closed or we // ecounter an error. func chPublish(c *EncodedConn, chVal reflect.Value, subject string) { for { val, ok := chVal.Recv() if !ok { // Channel has most likely been closed. return } if e := c.Publish(subject, val.Interface()); e != nil { if c.Conn.Opts.AsyncErrorCB != nil { // FIXME(dlc) - Not sure this is the right thing to do. go c.Conn.Opts.AsyncErrorCB(c.Conn, nil, e) } return } } }
func ConnectTypedWriteChannelToRaw(writeChan reflect.Value, c chan []byte, wg *sync.WaitGroup) { wg.Add(1) go func() { defer wg.Done() var t reflect.Value for ok := true; ok; { if t, ok = writeChan.Recv(); ok { var buf bytes.Buffer enc := gob.NewEncoder(&buf) if err := enc.EncodeValue(t); err != nil { log.Fatal("data type:", t.Type().String(), " ", t.Kind(), " encode error:", err) } c <- buf.Bytes() } } close(c) }() }
func reduceChan(c reflect.Value, seed, f interface{}) (r interface{}, ok bool) { switch f := f.(type) { case func(interface{}, interface{}) interface{}: v := reflect.New(c.Type().Elem()).Elem() v.Set(reflect.ValueOf(seed)) for { if x, open := c.Recv(); open { v = reflect.ValueOf(f(v.Interface(), x)) } else { break } } r = v.Interface() ok = true default: if f := reflect.ValueOf(f); f.Kind() == reflect.Func { v := reflect.New(c.Type().Elem()).Elem() v.Set(reflect.ValueOf(seed)) switch f.Type().NumIn() { case 2: for { if x, open := c.Recv(); open { v = f.Call([]reflect.Value{v, x})[0] } else { break } } ok = true } if ok { r = v.Interface() } } } return }
func eachChannel(enum *Enumerator, c R.Value) (i int) { var forEachReceived func(func(R.Value)) var x R.Value var open bool if enum.Span == 1 { forEachReceived = func(f func(R.Value)) { for { if x, open = c.Recv(); !open { PanicWithIndex(enum.cursor) } f(x) i++ } enum.cursor++ } } else { forEachReceived = func(f func(R.Value)) { var offset int for { for offset = enum.Span; offset > 0; offset-- { if x, open = c.Recv(); !open { PanicWithIndex(enum.cursor + enum.Span) } } f(x) i++ } enum.cursor += enum.Span } } switch f := enum.f.(type) { case func(interface{}): forEachReceived(func(v R.Value) { f(v.Interface()) }) case func(int, interface{}): forEachReceived(func(v R.Value) { f(enum.cursor, v.Interface()) }) case func(interface{}, interface{}): forEachReceived(func(v R.Value) { f(enum.cursor, v.Interface()) }) case func(R.Value): forEachReceived(func(v R.Value) { f(v) }) case func(int, R.Value): forEachReceived(func(v R.Value) { f(enum.cursor, v) }) case func(interface{}, R.Value): forEachReceived(func(v R.Value) { f(enum.cursor, v) }) case func(R.Value, R.Value): forEachReceived(func(v R.Value) { f(R.ValueOf(enum.cursor), v) }) case chan interface{}: forEachReceived(func(v R.Value) { f <- v.Interface() }) case chan R.Value: forEachReceived(func(v R.Value) { f <- v }) // case []chan interface{}: // case []chan R.Value: default: if f := R.ValueOf(f); f.Kind() == R.Func { if t := f.Type(); !t.IsVariadic() { switch t.NumIn() { case 1: // f(v) p := make([]R.Value, 1, 1) forEachReceived(func(v R.Value) { p[0] = v f.Call(p) }) case 2: // f(i, v) p := make([]R.Value, 2, 2) forEachReceived(func(v R.Value) { p[0], p[1] = R.ValueOf(enum.cursor), v f.Call(p) }) default: panic(UNHANDLED_ITERATOR) } } } else { panic(UNHANDLED_ITERATOR) } } return }
func whileChannel(c R.Value, r bool, f interface{}) (count int) { switch f := f.(type) { case func(interface{}) bool: for v, open := c.Recv(); open && f(v.Interface()) == r; count++ { v, open = c.Recv() } case func(int, interface{}) bool: for v, open := c.Recv(); open && f(count, v.Interface()) == r; count++ { v, open = c.Recv() } case func(interface{}, interface{}) bool: for v, open := c.Recv(); open && f(count, v.Interface()) == r; count++ { v, open = c.Recv() } case func(...interface{}) bool: p := make([]interface{}, 0, 4) for v, open := c.Recv(); open; { p = append(p, v.Interface()) v, open = c.Recv() } if f(p...) == r { count = 1 } case func(bool, ...interface{}) int: p := make([]interface{}, 0, 4) for v, open := c.Recv(); open; { p = append(p, v.Interface()) v, open = c.Recv() } count = f(r, p...) case func(R.Value) bool: for v, open := c.Recv(); open && f(v) == r; count++ { v, open = c.Recv() } case func(int, R.Value) bool: for v, open := c.Recv(); open && f(count, v) == r; count++ { v, open = c.Recv() } case func(interface{}, R.Value) bool: for v, open := c.Recv(); open && f(count, v) == r; count++ { v, open = c.Recv() } case func(R.Value, R.Value) bool: for v, open := c.Recv(); open && f(R.ValueOf(count), v) == r; count++ { v, open = c.Recv() } case func(...R.Value) bool: p := make([]R.Value, 0, 4) for v, open := c.Recv(); open; { p = append(p, v) v, open = c.Recv() } if f(p...) == r { count = 1 } case func(bool, ...R.Value) int: p := make([]R.Value, 0, 4) for v, open := c.Recv(); open; { p = append(p, v) v, open = c.Recv() } count = f(r, p...) default: if f := R.ValueOf(f); f.Kind() == R.Func { if t := f.Type(); t.IsVariadic() { switch t.NumIn() { case 1: // f(...v) bool p := make([]R.Value, 0, 4) i := 0 for v, open := c.Recv(); open; i++ { p = append(p, v) v, open = c.Recv() } if f.Call(p)[0].Bool() == r { count = 1 } case 2: // f(bool, ...v) int p := make([]R.Value, 0, 4) i := 0 for v, open := c.Recv(); open; i++ { p = append(p, v) v, open = c.Recv() } count = int(f.Call(p)[0].Int()) } } else { switch t.NumIn() { case 1: // f(v) bool open := false p := make([]R.Value, 1, 1) for p[0], open = c.Recv(); open && f.Call(p)[0].Bool() == r; count++ { p[0], open = c.Recv() } case 2: // f(i, v) bool open := false p := make([]R.Value, 2, 2) p[0] = R.ValueOf(0) for p[1], open = c.Recv(); open && f.Call(p)[0].Bool() == r; count++ { p[0] = R.ValueOf(count) p[1], open = c.Recv() } } } } } return }
func whileChannel(c R.Value, r bool, f interface{}) (count int) { switch f := f.(type) { case func(interface{}) bool: for v, open := c.Recv(); open && f(v.Interface()) == r; count++ { v, open = c.Recv() } case func(int, interface{}) bool: for v, open := c.Recv(); open && f(count, v.Interface()) == r; count++ { v, open = c.Recv() } case func(interface{}, interface{}) bool: for v, open := c.Recv(); open && f(count, v.Interface()) == r; count++ { v, open = c.Recv() } case func(R.Value) bool: for v, open := c.Recv(); open && f(v) == r; count++ { v, open = c.Recv() } case func(int, R.Value) bool: for v, open := c.Recv(); open && f(count, v) == r; count++ { v, open = c.Recv() } case func(interface{}, R.Value) bool: for v, open := c.Recv(); open && f(count, v) == r; count++ { v, open = c.Recv() } case func(R.Value, R.Value) bool: for v, open := c.Recv(); open && f(R.ValueOf(count), v) == r; count++ { v, open = c.Recv() } default: if f := R.ValueOf(f); f.Kind() == R.Func { if t := f.Type(); t.NumOut() == 1 { switch t.NumIn() { case 1: // f(v) bool open := false p := make([]R.Value, 1, 1) for p[0], open = c.Recv(); open && f.Call(p)[0].Bool() == r; count++ { p[0], open = c.Recv() } case 2: // f(i, v) bool open := false p := make([]R.Value, 2, 2) p[0] = R.ValueOf(0) for p[1], open = c.Recv(); open && f.Call(p)[0].Bool() == r; count++ { p[0] = R.ValueOf(count) p[1], open = c.Recv() } default: panic(UNHANDLED_ITERATOR) } } } } return }
func (t *Transport) fromChan(cval reflect.Value) (uint64, uint64, error) { sid, cid := t.sid, atomic.AddUint64(&t.nextCID, 1) // Type check! woo if cval.Kind() != reflect.Chan { return sid, cid, fmt.Errorf("fatchan: cannot connect a %s - must be a channel", cval.Type()) } if cval.Type().ChanDir()&reflect.RecvDir == 0 { return sid, cid, fmt.Errorf("fatchan: cannot connect a %s - send-only channel", cval.Type()) } var raw [8]byte send := func(buf *bytes.Buffer) error { t.write.Lock() defer t.write.Unlock() // Send the cid n := binary.PutUvarint(raw[:], cid) if _, err := t.rwc.Write(raw[:n]); err != nil { return err } // Send the length n = binary.PutUvarint(raw[:], uint64(buf.Len())) if _, err := t.rwc.Write(raw[:n]); err != nil { return err } // Send the bytes if _, err := io.Copy(t.rwc, buf); err != nil { return err } return nil } go func() { buf := new(bytes.Buffer) for { // Keep reusing the same buffer buf.Reset() // Wait for an object from the channel v, ok := cval.Recv() if !ok { send(buf) return } // Encode the object if err := t.encodeValue(buf, v); err != nil { t.err(sid, cid, err) continue } // Send the encoding if err := send(buf); err != nil { t.err(sid, cid, err) break } } for { v, ok := cval.Recv() if !ok { break } t.err(sid, cid, fmt.Errorf("discarding %+v - channel closed", v)) } t.err(sid, cid, io.EOF) }() return sid, cid, nil }
// Iterate over a range of values, issuing a callback for each one. The callback // fn is expected to take two arguments (index/key, value pair) and return an // error. func doRange(t *testingT, v reflect.Value, fn interface{}) { t = t.sub("internal doRange") fnval := reflect.ValueOf(fn) fntyp := fnval.Type() if numin := fntyp.NumIn(); numin != 2 { t.Fatalf("function of %d arguments %v", numin, fn) } else if numout := fntyp.NumOut(); numout != 1 { t.Fatalf("function of %d return values %v", numout, fn) } zero := reflect.Zero(fnval.Type().In(1)) var out reflect.Value switch k := v.Kind(); k { case reflect.Slice: for i, n := 0, v.Len(); i < n; i++ { ival, vval := reflect.ValueOf(i), v.Index(i) arg := validValue(t.sub(sprintf("index %d", i)), vval, zero) if !arg.IsValid() { continue } out = fnval.Call([]reflect.Value{ival, arg})[0] if !out.IsNil() { t.Error(out.Interface()) break } } case reflect.Map: for _, kval := range v.MapKeys() { vval := v.MapIndex(kval) arg := validValue(t.sub(sprintf("index %v", kval.Interface())), vval, zero) if !arg.IsValid() { continue } out = fnval.Call([]reflect.Value{kval, arg})[0] if !out.IsNil() { t.Error(out.Interface()) break } } case reflect.Chan: var vval reflect.Value var ok bool for i := 0; true; i++ { ival := reflect.ValueOf(i) if vval, ok = v.Recv(); !ok { break } arg := validValue(t.sub(sprintf("received value %d", i)), vval, zero) if !arg.IsValid() { continue } out = fnval.Call([]reflect.Value{ival, arg})[0] if !out.IsNil() { t.Error(out.Interface()) break } } default: t.Fatalf("unacceptable type for range %v", v.Type()) } }
func rangeChannel(c R.Value, f interface{}) (ok bool) { switch f := f.(type) { case func(interface{}): for v, open := c.Recv(); open; { f(v.Interface()) v, open = c.Recv() } ok = true case func(int, interface{}): i := 0 for v, open := c.Recv(); open; i++ { f(i, v.Interface()) v, open = c.Recv() } ok = true case func(interface{}, interface{}): i := 0 for v, open := c.Recv(); open; i++ { f(i, v.Interface()) v, open = c.Recv() } ok = true case func(...interface{}): p := make([]interface{}, 0, 4) for v, open := c.Recv(); open; { p = append(p, v.Interface()) v, open = c.Recv() } f(p...) ok = true case func(R.Value): for v, open := c.Recv(); open; { f(v) v, open = c.Recv() } ok = true case func(int, R.Value): i := 0 for v, open := c.Recv(); open; i++ { f(i, v) v, open = c.Recv() } ok = true case func(interface{}, R.Value): i := 0 for v, open := c.Recv(); open; i++ { f(i, v) v, open = c.Recv() } ok = true case func(...R.Value): p := make([]R.Value, 0, 4) for v, open := c.Recv(); open; { p = append(p, v) v, open = c.Recv() } f(p...) ok = true default: if f := R.ValueOf(f); f.Kind() == R.Func { if t := f.Type(); t.IsVariadic() { // f(...v) p := make([]R.Value, 0, 4) for v, open := c.Recv(); open; { p = append(p, v) v, open = c.Recv() } f.Call(p) } else { switch t.NumIn() { case 1: // f(v) p := make([]R.Value, 1, 1) for v, open := c.Recv(); open; { p[0] = v f.Call(p) v, open = c.Recv() } ok = true case 2: // f(i, v) p := make([]R.Value, 2, 2) i := 0 for v, open := c.Recv(); open; i++ { p[0], p[1] = R.ValueOf(i), v f.Call(p) v, open = c.Recv() } ok = true } } } } return }
func (tpl *Template) run(wr io.Writer, defer_out *[][]byte, ctx ...interface{}) (ret bool, err error) { for _, va := range tpl.elems { switch el := va.(type) { case *TxtElem: _, err = wr.Write(el.txt) if err != nil { return } case *VarFunElem: var val reflect.Value val, err = execVarFun(wr, el, ctx, tpl.Strict) if err != nil { return } // Dereferencja zwroconej wartosci dereference(&val) if !val.IsValid() { break } switch vtn := val.Interface().(type) { case Template: // Zagniezdzony szablon err = vtn.Run(wr, ctx...) if err != nil { err = RunErr{el.ln, RUN_NESTED, err} return } case NestedTemplate: // Zagniezdzony szablon z wlasnym kontekstem err = vtn.tpl.Run(wr, vtn.ctx...) if err != nil { err = RunErr{el.ln, RUN_NESTED, err} return } case []byte: // Raw text if el.filt && tpl.EscapeFunc != nil { err = tpl.EscapeFunc(wr, vtn) } else { _, err = wr.Write(vtn) } default: // Inna wartosc if el.filt && tpl.EscapeFunc != nil { // Wysylamy z wykorzystaniem EscapeFunc var buf bytes.Buffer fmt.Fprint(&buf, vtn) err = tpl.EscapeFunc(wr, buf.Bytes()) } else { // Wysylamy _, err = fmt.Fprint(wr, vtn) } } //# 20.17 case *IfElem: var v1, v2 reflect.Value // Parametry musza istniec jesli porownujemy je ze soba. v1, err = execParam(wr, el.arg1, ctx, el.ln, el.cmp != if_nocmp) if err != nil { return } var tf bool if el.cmp == if_nocmp { tf = getBool(v1) } else { v2, err = execParam(wr, el.arg2, ctx, el.ln, true) if err != nil { return } var stat int tf, stat = getCmp(v1, v2, el.cmp) if stat != RUN_OK { err = RunErr{el.ln, stat, nil} return } } // Aby wyswietlic blok if'a tworzymy kopie glownego szablonu. ift := *tpl // W kopii podmieniamy liste elementow na liste wybranego bloku. if tf { ift.elems = el.true_block } else { ift.elems = el.false_block } // Renderujemy szablon wybranego bloku. ret, err = ift.run(wr, defer_out, ctx...) if ret || err != nil { return } case *ForElem: var val reflect.Value val, err = execVarFun(wr, el.arg, ctx, false) if err != nil { return } // Tworzymy kopie glownego szablonu dla blokow for'a. for_tpl := *tpl // Dereferencja argumentu dereference(&val) switch val.Kind() { case reflect.Array, reflect.Slice: val_len := val.Len() if val_len != 0 { for_tpl.elems = el.iter_block // Tworzymy kontekst dla iteracyjnego bloku for local_ctx := make(map[string]interface{}) for_ctx := append(ctx, local_ctx) for ii := 0; ii < val_len; ii++ { ev := val.Index(ii) if ev.IsValid() { local_ctx[el.val] = ev.Interface() } else { local_ctx[el.val] = nil } local_ctx[el.iter] = ii + el.iter_inc ret, err = for_tpl.run(wr, defer_out, for_ctx...) if ret || err != nil { return } } } else { // Pusta tablica for_tpl.elems = el.else_block ret, err = for_tpl.run(wr, defer_out, ctx...) if ret || err != nil { return } } case reflect.Map: if val.Len() != 0 { if el.iter_inc != 0 { err = RunErr{el.ln, RUN_INC_MAP_KEY, nil} return } for_tpl.elems = el.iter_block // Tworzymy kontekst dla iteracyjnego bloku for local_ctx := make(map[string]interface{}) for_ctx := append(ctx, local_ctx) for _, key := range val.MapKeys() { ev := val.MapIndex(key) if ev.IsValid() { local_ctx[el.val] = ev.Interface() } else { local_ctx[el.val] = nil } local_ctx[el.iter] = key.Interface() ret, err = for_tpl.run(wr, defer_out, for_ctx...) if ret || err != nil { return } } } else { // Pusty slownik for_tpl.elems = el.else_block ret, err = for_tpl.run(wr, defer_out, ctx...) if ret || err != nil { return } } case reflect.Chan: for_tpl.elems = el.iter_block // Tworzymy kontekst dla iteracyjnego bloku for local_ctx := make(map[string]interface{}) for_ctx := append(ctx, local_ctx) ii := el.iter_inc for { ev, ok := val.Recv() if !ok { break } if ev.IsValid() { local_ctx[el.val] = ev.Interface() } else { local_ctx[el.val] = nil } local_ctx[el.iter] = ii ret, err = for_tpl.run(wr, defer_out, for_ctx...) if ret || err != nil { return } ii++ } if ii == el.iter_inc { // Nic nie odebralismy z kanalu for_tpl.elems = el.else_block ret, err = for_tpl.run(wr, defer_out, ctx...) if ret || err != nil { return } } case reflect.Invalid: for_tpl.elems = el.else_block ret, err = for_tpl.run(wr, defer_out, ctx...) if ret || err != nil { return } default: // Zmienna jest skalarem, różnym od nil for_tpl.elems = el.iter_block ret, err = for_tpl.run( wr, defer_out, append( ctx, map[string]interface{}{ el.val: val.Interface(), el.iter: nil, }, )..., ) if ret || err != nil { return } } case *ReturnElem: ret = true return case *DeferElem: buf := new(bytes.Buffer) // Tworzymy kopie glonego szablonu dla bloku defer defer_tpl := *tpl // W kopii podmieniamy liste elementow na liste bloku defer defer_tpl.elems = el.defer_block // Uruchamiamy blok defer a jego wyjscie zapisujemy w buforze _, err = defer_tpl.run(buf, defer_out, ctx...) if err != nil { return } // Zapisujemy wynik na stos opoznionego wyjscia *defer_out = append(*defer_out, buf.Bytes()) default: panic(fmt.Sprintln("Blaa!:", el)) panic("tmpl:exec: Unknown element!") } } return }
func (f encFnInfo) kSlice(rv reflect.Value) { ti := f.ti // array may be non-addressable, so we have to manage with care // (don't call rv.Bytes, rv.Slice, etc). // E.g. type struct S{B [2]byte}; // Encode(S{}) will bomb on "panic: slice of unaddressable array". if f.seq != seqTypeArray { if rv.IsNil() { f.ee.EncodeNil() return } // If in this method, then there was no extension function defined. // So it's okay to treat as []byte. if ti.rtid == uint8SliceTypId { f.ee.EncodeStringBytes(c_RAW, rv.Bytes()) return } } rtelem := ti.rt.Elem() l := rv.Len() if rtelem.Kind() == reflect.Uint8 { switch f.seq { case seqTypeArray: // if l == 0 { f.ee.encodeStringBytes(c_RAW, nil) } else if rv.CanAddr() { f.ee.EncodeStringBytes(c_RAW, rv.Slice(0, l).Bytes()) } else { var bs []byte if l <= cap(f.e.b) { bs = f.e.b[:l] } else { bs = make([]byte, l) } reflect.Copy(reflect.ValueOf(bs), rv) // TODO: Test that reflect.Copy works instead of manual one-by-one // for i := 0; i < l; i++ { // bs[i] = byte(rv.Index(i).Uint()) // } f.ee.EncodeStringBytes(c_RAW, bs) } case seqTypeSlice: f.ee.EncodeStringBytes(c_RAW, rv.Bytes()) case seqTypeChan: bs := f.e.b[:0] // do not use range, so that the number of elements encoded // does not change, and encoding does not hang waiting on someone to close chan. // for b := range rv.Interface().(<-chan byte) { // bs = append(bs, b) // } ch := rv.Interface().(<-chan byte) for i := 0; i < l; i++ { bs = append(bs, <-ch) } f.ee.EncodeStringBytes(c_RAW, bs) } return } if ti.mbs { if l%2 == 1 { f.e.errorf("mapBySlice requires even slice length, but got %v", l) return } f.ee.EncodeMapStart(l / 2) } else { f.ee.EncodeArrayStart(l) } e := f.e if l > 0 { for rtelem.Kind() == reflect.Ptr { rtelem = rtelem.Elem() } // if kind is reflect.Interface, do not pre-determine the // encoding type, because preEncodeValue may break it down to // a concrete type and kInterface will bomb. var fn encFn if rtelem.Kind() != reflect.Interface { rtelemid := reflect.ValueOf(rtelem).Pointer() fn = e.getEncFn(rtelemid, rtelem, true, true) } // TODO: Consider perf implication of encoding odd index values as symbols if type is string for j := 0; j < l; j++ { if f.seq == seqTypeChan { if rv2, ok2 := rv.Recv(); ok2 { e.encodeValue(rv2, fn) } } else { e.encodeValue(rv.Index(j), fn) } } } f.ee.EncodeEnd() }
func skipToChannelOffset(c R.Value, offset int) int { for open := true; open && offset > 0; offset-- { _, open = c.Recv() } return offset }