Skip to content

Commit 9258db9

Browse files
committed
Optimization: Only compare boundary markers if length == boundary.Length
Applied improvement to MimeParser and MimeReader
1 parent fa96777 commit 9258db9

File tree

2 files changed

+54
-54
lines changed

2 files changed

+54
-54
lines changed

MimeKit/MimeParser.cs

+27-27
Original file line numberDiff line numberDiff line change
@@ -1239,35 +1239,25 @@ static unsafe bool IsBoundary (byte* text, int length, Boundary boundary, out bo
12391239
{
12401240
final = false;
12411241

1242-
if (boundary.Length > length)
1243-
return false;
1242+
if (boundary.IsMboxMarker) {
1243+
// for mbox markers, we only care about the first 5 characters
1244+
if (length < boundary.Length)
1245+
return false;
1246+
1247+
length = boundary.Length;
1248+
} else {
1249+
// if the length isn't exactly equal to either the normal or final boundary lengths,
1250+
// then this clearly isn't a match
1251+
if (boundary.Length != length && boundary.FinalLength != length)
1252+
return false;
1253+
}
12441254

12451255
fixed (byte* boundaryptr = boundary.Marker) {
12461256
// make sure that the text matches the boundary
1247-
if (!CStringsEqual (text, boundaryptr, boundary.Length))
1257+
if (!CStringsEqual (text, boundaryptr, length))
12481258
return false;
12491259

1250-
// if this is an mbox marker, we're done
1251-
if (boundary.IsMboxMarker) {
1252-
final = true;
1253-
return true;
1254-
}
1255-
1256-
byte* inptr = text + boundary.Length;
1257-
byte* inend = text + length;
1258-
1259-
if (length >= boundary.FinalLength && inptr[0] == (byte) '-' && inptr[1] == (byte) '-') {
1260-
final = true;
1261-
inptr += 2;
1262-
}
1263-
1264-
// the boundary may optionally be followed by lwsp
1265-
while (inptr < inend) {
1266-
if (!(*inptr).IsWhitespace ())
1267-
return false;
1268-
1269-
inptr++;
1270-
}
1260+
final = length == boundary.FinalLength;
12711261
}
12721262

12731263
return true;
@@ -1279,20 +1269,30 @@ unsafe BoundaryType CheckBoundary (int startIndex, byte* start, int length)
12791269
return BoundaryType.None;
12801270

12811271
if (boundaries != null) {
1272+
byte* end = start + length;
12821273
bool final;
12831274

1275+
// ignore trailing whitespace characters
1276+
if (end[-1] == (byte) '\r')
1277+
end--;
1278+
1279+
while (end > start && end[-1].IsWhitespace ())
1280+
end--;
1281+
1282+
int matchLength = (int) (end - start);
1283+
12841284
currentBoundary = boundaries;
12851285

12861286
if (!currentBoundary.IsMboxMarker) {
12871287
// check immediate boundary
1288-
if (IsBoundary (start, length, currentBoundary, out final))
1288+
if (IsBoundary (start, matchLength, currentBoundary, out final))
12891289
return final ? BoundaryType.ImmediateEndBoundary : BoundaryType.ImmediateBoundary;
12901290

12911291
currentBoundary = currentBoundary.Next;
12921292

12931293
// check parent boundaries
12941294
while (currentBoundary != null && !currentBoundary.IsMboxMarker) {
1295-
if (IsBoundary (start, length, currentBoundary, out final))
1295+
if (IsBoundary (start, matchLength, currentBoundary, out final))
12961296
return final ? BoundaryType.ParentEndBoundary : BoundaryType.ParentBoundary;
12971297

12981298
currentBoundary = currentBoundary.Next;
@@ -1303,7 +1303,7 @@ unsafe BoundaryType CheckBoundary (int startIndex, byte* start, int length)
13031303
// now it is time to check the mbox From-marker
13041304
long curOffset = contentEnd > 0 ? GetOffset (startIndex) : contentEnd;
13051305

1306-
if (curOffset >= contentEnd && IsBoundary (start, length, currentBoundary, out final))
1306+
if (curOffset >= contentEnd && IsBoundary (start, matchLength, currentBoundary, out final))
13071307
return BoundaryType.ParentEndBoundary;
13081308
}
13091309
}

MimeKit/MimeReader.cs

+27-27
Original file line numberDiff line numberDiff line change
@@ -1849,35 +1849,25 @@ static unsafe bool IsBoundary (byte* text, int length, Boundary boundary, out bo
18491849
{
18501850
final = false;
18511851

1852-
if (boundary.Length > length)
1853-
return false;
1852+
if (boundary.IsMboxMarker) {
1853+
// for mbox markers, we only care about the first 5 characters
1854+
if (length < boundary.Length)
1855+
return false;
1856+
1857+
length = boundary.Length;
1858+
} else {
1859+
// if the length isn't exactly equal to either the normal or final boundary lengths,
1860+
// then this clearly isn't a match
1861+
if (boundary.Length != length && boundary.FinalLength != length)
1862+
return false;
1863+
}
18541864

18551865
fixed (byte* boundaryptr = boundary.Marker) {
18561866
// make sure that the text matches the boundary
1857-
if (!CStringsEqual (text, boundaryptr, boundary.Length))
1867+
if (!CStringsEqual (text, boundaryptr, length))
18581868
return false;
18591869

1860-
// if this is an mbox marker, we're done
1861-
if (boundary.IsMboxMarker) {
1862-
final = true;
1863-
return true;
1864-
}
1865-
1866-
byte* inptr = text + boundary.Length;
1867-
byte* inend = text + length;
1868-
1869-
if (length >= boundary.FinalLength && inptr[0] == (byte) '-' && inptr[1] == (byte) '-') {
1870-
final = true;
1871-
inptr += 2;
1872-
}
1873-
1874-
// the boundary may optionally be followed by lwsp
1875-
while (inptr < inend) {
1876-
if (!(*inptr).IsWhitespace ())
1877-
return false;
1878-
1879-
inptr++;
1880-
}
1870+
final = length == boundary.FinalLength;
18811871
}
18821872

18831873
return true;
@@ -1889,20 +1879,30 @@ unsafe BoundaryType CheckBoundary (int startIndex, byte* start, int length)
18891879
return BoundaryType.None;
18901880

18911881
if (boundaries != null) {
1882+
byte* end = start + length;
18921883
bool final;
18931884

1885+
// ignore trailing whitespace characters
1886+
if (end[-1] == (byte) '\r')
1887+
end--;
1888+
1889+
while (end > start && end[-1].IsWhitespace ())
1890+
end--;
1891+
1892+
int matchLength = (int) (end - start);
1893+
18941894
currentBoundary = boundaries;
18951895

18961896
if (!currentBoundary.IsMboxMarker) {
18971897
// check immediate boundary
1898-
if (IsBoundary (start, length, currentBoundary, out final))
1898+
if (IsBoundary (start, matchLength, currentBoundary, out final))
18991899
return final ? BoundaryType.ImmediateEndBoundary : BoundaryType.ImmediateBoundary;
19001900

19011901
currentBoundary = currentBoundary.Next;
19021902

19031903
// check parent boundaries
19041904
while (currentBoundary != null && !currentBoundary.IsMboxMarker) {
1905-
if (IsBoundary (start, length, currentBoundary, out final))
1905+
if (IsBoundary (start, matchLength, currentBoundary, out final))
19061906
return final ? BoundaryType.ParentEndBoundary : BoundaryType.ParentBoundary;
19071907

19081908
currentBoundary = currentBoundary.Next;
@@ -1913,7 +1913,7 @@ unsafe BoundaryType CheckBoundary (int startIndex, byte* start, int length)
19131913
// now it is time to check the mbox From-marker
19141914
long curOffset = contentEnd > 0 ? GetOffset (startIndex) : contentEnd;
19151915

1916-
if (curOffset >= contentEnd && IsBoundary (start, length, currentBoundary, out final))
1916+
if (curOffset >= contentEnd && IsBoundary (start, matchLength, currentBoundary, out final))
19171917
return BoundaryType.ParentEndBoundary;
19181918
}
19191919
}

0 commit comments

Comments
 (0)