forked from axigenmessaging/tnefdecoder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtnef.go
154 lines (129 loc) · 3.54 KB
/
tnef.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package tnefdecoder
import (
"strings"
rtf "github.com/linanh/rtfconverter"
)
/**
* may be any value type; when you use it, usualy you know what type has the attribute value so you can do a type assertion
*/
type GenericValue interface{}
type TnefObject struct {
// tnef attributes (extracted from TNEFVersion, OEMCodePage, MessageAttribute) + MAPI attributes (extracted from MessageProps)
Attributes []*Attribute
// attachments extracted from AttachData
Attachments []*Attachment
TextBody []byte
HtmlBody []byte
Encoding string
}
/**
* get an attribute by MAPI ID/TNEF Attribute ID
*/
func (t *TnefObject) GetAttribute(attrId int, attrType string) (attr *Attribute) {
for _, attr = range t.Attributes {
if attr.Id == attrId && attr.Type == attrType {
return
}
}
return nil
}
func (t *TnefObject) GetHtmlBody() []byte {
if t.HtmlBody == nil {
attr := t.GetAttribute(MapiPidTagBodyHtml, "mapi")
if attr != nil {
t.HtmlBody = []byte(attr.GetStringValue())
} else {
t.HtmlBody = []byte("")
}
}
return t.HtmlBody
}
func (t *TnefObject) SetHtmlBody(v []byte) {
t.HtmlBody = v
}
func (t *TnefObject) GetTextBody() []byte {
if t.TextBody == nil {
attr := t.GetAttribute(MapiPidTagBody, "mapi")
if attr != nil {
t.TextBody = []byte(attr.GetStringValue())
} else {
t.TextBody = []byte("")
}
}
return t.TextBody
}
func (t *TnefObject) SetTextBody(v []byte) {
t.TextBody = v
}
/**
* return message class
* If the value of the attMessageClass or attOriginalMessageClass attribute begins with the string "Microsoft Mail v3.0 ",
* the TNEF Reader MUST ignore the "Microsoft Mail v3.0 " prefix when attempting to match the value of the attMessageClass or attOriginalMessageClass
*/
func (t *TnefObject) GetMessageClass() string {
attr := t.GetAttribute(AttMessageClass, "mapped")
messageClass := ""
if attr != nil {
messageClass = attr.GetStringValue()
}
if messageClass == "" {
attr = t.GetAttribute(AttOriginalMessageClass, "mapped")
if attr != nil {
messageClass = attr.GetStringValue()
}
}
messageClass = strings.TrimPrefix(messageClass, "Microsoft Mail v3.0 ")
return messageClass
}
/**
* Value Meaning
* 0x00000000 Undefined body
* 0x00000001 Plain text body
* 0x00000002 Rich Text Format (RTF) compressed body
* 0x00000003 HTML body
* 0x00000004 Clear-signed body
*/
func (t *TnefObject) GetBodyFormat() int {
attr := t.GetAttribute(MapiPidTagNativeBody, "mapi")
if attr != nil {
return attr.GetIntValue()
}
return 0
}
/**
* decode compressed RTF from MapiPidTagRtfCompressed
* if exists, will rewrite TNEF object TEXT / HTML value or add an attachment
*/
func (t *TnefObject) DecodeRtf() {
rtfContentAttr := t.GetAttribute(MapiPidTagRtfCompressed, "mapi")
if rtfContentAttr != nil && len(rtfContentAttr.GetBinaryValue()) > 0 {
/**
* Try to decompress RTF
* @TODO: to check if we can use MapiPidTagNativeBody or MapiPidTagRtfInSync
*/
data, err := rtf.Decompress(rtfContentAttr.GetBinaryValue())
if err == nil {
attachRtf := true
c := rtf.NewConverter()
c.SetBytes(data)
html, err := c.Convert("html")
if err == nil && html != nil && len(html) > 0 {
attachRtf = false
t.SetHtmlBody(html)
} else {
text, err := c.Convert("text")
if err == nil && text != nil && len(text) > 0 {
attachRtf = false
t.SetTextBody(text)
}
}
if attachRtf {
// add the file as attachment
attachment := NewAttachment()
attachment.SetFilename("message.rtf")
attachment.SetData(data)
t.Attachments = append(t.Attachments, attachment)
}
}
}
}