From 2879d9d1862a5abd795f4d8c160c0282b0e3ba28 Mon Sep 17 00:00:00 2001 From: Yonah Date: Thu, 19 Mar 2026 00:49:07 +0900 Subject: [PATCH] streamdata: metadata load helper This loads metadata by ident. Signed-off-by: Yonah --- streamdata.go | 18 ++++++++++++++++++ streamdata_test.go | 44 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/streamdata.go b/streamdata.go index a34f864..9188884 100644 --- a/streamdata.go +++ b/streamdata.go @@ -197,3 +197,21 @@ func (c *Channel) Add(ident *Ident, f func(v *VOD, w io.Writer) error) error { return nil } + +// Load loads the metadata of a [VOD] by [Ident] and returns its address. +func (c *Channel) Load(ident *Ident) (*VOD, error) { + var v VOD + if r, err := c.root.Open(path.Join( + channelPathVOD, + ident.String(), + )); err != nil { + return nil, err + } else if err = json.NewDecoder(r).Decode(&v); err != nil { + _ = r.Close() + return nil, err + } else if err = r.Close(); err != nil { + return nil, err + } else { + return &v, nil + } +} diff --git a/streamdata_test.go b/streamdata_test.go index 60ab268..e158648 100644 --- a/streamdata_test.go +++ b/streamdata_test.go @@ -265,7 +265,7 @@ func TestChannelAdd(t *testing.T) { Date: time.Unix(0, 0).UTC(), Category: "\t", } - if err := c.Add(&streamdata.Ident{ + ident := streamdata.Ident{ Serial: 0xfdfdfdfd, Channel: 0xcafe, Data: [streamdata.IdentFFLen]byte{ @@ -275,7 +275,8 @@ func TestChannelAdd(t *testing.T) { 0xf0, 0x0d, 0, 0, 0, 0, 0, 0, }, - }, func(v *streamdata.VOD, w io.Writer) error { + } + if err := c.Add(&ident, func(v *streamdata.VOD, w io.Writer) error { *v = wantVOD _, err := w.Write(wantData) return err @@ -300,11 +301,50 @@ func TestChannelAdd(t *testing.T) { t.Errorf("Add: %#v, want %#v", got, wantVOD) } + if gotVOD, err := c.Load(&ident); err != nil { + t.Fatalf("Load: error = %v", err) + } else if *gotVOD != wantVOD { + t.Errorf("Load: %#v, want %#v", *gotVOD, wantVOD) + } + if gotData, err := os.ReadFile(path.Join(d, "vod", wantIdent+streamdata.ChannelVODSuffix)); err != nil { t.Fatal(err) } else if string(gotData) != string(wantData) { t.Errorf("Add: data = %#v, want %#v", gotData, wantData) } + + if fi, err := os.Stat(path.Join(d, "vod", wantIdent)); err != nil { + t.Fatal(err) + } else if fi.Mode().Perm() != 0444 { + t.Errorf("Perm: %#o", fi.Mode().Perm()) + } + if fi, err := os.Stat(path.Join(d, "vod", wantIdent+streamdata.ChannelVODSuffix)); err != nil { + t.Fatal(err) + } else if fi.Mode().Perm() != 0444 { + t.Errorf("Perm: %#o", fi.Mode().Perm()) + } + + if err := os.Chmod(path.Join(d, "vod", wantIdent), 0); err != nil { + t.Fatal(err) + } + wantErr = &os.PathError{ + Op: "openat", + Path: path.Join("vod", wantIdent), + Err: syscall.EACCES, + } + if _, err := c.Load(&ident); !reflect.DeepEqual(err, wantErr) { + t.Fatalf("(perm) Load: error = %#v, want %#v", err, wantErr) + } + + if err := os.Chmod(path.Join(d, "vod", wantIdent), 0600); err != nil { + t.Fatal(err) + } else if err = os.WriteFile(path.Join(d, "vod", wantIdent), nil, 0); err != nil { + t.Fatal(err) + } + wantErr = io.EOF + if _, err := c.Load(&ident); !reflect.DeepEqual(err, wantErr) { + t.Fatalf("(invalid) Load: error = %#v, want %#v", err, wantErr) + } } func TestErrors(t *testing.T) {