mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-02-04 09:15:08 +01:00
repository cleanup
This commit is contained in:
8
common/bfutil/bfutil.go
Normal file
8
common/bfutil/bfutil.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package bfutil
|
||||
|
||||
import "bytes"
|
||||
|
||||
// UpToNull returns the given byte slice's data, up to (not including) the first null byte.
|
||||
func UpToNull(data []byte) []byte {
|
||||
return bytes.SplitN(data, []byte{0x00}, 2)[0]
|
||||
}
|
||||
21
common/byteframe/LICENSE
Normal file
21
common/byteframe/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 Andrew Gutekanst
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
375
common/byteframe/byteframe.go
Normal file
375
common/byteframe/byteframe.go
Normal file
@@ -0,0 +1,375 @@
|
||||
package byteframe
|
||||
|
||||
/*
|
||||
This is HEAVILY based on the code from
|
||||
https://github.com/sinni800/sgemu/blob/master/Core/Packet.go
|
||||
*/
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"math"
|
||||
)
|
||||
|
||||
// ByteFrame is a struct for reading and writing raw byte data.
|
||||
type ByteFrame struct {
|
||||
index uint
|
||||
usedSize uint
|
||||
buf []byte
|
||||
byteOrder binary.ByteOrder
|
||||
}
|
||||
|
||||
// NewByteFrame creates a new ByteFrame with valid default values.
|
||||
// byteOrder defaults to big endian.
|
||||
func NewByteFrame() *ByteFrame {
|
||||
b := &ByteFrame{
|
||||
index: 0,
|
||||
usedSize: 0,
|
||||
buf: make([]byte, 4),
|
||||
byteOrder: binary.BigEndian,
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// NewByteFrameFromBytes creates a new ByteFrame with valid default values.
|
||||
// makes a copy of the given buf and initalizes with it.
|
||||
// byteOrder defaults to big endian.
|
||||
func NewByteFrameFromBytes(buf []byte) *ByteFrame {
|
||||
b := &ByteFrame{
|
||||
index: 0,
|
||||
usedSize: uint(len(buf)),
|
||||
buf: make([]byte, len(buf)),
|
||||
byteOrder: binary.BigEndian,
|
||||
}
|
||||
copy(b.buf, buf)
|
||||
return b
|
||||
}
|
||||
|
||||
// grow either doubles the backing buffer size, or grows it by the size specified, whichever is larger.
|
||||
func (b *ByteFrame) grow(size uint) {
|
||||
bytesToAdd := uint(0)
|
||||
if size > uint(len(b.buf)) {
|
||||
bytesToAdd = size
|
||||
} else {
|
||||
bytesToAdd = uint(len(b.buf))
|
||||
}
|
||||
|
||||
newBuf := make([]byte, uint(len(b.buf))+bytesToAdd)
|
||||
copy(newBuf, b.buf)
|
||||
b.buf = newBuf
|
||||
}
|
||||
|
||||
// wcheck checks if we have enough space to write.
|
||||
func (b *ByteFrame) wcheck(size uint) {
|
||||
if b.index+size > uint(len(b.buf)) {
|
||||
b.grow(size)
|
||||
}
|
||||
}
|
||||
|
||||
// wprologue is a helpler function to update state after a write.
|
||||
func (b *ByteFrame) wprologue(size uint) {
|
||||
|
||||
tmp := int(b.index+size) - int(b.usedSize)
|
||||
if tmp > 0 {
|
||||
b.usedSize += uint(tmp)
|
||||
}
|
||||
|
||||
b.index += size
|
||||
}
|
||||
|
||||
// rcheck checks if we have enough data to read.
|
||||
func (b *ByteFrame) rcheck(size uint) bool {
|
||||
if b.index+size > uint(len(b.buf)) || b.index+size > b.usedSize+1 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (b *ByteFrame) rprologue(size uint) {
|
||||
b.index += size
|
||||
}
|
||||
|
||||
func (b *ByteFrame) rerr() {
|
||||
panic("Error while reading!")
|
||||
}
|
||||
|
||||
// Seek (implements the io.Seeker interface)
|
||||
func (b *ByteFrame) Seek(offset int64, whence int) (int64, error) {
|
||||
switch whence {
|
||||
case io.SeekStart:
|
||||
if offset > int64(b.usedSize) {
|
||||
return int64(b.index), errors.New("cannot seek beyond the max index")
|
||||
}
|
||||
b.index = uint(offset)
|
||||
break
|
||||
case io.SeekCurrent:
|
||||
newPos := int64(b.index) + offset
|
||||
if newPos > int64(b.usedSize) {
|
||||
return int64(b.index), errors.New("cannot seek beyond the max index")
|
||||
} else if newPos < 0 {
|
||||
return int64(b.index), errors.New("cannot seek before the buffer start")
|
||||
}
|
||||
b.index = uint(newPos)
|
||||
break
|
||||
case io.SeekEnd:
|
||||
newPos := int64(b.usedSize) + offset
|
||||
if newPos > int64(b.usedSize) {
|
||||
return int64(b.index), errors.New("cannot seek beyond the max index")
|
||||
} else if newPos < 0 {
|
||||
return int64(b.index), errors.New("cannot seek before the buffer start")
|
||||
}
|
||||
b.index = uint(newPos)
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
return int64(b.index), nil
|
||||
}
|
||||
|
||||
// Data returns the data from the buffer start up to the max index.
|
||||
func (b *ByteFrame) Data() []byte {
|
||||
return b.buf[:b.usedSize]
|
||||
}
|
||||
|
||||
// DataFromCurrent returns the data from the current index up to the max index.
|
||||
func (b *ByteFrame) DataFromCurrent() []byte {
|
||||
return b.buf[b.index:b.usedSize]
|
||||
}
|
||||
|
||||
// SetLE sets the byte order to litte endian.
|
||||
func (b *ByteFrame) SetLE() {
|
||||
b.byteOrder = binary.LittleEndian
|
||||
}
|
||||
|
||||
// SetBE sets the byte order to big endian.
|
||||
func (b *ByteFrame) SetBE() {
|
||||
b.byteOrder = binary.BigEndian
|
||||
}
|
||||
|
||||
// WriteUint8 writes a uint8 at the current index.
|
||||
func (b *ByteFrame) WriteUint8(x uint8) {
|
||||
b.wcheck(1)
|
||||
b.buf[b.index] = x
|
||||
b.wprologue(1)
|
||||
}
|
||||
|
||||
// WriteBool writes a bool at the current index
|
||||
// (1 byte. true -> 1, false -> 0)
|
||||
func (b *ByteFrame) WriteBool(x bool) {
|
||||
if x {
|
||||
b.WriteUint8(1)
|
||||
} else {
|
||||
b.WriteUint8(0)
|
||||
}
|
||||
}
|
||||
|
||||
// WriteUint16 writes a uint16 at the current index.
|
||||
func (b *ByteFrame) WriteUint16(x uint16) {
|
||||
b.wcheck(2)
|
||||
b.byteOrder.PutUint16(b.buf[b.index:], x)
|
||||
b.wprologue(2)
|
||||
}
|
||||
|
||||
// WriteUint32 writes a uint32 at the current index.
|
||||
func (b *ByteFrame) WriteUint32(x uint32) {
|
||||
b.wcheck(4)
|
||||
b.byteOrder.PutUint32(b.buf[b.index:], x)
|
||||
b.wprologue(4)
|
||||
}
|
||||
|
||||
// WriteUint64 writes a uint64 at the current index.
|
||||
func (b *ByteFrame) WriteUint64(x uint64) {
|
||||
b.wcheck(8)
|
||||
b.byteOrder.PutUint64(b.buf[b.index:], x)
|
||||
b.wprologue(8)
|
||||
}
|
||||
|
||||
// WriteInt8 writes a int8 at the current index.
|
||||
func (b *ByteFrame) WriteInt8(x int8) {
|
||||
b.wcheck(1)
|
||||
b.buf[b.index] = byte(x)
|
||||
b.wprologue(1)
|
||||
}
|
||||
|
||||
// WriteInt16 writes a int16 at the current index.
|
||||
func (b *ByteFrame) WriteInt16(x int16) {
|
||||
b.wcheck(2)
|
||||
b.byteOrder.PutUint16(b.buf[b.index:], uint16(x))
|
||||
b.wprologue(2)
|
||||
}
|
||||
|
||||
// WriteInt32 writes a int32 at the current index.
|
||||
func (b *ByteFrame) WriteInt32(x int32) {
|
||||
b.wcheck(4)
|
||||
b.byteOrder.PutUint32(b.buf[b.index:], uint32(x))
|
||||
b.wprologue(4)
|
||||
}
|
||||
|
||||
// WriteInt64 writes a int64 at the current index.
|
||||
func (b *ByteFrame) WriteInt64(x int64) {
|
||||
b.wcheck(8)
|
||||
b.byteOrder.PutUint64(b.buf[b.index:], uint64(x))
|
||||
b.wprologue(8)
|
||||
}
|
||||
|
||||
// WriteFloat32 writes a float32 at the current index.
|
||||
func (b *ByteFrame) WriteFloat32(x float32) {
|
||||
b.wcheck(4)
|
||||
tmp := math.Float32bits(x)
|
||||
b.byteOrder.PutUint32(b.buf[b.index:], tmp)
|
||||
b.wprologue(4)
|
||||
}
|
||||
|
||||
// WriteFloat64 writes a float64 at the current index
|
||||
func (b *ByteFrame) WriteFloat64(x float64) {
|
||||
b.wcheck(8)
|
||||
tmp := math.Float64bits(x)
|
||||
b.byteOrder.PutUint64(b.buf[b.index:], tmp)
|
||||
b.wprologue(8)
|
||||
}
|
||||
|
||||
// WriteBytes writes a slice of bytes at the current index.
|
||||
func (b *ByteFrame) WriteBytes(x []byte) {
|
||||
b.wcheck(uint(len(x)))
|
||||
copy(b.buf[b.index:], x)
|
||||
b.wprologue(uint(len(x)))
|
||||
}
|
||||
|
||||
// WriteNullTerminatedBytes write a slice bytes with an additional NULL terminator.
|
||||
func (b *ByteFrame) WriteNullTerminatedBytes(x []byte) {
|
||||
b.WriteBytes(x)
|
||||
b.WriteUint8(0)
|
||||
}
|
||||
|
||||
// ReadUint8 reads a uint8 at the current index.
|
||||
func (b *ByteFrame) ReadUint8() (x uint8) {
|
||||
if !b.rcheck(1) {
|
||||
b.rerr()
|
||||
}
|
||||
x = uint8(b.buf[b.index])
|
||||
b.rprologue(1)
|
||||
return
|
||||
}
|
||||
|
||||
// ReadBool reads a bool at the current index
|
||||
// (1 byte. b > 0 -> true, b == 0 -> false)
|
||||
func (b *ByteFrame) ReadBool() (x bool) {
|
||||
tmp := b.ReadUint8()
|
||||
x = tmp > 0
|
||||
return
|
||||
}
|
||||
|
||||
// ReadUint16 reads a uint16 at the current index.
|
||||
func (b *ByteFrame) ReadUint16() (x uint16) {
|
||||
if !b.rcheck(2) {
|
||||
b.rerr()
|
||||
}
|
||||
x = b.byteOrder.Uint16(b.buf[b.index:])
|
||||
b.rprologue(2)
|
||||
return
|
||||
}
|
||||
|
||||
// ReadUint32 reads a uint32 at the current index.
|
||||
func (b *ByteFrame) ReadUint32() (x uint32) {
|
||||
if !b.rcheck(4) {
|
||||
b.rerr()
|
||||
}
|
||||
x = b.byteOrder.Uint32(b.buf[b.index:])
|
||||
b.rprologue(4)
|
||||
return
|
||||
}
|
||||
|
||||
// ReadUint64 reads a uint64 at the current index.
|
||||
func (b *ByteFrame) ReadUint64() (x uint64) {
|
||||
if !b.rcheck(8) {
|
||||
b.rerr()
|
||||
}
|
||||
x = b.byteOrder.Uint64(b.buf[b.index:])
|
||||
b.rprologue(8)
|
||||
return
|
||||
}
|
||||
|
||||
// ReadInt8 reads a int8 at the current index.
|
||||
func (b *ByteFrame) ReadInt8() (x int8) {
|
||||
if !b.rcheck(1) {
|
||||
b.rerr()
|
||||
}
|
||||
x = int8(b.buf[b.index])
|
||||
b.rprologue(1)
|
||||
return
|
||||
}
|
||||
|
||||
// ReadInt16 reads a int16 at the current index.
|
||||
func (b *ByteFrame) ReadInt16() (x int16) {
|
||||
if !b.rcheck(2) {
|
||||
b.rerr()
|
||||
}
|
||||
x = int16(b.byteOrder.Uint16(b.buf[b.index:]))
|
||||
b.rprologue(2)
|
||||
return
|
||||
}
|
||||
|
||||
// ReadInt32 reads a int32 at the current index.
|
||||
func (b *ByteFrame) ReadInt32() (x int32) {
|
||||
if !b.rcheck(4) {
|
||||
b.rerr()
|
||||
}
|
||||
x = int32(b.byteOrder.Uint32(b.buf[b.index:]))
|
||||
b.rprologue(4)
|
||||
return
|
||||
}
|
||||
|
||||
// ReadInt64 reads a int64 at the current index.
|
||||
func (b *ByteFrame) ReadInt64() (x int64) {
|
||||
if !b.rcheck(8) {
|
||||
b.rerr()
|
||||
}
|
||||
x = int64(b.byteOrder.Uint64(b.buf[b.index:]))
|
||||
b.rprologue(8)
|
||||
return
|
||||
}
|
||||
|
||||
// ReadFloat32 reads a float32 at the current index.
|
||||
func (b *ByteFrame) ReadFloat32() (x float32) {
|
||||
if !b.rcheck(4) {
|
||||
b.rerr()
|
||||
}
|
||||
x = math.Float32frombits(b.byteOrder.Uint32(b.buf[b.index:]))
|
||||
b.rprologue(4)
|
||||
return
|
||||
}
|
||||
|
||||
// ReadFloat64 reads a float64 at the current index.
|
||||
func (b *ByteFrame) ReadFloat64() (x float64) {
|
||||
if !b.rcheck(8) {
|
||||
b.rerr()
|
||||
}
|
||||
x = math.Float64frombits(b.byteOrder.Uint64(b.buf[b.index:]))
|
||||
b.rprologue(8)
|
||||
return
|
||||
}
|
||||
|
||||
// ReadBytes reads `size` many bytes at the current index.
|
||||
func (b *ByteFrame) ReadBytes(size uint) (x []byte) {
|
||||
if !b.rcheck(size) {
|
||||
b.rerr()
|
||||
}
|
||||
x = b.buf[b.index : b.index+size]
|
||||
b.rprologue(size)
|
||||
return
|
||||
}
|
||||
|
||||
// ReadNullTerminatedBytes reads bytes up to a NULL terminator.
|
||||
func (b *ByteFrame) ReadNullTerminatedBytes() []byte {
|
||||
tmpData := b.DataFromCurrent()
|
||||
tmp := bytes.SplitN(tmpData, []byte{0x00}, 2)[0]
|
||||
|
||||
if len(tmp) == len(tmpData) {
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
b.rprologue(uint(len(tmp)) + 1)
|
||||
return tmp
|
||||
}
|
||||
46
common/pascalstring/pascalstring.go
Normal file
46
common/pascalstring/pascalstring.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package pascalstring
|
||||
|
||||
import (
|
||||
"erupe-ce/common/byteframe"
|
||||
"golang.org/x/text/encoding/japanese"
|
||||
"golang.org/x/text/transform"
|
||||
)
|
||||
|
||||
func Uint8(bf *byteframe.ByteFrame, x string, t bool) {
|
||||
if t {
|
||||
e := japanese.ShiftJIS.NewEncoder()
|
||||
xt, _, err := transform.String(e, x)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
x = xt
|
||||
}
|
||||
bf.WriteUint8(uint8(len(x) + 1))
|
||||
bf.WriteNullTerminatedBytes([]byte(x))
|
||||
}
|
||||
|
||||
func Uint16(bf *byteframe.ByteFrame, x string, t bool) {
|
||||
if t {
|
||||
e := japanese.ShiftJIS.NewEncoder()
|
||||
xt, _, err := transform.String(e, x)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
x = xt
|
||||
}
|
||||
bf.WriteUint16(uint16(len(x) + 1))
|
||||
bf.WriteNullTerminatedBytes([]byte(x))
|
||||
}
|
||||
|
||||
func Uint32(bf *byteframe.ByteFrame, x string, t bool) {
|
||||
if t {
|
||||
e := japanese.ShiftJIS.NewEncoder()
|
||||
xt, _, err := transform.String(e, x)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
x = xt
|
||||
}
|
||||
bf.WriteUint32(uint32(len(x) + 1))
|
||||
bf.WriteNullTerminatedBytes([]byte(x))
|
||||
}
|
||||
52
common/stringstack/stringstack.go
Normal file
52
common/stringstack/stringstack.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package stringstack
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
// StringStack is a basic LIFO "stack" for storing strings.
|
||||
type StringStack struct {
|
||||
Locked bool
|
||||
stack []string
|
||||
}
|
||||
|
||||
// New creates a new instance of StringStack
|
||||
func New() *StringStack {
|
||||
return &StringStack{Locked: false}
|
||||
}
|
||||
|
||||
// Set sets up a new StringStack
|
||||
func (s *StringStack) Set(v string) {
|
||||
s.stack = []string{v}
|
||||
}
|
||||
|
||||
// Lock freezes the StringStack
|
||||
func (s *StringStack) Lock() {
|
||||
if !s.Locked {
|
||||
s.Locked = true
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock unfreezes the StringStack
|
||||
func (s *StringStack) Unlock() {
|
||||
if s.Locked {
|
||||
s.Locked = false
|
||||
}
|
||||
}
|
||||
|
||||
// Push pushes a string onto the stack.
|
||||
func (s *StringStack) Push(v string) {
|
||||
s.stack = append(s.stack, v)
|
||||
}
|
||||
|
||||
// Pop pops a string from the stack.
|
||||
func (s *StringStack) Pop() (string, error) {
|
||||
if len(s.stack) == 0 {
|
||||
return "", errors.New("no items on stack")
|
||||
}
|
||||
|
||||
x := s.stack[len(s.stack)-1]
|
||||
s.stack = s.stack[:len(s.stack)-1]
|
||||
|
||||
return x, nil
|
||||
}
|
||||
186
common/stringsupport/string_convert.go
Normal file
186
common/stringsupport/string_convert.go
Normal file
@@ -0,0 +1,186 @@
|
||||
package stringsupport
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/text/encoding"
|
||||
"golang.org/x/text/encoding/japanese"
|
||||
"golang.org/x/text/transform"
|
||||
)
|
||||
|
||||
// StringConverter is a small helper for encoding/decoding strings.
|
||||
type StringConverter struct {
|
||||
Encoding encoding.Encoding
|
||||
}
|
||||
|
||||
// Decode decodes the given bytes as the set encoding.
|
||||
func (sc *StringConverter) Decode(data []byte) (string, error) {
|
||||
decoded, err := ioutil.ReadAll(transform.NewReader(bytes.NewBuffer(data), sc.Encoding.NewDecoder()))
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(decoded), nil
|
||||
}
|
||||
|
||||
// MustDecode decodes the given bytes as the set encoding. Panics on decode failure.
|
||||
func (sc *StringConverter) MustDecode(data []byte) string {
|
||||
decoded, err := sc.Decode(data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return decoded
|
||||
}
|
||||
|
||||
// Encode encodes the given string as the set encoding.
|
||||
func (sc *StringConverter) Encode(data string) ([]byte, error) {
|
||||
encoded, err := ioutil.ReadAll(transform.NewReader(bytes.NewBuffer([]byte(data)), sc.Encoding.NewEncoder()))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return encoded, nil
|
||||
}
|
||||
|
||||
// MustEncode encodes the given string as the set encoding. Panics on encode failure.
|
||||
func (sc *StringConverter) MustEncode(data string) []byte {
|
||||
encoded, err := sc.Encode(data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return encoded
|
||||
}
|
||||
|
||||
/*
|
||||
func MustConvertShiftJISToUTF8(text string) string {
|
||||
result, err := ConvertShiftJISToUTF8(text)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return result
|
||||
}
|
||||
func MustConvertUTF8ToShiftJIS(text string) string {
|
||||
result, err := ConvertUTF8ToShiftJIS(text)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return result
|
||||
}
|
||||
func ConvertShiftJISToUTF8(text string) (string, error) {
|
||||
r := bytes.NewBuffer([]byte(text))
|
||||
decoded, err := ioutil.ReadAll(transform.NewReader(r, japanese.ShiftJIS.NewDecoder()))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(decoded), nil
|
||||
}
|
||||
*/
|
||||
|
||||
func UTF8ToSJIS(x string) []byte {
|
||||
e := japanese.ShiftJIS.NewEncoder()
|
||||
xt, _, err := transform.String(e, x)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return []byte(xt)
|
||||
}
|
||||
|
||||
func SJISToUTF8(b []byte) string {
|
||||
d := japanese.ShiftJIS.NewDecoder()
|
||||
result, err := ioutil.ReadAll(transform.NewReader(bytes.NewReader(b), d))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(result)
|
||||
}
|
||||
|
||||
func PaddedString(x string, size uint, t bool) []byte {
|
||||
if t {
|
||||
e := japanese.ShiftJIS.NewEncoder()
|
||||
xt, _, err := transform.String(e, x)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
x = xt
|
||||
}
|
||||
out := make([]byte, size)
|
||||
copy(out, x)
|
||||
out[len(out)-1] = 0
|
||||
return out
|
||||
}
|
||||
|
||||
func CSVAdd(csv string, v int) string {
|
||||
if len(csv) == 0 {
|
||||
return strconv.Itoa(v)
|
||||
}
|
||||
return csv + "," + strconv.Itoa(v)
|
||||
}
|
||||
|
||||
func CSVRemove(csv string, v int) string {
|
||||
s := strings.Split(csv, ",")
|
||||
for i, e := range s {
|
||||
if e == strconv.Itoa(v) {
|
||||
s[i] = s[len(s)-1]
|
||||
s = s[:len(s)-1]
|
||||
}
|
||||
}
|
||||
return strings.Join(s, ",")
|
||||
}
|
||||
|
||||
func CSVContains(csv string, v int) bool {
|
||||
s := strings.Split(csv, ",")
|
||||
for i := 0; i < len(s); i++ {
|
||||
j, _ := strconv.ParseInt(s[i], 10, 64)
|
||||
if int(j) == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func CSVLength(csv string) int {
|
||||
if csv == "" {
|
||||
return 0
|
||||
}
|
||||
s := strings.Split(csv, ",")
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func CSVElems(csv string) []int {
|
||||
var r []int
|
||||
if csv == "" {
|
||||
return r
|
||||
}
|
||||
s := strings.Split(csv, ",")
|
||||
for i := 0; i < len(s); i++ {
|
||||
j, _ := strconv.ParseInt(s[i], 10, 64)
|
||||
r = append(r, int(j))
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// ConvertUTF8ToShiftJIS converts a UTF8 string to a Shift-JIS []byte.
|
||||
func ConvertUTF8ToShiftJIS(text string) ([]byte, error) {
|
||||
r := bytes.NewBuffer([]byte(text))
|
||||
encoded, err := ioutil.ReadAll(transform.NewReader(r, japanese.ShiftJIS.NewEncoder()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return encoded, nil
|
||||
}
|
||||
|
||||
func ConvertUTF8ToSJIS(text string) (string, error) {
|
||||
r, _, err := transform.String(japanese.ShiftJIS.NewEncoder(), text)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
Reference in New Issue
Block a user