summaryrefslogtreecommitdiff
path: root/lib.go
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2020-04-02 00:41:14 +0800
committerxuri <xuri.me@gmail.com>2020-04-05 13:51:00 +0800
commit0f2a9053246c3ae45e6c7ba911a1fb135664abdf (patch)
tree7428d041bcd06956933003598fa56b0b0c246945 /lib.go
parent59f6af21a378fdde21422a92b79a7b03bba313d4 (diff)
Performance improvements
Diffstat (limited to 'lib.go')
-rw-r--r--lib.go42
1 files changed, 40 insertions, 2 deletions
diff --git a/lib.go b/lib.go
index 2d606fa..83cdb4a 100644
--- a/lib.go
+++ b/lib.go
@@ -17,6 +17,7 @@ import (
"log"
"strconv"
"strings"
+ "unsafe"
)
// ReadZipReader can be used to read an XLSX in memory without touching the
@@ -103,7 +104,7 @@ func JoinCellName(col string, row int) (string, error) {
if row < 1 {
return "", newInvalidRowNumberError(row)
}
- return fmt.Sprintf("%s%d", normCol, row), nil
+ return normCol + strconv.Itoa(row), nil
}
// ColumnNameToNumber provides a function to convert Excel sheet column name
@@ -190,6 +191,7 @@ func CoordinatesToCellName(col, row int) (string, error) {
}
colname, err := ColumnNumberToName(col)
if err != nil {
+ // Error should never happens here.
return "", fmt.Errorf("invalid cell coordinates [%d, %d]: %v", col, row, err)
}
return fmt.Sprintf("%s%d", colname, row), nil
@@ -235,11 +237,47 @@ func namespaceStrictToTransitional(content []byte) []byte {
StrictNameSpaceSpreadSheet: NameSpaceSpreadSheet,
}
for s, n := range namespaceTranslationDic {
- content = bytes.Replace(content, []byte(s), []byte(n), -1)
+ content = bytesReplace(content, stringToBytes(s), stringToBytes(n), -1)
}
return content
}
+// stringToBytes cast a string to bytes pointer and assign the value of this
+// pointer.
+func stringToBytes(s string) []byte {
+ return *(*[]byte)(unsafe.Pointer(&s))
+}
+
+// bytesReplace replace old bytes with given new.
+func bytesReplace(s, old, new []byte, n int) []byte {
+ if n == 0 {
+ return s
+ }
+
+ if len(old) < len(new) {
+ return bytes.Replace(s, old, new, n)
+ }
+
+ if n < 0 {
+ n = len(s)
+ }
+
+ var wid, i, j, w int
+ for i, j = 0, 0; i < len(s) && j < n; j++ {
+ wid = bytes.Index(s[i:], old)
+ if wid < 0 {
+ break
+ }
+
+ w += copy(s[w:], s[i:i+wid])
+ w += copy(s[w:], new)
+ i += wid + len(old)
+ }
+
+ w += copy(s[w:], s[i:])
+ return s[0:w]
+}
+
// genSheetPasswd provides a method to generate password for worksheet
// protection by given plaintext. When an Excel sheet is being protected with
// a password, a 16-bit (two byte) long hash is generated. To verify a