package cif import ( "encoding/json" "errors" "io" "git.fjla.uk/owlboard/go-types/pkg/upstreamApi" "git.fjla.uk/owlboard/timetable-mgr/log" "go.uber.org/zap" ) // Accepts the CIF data as a stream and outputs parsed data func parseCifDataStream(dataStream io.ReadCloser) (*ParsedData, error) { defer dataStream.Close() log.Debug("Starting CIF Datastream parsing") if dataStream == nil { return nil, errors.New("unable to parse nil pointer") } var parsed ParsedData parsed.Assoc = make([]upstreamApi.JsonAssociationV1, 0) parsed.Sched = make([]upstreamApi.JsonScheduleV1, 0) // Create JSON Decoder decoder := json.NewDecoder(dataStream) // Iterate over JSON Objects using stream decoder for decoder.More() { var obj map[string]json.RawMessage if err := decoder.Decode(&obj); err != nil { log.Error("Error decoding JSON String") return nil, err } // Handle parsed data for key, value := range obj { switch key { case "JsonTimetableV1": var timetable upstreamApi.JsonTimetableV1 if err := json.Unmarshal(value, &timetable); err != nil { log.Error("Error decoding JSONTimetableV1 object", zap.Error(err)) continue } parsed.Header = timetable case "TiplocV1": // This data is not used and is sourced from CORPUS continue case "JsonAssociationV1": // Association data is not currently used // but may be used in the future continue case "JsonScheduleV1": var schedule upstreamApi.JsonScheduleV1 if err := json.Unmarshal(value, &schedule); err != nil { log.Error("Error decoding JSONScheduleV1 object", zap.Error(err)) continue } parsed.Sched = append(parsed.Sched, schedule) case "EOF": log.Debug("Reached EOF") default: log.Warn("Unknown CIF Data type", zap.String("key", key)) } } } log.Debug("CIF Parsing completed") return &parsed, nil }