author | Alberto Bertogli
<albertito@blitiri.com.ar> 2016-09-17 22:04:20 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2016-10-09 23:51:03 UTC |
parent | e2fdcb370561d4a21a9781bf667fbe6034b80d40 |
internal/protoio/protoio.go | +48 | -0 |
internal/protoio/protoio_test.go | +67 | -0 |
internal/protoio/testpb/dummy.go | +3 | -0 |
internal/protoio/testpb/testpb.pb.go | +53 | -0 |
internal/protoio/testpb/testpb.proto | +8 | -0 |
diff --git a/internal/protoio/protoio.go b/internal/protoio/protoio.go new file mode 100644 index 0000000..d17a98a --- /dev/null +++ b/internal/protoio/protoio.go @@ -0,0 +1,48 @@ +// Package protoio contains I/O functions for protocol buffers. +package protoio + +import ( + "io/ioutil" + "os" + + "blitiri.com.ar/go/chasquid/internal/safeio" + + "github.com/golang/protobuf/proto" +) + +// ReadMessage reads a protocol buffer message from fname, and unmarshalls it +// into pb. +func ReadMessage(fname string, pb proto.Message) error { + in, err := ioutil.ReadFile(fname) + if err != nil { + return err + } + return proto.Unmarshal(in, pb) +} + +// ReadTextMessage reads a text format protocol buffer message from fname, and +// unmarshalls it into pb. +func ReadTextMessage(fname string, pb proto.Message) error { + in, err := ioutil.ReadFile(fname) + if err != nil { + return err + } + return proto.UnmarshalText(string(in), pb) +} + +// WriteMessage marshals pb and atomically writes it into fname. +func WriteMessage(fname string, pb proto.Message, perm os.FileMode) error { + out, err := proto.Marshal(pb) + if err != nil { + return err + } + + return safeio.WriteFile(fname, out, perm) +} + +// WriteTextMessage marshals pb in text format and atomically writes it into +// fname. +func WriteTextMessage(fname string, pb proto.Message, perm os.FileMode) error { + out := proto.MarshalTextString(pb) + return safeio.WriteFile(fname, []byte(out), perm) +} diff --git a/internal/protoio/protoio_test.go b/internal/protoio/protoio_test.go new file mode 100644 index 0000000..7260a00 --- /dev/null +++ b/internal/protoio/protoio_test.go @@ -0,0 +1,67 @@ +package protoio + +import ( + "io/ioutil" + "os" + "testing" + + "blitiri.com.ar/go/chasquid/internal/protoio/testpb" +) + +func mustTempDir(t *testing.T) string { + dir, err := ioutil.TempDir("", "safeio_test") + if err != nil { + t.Fatal(err) + } + + err = os.Chdir(dir) + if err != nil { + t.Fatal(err) + } + + t.Logf("test directory: %q", dir) + + return dir +} + +func TestBin(t *testing.T) { + dir := mustTempDir(t) + pb := &testpb.M{"hola"} + + if err := WriteMessage("f", pb, 0600); err != nil { + t.Error(err) + } + + pb2 := &testpb.M{} + if err := ReadMessage("f", pb2); err != nil { + t.Error(err) + } + if pb.Content != pb2.Content { + t.Errorf("content mismatch, got %q, expected %q", pb2.Content, pb.Content) + } + + if !t.Failed() { + os.RemoveAll(dir) + } +} + +func TestText(t *testing.T) { + dir := mustTempDir(t) + pb := &testpb.M{"hola"} + + if err := WriteTextMessage("f", pb, 0600); err != nil { + t.Error(err) + } + + pb2 := &testpb.M{} + if err := ReadTextMessage("f", pb2); err != nil { + t.Error(err) + } + if pb.Content != pb2.Content { + t.Errorf("content mismatch, got %q, expected %q", pb2.Content, pb.Content) + } + + if !t.Failed() { + os.RemoveAll(dir) + } +} diff --git a/internal/protoio/testpb/dummy.go b/internal/protoio/testpb/dummy.go new file mode 100644 index 0000000..f9c04d1 --- /dev/null +++ b/internal/protoio/testpb/dummy.go @@ -0,0 +1,3 @@ +package testpb + +//go:generate protoc --go_out=. testpb.proto diff --git a/internal/protoio/testpb/testpb.pb.go b/internal/protoio/testpb/testpb.pb.go new file mode 100644 index 0000000..f20e2c4 --- /dev/null +++ b/internal/protoio/testpb/testpb.pb.go @@ -0,0 +1,53 @@ +// Code generated by protoc-gen-go. +// source: testpb.proto +// DO NOT EDIT! + +/* +Package testpb is a generated protocol buffer package. + +It is generated from these files: + testpb.proto + +It has these top-level messages: + M +*/ +package testpb + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type M struct { + Content string `protobuf:"bytes,1,opt,name=content" json:"content,omitempty"` +} + +func (m *M) Reset() { *m = M{} } +func (m *M) String() string { return proto.CompactTextString(m) } +func (*M) ProtoMessage() {} +func (*M) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func init() { + proto.RegisterType((*M)(nil), "testpb.M") +} + +func init() { proto.RegisterFile("testpb.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 69 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x49, 0x2d, 0x2e, + 0x29, 0x48, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x83, 0xf0, 0x94, 0x44, 0xb8, 0x18, + 0x7d, 0x85, 0xf8, 0xb9, 0xd8, 0x93, 0xf3, 0xf3, 0x4a, 0x52, 0xf3, 0x4a, 0x24, 0x18, 0x15, 0x18, + 0x35, 0x38, 0x93, 0xd8, 0xc0, 0x8a, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa9, 0x18, 0x08, + 0x20, 0x34, 0x00, 0x00, 0x00, +} diff --git a/internal/protoio/testpb/testpb.proto b/internal/protoio/testpb/testpb.proto new file mode 100644 index 0000000..a93ffcb --- /dev/null +++ b/internal/protoio/testpb/testpb.proto @@ -0,0 +1,8 @@ + +syntax = "proto3"; + +package testpb; + +message M { + string content = 1; +}