aboutsummaryrefslogtreecommitdiff
path: root/modules/mahonia/translate.go
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mahonia/translate.go')
-rw-r--r--modules/mahonia/translate.go50
1 files changed, 50 insertions, 0 deletions
diff --git a/modules/mahonia/translate.go b/modules/mahonia/translate.go
new file mode 100644
index 00000000..ea415844
--- /dev/null
+++ b/modules/mahonia/translate.go
@@ -0,0 +1,50 @@
+package mahonia
+
+import "unicode/utf8"
+
+// Translate enables a Decoder to implement go-charset's Translator interface.
+func (d Decoder) Translate(data []byte, eof bool) (n int, cdata []byte, err error) {
+ cdata = make([]byte, len(data)+1)
+ destPos := 0
+
+ for n < len(data) {
+ rune, size, status := d(data[n:])
+
+ switch status {
+ case STATE_ONLY:
+ n += size
+ continue
+
+ case NO_ROOM:
+ if !eof {
+ return n, cdata[:destPos], nil
+ }
+ rune = 0xfffd
+ n = len(data)
+
+ default:
+ n += size
+ }
+
+ if rune < 128 {
+ if destPos >= len(cdata) {
+ cdata = doubleLength(cdata)
+ }
+ cdata[destPos] = byte(rune)
+ destPos++
+ } else {
+ if destPos+utf8.RuneLen(rune) > len(cdata) {
+ cdata = doubleLength(cdata)
+ }
+ destPos += utf8.EncodeRune(cdata[destPos:], rune)
+ }
+ }
+
+ return n, cdata[:destPos], nil
+}
+
+func doubleLength(b []byte) []byte {
+ b2 := make([]byte, 2*len(b))
+ copy(b2, b)
+ return b2
+}