@ -53,7 +53,7 @@ exports.parseNamespaces = function(str, literals) {
else {
result = exports . parseExpr ( str , literals ) ;
vals = [ ] ;
for ( var i = 0 , len = result . length ; i < len ; ++ i ) {
for ( var i = 0 , len = result . length ; i < len ; ++ i ) {
var val = {
prefix : result [ i ] [ 0 ] ,
delimiter : result [ i ] [ 1 ]
@ -61,10 +61,10 @@ exports.parseNamespaces = function(str, literals) {
if ( result [ i ] . length > 2 ) {
// extension data
val . extensions = [ ] ;
for ( var j = 2 , len2 = result [ i ] . length ; j < len2 ; j += 2 ) {
for ( var j = 2 , len2 = result [ i ] . length ; j < len2 ; j += 2 ) {
val . extensions . push ( {
name : result [ i ] [ j ] ,
flags : result [ i ] [ j + 1 ]
flags : result [ i ] [ j + 1 ]
} ) ;
}
}
@ -78,21 +78,42 @@ exports.parseFetchBodies = function(str, literals) {
literals . lp = 0 ;
var result = exports . parseExpr ( str , literals ) ,
bodies ;
for ( var i = 0 , len = result . length ; i < len ; i += 2 ) {
for ( var i = 0 , len = result . length ; i < len ; i += 2 ) {
if ( Array . isArray ( result [ i ] ) ) {
if ( result [ i ] . length === 0 )
result [ i ] . push ( '' ) ;
else if ( result [ i ] . length > 1 ) {
//else if (result[i].length === 2 && typeof result[i][1] === 'number') {
// OK, so ordinarily this is where we'd transform a partial fetch
// key so that it matches up with a key in our request's fetchers object
// but since IMAP sucks, we have no way to match up a partial fetch
// response if less than the number of octets we requested were returned.
//
// Example: We request BODY[TEXT]<0.32>, but BODY[TEXT] is only 16 bytes,
// then we get back: BODY[TEXT]<0> {16}
// This leaves us with no way to find out what the original
// length request was. ARGH!!!^%&#^@#$%&$!
// Because of this and the fact that the server can return requested
// values in any order, I am disabling partial fetches entirely.
// BODY[TEXT]<0.32>
/ * r e s u l t [ i ] [ 0 ] + = ' < ' ;
result [ i ] [ 0 ] += result [ i ] [ 1 ] ; // starting octet
result [ i ] [ 0 ] += '.' ;
if ( typeof result [ i + 1 ] === 'number' )
result [ i ] [ 0 ] += result [ i + 1 ] ;
else if ( typeof
result [ i ] [ 0 ] += '>' ; * /
} else if ( result [ i ] . length > 1 ) {
// HEADER.FIELDS (foo)
result [ i ] [ 0 ] += ' (' ;
result [ i ] [ 0 ] += result [ i ] . slice ( 1 ) . join ( ' ' ) ;
result [ i ] [ 0 ] += ')' ;
}
if ( bodies === undefined )
bodies = [ 'BODY[' + result [ i ] [ 0 ] + ']' , result [ i + 1 ] ] ;
bodies = [ 'BODY[' + result [ i ] [ 0 ] + ']' , result [ i + 1 ] ] ;
else {
bodies . push ( 'BODY[' + result [ i ] [ 0 ] + ']' ) ;
bodies . push ( result [ i + 1 ] ) ;
bodies . push ( result [ i + 1 ] ) ;
}
}
}
@ -102,22 +123,22 @@ exports.parseFetchBodies = function(str, literals) {
exports . parseFetch = function ( str , literals , fetchData ) {
literals . lp = 0 ;
var result = exports . parseExpr ( str , literals ) ;
for ( var i = 0 , len = result . length ; i < len ; i += 2 ) {
for ( var i = 0 , len = result . length ; i < len ; i += 2 ) {
if ( Array . isArray ( result [ i ] ) )
continue ;
result [ i ] = result [ i ] . toUpperCase ( ) ;
if ( result [ i ] === 'UID' )
fetchData . uid = parseInt ( result [ i + 1 ] , 10 ) ;
fetchData . uid = parseInt ( result [ i + 1 ] , 10 ) ;
else if ( result [ i ] === 'INTERNALDATE' )
fetchData . date = result [ i + 1 ] ;
fetchData . date = result [ i + 1 ] ;
else if ( result [ i ] === 'FLAGS' )
fetchData . flags = result [ i + 1 ] . filter ( utils . isNotEmpty ) ;
fetchData . flags = result [ i + 1 ] . filter ( utils . isNotEmpty ) ;
else if ( result [ i ] === 'BODYSTRUCTURE' )
fetchData . structure = exports . parseBodyStructure ( result [ i + 1 ] , literals ) ;
fetchData . structure = exports . parseBodyStructure ( result [ i + 1 ] , literals ) ;
else if ( result [ i ] === 'RFC822.SIZE' )
fetchData . size = parseInt ( result [ i + 1 ] , 10 ) ;
fetchData . size = parseInt ( result [ i + 1 ] , 10 ) ;
else if ( typeof result [ i ] === 'string' ) // simple extensions
fetchData [ result [ i ] . toLowerCase ( ) ] = result [ i + 1 ] ;
fetchData [ result [ i ] . toLowerCase ( ) ] = result [ i + 1 ] ;
}
} ;
@ -140,8 +161,8 @@ exports.parseBodyStructure = function(cur, literals, prefix, partID) {
if ( partLen > next ) {
if ( Array . isArray ( cur [ next ] ) ) {
part . params = { } ;
for ( i = 0 , len = cur [ next ] . length ; i < len ; i += 2 )
part . params [ cur [ next ] [ i ] . toLowerCase ( ) ] = cur [ next ] [ i + 1 ] ;
for ( i = 0 , len = cur [ next ] . length ; i < len ; i += 2 )
part . params [ cur [ next ] [ i ] . toLowerCase ( ) ] = cur [ next ] [ i + 1 ] ;
} else
part . params = cur [ next ] ;
++ next ;
@ -168,8 +189,8 @@ exports.parseBodyStructure = function(cur, literals, prefix, partID) {
}
if ( Array . isArray ( cur [ 2 ] ) ) {
part . params = { } ;
for ( i = 0 , len = cur [ 2 ] . length ; i < len ; i += 2 )
part . params [ cur [ 2 ] [ i ] . toLowerCase ( ) ] = cur [ 2 ] [ i + 1 ] ;
for ( i = 0 , len = cur [ 2 ] . length ; i < len ; i += 2 )
part . params [ cur [ 2 ] [ i ] . toLowerCase ( ) ] = cur [ 2 ] [ i + 1 ] ;
if ( cur [ 1 ] === null )
++ next ;
}
@ -177,7 +198,7 @@ exports.parseBodyStructure = function(cur, literals, prefix, partID) {
// envelope
if ( partLen > next && Array . isArray ( cur [ next ] ) ) {
part . envelope = { } ;
for ( i = 0 , len = cur [ next ] . length ; i < len ; ++ i ) {
for ( i = 0 , len = cur [ next ] . length ; i < len ; ++ i ) {
if ( i === 0 )
part . envelope . date = cur [ next ] [ i ] ;
else if ( i === 1 )
@ -186,7 +207,7 @@ exports.parseBodyStructure = function(cur, literals, prefix, partID) {
var val = cur [ next ] [ i ] ;
if ( Array . isArray ( val ) ) {
var addresses = [ ] , inGroup = false , curGroup ;
for ( var j = 0 , len2 = val . length ; j < len2 ; ++ j ) {
for ( var j = 0 , len2 = val . length ; j < len2 ; ++ j ) {
if ( val [ j ] [ 3 ] === null ) { // start group addresses
inGroup = true ;
curGroup = {
@ -267,8 +288,10 @@ exports.parseStructExtra = function(part, partLen, cur, next) {
disposition . type = cur [ next ] [ 0 ] ;
if ( Array . isArray ( cur [ next ] [ 1 ] ) ) {
disposition . params = { } ;
for ( var i = 0 , len = cur [ next ] [ 1 ] . length ; i < len ; i += 2 )
disposition . params [ cur [ next ] [ 1 ] [ i ] . toLowerCase ( ) ] = cur [ next ] [ 1 ] [ i + 1 ] ;
for ( var i = 0 , len = cur [ next ] [ 1 ] . length , key ; i < len ; i += 2 ) {
key = cur [ next ] [ 1 ] [ i ] . toLowerCase ( ) ;
disposition . params [ key ] = cur [ next ] [ 1 ] [ i + 1 ] ;
}
}
} else if ( cur [ next ] !== null )
disposition . type = cur [ next ] ;
@ -301,36 +324,47 @@ exports.parseStructExtra = function(part, partLen, cur, next) {
exports . parseExpr = function ( o , literals , result , start ) {
start = start || 0 ;
var inQuote = false , lastPos = start - 1 , isTop = false ;
var inQuote = false , lastPos = start - 1 , isTop = false , inLitStart = false ,
val ;
if ( ! result )
result = [ ] ;
if ( typeof o === 'string' ) {
o = { str : o } ;
isTop = true ;
}
for ( var i = start , len = o . str . length ; i < len ; ++ i ) {
for ( var i = start , len = o . str . length ; i < len ; ++ i ) {
if ( ! inQuote ) {
if ( o . str [ i ] === '"' )
inQuote = true ;
else if ( o . str [ i ] === ' ' || o . str [ i ] === ')' || o . str [ i ] === ']' ) {
if ( i - ( lastPos + 1 ) > 0 )
result . push ( exports . convStr ( o . str . substring ( lastPos + 1 , i ) , literals ) ) ;
if ( i - ( lastPos + 1 ) > 0 ) {
val = exports . convStr ( o . str . substring ( lastPos + 1 , i ) , literals ) ;
result . push ( val ) ;
}
if ( ( o . str [ i ] === ')' || o . str [ i ] === ']' ) && ! isTop )
return i ;
lastPos = i ;
} else if ( ( o . str [ i ] === '(' || o . str [ i ] === '[' )
/*&& (i === 0 || !isAlpha(o.str.charCodeAt(i-1)))*/ ) {
} else if ( ( o . str [ i ] === '(' || o . str [ i ] === '[' ) ) {
var innerResult = [ ] ;
i = exports . parseExpr ( o , literals , innerResult , i + 1 ) ;
i = exports . parseExpr ( o , literals , innerResult , i + 1 ) ;
lastPos = i ;
result . push ( innerResult ) ;
}
} / * else if ( i > 0 && o . str [ i ] === '<' && o . str [ i - 1 ] === ']' ) {
lastPos = i ;
inLitStart = true ;
} else if ( o . str [ i ] === '>' && inLitStart ) {
val = exports . convStr ( o . str . substring ( lastPos + 1 , i ) , literals ) ;
result [ result . length - 1 ] . push ( val ) ;
inLitStart = false ;
} * /
} else if ( o . str [ i ] === '"' &&
( o . str [ i - 1 ] &&
( o . str [ i - 1 ] !== '\\' || ( o . str [ i - 2 ] && o . str [ i - 2 ] === '\\' ) ) ) )
( o . str [ i - 1 ] &&
( o . str [ i - 1 ] !== '\\'
|| ( o . str [ i - 2 ] && o . str [ i - 2 ] === '\\' )
) ) )
inQuote = false ;
if ( i + 1 === len && len - ( lastPos + 1 ) > 0 )
result . push ( exports . convStr ( o . str . substring ( lastPos + 1 ) , literals ) ) ;
if ( i + 1 === len && len - ( lastPos + 1 ) > 0 )
result . push ( exports . convStr ( o . str . substring ( lastPos + 1 ) , literals ) ) ;
}
return ( isTop ? result : start ) ;
} ;