package n9m import ( "bytes" "encoding/json" "log" "github.com/icza/bitio" ) // Read package func (e *Package) ReadPackage() bool { if len(e.Accum) < 12 { return false } r := bitio.NewReader(bytes.NewBuffer(e.Accum)) e.Version = uint8(r.TryReadBits(2)) e.EncryptionFlag = r.TryReadBool() e.CompressFlag = r.TryReadBool() e.CSRCCount = uint8(r.TryReadBits(4)) e.PayloadType = PayloadType(r.TryReadBits(8)) e.SSRC = uint16(r.TryReadBits(16)) if e.EncryptionFlag && e.CompressFlag { // TODO: get snippet, that use this code r.TryReadBits(8 * 4) e.payloadLen = r.TryReadBits(8) r.TryReadBits(3 * 8) if uint64(len(e.Accum)) < e.payloadLen+12 { return false } } else { e.payloadLen = r.TryReadBits(32) // WTF: e.CC is useless for i := uint64(0); i < 1; i++ { e.CSRC[i] = r.TryReadBits(32) } } if e.payloadLen > 1e6 { log.Printf("%v\n", e) log.Panicln("CORRUPTED PACKAGE") } numOfBytes := 0 if e.payloadLen != 0 { e.RawPayload = make([]byte, e.payloadLen) numOfBytes = r.TryRead(e.RawPayload) } else { e.RawPayload = []byte{} } if numOfBytes != int(e.payloadLen) { return false } e.Accum = e.Accum[12+e.payloadLen:] if e.PayloadType == PayloadTypeData { if err := json.Unmarshal(e.RawPayload, &e.Payload); err != nil { log.Printf("Error parsing JSON payload: %v", err) return false } } if r.TryError != nil { log.Printf("TryError encountered: %v", r.TryError) return false } return true } func (e *Package) PackPayload() (err error) { e.RawPayload, err = json.Marshal(e.Payload) e.payloadLen = uint64(len(e.RawPayload)) if e.payloadLen != 0 { e.RawPayload = append(e.RawPayload, 0) e.payloadLen++ } return } func (e *Package) PackPackage() []byte { var err error if err = e.PackPayload(); err != nil { log.Printf("Error while packing payload: %v", err) return []byte{} } return e.PackRawPackage() } func (e *Package) PackRawPackage() []byte { var err error b := &bytes.Buffer{} w := bitio.NewWriter(b) w.TryWriteBits(uint64(e.Version), 2) w.TryWriteBool(e.EncryptionFlag) w.TryWriteBool(e.CompressFlag) w.TryWriteBits(uint64(e.CSRCCount), 4) w.TryWriteBits(uint64(e.PayloadType), 8) w.TryWriteBits(uint64(e.SSRC), 16) w.TryWriteBits(e.payloadLen, 32) // WTF: e.CC is useless for i := uint64(0); i < 1; i++ { w.TryWriteBits(e.CSRC[i], 32) } if e.payloadLen != 0 { w.TryWrite(e.RawPayload) } if err = w.Close(); err != nil { log.Printf("Error while closing writer: %v", err) return []byte{} } return b.Bytes() } func (e *Package) GetParametersAs(parameters any) error { marshal, err := json.Marshal(e.Payload.Parameter) if err != nil { return err } return json.Unmarshal(marshal, parameters) }