From c96d3eec0c4cce736bf32252afadc89a32ee10d5 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Wed, 22 Feb 2017 16:05:18 +0000 Subject: [PATCH] Marshal and Unmarshal methods for roomserver input api (#16) * Marshal and Unmarshal methods for roomserver input api * Comments for why we don't json.marshal the InputRoomEvent directly * More comments * s/m.room.create/the first event/ --- .../dendrite/roomserver/api/input.go | 58 +++++++++++++++++++ .../dendrite/roomserver/input/events.go | 9 ++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/github.com/matrix-org/dendrite/roomserver/api/input.go b/src/github.com/matrix-org/dendrite/roomserver/api/input.go index fd177b19d..ad32286ab 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/api/input.go +++ b/src/github.com/matrix-org/dendrite/roomserver/api/input.go @@ -1,6 +1,10 @@ // Package api provides the types that are used to communicate with the roomserver. package api +import ( + "encoding/json" +) + const ( // KindOutlier event fall outside the contiguous event graph. // We do not have the state for these events. @@ -36,7 +40,61 @@ type InputRoomEvent struct { // For example many matrix events forget to reference the m.room.create event even though it is needed for auth. // (since synapse allows this to happen we have to allow it as well.) AuthEventIDs []string + // Whether the state is supplied as a list of event IDs or whether it + // should be derived from the state at the previous events. + HasState bool // Optional list of state event IDs forming the state before this event. // These state events must have already been persisted. + // These are only used if HasState is true. + // The list can be empty, for example when storing the first event in a room. StateEventIDs []string } + +// UnmarshalJSON implements json.Unmarshaller +func (ire *InputRoomEvent) UnmarshalJSON(data []byte) error { + // Create a struct rather than unmarshalling directly into the InputRoomEvent + // so that we can use json.RawMessage. + // We use json.RawMessage so that the event JSON is sent as JSON rather than + // being base64 encoded which is the default for []byte. + var content struct { + Kind int + Event *json.RawMessage + AuthEventIDs []string + StateEventIDs []string + HasState bool + } + if err := json.Unmarshal(data, &content); err != nil { + return err + } + ire.Kind = content.Kind + ire.AuthEventIDs = content.AuthEventIDs + ire.StateEventIDs = content.StateEventIDs + ire.HasState = content.HasState + if content.Event != nil { + ire.Event = []byte(*content.Event) + } + return nil +} + +// MarshalJSON implements json.Marshaller +func (ire InputRoomEvent) MarshalJSON() ([]byte, error) { + // Create a struct rather than marshalling directly from the InputRoomEvent + // so that we can use json.RawMessage. + // We use json.RawMessage so that the event JSON is sent as JSON rather than + // being base64 encoded which is the default for []byte. + event := json.RawMessage(ire.Event) + content := struct { + Kind int + Event *json.RawMessage + AuthEventIDs []string + StateEventIDs []string + HasState bool + }{ + Kind: ire.Kind, + AuthEventIDs: ire.AuthEventIDs, + StateEventIDs: ire.StateEventIDs, + Event: &event, + HasState: ire.HasState, + } + return json.Marshal(&content) +} diff --git a/src/github.com/matrix-org/dendrite/roomserver/input/events.go b/src/github.com/matrix-org/dendrite/roomserver/input/events.go index e146d5734..91999916e 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/input/events.go +++ b/src/github.com/matrix-org/dendrite/roomserver/input/events.go @@ -69,7 +69,7 @@ func processRoomEvent(db RoomEventDatabase, input api.InputRoomEvent) error { if stateAtEvent.BeforeStateSnapshotNID == 0 { // We haven't calculated a state for this event yet. // Lets calculate one. - if input.StateEventIDs != nil { + if input.HasState { // We've been told what the state at the event is so we don't need to calculate it. // Check that those state events are in the database and store the state. entries, err := db.StateEntriesForEventIDs(input.StateEventIDs) @@ -89,6 +89,11 @@ func processRoomEvent(db RoomEventDatabase, input api.InputRoomEvent) error { db.SetState(stateAtEvent.EventNID, stateAtEvent.BeforeStateSnapshotNID) } + if input.Kind == api.KindBackfill { + // Backfill is not implemented. + panic("Not implemented") + } + // Update the extremities of the event graph for the room if err := updateLatestEvents(db, roomNID, stateAtEvent, event); err != nil { return err @@ -102,5 +107,5 @@ func processRoomEvent(db RoomEventDatabase, input api.InputRoomEvent) error { // - The event itself // - The visiblity of the event, i.e. who is allowed to see the event. // - The changes to the current state of the room. - panic("Not implemented") + return nil }