package sip2 import ( "log" "strconv" "strings" ) const ( yes string = "Y" trueVal string = "1" okVal string = "ok" language string = "language" patronStatus string = "patron status" date string = "transaction date" patronIdentifier string = "patron identifier" patronPassword string = "patron password" personalName string = "personal name" screenMessage string = "screen message" institutionID string = "institution id" validPatron string = "valid patron" validPatronPassword string = "valid patron password" loginResponse string = "Login Response" patronStatusResponse string = "Patron Status Response" ) type fixedFieldSpec struct { length int label string } type fixedField struct { spec fixedFieldSpec value string } type variableFieldSpec struct { id string label string } type variableField struct { spec variableFieldSpec value string } type messageSpec struct { id int label string fields []fixedFieldSpec } type message struct { fields []variableField fixedFields []fixedField msgTxt string } type Parser struct { msgByCodeMap map[int]messageSpec variableFieldByCodeMap map[string]variableFieldSpec } func getParser() *Parser { languageSpec := fixedFieldSpec{3, language} patronStatusSpec := fixedFieldSpec{14, patronStatus} dateSpec := fixedFieldSpec{18, date} okSpec := fixedFieldSpec{1, okVal} msgByCodeMap := map[int]messageSpec{ 94: messageSpec{94, loginResponse, []fixedFieldSpec{okSpec}}, 24: messageSpec{24, patronStatusResponse, []fixedFieldSpec{patronStatusSpec, languageSpec, dateSpec}}, } variableFieldByCodeMap := map[string]variableFieldSpec{ "AA": variableFieldSpec{"AA", patronIdentifier}, "AD": variableFieldSpec{"AD", patronPassword}, "AE": variableFieldSpec{"AE", personalName}, "AF": variableFieldSpec{"AF", screenMessage}, "AO": variableFieldSpec{"AO", institutionID}, "BL": variableFieldSpec{"BL", validPatron}, "CQ": variableFieldSpec{"CQ", validPatronPassword}, } return &Parser{msgByCodeMap, variableFieldByCodeMap} } func (p *Parser) getMessageSpecByCode(code int) messageSpec { return p.msgByCodeMap[code] } func (p *Parser) getVariableFieldByCode(code string) variableFieldSpec { return p.variableFieldByCodeMap[code] } func (p *Parser) getFixedFieldValue(msg *message, field string) (string, bool) { for _, v := range msg.fixedFields { if v.spec.label == field { return v.value, true } } return "", false } func (p *Parser) getFieldValue(msg *message, field string) (string, bool) { for _, v := range msg.fields { if v.spec.label == field { return v.value, true } } return "", false } func (p *Parser) parseMessage(msg string) *message { txt := msg[:len(msg)-len(telnetTerminator)] code, err := strconv.Atoi(txt[:2]) if nil != err { log.Printf("Error parsing integer: %s\n", txt[:2]) } spec := p.getMessageSpecByCode(code) txt = txt[2:] message := new(message) for _, sp := range spec.fields { value := txt[:sp.length] txt = txt[sp.length:] message.fixedFields = append(message.fixedFields, fixedField{sp, value}) } if len(txt) == 0 { return message } for _, part := range strings.Split(txt, "|") { if len(part) > 0 { partSpec := p.getVariableFieldByCode(part[:2]) value := part[2:] message.fields = append(message.fields, variableField{partSpec, value}) } } return message }