ludc
2023-08-24 56c45e1f4be85d6bbfb3a03437021c6742b32ad9
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
/* 15.2.12.2 Custom File Properties Part */
XMLNS.CUST_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties";
RELS.CUST_PROPS  = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties';
 
var custregex = /<[^>]+>[^<]*/g;
function parse_cust_props(data, opts) {
    var p = {}, name;
    var m = data.match(custregex);
    if(m) for(var i = 0; i != m.length; ++i) {
        var x = m[i], y = parsexmltag(x);
        switch(y[0]) {
            case '<?xml': break;
            case '<Properties':
                if(y.xmlns !== XMLNS.CUST_PROPS) throw "unrecognized xmlns " + y.xmlns;
                if(y.xmlnsvt && y.xmlnsvt !== XMLNS.vt) throw "unrecognized vt " + y.xmlnsvt;
                break;
            case '<property': name = y.name; break;
            case '</property>': name = null; break;
            default: if (x.indexOf('<vt:') === 0) {
                var toks = x.split('>');
                var type = toks[0].substring(4), text = toks[1];
                /* 22.4.2.32 (CT_Variant). Omit the binary types from 22.4 (Variant Types) */
                switch(type) {
                    case 'lpstr': case 'lpwstr': case 'bstr': case 'lpwstr':
                        p[name] = unescapexml(text);
                        break;
                    case 'bool':
                        p[name] = parsexmlbool(text, '<vt:bool>');
                        break;
                    case 'i1': case 'i2': case 'i4': case 'i8': case 'int': case 'uint':
                        p[name] = parseInt(text, 10);
                        break;
                    case 'r4': case 'r8': case 'decimal':
                        p[name] = parseFloat(text);
                        break;
                    case 'filetime': case 'date':
                        p[name] = new Date(text);
                        break;
                    case 'cy': case 'error':
                        p[name] = unescapexml(text);
                        break;
                    default:
                        if(typeof console !== 'undefined') console.warn('Unexpected', x, type, toks);
                }
            } else if(x.substr(0,2) === "</") {
            } else if(opts.WTF) throw new Error(x);
        }
    }
    return p;
}
 
var CUST_PROPS_XML_ROOT = writextag('Properties', null, {
    'xmlns': XMLNS.CUST_PROPS,
    'xmlns:vt': XMLNS.vt
});
 
function write_cust_props(cp, opts) {
    var o = [XML_HEADER, CUST_PROPS_XML_ROOT];
    if(!cp) return o.join("");
    var pid = 1;
    keys(cp).forEach(function custprop(k) { ++pid;
        o[o.length] = (writextag('property', write_vt(cp[k]), {
            'fmtid': '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}',
            'pid': pid,
            'name': k
        }));
    });
    if(o.length>2){ o[o.length] = '</Properties>'; o[1]=o[1].replace("/>",">"); }
    return o.join("");
}