id3-go/encodedbytes/util.go

145 wiersze
2.8 KiB
Go
Czysty Zwykły widok Historia

2013-12-19 21:16:01 +00:00
// Copyright 2013 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package encodedbytes
2013-12-19 21:16:01 +00:00
import (
"bytes"
2013-12-19 21:16:01 +00:00
"errors"
2013-12-20 00:15:49 +00:00
iconv "github.com/djimenez/iconv-go"
2013-12-19 21:16:01 +00:00
)
const (
BytesPerInt = 4
SynchByteLength = 7
NormByteLength = 8
2013-12-31 23:38:19 +00:00
NativeEncoding = 3
UTF16NullLength = 2
2013-12-19 21:16:01 +00:00
)
2013-12-20 00:15:49 +00:00
var (
EncodingMap = [...]string{
"ISO-8859-1",
"UTF-16",
"UTF-16BE",
2014-01-01 00:19:43 +00:00
"UTF-8",
2013-12-20 00:15:49 +00:00
}
Decoders = make([]*iconv.Converter, len(EncodingMap))
Encoders = make([]*iconv.Converter, len(EncodingMap))
)
func init() {
n := EncodingForIndex(NativeEncoding)
2013-12-20 00:15:49 +00:00
for i, e := range EncodingMap {
2013-12-31 23:38:19 +00:00
Decoders[i], _ = iconv.NewConverter(e, n)
Encoders[i], _ = iconv.NewConverter(n, e)
2013-12-20 00:15:49 +00:00
}
}
2014-01-23 15:06:16 +00:00
// Form an integer from concatenated bits
2014-01-16 02:03:03 +00:00
func ByteInt(buf []byte, base uint) (i uint32, err error) {
if len(buf) > BytesPerInt {
2013-12-19 21:16:01 +00:00
err = errors.New("byte integer: invalid []byte length")
return
}
for _, b := range buf {
if base < NormByteLength && b >= (1<<base) {
err = errors.New("byte integer: exceed max bit")
return
}
2014-01-16 02:03:03 +00:00
i = (i << base) | uint32(b)
2013-12-19 21:16:01 +00:00
}
return
}
2014-01-16 02:03:03 +00:00
func SynchInt(buf []byte) (i uint32, err error) {
i, err = ByteInt(buf, SynchByteLength)
2013-12-19 21:16:01 +00:00
return
}
2014-01-16 02:03:03 +00:00
func NormInt(buf []byte) (i uint32, err error) {
i, err = ByteInt(buf, NormByteLength)
2013-12-19 21:16:01 +00:00
return
}
2013-12-20 00:15:49 +00:00
2014-01-23 15:06:16 +00:00
// Form a byte slice from an integer
2014-01-16 02:03:03 +00:00
func IntBytes(n uint32, base uint) []byte {
mask := uint32(1<<base - 1)
2013-12-20 06:15:59 +00:00
bytes := make([]byte, BytesPerInt)
for i, _ := range bytes {
bytes[len(bytes)-i-1] = byte(n & mask)
n >>= base
}
return bytes
}
2014-01-16 02:03:03 +00:00
func SynchBytes(n uint32) []byte {
return IntBytes(n, SynchByteLength)
2013-12-20 06:15:59 +00:00
}
2014-01-16 02:03:03 +00:00
func NormBytes(n uint32) []byte {
return IntBytes(n, NormByteLength)
2013-12-20 06:15:59 +00:00
}
func EncodingForIndex(b byte) string {
2013-12-20 00:15:49 +00:00
encodingIndex := int(b)
if encodingIndex < 0 || encodingIndex > len(EncodingMap) {
encodingIndex = 0
}
return EncodingMap[encodingIndex]
}
func IndexForEncoding(e string) byte {
2013-12-20 00:15:49 +00:00
for i, v := range EncodingMap {
if v == e {
return byte(i)
}
}
return 0
}
2013-12-31 23:38:19 +00:00
func afterNullIndex(data []byte, encoding byte) int {
encodingString := EncodingForIndex(encoding)
2013-12-31 23:38:19 +00:00
if encodingString == "UTF-16" || encodingString == "UTF-16BE" {
limit, byteCount := len(data), UTF16NullLength
null := bytes.Repeat([]byte{0x0}, byteCount)
for i, _ := range data[:limit/byteCount] {
atIndex := byteCount * i
afterIndex := atIndex + byteCount
if bytes.Equal(data[atIndex:afterIndex], null) {
return afterIndex
}
}
} else {
if index := bytes.IndexByte(data, 0x00); index >= 0 {
return index + 1
}
}
return -1
}
2013-12-30 07:29:36 +00:00
func EncodedDiff(ea byte, a string, eb byte, b string) (int, error) {
2014-01-05 04:59:45 +00:00
encodedStringA, err := Encoders[ea].ConvertString(a)
2013-12-30 07:29:36 +00:00
if err != nil {
return 0, err
}
2014-01-05 04:59:45 +00:00
encodedStringB, err := Encoders[eb].ConvertString(b)
2013-12-30 07:29:36 +00:00
if err != nil {
return 0, err
}
2014-01-05 04:59:45 +00:00
return len(encodedStringA) - len(encodedStringB), nil
2013-12-30 07:29:36 +00:00
}