...
1
2
3
4
5 package mo
6
7 import (
8 "bytes"
9 "encoding/binary"
10 "sort"
11 "strings"
12 )
13
14 type moHeader struct {
15 MagicNumber uint32
16 MajorVersion uint16
17 MinorVersion uint16
18 MsgIdCount uint32
19 MsgIdOffset uint32
20 MsgStrOffset uint32
21 HashSize uint32
22 HashOffset uint32
23 }
24
25 type moStrPos struct {
26 Size uint32
27 Addr uint32
28 }
29
30 func encodeFile(f *File) []byte {
31 hdr := &moHeader{
32 MagicNumber: MoMagicLittleEndian,
33 }
34 data := encodeData(hdr, f)
35 data = append(encodeHeader(hdr), data...)
36 return data
37 }
38
39
40 func encodeData(hdr *moHeader, f *File) []byte {
41 msgList := []Message{f.MimeHeader.toMessage()}
42 for _, v := range f.Messages {
43 if len(v.MsgId) == 0 {
44 continue
45 }
46 if len(v.MsgStr) == 0 && len(v.MsgStrPlural) == 0 {
47 continue
48 }
49 msgList = append(msgList, v)
50 }
51 sort.Slice(msgList, func(i, j int) bool {
52 return msgList[i].less(&msgList[j])
53 })
54
55 var buf bytes.Buffer
56 var msgIdPosList = make([]moStrPos, len(msgList))
57 var msgStrPosList = make([]moStrPos, len(msgList))
58 for i, v := range msgList {
59
60 msgId := encodeMsgId(v)
61 msgIdPosList[i].Addr = uint32(buf.Len() + MoHeaderSize)
62 msgIdPosList[i].Size = uint32(len(msgId))
63 buf.WriteString(msgId)
64
65 msgStr := encodeMsgStr(v)
66 msgStrPosList[i].Addr = uint32(buf.Len() + MoHeaderSize)
67 msgStrPosList[i].Size = uint32(len(msgStr))
68 buf.WriteString(msgStr)
69 }
70
71 hdr.MsgIdOffset = uint32(buf.Len() + MoHeaderSize)
72 binary.Write(&buf, binary.LittleEndian, msgIdPosList)
73 hdr.MsgStrOffset = uint32(buf.Len() + MoHeaderSize)
74 binary.Write(&buf, binary.LittleEndian, msgStrPosList)
75
76 hdr.MsgIdCount = uint32(len(msgList))
77 return buf.Bytes()
78 }
79
80
81 func encodeHeader(hdr *moHeader) []byte {
82 var buf bytes.Buffer
83 binary.Write(&buf, binary.LittleEndian, hdr)
84 return buf.Bytes()
85 }
86
87 func encodeMsgId(v Message) string {
88 if v.MsgContext != "" && v.MsgIdPlural != "" {
89 return v.MsgContext + EotSeparator + v.MsgId + NulSeparator + v.MsgIdPlural
90 }
91 if v.MsgContext != "" && v.MsgIdPlural == "" {
92 return v.MsgContext + EotSeparator + v.MsgId
93 }
94 if v.MsgContext == "" && v.MsgIdPlural != "" {
95 return v.MsgId + NulSeparator + v.MsgIdPlural
96 }
97 return v.MsgId
98 }
99
100 func encodeMsgStr(v Message) string {
101 if v.MsgIdPlural != "" {
102 return strings.Join(v.MsgStrPlural, NulSeparator)
103 }
104 return v.MsgStr
105 }
106
View as plain text