Exemplo n.º 1
0
func main() {
	m1 := &test.Member{
		Name: proto.String("Linus"),
		Age:  proto.Int32(99),
	}
	m1.Skills = []test.Skill{test.Skill_ASM, test.Skill_C}
	m1_data, err := proto.Marshal(m1)
	if err != nil {
		log.Fatal("marshaling error: ", err)
		os.Exit(1)
	}
	fmt.Println("m1:          ", m1)
	fmt.Println("m1.Skills:   ", m1.Skills)
	fmt.Println("actual data: ", m1_data)
	println("=== unmarshalling m1 into m2 ===")

	m2 := &test.Member{}
	proto.Unmarshal(m1_data, m2)
	fmt.Println("m2:          ", m2)

	port := 9090
	fmt.Println("=== END EXAMPLES / SERVER STARTING at %d ===", port)
	service := fmt.Sprintf(":%d", port)
	tcpAddr, err := net.ResolveTCPAddr("ip4", service)
	checkError(err)

	listener, err := net.ListenTCP("tcp", tcpAddr)
	checkError(err)

	for {
		conn, err := listener.Accept()
		checkError(err)

		input := make([]byte, 1024)
		n, err := conn.Read(input)
		input = input[:n]
		fmt.Println("input: ", input)
		club := &test.Club{}
		err = proto.Unmarshal(input, club)
		checkError(err)

		sum := int32(0)
		fmt.Println("len: ", len(club.Member))
		for _, m := range club.Member {
			sum += *m.Age
		}
		avg := float64(sum) / float64(len(club.Member))
		fmt.Printf("avg age: %f   (sum: %d)\n", avg, sum)
		reply := &test.Reply{Average: proto.Float64(avg)}
		out_data, err := proto.Marshal(reply)
		conn.Write(out_data) // don't care about return value
		conn.Close()         // we're finished with this client
	}

}
Exemplo n.º 2
0
Arquivo: client.go Projeto: kr/doozer
func (c *conn) writeT(t *T) os.Error {
	if c.err != nil {
		return c.err
	}

	buf, err := pb.Marshal(t)
	if err != nil {
		return err
	}

	c.err = binary.Write(c.c, binary.BigEndian, int32(len(buf)))
	if c.err != nil {
		return c.err
	}

	for len(buf) > 0 {
		n, err := c.c.Write(buf)
		if err != nil {
			c.err = err
			return err
		}

		buf = buf[n:]
	}

	return nil
}
Exemplo n.º 3
0
func TestMarshalUnmarshalBase64(t *testing.T) {
	var encbuf []byte
	var decbuf []byte
	t.Logf("start with buf %s\n", proto.CompactTextString(&cr))
	t.Log("marshalling protobuf")
	buf, err := proto.Marshal(&cr)
	if err != nil {
		t.Error("marshal error: ", err)
	}
	t.Log("marshalled")
	t.Log("urlencoding")
	t.Logf("need %d size buffer\n", base64.URLEncoding.EncodedLen(len(buf)-1))
	t.Log(buf)
	t.Logf("%v %s\n", buf, buf)
	encbuf = make([]byte, base64.URLEncoding.EncodedLen(len(buf)), base64.URLEncoding.EncodedLen(len(buf)))
	base64.URLEncoding.Encode(encbuf, buf)
	t.Log("urlencoded")
	t.Log("urldecoding")
	t.Logf("need %d size buffer\n", base64.URLEncoding.DecodedLen(len(encbuf)))
	t.Logf("%v %s\n", encbuf, encbuf)
	decbuf = make([]byte, base64.URLEncoding.DecodedLen(len(encbuf)), base64.URLEncoding.DecodedLen(len(encbuf)))
	n, err := base64.URLEncoding.Decode(decbuf, encbuf)
	t.Logf("wrote %d bytes from encbuf to decbuf. len(encbuf)=%d, len(buf)=%d\n", n, len(encbuf), len(buf))
	if err != nil {
		t.Error("urldecode error: ", err)
	}
	t.Log("urldecoded")

	t.Log(buf, decbuf)
	rcr := &CheckResult{}
	t.Log("unmarshalling")
	err = proto.Unmarshal(decbuf, rcr)
	t.Logf("%s\n", proto.CompactTextString(rcr))
}
Exemplo n.º 4
0
func mustMarshal(p interface{}) []byte {
	buf, err := proto.Marshal(p)
	if err != nil {
		panic(err)
	}
	return buf
}
Exemplo n.º 5
0
func (r *run) broadcast(m *msg) {
	if m != nil {
		m.Seqn = &r.seqn
		b, _ := proto.Marshal(m)
		for _, addr := range r.addr {
			r.out <- Packet{addr, b}
		}
	}
}
Exemplo n.º 6
0
Arquivo: server.go Projeto: kr/doozerd
func (c *conn) respond(t *T, flag int32, cc chan bool, r *R) {
	r.Tag = t.Tag
	r.Flags = pb.Int32(flag)
	tag := pb.GetInt32(t.Tag)

	if flag&Done != 0 {
		c.closeTxn(tag)
	}

	if c.poisoned {
		select {
		case cc <- true:
		default:
		}
		return
	}

	buf, err := pb.Marshal(r)
	c.wl.Lock()
	defer c.wl.Unlock()
	if err != nil {
		c.poisoned = true
		select {
		case cc <- true:
		default:
		}
		log.Println(err)
		return
	}

	err = binary.Write(c.c, binary.BigEndian, int32(len(buf)))
	if err != nil {
		c.poisoned = true
		select {
		case cc <- true:
		default:
		}
		log.Println(err)
		return
	}

	for len(buf) > 0 {
		n, err := c.c.Write(buf)
		if err != nil {
			c.poisoned = true
			select {
			case cc <- true:
			default:
			}
			log.Println(err)
			return
		}

		buf = buf[n:]
	}
}
Exemplo n.º 7
0
func DoMarshalling(value interface{}) (key string, data []byte, err os.Error) {
	data, err = proto.Marshal(value)
	if err == nil {
		h := sha256.New()
		nr, err := h.Write([]byte(data))
		if err == nil && nr == len([]byte(data)) {
			key = hex.EncodeToString(h.Sum())
		}
	}
	return
}
Exemplo n.º 8
0
func SendProtobuf(writer io.Writer, pb interface{}) os.Error {
	var data []byte
	var err os.Error
	if data, err = proto.Marshal(pb); err != nil {
		return err
	}
	size := uint64(len(data))
	binary.Write(writer, binary.LittleEndian, size)
	_, err = writer.Write(data)
	return err
}
func (c *context) Call(service, method string, in, out interface{}) os.Error {
	data, err := proto.Marshal(in)
	if err != nil {
		return err
	}
	res, err := call(service, method, data)
	if err != nil {
		return err
	}
	return proto.Unmarshal(res, out)
}
Exemplo n.º 10
0
// Encode returns an opaque representation of the key
// suitable for use in HTML and URLs.
// This is compatible with the Python and Java runtimes.
func (k *Key) Encode() string {
	ref := keyToProto("", k)

	b, err := proto.Marshal(ref)
	if err != nil {
		panic(err)
	}

	// Trailing padding is stripped.
	return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=")
}
Exemplo n.º 11
0
func TestMarshalUnmarshal(t *testing.T) {
	t.Log("marshalling protobuf")
	buf, err := proto.Marshal(&cr)
	if err != nil {
		log.Fatal("marshal error: ", err)
	}
	t.Log("marshalled")
	rcr := new(CheckResult)
	t.Log("unmarshalling")
	err = proto.Unmarshal(buf, rcr)
	t.Log(rcr)
}
Exemplo n.º 12
0
func newTestMessage() *pb.MyMessage {
	msg := &pb.MyMessage{
		Count: proto.Int32(42),
		Name:  proto.String("Dave"),
		Quote: proto.String(`"I didn't want to go."`),
		Pet:   []string{"bunny", "kitty", "horsey"},
		Inner: &pb.InnerMessage{
			Host:      proto.String("footrest.syd"),
			Port:      proto.Int32(7001),
			Connected: proto.Bool(true),
		},
		Others: []*pb.OtherMessage{
			&pb.OtherMessage{
				Key:   proto.Int64(0xdeadbeef),
				Value: []byte{1, 65, 7, 12},
			},
			&pb.OtherMessage{
				Weight: proto.Float32(6.022),
				Inner: &pb.InnerMessage{
					Host: proto.String("lesha.mtv"),
					Port: proto.Int32(8002),
				},
			},
		},
		Bikeshed: pb.NewMyMessage_Color(pb.MyMessage_BLUE),
		Somegroup: &pb.MyMessage_SomeGroup{
			GroupField: proto.Int32(8),
		},
		// One normally wouldn't do this.
		// This is an undeclared tag 13, as a varint (wire type 0) with value 4.
		XXX_unrecognized: []byte{13<<3 | 0, 4},
	}
	ext := &pb.Ext{
		Data: proto.String("Big gobs for big rats"),
	}
	if err := proto.SetExtension(msg, pb.E_Ext_More, ext); err != nil {
		panic(err)
	}

	// Add an unknown extension. We marshal a pb.Ext, and fake the ID.
	b, err := proto.Marshal(&pb.Ext{Data: proto.String("3G skiing")})
	if err != nil {
		panic(err)
	}
	b = append(proto.EncodeVarint(104<<3|proto.WireBytes), b...)
	proto.SetRawExtension(msg, 104, b)

	// Extensions can be plain fields, too, so let's test that.
	b = append(proto.EncodeVarint(105<<3|proto.WireVarint), 19)
	proto.SetRawExtension(msg, 105, b)

	return msg
}
Exemplo n.º 13
0
// Send a protobuf-encoded message
func (c *Client) sendProtoMessage(kind uint16, msg interface{}) (err os.Error) {
	d, err := proto.Marshal(msg)
	if err != nil {
		return
	}

	c.msgchan <- &Message{
		buf:  d,
		kind: kind,
	}

	return
}
Exemplo n.º 14
0
func PrintLocationsAsProto(locations map[string]Location) []byte {
	locProto := &locationProto.LocationInfo{
		make([]*locationProto.Location, len(locations)), nil}
	loc := locProto.Location
	for name, location := range locations {
		loc[0] = &locationProto.Location{
			proto.String(name), proto.Float64(float64(location.lat)), proto.Float64(float64(location.lng)),
			nil, proto.Float64(float64(location.accuracy)), proto.Int64(location.timestamp), nil}
		loc = loc[1:]
	}
	data, _ := proto.Marshal(locProto)
	return data
}
Exemplo n.º 15
0
func (this *PushProtoHandler) UpdatePlayerCoordinate(x, y int) {
	fmt.Printf("Updating player coordinate\n")
	m := NewUpdatePlayerCoord()
	m.Coord = new(Coordinate)
	m.Coord.X = proto.Int32(int32(x))
	m.Coord.Y = proto.Int32(int32(y))
	data, err := proto.Marshal(m)
	if err != nil {
		fmt.Printf("E: %s", err)
		return
	}
	this.Proxy.SendMsg(data, PORT_PUSH, Server_UPDATELOCATION, false)
}
Exemplo n.º 16
0
func (mut *mutation) serialize(writer typedio.Writer) (err os.Error) {
	err = writer.WriteUint16(mut.typ) // type
	if err != nil {
		return
	}

	switch mut.typ {

	case mut_create_vs:
	case mut_commit_vs:
	case mut_rollback_vs:
		err = writer.WriteUint32(mut.vs) // viewstate
		if err != nil {
			return
		}

	case mut_obj_op:
		err = writer.WriteUint16(operation2id(mut.op.(operation))) // operation id
		if err != nil {
			return
		}

		var bytes []uint8
		bytes, err = proto.Marshal(mut.op)
		if err != nil {
			return
		}

		err = writer.WriteUint32(uint32(len(bytes))) // operation size
		if err != nil {
			return
		}

		_, err = writer.Write(bytes) // operation
		if err != nil {
			return
		}

		_, err = writer.Write([]byte{mut.flags}) // flags
		if err != nil {
			return
		}

		err = writer.WriteUint64(mut.lastPos) // object last position
		if err != nil {
			return
		}
	}

	return
}
Exemplo n.º 17
0
// makePingPacket() creates a current ping packet for sending to needle server
func (p *Peer) makePingPacket() []byte {
	p.lk.Lock()
	defer p.lk.Unlock()

	payload := &proto.Ping{
		Id:      &p.id,
		Dialing: p.dials.GetIds(),
	}
	buf, err := pb.Marshal(payload)
	if err != nil {
		return nil
	}
	return buf
}
Exemplo n.º 18
0
// Send permission denied by who, what, where
func (c *Client) sendPermissionDenied(who *Client, where *Channel, what Permission) {
	d, err := proto.Marshal(&mumbleproto.PermissionDenied{
		Permission: proto.Uint32(uint32(what)),
		ChannelId:  proto.Uint32(uint32(where.Id)),
		Session:    proto.Uint32(who.Session),
		Type:       mumbleproto.NewPermissionDenied_DenyType(mumbleproto.PermissionDenied_Permission),
	})
	if err != nil {
		c.Panic(err.String())
	}
	c.msgchan <- &Message{
		buf:  d,
		kind: MessagePermissionDenied,
	}
}
Exemplo n.º 19
0
func (c *conn) write(r *response) error {
	buf, err := proto.Marshal(r)
	if err != nil {
		return err
	}

	c.wl.Lock()
	defer c.wl.Unlock()

	err = binary.Write(c.c, binary.BigEndian, int32(len(buf)))
	if err != nil {
		return err
	}

	_, err = c.c.Write(buf)
	return err
}
Exemplo n.º 20
0
// listenLoop() receives pongs from the needle server and cargo packets from peers
func (p *Peer) listenLoop() {
	for {
		buf := make([]byte, MaxPacketSize)
		n, addr, err := p.conn.ReadFromUDP(buf)
		if err != nil {
			continue
		}
		Logf("Packet from %s/%d\n", addr.String(), n)

		payload := &proto.PeerBound{}
		err = pb.Unmarshal(buf[0:n], payload)
		if err != nil {
			continue
		}

		switch {
		case payload.Pong != nil:
			for _, m := range payload.Pong.Punches {
				// Resolve remote peer
				addr, err := net.ResolveUDPAddr(*m.Address)
				if err != nil {
					break
				}

				// Prepare cargo packet
				payload := &proto.PeerBound{}
				payload.Cargo = &proto.Cargo{}
				payload.Cargo.OriginId = &p.id
				packet, err := pb.Marshal(payload)
				if err != nil {
					break
				}
				// Start sending empty cargos
				go func() {
					for {
						p.conn.WriteToUDP(packet, addr)
						time.Sleep(1e9)
					}
				}()
			}
		case payload.Cargo != nil:
			fmt.Printf("  cargo from %s\n", *payload.Cargo.OriginId)
		}

	}
}
Exemplo n.º 21
0
func sendLearn(out chan<- Packet, p *packet, st *store.Store) {
	if p.msg.Cmd != nil && *p.msg.Cmd == msg_INVITE {
		ch, err := st.Wait(store.Any, *p.Seqn)

		if err == store.ErrTooLate {
			log.Println(err)
		} else {
			e := <-ch
			m := msg{
				Seqn:  &e.Seqn,
				Cmd:   learn,
				Value: []byte(e.Mut),
			}
			buf, _ := proto.Marshal(&m)
			out <- Packet{p.Addr, buf}
		}
	}
}
Exemplo n.º 22
0
func sendMessage(w io.Writer, msg *protocol.Message) os.Error {
	// Marshal protobuf
	bs, err := proto.Marshal(msg)
	if err != nil {
		return err
	}

	// Send pb
	if bs, err = prependByteLength(bs); err != nil {
		return err
	}
	if n, err := w.Write(bs); err != nil {
		return err
	} else if n != len(bs) {
		return os.NewError(fmt.Sprintf("Wrote only %d bytes out of %d bytes!", n, len(bs)))
	}

	return nil
}
Exemplo n.º 23
0
// write writes a protocol buffer to the socketAPI socket.
func write(w *bufio.Writer, pb interface{}) os.Error {
	b, err := proto.Marshal(pb)
	if err != nil {
		return err
	}
	_, err = w.WriteString(strconv.Itoa(len(b)))
	if err != nil {
		return err
	}
	err = w.WriteByte('\n')
	if err != nil {
		return err
	}
	_, err = w.Write(b)
	if err != nil {
		return err
	}
	return w.Flush()
}
Exemplo n.º 24
0
func main() {
	p := example.Person{
		Name: proto.String("Taro Yamada"),
		Age:  proto.Int32(8),
	}

	pet := example.Pet{Name: proto.String("Mike")}
	p.Pet = append(p.Pet, &pet)
	fmt.Println("-- p.String()  --")
	fmt.Println(p.String())
	fmt.Println("-- MarshalText --")
	fmt.Print(PrintToString(&p)) // not compact

	fmt.Println("-- Marshal --")
	m, _ := proto.Marshal(&p)
	fmt.Println(m)

	fmt.Println("-- CompactTextString --")
	fmt.Println(proto.CompactTextString(&p))
}
Exemplo n.º 25
0
// makePongPacket() prepares a pong packet for the given id
func (s *Server) makePongPacket_NL(id string) []byte {
	c, ok := s.peers[id]
	if !ok {
		return nil
	}

	payload := &proto.PeerBound{}
	payload.Pong = &proto.Pong{}

	prep := make(map[string]string)

	for cid, _ := range c.rings {
		a := s.lookupAddr_NL(cid)
		if a == nil {
			continue
		}
		prep[cid] = a.String()
	}

	for did, _ := range c.dials {
		a := s.lookupAddr_NL(did)
		if a == nil {
			continue
		}
		prep[did] = a.String()
	}

	// XXX: Make sure that packet does not exceed allowed size
	payload.Pong.Punches = make([]*proto.PunchPoint, len(prep))
	k := 0
	for pId, pAddr := range prep {
		payload.Pong.Punches[k] = &proto.PunchPoint{Id: &pId, Address: &pAddr}
		k++
	}

	packet, err := pb.Marshal(payload)
	if err != nil {
		return nil
	}
	return packet
}
Exemplo n.º 26
0
// Send permission denied by type (and user)
func (c *Client) sendPermissionDeniedTypeUser(kind string, user *Client) {
	val, ok := mumbleproto.PermissionDenied_DenyType_value[kind]
	if ok {
		pd := &mumbleproto.PermissionDenied{}
		pd.Type = mumbleproto.NewPermissionDenied_DenyType(val)
		if user != nil {
			pd.Session = proto.Uint32(uint32(user.Session))
		}
		d, err := proto.Marshal(pd)
		if err != nil {
			c.Panic(err.String())
			return
		}
		c.msgchan <- &Message{
			buf:  d,
			kind: MessagePermissionDenied,
		}
	} else {
		log.Panic("Unknown permission denied type.")
	}
}
Exemplo n.º 27
0
// Write an mmn.Line to the connection.
func (c *Conn) WriteLine(line *mmn.Line) (err error) {

	var buf []byte
	buf, err = proto.Marshal(line)
	if err != nil {
		panic("Error marshalling protobuf struct.")
	}

	// Write the length of the line.
	lenBuf := proto.EncodeVarint(uint64(len(buf)))
	_, err = c.conn.Write(lenBuf)
	if err != nil {
		c.Close()
	}

	// Write the line.
	_, err = c.conn.Write(buf)
	if err != nil {
		c.Close()
	}

	return
}
Exemplo n.º 28
0
/*
func SubMsg(data []byte, t int32, encap bool) []byte {
        header := NewSubHeader()
        header.Type = proto.Int32(t)
        header.Encap = proto.Bool(encap)
        hdrdata,_ := proto.Marhal(header)
        hdrlen := uint32(len(hdrdata))
        datalen :=  uint32(len(data))
        buf := make([]byte, 8+hdrlen+datalen)
        binary.Write(this.SBuffer, binary.BigEndian, [2]uint32{hdrlen,datalen})
        copy(buf[8:8+len(hdrdata)],hdrdata)
        copy(buf[8+len(hdrdata):-1], data)
        return buf

}
func UnSubMsg(data []byte) (*SubHeader, []byte) {
    var hdrlen uint32
    var datalen uint32
    hdr,err := data[0:8]
    if err != nil  {
        return nil,err
    }
    fmt.Printf("len(data) = %d\n", len(data))
    err = binary.Read(data[0:4], binary.BigEndian, &hdrlen)
        if err != nil { return nil,nil,err }
    err = binary.Read(data[4:8], binary.BigEndian, &datalen)
        if err != nil { return nil,nil,err }
            fmt.Printf("hdrlen=%d, datalen=%d\n", hdrlen, datalen)
    if !(hdrlen < 96 && datalen < 16000 ) {
        return nil,nil,os.ENOMEM
    }
    hdrdata := make(Buf, hdrlen)
    newdata := make(Buf, datalen)
    tmp,err := this.Read(this.Buffer[0:hdrlen])
    if err != nil {
        //this.Conn.Close()
        return nil,nil,err
    }
    copy(hdrdata,tmp)
    header := NewHeader()
    err = proto.Unmarshal(hdrdata, header)
    if err != nil {
        return nil,nil,err
    }
    tmp,err = this.Read(this.Buffer[0:datalen])
    if err != nil {
        return nil,nil,err
    }
    copy(newdata,tmp)


    return header, newdata,nil
}
*/
func (this *ProtoProxy) SendMsg(data []byte, port int32, t int32, encap bool) {
	h := NewHot(func(shared map[string]interface{}) {
		//self := shared["self"].(*GenericHot)
		header := NewHeader()
		header.Type = proto.Int32(t)
		header.Port = proto.Int32(port)
		header.Encap = proto.Bool(encap)
		hdrdata, err := proto.Marshal(header)
		if err != nil {
			fmt.Printf("%s\n", err)
			return
		}
		hdrlen := uint32(len(hdrdata))
		datalen := uint32(len(data))
		binary.Write(this.SBuffer, binary.BigEndian, [2]uint32{hdrlen, datalen})
		copy(this.SBuffer[8:8+len(hdrdata)], hdrdata)
		copy(this.SBuffer[8+len(hdrdata):8+len(hdrdata)+len(data)], data)
		//fmt.Printf("Writing this: [%d]%s\n", len(this.SBuffer[0:hdrlen+len(data)]), this.SBuffer[0:hdrlen+len(data)])
		this.Conn.Write(this.SBuffer[0 : 8+len(hdrdata)+len(data)])
	})
	this.QueryHot(h)

}
Exemplo n.º 29
0
func (c *Conn) mux(errch chan os.Error) {
	txns := make(map[int32]*txn)
	var n int32 // next tag
	var err os.Error

	for {
		select {
		case t := <-c.send:
			// find an unused tag
			for t := txns[n]; t != nil; t = txns[n] {
				n++
			}
			txns[n] = t

			// don't take n's address; it will change
			tag := n
			t.req.Tag = &tag

			var buf []byte
			buf, err = proto.Marshal(&t.req)
			if err != nil {
				txns[n] = nil
				t.err = err
				t.done <- true
				continue
			}

			err = c.write(buf)
			if err != nil {
				goto error
			}
		case buf := <-c.msg:
			var r response
			err = proto.Unmarshal(buf, &r)
			if err != nil {
				log.Print(err)
				continue
			}

			if r.Tag == nil {
				log.Printf("nil tag: %# v", pretty.Formatter(r))
				continue
			}
			t := txns[*r.Tag]
			if t == nil {
				log.Printf("unexpected: %# v", pretty.Formatter(r))
				continue
			}

			txns[*r.Tag] = nil, false
			t.resp = &r
			t.done <- true
		case err = <-errch:
			goto error
		case <-c.stop:
			err = ErrClosed
			goto error
		}
	}

error:
	c.err = err
	for _, t := range txns {
		t.err = err
		t.done <- true
	}
	c.conn.Close()
	close(c.stopped)
}
Exemplo n.º 30
0
func main() {
	flag.Usage = usage
	flag.Parse()
	if *helpShort || *helpLong || flag.NArg() == 0 {
		flag.Usage()
		os.Exit(1)
	}

	fds, err := parser.ParseFiles(flag.Args(), strings.Split(*importPath, ",", -1))
	if err != nil {
		log.Exitf("Failed parsing: %v", err)
	}
	resolver.ResolveSymbols(fds)
	fmt.Println("-----")
	proto.MarshalText(os.Stdout, fds)
	fmt.Println("-----")

	// Find plugin.
	pluginPath := fullPath(*pluginBinary, strings.Split(os.Getenv("PATH"), ":", -1))
	if pluginPath == "" {
		log.Exitf("Failed finding plugin binary %q", *pluginBinary)
	}

	// Start plugin subprocess.
	pluginIn, meOut, err := os.Pipe()
	if err != nil {
		log.Exitf("Failed creating pipe: %v", err)
	}
	meIn, pluginOut, err := os.Pipe()
	if err != nil {
		log.Exitf("Failed creating pipe: %v", err)
	}
	pid, err := os.ForkExec(pluginPath, nil, nil, "/", []*os.File{pluginIn, pluginOut, os.Stderr})
	if err != nil {
		log.Exitf("Failed forking plugin: %v", err)
	}
	pluginIn.Close()
	pluginOut.Close()

	// Send request.
	cgRequest := &plugin.CodeGeneratorRequest{
		FileToGenerate: flag.Args(),
		// TODO: proto_file should be topologically sorted (bottom-up)
		ProtoFile: fds.File,
	}
	buf, err := proto.Marshal(cgRequest)
	if err != nil {
		log.Exitf("Failed marshaling CG request: %v", err)
	}
	_, err = meOut.Write(buf)
	if err != nil {
		log.Exitf("Failed writing CG request: %v", err)
	}
	meOut.Close()

	w, err := os.Wait(pid, 0)
	if err != nil {
		log.Exitf("Failed waiting for plugin: %v", err)
	}
	if w.ExitStatus() != 0 {
		log.Exitf("Plugin exited with status %d", w.ExitStatus())
	}

	// Read response.
	cgResponse := new(plugin.CodeGeneratorResponse)
	if buf, err = ioutil.ReadAll(meIn); err != nil {
		log.Exitf("Failed reading CG response: %v", err)
	}
	if err = proto.Unmarshal(buf, cgResponse); err != nil {
		log.Exitf("Failed unmarshaling CG response: %v", err)
	}

	// TODO: check cgResponse.Error

	// TODO: write files
	for _, f := range cgResponse.File {
		fmt.Printf("--[ %v ]--\n", proto.GetString(f.Name))
		fmt.Println(proto.GetString(f.Content))
	}
	fmt.Println("-----")
}