diff --git a/exec/imapservice.js b/exec/imapservice.js index 9bd5bbe7967ea2f30148a6238b7bae23959c9dc5..bb17fd4712150ea93b39bc688a34abfe19cba414 100644 --- a/exec/imapservice.js +++ b/exec/imapservice.js @@ -1307,9 +1307,69 @@ function exit_func() save_cfg(true); } +function binify(seen) +{ + var i; + var ret = {}; + var s; + var base = -1; + var bstr = ''; + var byte; + var bo; + var bit; + + // We don't need to save zeros, delete 'em. + for (i in seen) { + if (seen[i] == 0) + delete seen[i]; + + } + // Get an array of bits to set... + s=Object.keys(seen); + // Convert them to numbers... + for (i in s) + s[i] = parseInt(s[i], 10); + // Sort them... + s = s.sort(function(a,b) { return a-b }); + // Now go through them building up strings... + for (i=0; i<s.length; i++) { + // Starting a new string? + if (bstr == '') { + // Don't start a string for the last bit. + if (i+1 == s.length) + continue; + // If the next bit isn't within 4 bytes, don't bother starting a string + if (s[i+1] > s[i]+32) + continue; + base = s[i]; + bstr = ascii(1); + delete seen[s[i]]; + } + else { + bo = Math.floor((s[i]-base)/8); + while (bstr.length < bo) + bstr += ascii(0); + byte = ascii(bstr[bo]); + bit = (s[i]-base)-(bo*8); + byte |= 1<<bit; + delete seen[s[i]]; + bstr = bstr.substr(0, bo)+ascii(byte); + // Last bit? + if (i+1 == s.length || s[i+1] > s[i]+32) { + ret[base]=base64_encode(bstr); + bstr = ''; + } + } + } + if (Object.keys(ret).length == 0) + return undefined; + return ret; +} + function save_cfg(lck) { var cfg; + var b; var s; if(user.number > 0) { @@ -1320,8 +1380,16 @@ function save_cfg(lck) s=saved_config[sub].Seen; delete saved_config[sub].Seen; cfgfile.iniSetObject(sub,saved_config[sub]); - if(s != undefined) - cfgfile.iniSetObject(sub+'.seen',s); + if(s != undefined) { + // First, try any "binary" Seen compression + b = binify(s); + cfgfile.iniRemoveSection(sub+'.bseen'); + if (b != undefined) + cfgfile.iniSetObject(sub+'.bseen',b); + cfgfile.iniRemoveSection(sub+'.seen'); + if (Object.keys(s).length > 0) + cfgfile.iniSetObject(sub+'.seen',s); + } saved_config[sub].Seen=s; } cfgfile.flush(); @@ -2111,6 +2179,14 @@ function read_cfg(sub, lck) var sec; var seen; var this_sec; + var got_bseen=[]; + var bseen; + var i; + var j; + + var byte; + var bit; + var asc; if(saved_config[sub]==undefined) saved_config[sub]={}; @@ -2128,6 +2204,14 @@ function read_cfg(sub, lck) if(saved_config[this_sec].Seen==null) saved_config[this_sec].Seen={}; } + else if(secs[sec].search(/\.bseen$/)!=-1) { + got_bseen.push(secs[sec]); + this_sec = secs[sec].replace(/(?:\.bseen)+$/,''); + if(saved_config[this_sec]==undefined) + saved_config[this_sec]={}; + if(saved_config[this_sec].Seen==undefined) + saved_config[this_sec].Seen={}; + } else { if(saved_config[secs[sec]] != undefined && saved_config[secs[sec]].Seen != undefined) seen = saved_config[secs[sec]].Seen; @@ -2139,6 +2223,25 @@ function read_cfg(sub, lck) saved_config[secs[sec]].Seen=seen; } } + for (i in got_bseen) { + this_sec = got_bseen[i].replace(/(?:\.bseen)+$/,''); + bseen = cfgfile.iniGetObject(got_bseen[i]); + if (bseen == null) + continue; + for (j in bseen) { + base = parseInt(j, 10); + bstr = base64_decode(bseen[j]); + for (byte = 0; byte < bstr.length; byte++) { + asc = ascii(bstr[byte]); + if (asc == 0) + continue; + for (bit=0; bit<8; bit++) { + if (asc & (1<<bit)) + saved_config[this_sec].Seen[base+(byte*8+bit)]=1; + } + } + } + } if (lck) unlock_cfg();