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.
|
2014-01-12 17:34:04 +00:00
|
|
|
package encodedbytes
|
2013-12-19 21:16:01 +00:00
|
|
|
|
|
|
|
import (
|
2013-12-20 04:23:21 +00:00
|
|
|
"bytes"
|
2013-12-19 21:16:01 +00:00
|
|
|
"errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
BytesPerInt = 4
|
|
|
|
SynchByteLength = 7
|
|
|
|
NormByteLength = 8
|
2013-12-31 23:38:19 +00:00
|
|
|
NativeEncoding = 3
|
2013-12-19 21:16:01 +00:00
|
|
|
)
|
|
|
|
|
2014-05-16 19:24:56 +00:00
|
|
|
type Encoding struct {
|
|
|
|
Name string
|
|
|
|
NullLength int
|
|
|
|
}
|
|
|
|
|
2013-12-20 00:15:49 +00:00
|
|
|
var (
|
2014-05-16 19:24:56 +00:00
|
|
|
EncodingMap = [...]Encoding{
|
|
|
|
{Name: "ISO-8859-1", NullLength: 1},
|
|
|
|
{Name: "UTF-16", NullLength: 2},
|
|
|
|
{Name: "UTF-16BE", NullLength: 2},
|
|
|
|
{Name: "UTF-8", NullLength: 1},
|
2013-12-20 00:15:49 +00:00
|
|
|
}
|
2017-03-25 13:39:14 +00:00
|
|
|
Decoders = make([]*Converter, len(EncodingMap))
|
|
|
|
Encoders = make([]*Converter, len(EncodingMap))
|
2013-12-20 00:15:49 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
2014-01-12 17:34:04 +00:00
|
|
|
n := EncodingForIndex(NativeEncoding)
|
2013-12-20 00:15:49 +00:00
|
|
|
for i, e := range EncodingMap {
|
2017-03-25 13:39:14 +00:00
|
|
|
Decoders[i], _ = NewConverter(e.Name, n)
|
|
|
|
Encoders[i], _ = NewConverter(n, e.Name)
|
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) {
|
2013-12-31 04:01:32 +00:00
|
|
|
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) {
|
2014-01-12 17:34:04 +00:00
|
|
|
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) {
|
2014-01-12 17:34:04 +00:00
|
|
|
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 {
|
2014-01-12 17:34:04 +00:00
|
|
|
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 {
|
2014-01-12 17:34:04 +00:00
|
|
|
return IntBytes(n, NormByteLength)
|
2013-12-20 06:15:59 +00:00
|
|
|
}
|
|
|
|
|
2014-01-12 17:34:04 +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
|
|
|
|
}
|
|
|
|
|
2014-05-16 19:24:56 +00:00
|
|
|
return EncodingMap[encodingIndex].Name
|
|
|
|
}
|
|
|
|
|
|
|
|
func EncodingNullLengthForIndex(b byte) int {
|
|
|
|
encodingIndex := int(b)
|
|
|
|
if encodingIndex < 0 || encodingIndex > len(EncodingMap) {
|
|
|
|
encodingIndex = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
return EncodingMap[encodingIndex].NullLength
|
2013-12-20 00:15:49 +00:00
|
|
|
}
|
|
|
|
|
2014-01-12 17:34:04 +00:00
|
|
|
func IndexForEncoding(e string) byte {
|
2013-12-20 00:15:49 +00:00
|
|
|
for i, v := range EncodingMap {
|
2014-05-16 19:24:56 +00:00
|
|
|
if v.Name == e {
|
2013-12-20 00:15:49 +00:00
|
|
|
return byte(i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0
|
|
|
|
}
|
2013-12-20 04:23:21 +00:00
|
|
|
|
2014-05-16 19:24:56 +00:00
|
|
|
func nullIndex(data []byte, encoding byte) (atIndex, afterIndex int) {
|
|
|
|
byteCount := EncodingNullLengthForIndex(encoding)
|
|
|
|
limit := len(data)
|
|
|
|
null := bytes.Repeat([]byte{0x0}, byteCount)
|
2013-12-20 04:23:21 +00:00
|
|
|
|
2014-05-16 19:24:56 +00:00
|
|
|
for i, _ := range data[:limit/byteCount] {
|
|
|
|
atIndex = byteCount * i
|
|
|
|
afterIndex = atIndex + byteCount
|
2013-12-20 04:23:21 +00:00
|
|
|
|
2014-05-16 19:24:56 +00:00
|
|
|
if bytes.Equal(data[atIndex:afterIndex], null) {
|
|
|
|
return
|
2013-12-20 04:23:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-16 19:24:56 +00:00
|
|
|
atIndex = -1
|
|
|
|
afterIndex = -1
|
|
|
|
return
|
2013-12-20 04:23:21 +00:00
|
|
|
}
|
2013-12-30 07:29:36 +00:00
|
|
|
|
2014-07-05 01:11:23 +00:00
|
|
|
func EncodedDiff(newEncoding byte, newString string, oldEncoding byte, oldString string) (int, error) {
|
|
|
|
newEncodedString, err := Encoders[newEncoding].ConvertString(newString)
|
2013-12-30 07:29:36 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
2014-07-05 01:11:23 +00:00
|
|
|
oldEncodedString, err := Encoders[oldEncoding].ConvertString(oldString)
|
2013-12-30 07:29:36 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
2014-07-05 01:11:23 +00:00
|
|
|
return len(newEncodedString) - len(oldEncodedString), nil
|
2013-12-30 07:29:36 +00:00
|
|
|
}
|