diff options
Diffstat (limited to 'vendor/github.com/Rhymen/go-whatsapp/binary/encoder.go')
-rw-r--r-- | vendor/github.com/Rhymen/go-whatsapp/binary/encoder.go | 351 |
1 files changed, 0 insertions, 351 deletions
diff --git a/vendor/github.com/Rhymen/go-whatsapp/binary/encoder.go b/vendor/github.com/Rhymen/go-whatsapp/binary/encoder.go deleted file mode 100644 index 59003e7a..00000000 --- a/vendor/github.com/Rhymen/go-whatsapp/binary/encoder.go +++ /dev/null @@ -1,351 +0,0 @@ -package binary - -import ( - "fmt" - "github.com/Rhymen/go-whatsapp/binary/token" - "math" - "strconv" - "strings" -) - -type binaryEncoder struct { - data []byte -} - -func NewEncoder() *binaryEncoder { - return &binaryEncoder{make([]byte, 0)} -} - -func (w *binaryEncoder) GetData() []byte { - return w.data -} - -func (w *binaryEncoder) pushByte(b byte) { - w.data = append(w.data, b) -} - -func (w *binaryEncoder) pushBytes(bytes []byte) { - w.data = append(w.data, bytes...) -} - -func (w *binaryEncoder) pushIntN(value, n int, littleEndian bool) { - for i := 0; i < n; i++ { - var curShift int - if littleEndian { - curShift = i - } else { - curShift = n - i - 1 - } - w.pushByte(byte((value >> uint(curShift*8)) & 0xFF)) - } -} - -func (w *binaryEncoder) pushInt20(value int) { - w.pushBytes([]byte{byte((value >> 16) & 0x0F), byte((value >> 8) & 0xFF), byte(value & 0xFF)}) -} - -func (w *binaryEncoder) pushInt8(value int) { - w.pushIntN(value, 1, false) -} - -func (w *binaryEncoder) pushInt16(value int) { - w.pushIntN(value, 2, false) -} - -func (w *binaryEncoder) pushInt32(value int) { - w.pushIntN(value, 4, false) -} - -func (w *binaryEncoder) pushInt64(value int) { - w.pushIntN(value, 8, false) -} - -func (w *binaryEncoder) pushString(value string) { - w.pushBytes([]byte(value)) -} - -func (w *binaryEncoder) writeByteLength(length int) error { - if length > math.MaxInt32 { - return fmt.Errorf("length is too large: %d", length) - } else if length >= (1 << 20) { - w.pushByte(token.BINARY_32) - w.pushInt32(length) - } else if length >= 256 { - w.pushByte(token.BINARY_20) - w.pushInt20(length) - } else { - w.pushByte(token.BINARY_8) - w.pushInt8(length) - } - - return nil -} - -func (w *binaryEncoder) WriteNode(n Node) error { - numAttributes := 0 - if n.Attributes != nil { - numAttributes = len(n.Attributes) - } - - hasContent := 0 - if n.Content != nil { - hasContent = 1 - } - - w.writeListStart(2*numAttributes + 1 + hasContent) - if err := w.writeString(n.Description, false); err != nil { - return err - } - - if err := w.writeAttributes(n.Attributes); err != nil { - return err - } - - if err := w.writeChildren(n.Content); err != nil { - return err - } - - return nil -} - -func (w *binaryEncoder) writeString(tok string, i bool) error { - if !i && tok == "c.us" { - if err := w.writeToken(token.IndexOfSingleToken("s.whatsapp.net")); err != nil { - return err - } - return nil - } - - tokenIndex := token.IndexOfSingleToken(tok) - if tokenIndex == -1 { - jidSepIndex := strings.Index(tok, "@") - if jidSepIndex < 1 { - w.writeStringRaw(tok) - } else { - w.writeJid(tok[:jidSepIndex], tok[jidSepIndex+1:]) - } - } else { - if tokenIndex < token.SINGLE_BYTE_MAX { - if err := w.writeToken(tokenIndex); err != nil { - return err - } - } else { - singleByteOverflow := tokenIndex - token.SINGLE_BYTE_MAX - dictionaryIndex := singleByteOverflow >> 8 - if dictionaryIndex < 0 || dictionaryIndex > 3 { - return fmt.Errorf("double byte dictionary token out of range: %v", tok) - } - if err := w.writeToken(token.DICTIONARY_0 + dictionaryIndex); err != nil { - return err - } - if err := w.writeToken(singleByteOverflow % 256); err != nil { - return err - } - } - } - - return nil -} - -func (w *binaryEncoder) writeStringRaw(value string) error { - if err := w.writeByteLength(len(value)); err != nil { - return err - } - - w.pushString(value) - - return nil -} - -func (w *binaryEncoder) writeJid(jidLeft, jidRight string) error { - w.pushByte(token.JID_PAIR) - - if jidLeft != "" { - if err := w.writePackedBytes(jidLeft); err != nil { - return err - } - } else { - if err := w.writeToken(token.LIST_EMPTY); err != nil { - return err - } - } - - if err := w.writeString(jidRight, false); err != nil { - return err - } - - return nil -} - -func (w *binaryEncoder) writeToken(tok int) error { - if tok < len(token.SingleByteTokens) { - w.pushByte(byte(tok)) - } else if tok <= 500 { - return fmt.Errorf("invalid token: %d", tok) - } - - return nil -} - -func (w *binaryEncoder) writeAttributes(attributes map[string]string) error { - if attributes == nil { - return nil - } - - for key, val := range attributes { - if val == "" { - continue - } - - if err := w.writeString(key, false); err != nil { - return err - } - - if err := w.writeString(val, false); err != nil { - return err - } - } - - return nil -} - -func (w *binaryEncoder) writeChildren(children interface{}) error { - if children == nil { - return nil - } - - switch childs := children.(type) { - case string: - if err := w.writeString(childs, true); err != nil { - return err - } - case []byte: - if err := w.writeByteLength(len(childs)); err != nil { - return err - } - - w.pushBytes(childs) - case []Node: - w.writeListStart(len(childs)) - for _, n := range childs { - if err := w.WriteNode(n); err != nil { - return err - } - } - default: - return fmt.Errorf("cannot write child of type: %T", children) - } - - return nil -} - -func (w *binaryEncoder) writeListStart(listSize int) { - if listSize == 0 { - w.pushByte(byte(token.LIST_EMPTY)) - } else if listSize < 256 { - w.pushByte(byte(token.LIST_8)) - w.pushInt8(listSize) - } else { - w.pushByte(byte(token.LIST_16)) - w.pushInt16(listSize) - } -} - -func (w *binaryEncoder) writePackedBytes(value string) error { - if err := w.writePackedBytesImpl(value, token.NIBBLE_8); err != nil { - if err := w.writePackedBytesImpl(value, token.HEX_8); err != nil { - return err - } - } - - return nil -} - -func (w *binaryEncoder) writePackedBytesImpl(value string, dataType int) error { - numBytes := len(value) - if numBytes > token.PACKED_MAX { - return fmt.Errorf("too many bytes to pack: %d", numBytes) - } - - w.pushByte(byte(dataType)) - - x := 0 - if numBytes%2 != 0 { - x = 128 - } - w.pushByte(byte(x | int(math.Ceil(float64(numBytes)/2.0)))) - for i, l := 0, numBytes/2; i < l; i++ { - b, err := w.packBytePair(dataType, value[2*i:2*i+1], value[2*i+1:2*i+2]) - if err != nil { - return err - } - - w.pushByte(byte(b)) - } - - if (numBytes % 2) != 0 { - b, err := w.packBytePair(dataType, value[numBytes-1:], "\x00") - if err != nil { - return err - } - - w.pushByte(byte(b)) - } - - return nil -} - -func (w *binaryEncoder) packBytePair(packType int, part1, part2 string) (int, error) { - if packType == token.NIBBLE_8 { - n1, err := packNibble(part1) - if err != nil { - return 0, err - } - - n2, err := packNibble(part2) - if err != nil { - return 0, err - } - - return (n1 << 4) | n2, nil - } else if packType == token.HEX_8 { - n1, err := packHex(part1) - if err != nil { - return 0, err - } - - n2, err := packHex(part2) - if err != nil { - return 0, err - } - - return (n1 << 4) | n2, nil - } else { - return 0, fmt.Errorf("invalid pack type (%d) for byte pair: %s / %s", packType, part1, part2) - } -} - -func packNibble(value string) (int, error) { - if value >= "0" && value <= "9" { - return strconv.Atoi(value) - } else if value == "-" { - return 10, nil - } else if value == "." { - return 11, nil - } else if value == "\x00" { - return 15, nil - } - - return 0, fmt.Errorf("invalid string to pack as nibble: %v", value) -} - -func packHex(value string) (int, error) { - if (value >= "0" && value <= "9") || (value >= "A" && value <= "F") || (value >= "a" && value <= "f") { - d, err := strconv.ParseInt(value, 16, 0) - return int(d), err - } else if value == "\x00" { - return 15, nil - } - - return 0, fmt.Errorf("invalid string to pack as hex: %v", value) -} |