diff --git a/go/buscalls/buscalls.go b/go/buscalls/buscalls.go index 2d7ef190..cbf44903 100644 --- a/go/buscalls/buscalls.go +++ b/go/buscalls/buscalls.go @@ -105,7 +105,7 @@ const ChunkBytes = 512 << 10 // ObjectsPutChunkRequest is one chunk of a put session (design 47 G ยง518, A-21): the object `name` in the store `objects`, // `call` the bundle's id for this put, `seq` from 1 and one more each chunk, `last` true on the last chunk alone, and the -// chunk's bytes. +// chunk's bytes; the first chunk also carries the put's `description` (A-25). type ObjectsPutChunkRequest struct { Objects string `json:"objects"` Name string `json:"name"` @@ -113,6 +113,8 @@ type ObjectsPutChunkRequest struct { Seq uint32 `json:"seq"` Last bool `json:"last,omitempty"` Data []byte `json:"data"` + // Description is the put's, carried on the first chunk alone (design 47 G A-25). + Description string `json:"description,omitempty"` } // ObjectsChunkTaken is the answer to a chunk that is not the last: the sequence taken, or the reason it was not. diff --git a/go/busstate/busstate.go b/go/busstate/busstate.go index f81adfba..6abf2e8e 100644 --- a/go/busstate/busstate.go +++ b/go/busstate/busstate.go @@ -36,7 +36,7 @@ func call[T any](method string, params any) (T, error) { // object, never split over several. func (o Objects) Put(name string, data []byte, description string) (buscalls.ObjectInfo, error) { if len(data) > buscalls.ChunkBytes { - return o.putSession(name, data) + return o.putSession(name, data, description) } return call[buscalls.ObjectInfo](buscalls.ObjectsPut, buscalls.ObjectsPutRequest{Objects: o.local, Name: name, Data: data, Description: description}) diff --git a/go/busstate/session.go b/go/busstate/session.go index fbeee45d..0ba4068f 100644 --- a/go/busstate/session.go +++ b/go/busstate/session.go @@ -25,7 +25,7 @@ func callID() string { // put sends data as a put session: chunks of buscalls.ChunkBytes in order, each answered before the next is sent, the // answer to the last being the put's. -func (o Objects) putSession(name string, data []byte) (buscalls.ObjectInfo, error) { +func (o Objects) putSession(name string, data []byte, description string) (buscalls.ObjectInfo, error) { if err := stdio.RequireCapability(stdio.CapPutSessions); err != nil { return buscalls.ObjectInfo{}, fmt.Errorf("putting %s, larger than one call carries: %w", name, err) } @@ -33,8 +33,11 @@ func (o Objects) putSession(name string, data []byte) (buscalls.ObjectInfo, erro for seq, at := uint32(1), 0; ; seq++ { end := min(at+buscalls.ChunkBytes, len(data)) last := end == len(data) - raw, err := stdio.BusState(buscalls.ObjectsPutChunk, buscalls.ObjectsPutChunkRequest{Objects: o.local, Name: name, Call: id, - Seq: seq, Last: last, Data: data[at:end]}) + req := buscalls.ObjectsPutChunkRequest{Objects: o.local, Name: name, Call: id, Seq: seq, Last: last, Data: data[at:end]} + if seq == 1 { + req.Description = description // the first chunk carries it (design 47 G A-25) + } + raw, err := stdio.BusState(buscalls.ObjectsPutChunk, req) if err != nil { return buscalls.ObjectInfo{}, fmt.Errorf("putting %s, chunk %d: %w", name, seq, err) } diff --git a/go/busstate/session_test.go b/go/busstate/session_test.go index a5bf2eb1..7a9a3691 100644 --- a/go/busstate/session_test.go +++ b/go/busstate/session_test.go @@ -74,7 +74,7 @@ func TestAValueLargerThanOneChunkIsPutAndGotBySession(t *testing.T) { var tampered bool serveRuntime(t, func() { o := ObjectsOf("incoming") - _, putErr = o.Put("big", value, "") + _, putErr = o.Put("big", value, "a big one") d, err := o.Get("big") gotValue, getErr = d.Data, err tampered = true @@ -91,6 +91,9 @@ func TestAValueLargerThanOneChunkIsPutAndGotBySession(t *testing.T) { raw, _ := json.Marshal(p["data"]) var b []byte _ = json.Unmarshal(raw, &b) + if (p["description"] == "a big one") != (p["seq"].(float64) == 1) { + t.Errorf("chunk %v carries the description %v: the first chunk alone does", p["seq"], p["description"]) + } stored = append(stored, b...) seqs = append(seqs, uint32(p["seq"].(float64))) if p["last"] == true {