Merge branch 'upstream'
Former-commit-id: 0a8d9dbe585c0334de822df0c3d0034a95302b4d
This commit is contained in:
commit
77c59f05da
@ -93,6 +93,7 @@ GC_API GC_PTR (*GC_oom_fn) GC_PROTO((size_t bytes_requested));
|
||||
/* pointer to a previously allocated heap */
|
||||
/* object. */
|
||||
|
||||
// Keep somewhat in sync with mono/metadata/profiler.h:enum MonoGCEvent
|
||||
typedef enum {
|
||||
GC_EVENT_START,
|
||||
GC_EVENT_MARK_START,
|
||||
|
@ -1,4 +1,8 @@
|
||||
.TH mprof-report 1 ""
|
||||
.de Sp
|
||||
.if t .sp .5v
|
||||
.if n .sp
|
||||
..
|
||||
.TH mprof-report 1 ""
|
||||
.SH The Mono log profiler
|
||||
.PP
|
||||
The Mono \f[I]log\f[] profiler can be used to collect a lot of
|
||||
@ -237,6 +241,9 @@ Methods JITted using mono JIT, Methods JITted using LLVM, Total time
|
||||
spent JITting (sec), User Time, System Time, Total Time, Working Set,
|
||||
Private Bytes, Virtual Bytes, Page Faults and CPU Load Average (1min,
|
||||
5min and 15min).
|
||||
.IP \[bu] 2
|
||||
\f[I]coverage\f[]: collect code coverage data. This implies enabling
|
||||
the \f[I]calls\f[] option.
|
||||
.RE
|
||||
.SS Analyzing the profile data
|
||||
.PP
|
||||
@ -260,7 +267,7 @@ To see this info invoke mprof-report as follows:
|
||||
\f[B]mprof-report\ --traces\ output.mlpd\f[]
|
||||
.PP
|
||||
The maximum number of methods in each stack trace can be specified
|
||||
with the \f[I]\[em]maxframes=NUM\f[] option:
|
||||
with the \f[I]--maxframes=NUM\f[] option:
|
||||
.PP
|
||||
\f[B]mprof-report\ --traces\ --maxframes=4\ output.mlpd\f[]
|
||||
.PP
|
||||
@ -272,7 +279,7 @@ specific events when the \f[I]nocalls\f[] option is used, so in
|
||||
that case, if more stack frames are required in mprof-report, a
|
||||
bigger value for maxframes when profiling must be used, too.
|
||||
.PP
|
||||
The \f[I]\[em]traces\f[] option also controls the reverse reference
|
||||
The \f[I]--traces\f[] option also controls the reverse reference
|
||||
feature in the heapshot report: for each class it reports how many
|
||||
references to objects of that class come from other classes.
|
||||
.SS Sort order for methods and allocations
|
||||
@ -362,6 +369,10 @@ version
|
||||
\f[I]heapshot\f[]: live heap usage at heap shots
|
||||
.IP \[bu] 2
|
||||
\f[I]counters\f[]: counters samples
|
||||
.IP \[bu] 2
|
||||
\f[I]coverage\f[]: code coverage data
|
||||
.IP \[bu] 2
|
||||
\f[I]stats\f[]: event statistics
|
||||
.PP
|
||||
It is possible to limit some of the data displayed to a timeframe
|
||||
of the program execution with the option:
|
||||
@ -391,23 +402,23 @@ Instead of printing the usual reports from the profiler data, it is
|
||||
possible to track some interesting information about some specific
|
||||
object addresses.
|
||||
The objects are selected based on their address with the
|
||||
\f[I]\[em]track\f[] option as follows:
|
||||
\f[I]--track\f[] option as follows:
|
||||
.PP
|
||||
\f[B]--track=0xaddr1[,0xaddr2,...]\f[]
|
||||
.PP
|
||||
The reported info (if available in the data file), will be class
|
||||
name, size, creation time, stack trace of creation (with the
|
||||
\f[I]\[em]traces\f[] option), etc.
|
||||
\f[I]--traces\f[] option), etc.
|
||||
If heapshot data is available it will be possible to also track
|
||||
what other objects reference one of the listed addresses.
|
||||
.PP
|
||||
The object addresses can be gathered either from the profiler
|
||||
report in some cases (like in the monitor lock report), from the
|
||||
live application or they can be selected with the
|
||||
\f[I]\[em]find=FINDSPEC\f[] option.
|
||||
\f[I]--find=FINDSPEC\f[] option.
|
||||
FINDSPEC can be one of the following:
|
||||
.IP \[bu] 2
|
||||
\f[I]S:SIZE\f[]: where the object is selected if it's size is at
|
||||
\f[I]S:SIZE\f[]: where the object is selected if its size is at
|
||||
least \f[I]SIZE\f[]
|
||||
.IP \[bu] 2
|
||||
\f[I]T:NAME\f[]: where the object is selected if \f[I]NAME\f[]
|
||||
@ -432,6 +443,13 @@ By default mprof-report will print the summary data to the console.
|
||||
To print it to a file, instead, use the option:
|
||||
.PP
|
||||
\f[B]--out=FILENAME\f[]
|
||||
.SS Processing code coverage data
|
||||
.PP
|
||||
If you ran the profiler with the \f[I]coverage\f[] option, you can
|
||||
process the collected coverage data into an XML file by running
|
||||
mprof-report like this:
|
||||
.PP
|
||||
\f[B]mprof-report --coverage-out=coverage.xml output.mlpd\f[]
|
||||
.SS Dealing with profiler slowness
|
||||
.PP
|
||||
If the profiler needs to collect lots of data, the execution of the
|
||||
@ -439,20 +457,20 @@ program will slow down significantly, usually 10 to 20 times
|
||||
slower.
|
||||
There are several ways to reduce the impact of the profiler on the
|
||||
program execution.
|
||||
.SS Use the statistical sampling mode
|
||||
.PP
|
||||
.IP "\f[I]Use the statistical sampling mode\f[]" 4
|
||||
.Sp
|
||||
Statistical sampling allows executing a program under the profiler
|
||||
with minimal performance overhead (usually less than 10%).
|
||||
This mode allows checking where the program is spending most of
|
||||
it's execution time without significantly perturbing its behaviour.
|
||||
.SS Collect less data
|
||||
.PP
|
||||
its execution time without significantly perturbing its behaviour.
|
||||
.IP "\f[I]Collect less data\f[]" 4
|
||||
.Sp
|
||||
Collecting method enter/leave events can be very expensive,
|
||||
especially in programs that perform many millions of tiny calls.
|
||||
The profiler option \f[I]nocalls\f[] can be used to avoid
|
||||
collecting this data or it can be limited to only a few call levels
|
||||
with the \f[I]calldepth\f[] option.
|
||||
.PP
|
||||
.Sp
|
||||
Object allocation information is expensive as well, though much
|
||||
less than method enter/leave events.
|
||||
If it's not needed, it can be skipped with the \f[I]noalloc\f[]
|
||||
@ -463,14 +481,14 @@ expensive as well.
|
||||
The impact of stack trace information can be reduced by setting a
|
||||
low value with the \f[I]maxframes\f[] option or by eliminating them
|
||||
completely, by setting it to 0.
|
||||
.PP
|
||||
The other major source of data is the heapshot profiler option:
|
||||
especially if the managed heap is big, since every object needs to
|
||||
be inspected.
|
||||
.Sp
|
||||
The other major source of data is the \f[I]heapshot\f[] profiler
|
||||
option: especially if the managed heap is big, since every object
|
||||
needs to be inspected.
|
||||
The \f[I]MODE\f[] parameter of the \f[I]heapshot\f[] option can be
|
||||
used to reduce the frequency of the heap shots.
|
||||
.SS Reduce the timestamp overhead
|
||||
.PP
|
||||
.IP "\f[I]Reduce the timestamp overhead\f[]" 4
|
||||
.Sp
|
||||
On many operating systems or architectures what actually slows down
|
||||
profiling is the function provided by the system to get timestamp
|
||||
information.
|
||||
@ -486,15 +504,15 @@ There are a few ways to minimize the amount of data, for example by
|
||||
not collecting some of the more space-consuming information or by
|
||||
compressing the information on the fly or by just generating a
|
||||
summary report.
|
||||
.SS Reducing the amount of data
|
||||
.PP
|
||||
.IP "\f[I]Reducing the amount of data\f[]" 4
|
||||
.Sp
|
||||
Method enter/leave events can be excluded completely with the
|
||||
\f[I]nocalls\f[] option or they can be limited to just a few levels
|
||||
of calls with the \f[I]calldepth\f[] option.
|
||||
For example, the option:
|
||||
.PP
|
||||
.Sp
|
||||
\f[B]calldepth=10\f[]
|
||||
.PP
|
||||
.Sp
|
||||
will ignore the method events when there are more than 10 managed
|
||||
stack frames.
|
||||
This is very useful for programs that have deep recursion or for
|
||||
@ -503,59 +521,59 @@ the call stack.
|
||||
The optimal number for the calldepth option depends on the program
|
||||
and it needs to be balanced between providing enough profiling
|
||||
information and allowing fast execution speed.
|
||||
.PP
|
||||
.Sp
|
||||
Note that by default, if method events are not recorded at all, the
|
||||
profiler will collect stack trace information at events like
|
||||
allocations.
|
||||
To avoid gathering this data, use the \f[I]maxframes=0\f[] profiler
|
||||
option.
|
||||
.PP
|
||||
.Sp
|
||||
Allocation events can be eliminated with the \f[I]noalloc\f[]
|
||||
option.
|
||||
.PP
|
||||
.Sp
|
||||
Heap shot data can also be huge: by default it is collected at each
|
||||
major collection.
|
||||
To reduce the frequency, you can specify a heapshot mode: for
|
||||
example to collect every 5 collections (including major and minor):
|
||||
.PP
|
||||
.Sp
|
||||
\f[B]heapshot=5gc\f[]
|
||||
.PP
|
||||
.Sp
|
||||
or when at least 5 seconds passed since the last heap shot:
|
||||
.PP
|
||||
.Sp
|
||||
\f[B]heapshot=5000ms\f[]
|
||||
.SS Compressing the data
|
||||
.PP
|
||||
.IP "\f[I]Compressing the data\f[]" 4
|
||||
.Sp
|
||||
To reduce the amout of disk space used by the data, the data can be
|
||||
compressed either after it has been generated with the gzip
|
||||
command:
|
||||
.PP
|
||||
.Sp
|
||||
\f[B]gzip\ -9\ output.mlpd\f[]
|
||||
.PP
|
||||
.Sp
|
||||
or it can be compressed automatically by using the \f[I]zip\f[]
|
||||
profiler option.
|
||||
Note that in this case there could be a significant slowdown of the
|
||||
profiled program.
|
||||
.PP
|
||||
.Sp
|
||||
The mprof-report program will tranparently deal with either
|
||||
compressed or uncompressed data files.
|
||||
.SS Generating only a summary report
|
||||
.PP
|
||||
.IP "\f[I]Generating only a summary report\f[]" 4
|
||||
.Sp
|
||||
Often it's enough to look at the profiler summary report to
|
||||
diagnose an issue and in this case it's possible to avoid saving
|
||||
the profiler data file to disk.
|
||||
This can be accomplished with the \f[I]report\f[] profiler option,
|
||||
which will basically send the data to the mprof-report program for
|
||||
display.
|
||||
.PP
|
||||
.Sp
|
||||
To have more control of what summary information is reported (or to
|
||||
use a completely different program to decode the profiler data),
|
||||
the \f[I]output\f[] profiler option can be used, with \f[B]|\f[] as
|
||||
the first character: the rest of the output name will be executed
|
||||
as a program with the data fed in on the standard input.
|
||||
.PP
|
||||
.Sp
|
||||
For example, to print only the Monitor summary with stack trace
|
||||
information, you could use it like this:
|
||||
.PP
|
||||
.Sp
|
||||
\f[B]output=|mprof-report\ --reports=monitor\ --traces\ -\f[]
|
||||
.SH WEB SITE
|
||||
http://www.mono-project.com/docs/debug+profile/profile/profiler/
|
||||
@ -563,5 +581,4 @@ http://www.mono-project.com/docs/debug+profile/profile/profiler/
|
||||
.PP
|
||||
mono(1)
|
||||
.SH AUTHORS
|
||||
Paolo Molaro.
|
||||
|
||||
Paolo Molaro, Alex Rønne Petersen
|
||||
|
@ -125,9 +125,9 @@ namespace Mono.Data.Sqlite
|
||||
// Compatibility with versions < 3.5.0
|
||||
int n;
|
||||
|
||||
try {
|
||||
if (UnsafeNativeMethods.use_sqlite3_open_v2) {
|
||||
n = UnsafeNativeMethods.sqlite3_open_v2(ToUTF8(strFilename), out db, (int)flags, IntPtr.Zero);
|
||||
} catch (EntryPointNotFoundException) {
|
||||
} else {
|
||||
Console.WriteLine ("Your sqlite3 version is old - please upgrade to at least v3.5.0!");
|
||||
n = UnsafeNativeMethods.sqlite3_open (ToUTF8 (strFilename), out db);
|
||||
}
|
||||
|
@ -208,9 +208,9 @@ namespace Mono.Data.Sqlite
|
||||
#else
|
||||
ResetConnection(db);
|
||||
int n;
|
||||
try {
|
||||
if (UnsafeNativeMethods.use_sqlite3_close_v2) {
|
||||
n = UnsafeNativeMethods.sqlite3_close_v2(db);
|
||||
} catch (EntryPointNotFoundException) {
|
||||
} else {
|
||||
n = UnsafeNativeMethods.sqlite3_close(db);
|
||||
}
|
||||
#endif
|
||||
|
@ -16,6 +16,27 @@ namespace Mono.Data.Sqlite
|
||||
#endif
|
||||
internal static class UnsafeNativeMethods
|
||||
{
|
||||
internal static readonly bool use_sqlite3_close_v2 = false;
|
||||
internal static readonly bool use_sqlite3_open_v2 = false;
|
||||
internal static readonly bool use_sqlite3_create_function_v2 = false;
|
||||
static UnsafeNativeMethods()
|
||||
{
|
||||
// calculate the version number parts
|
||||
// https://www.sqlite.org/c3ref/c_source_id.html
|
||||
// (<major> * 1000000) + (<minor> * 1000) + (<release>)
|
||||
int versionNumber = sqlite3_libversion_number();
|
||||
int release = versionNumber % 1000;
|
||||
int minor = (versionNumber / 1000) % 1000;
|
||||
int major = versionNumber / 1000000;
|
||||
Version version = new Version(major, minor, release);
|
||||
|
||||
// set the various versions
|
||||
// https://sqlite.org/changes.html
|
||||
use_sqlite3_open_v2 = version >= new Version(3, 5, 0);
|
||||
use_sqlite3_close_v2 = version >= new Version(3, 7, 14);
|
||||
use_sqlite3_create_function_v2 = version >= new Version(3, 7, 3);
|
||||
}
|
||||
|
||||
#if !SQLITE_STANDARD
|
||||
|
||||
#if !USE_INTEROP_DLL
|
||||
@ -730,6 +751,13 @@ namespace Mono.Data.Sqlite
|
||||
#endif
|
||||
internal static extern int sqlite3_free (IntPtr ptr);
|
||||
|
||||
#if !PLATFORM_COMPACTFRAMEWORK
|
||||
[DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||
#else
|
||||
[DllImport(SQLITE_DLL)]
|
||||
#endif
|
||||
internal static extern int sqlite3_libversion_number();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,15 @@ System.IO.Pipes/AnonymousPipeClientStream.cs
|
||||
System.IO.Pipes/AnonymousPipeServerStream.cs
|
||||
System.IO.Pipes/NamedPipeClientStream.cs
|
||||
System.IO.Pipes/NamedPipeServerStream.cs
|
||||
System.IO.Pipes/PipeAccessRights.cs
|
||||
System.IO.Pipes/PipeAccessRule.cs
|
||||
System.IO.Pipes/PipeAuditRule.cs
|
||||
System.IO.Pipes/PipeDirection.cs
|
||||
System.IO.Pipes/PipeInterfaces.cs
|
||||
System.IO.Pipes/PipeOptions.cs
|
||||
System.IO.Pipes/PipeSecurity.cs
|
||||
System.IO.Pipes/PipeStream.cs
|
||||
System.IO.Pipes/PipeStreamImpersonationWorker.cs
|
||||
System.IO.Pipes/PipeTransmissionMode.cs
|
||||
|
||||
ReferenceSources/SR.cs
|
||||
|
@ -1,11 +1,6 @@
|
||||
#include common_System.Core.dll.sources
|
||||
#include dynamic_System.Core.dll.sources
|
||||
|
||||
System.IO.Pipes/PipeAccessRights.cs
|
||||
System.IO.Pipes/PipeAccessRule.cs
|
||||
System.IO.Pipes/PipeAuditRule.cs
|
||||
System.IO.Pipes/PipeSecurity.cs
|
||||
System.IO.Pipes/PipeStreamImpersonationWorker.cs
|
||||
System.IO.Pipes/PipeUnix.cs
|
||||
System.IO.Pipes/PipeWin32.cs
|
||||
|
||||
|
@ -450,7 +450,7 @@ namespace System.Net
|
||||
newWebHeaders.Add(headerName,webHeaders[headerName]);
|
||||
}
|
||||
|
||||
webHeaders = newWebHeaders;
|
||||
this.webHeaders = newWebHeaders;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.Win32.SafeHandles
|
||||
{
|
||||
public sealed class SafeAccessTokenHandle : SafeHandle
|
||||
{
|
||||
public override bool IsInvalid {
|
||||
get {
|
||||
return handle == IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public SafeAccessTokenHandle ()
|
||||
: base (IntPtr.Zero, true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -157,7 +157,11 @@ internal class Latin1Encoding : Encoding
|
||||
buffer = EncoderFallback.CreateFallbackBuffer ();
|
||||
if (Char.IsSurrogate (ch) && count > 1 &&
|
||||
Char.IsSurrogate (chars [charIndex]))
|
||||
buffer.Fallback (ch, chars [charIndex], charIndex++ - 1);
|
||||
{
|
||||
buffer.Fallback (ch, chars [charIndex], charIndex - 1);
|
||||
charIndex++;
|
||||
count--;
|
||||
}
|
||||
else
|
||||
buffer.Fallback (ch, charIndex - 1);
|
||||
if (fallback_chars == null || fallback_chars.Length < buffer.Remaining)
|
||||
|
@ -862,6 +862,22 @@ namespace System {
|
||||
}
|
||||
}
|
||||
#else
|
||||
public static string GetEnvironmentVariable (string variable, EnvironmentVariableTarget target)
|
||||
{
|
||||
if (target == EnvironmentVariableTarget.Process)
|
||||
return GetEnvironmentVariable (variable);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IDictionary GetEnvironmentVariables (EnvironmentVariableTarget target)
|
||||
{
|
||||
if (target == EnvironmentVariableTarget.Process)
|
||||
return GetEnvironmentVariables ();
|
||||
|
||||
return (IDictionary)new Hashtable ();
|
||||
}
|
||||
|
||||
public static void SetEnvironmentVariable (string variable, string value)
|
||||
{
|
||||
if (variable == null)
|
||||
@ -875,6 +891,14 @@ namespace System {
|
||||
|
||||
InternalSetEnvironmentVariable (variable, value);
|
||||
}
|
||||
|
||||
public static void SetEnvironmentVariable (string variable, string value, EnvironmentVariableTarget target)
|
||||
{
|
||||
if (target == EnvironmentVariableTarget.Process)
|
||||
SetEnvironmentVariable (variable, value);
|
||||
|
||||
// other targets ignored
|
||||
}
|
||||
#endif
|
||||
[MethodImplAttribute (MethodImplOptions.InternalCall)]
|
||||
internal static extern void InternalSetEnvironmentVariable (string variable, string value);
|
||||
|
@ -119,6 +119,40 @@ namespace MonoTests.System.Text
|
||||
Assert.AreEqual (testchars [i], (char) bytes [i]);
|
||||
}
|
||||
|
||||
[Test] // Test GetBytes(string)
|
||||
public void TestGetBytes7 ()
|
||||
{
|
||||
var latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
|
||||
var expected = new byte [] { 0x3F, 0x20, 0x3F, 0x20, 0x3F };
|
||||
var actual = latin1_encoding.GetBytes("\u24c8 \u2075 \u221e"); // normal replacement
|
||||
Assert.AreEqual (expected, actual, "#1");
|
||||
|
||||
expected = new byte [] { 0x3F, 0x3F };
|
||||
actual = latin1_encoding.GetBytes("\ud83d\ude0a"); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#2");
|
||||
|
||||
expected = new byte [] { 0x3F, 0x3F, 0x20 };
|
||||
actual = latin1_encoding.GetBytes("\ud83d\ude0a "); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#3");
|
||||
|
||||
expected = new byte [] { 0x20, 0x20, 0x3F, 0x3F, 0x20, 0x20 };
|
||||
actual = latin1_encoding.GetBytes(" \ud83d\ude0a "); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#4");
|
||||
|
||||
expected = new byte [] { 0x20, 0x20, 0x3F, 0x3F, 0x20, 0x20 };
|
||||
actual = latin1_encoding.GetBytes(" \ud834\udd1e "); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#5");
|
||||
|
||||
expected = new byte [] { 0x41, 0x42, 0x43, 0x00, 0x41, 0x42, 0x43 };
|
||||
actual = latin1_encoding.GetBytes("ABC\0ABC"); // embedded zero byte not replaced
|
||||
Assert.AreEqual (expected, actual, "#6");
|
||||
|
||||
expected = new byte [] { 0x20, 0x20, 0x3F, 0x20, 0x20 };
|
||||
actual = latin1_encoding.GetBytes(" \ud834 "); // invalid surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#7");
|
||||
}
|
||||
|
||||
[Test] // Test GetChars(byte[])
|
||||
public void TestGetChars1 ()
|
||||
{
|
||||
@ -212,6 +246,15 @@ namespace MonoTests.System.Text
|
||||
Assert.AreEqual (string.Empty, encoding.GetString (new byte [0], 0, 0), "#2");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException (typeof (EncoderFallbackException))]
|
||||
public void EncoderFallback ()
|
||||
{
|
||||
Encoding e = Encoding.ASCII.Clone () as Encoding;
|
||||
e.EncoderFallback = new EncoderExceptionFallback ();
|
||||
e.GetBytes ("\u24c8");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException (typeof (DecoderFallbackException))]
|
||||
public void DecoderFallback ()
|
||||
|
350
mcs/class/corlib/Test/System.Text/Latin1EncodingTest.cs
Normal file
350
mcs/class/corlib/Test/System.Text/Latin1EncodingTest.cs
Normal file
@ -0,0 +1,350 @@
|
||||
//
|
||||
// Latin1EncodingTest.cs
|
||||
//
|
||||
// Author:
|
||||
// Alexander Köplinger (alexander.koeplinger@xamarin.com)
|
||||
//
|
||||
// Copyright (C) 2016 Xamarin, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject to
|
||||
// the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework.Constraints;
|
||||
|
||||
#if !MOBILE
|
||||
using NUnit.Framework.SyntaxHelpers;
|
||||
#endif
|
||||
|
||||
namespace MonoTests.System.Text
|
||||
{
|
||||
[TestFixture]
|
||||
public class Latin1EncodingTest
|
||||
{
|
||||
private char[] testchars;
|
||||
private byte[] testbytes;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp ()
|
||||
{
|
||||
testchars = new char[4];
|
||||
testchars[0] = 'T';
|
||||
testchars[1] = 'e';
|
||||
testchars[2] = 's';
|
||||
testchars[3] = 't';
|
||||
testbytes = new byte[4];
|
||||
testbytes[0] = (byte) 'T';
|
||||
testbytes[1] = (byte) 'e';
|
||||
testbytes[2] = (byte) 's';
|
||||
testbytes[3] = (byte) 't';
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsBrowserDisplay ()
|
||||
{
|
||||
Assert.IsTrue (Encoding.GetEncoding ("latin1").IsBrowserDisplay);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsBrowserSave ()
|
||||
{
|
||||
Assert.IsTrue (Encoding.GetEncoding ("latin1").IsBrowserSave);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsMailNewsDisplay ()
|
||||
{
|
||||
Assert.IsTrue (Encoding.GetEncoding ("latin1").IsMailNewsDisplay);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsMailNewsSave ()
|
||||
{
|
||||
Assert.IsTrue (Encoding.GetEncoding ("latin1").IsMailNewsSave);
|
||||
}
|
||||
|
||||
[Test] // Test GetBytes(char[])
|
||||
public void TestGetBytes1 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
byte[] bytes = latin1_encoding.GetBytes(testchars);
|
||||
for (int i = 0; i < testchars.Length; i++)
|
||||
Assert.AreEqual (testchars[i], (char) bytes[i]);
|
||||
}
|
||||
|
||||
[Test] // Test GetBytes(char[], int, int)
|
||||
public void TestGetBytes2 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
byte[] bytes = latin1_encoding.GetBytes(testchars, 1, 1);
|
||||
Assert.AreEqual (1, bytes.Length, "#1");
|
||||
Assert.AreEqual (testchars [1], (char) bytes [0], "#2");
|
||||
}
|
||||
|
||||
[Test] // Test non-Latin1 char in char[]
|
||||
public void TestGetBytes3 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
testchars[2] = (char) 0x100;
|
||||
byte[] bytes = latin1_encoding.GetBytes(testchars);
|
||||
Assert.AreEqual ('T', (char) bytes [0], "#1");
|
||||
Assert.AreEqual ('e', (char) bytes [1], "#2");
|
||||
Assert.AreEqual ('?', (char) bytes [2], "#3");
|
||||
Assert.AreEqual ('t', (char) bytes [3], "#4");
|
||||
}
|
||||
|
||||
[Test] // Test GetBytes(char[], int, int, byte[], int)
|
||||
public void TestGetBytes4 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
byte[] bytes = new Byte[1];
|
||||
int cnt = latin1_encoding.GetBytes(testchars, 1, 1, bytes, 0);
|
||||
Assert.AreEqual (1, cnt, "#1");
|
||||
Assert.AreEqual (testchars [1], (char) bytes [0], "#2");
|
||||
}
|
||||
|
||||
[Test] // Test GetBytes(string, int, int, byte[], int)
|
||||
public void TestGetBytes5 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
byte[] bytes = new Byte[1];
|
||||
int cnt = latin1_encoding.GetBytes("Test", 1, 1, bytes, 0);
|
||||
Assert.AreEqual ('e', (char) bytes [0], "#1");
|
||||
}
|
||||
|
||||
[Test] // Test GetBytes(string)
|
||||
public void TestGetBytes6 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
byte[] bytes = latin1_encoding.GetBytes("Test");
|
||||
for (int i = 0; i < testchars.Length; i++)
|
||||
Assert.AreEqual (testchars [i], (char) bytes [i]);
|
||||
}
|
||||
|
||||
[Test] // Test GetBytes(string)
|
||||
public void TestGetBytes7 ()
|
||||
{
|
||||
var latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
|
||||
var expected = new byte [] { 0x3F, 0x20, 0x3F, 0x20, 0x3F };
|
||||
var actual = latin1_encoding.GetBytes("\u24c8 \u2075 \u221e"); // normal replacement
|
||||
Assert.AreEqual (expected, actual, "#1");
|
||||
|
||||
expected = new byte [] { 0x3F, 0x3F };
|
||||
actual = latin1_encoding.GetBytes("\ud83d\ude0a"); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#2");
|
||||
|
||||
expected = new byte [] { 0x3F, 0x3F, 0x20 };
|
||||
actual = latin1_encoding.GetBytes("\ud83d\ude0a "); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#3");
|
||||
|
||||
expected = new byte [] { 0x20, 0x20, 0x3F, 0x3F, 0x20, 0x20 };
|
||||
actual = latin1_encoding.GetBytes(" \ud83d\ude0a "); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#4");
|
||||
|
||||
expected = new byte [] { 0x20, 0x20, 0x3F, 0x3F, 0x20, 0x20 };
|
||||
actual = latin1_encoding.GetBytes(" \ud834\udd1e "); // surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#5");
|
||||
|
||||
expected = new byte [] { 0x41, 0x42, 0x43, 0x00, 0x41, 0x42, 0x43 };
|
||||
actual = latin1_encoding.GetBytes("ABC\0ABC"); // embedded zero byte not replaced
|
||||
Assert.AreEqual (expected, actual, "#6");
|
||||
|
||||
expected = new byte [] { 0x20, 0x20, 0x3F, 0x20, 0x20 };
|
||||
actual = latin1_encoding.GetBytes(" \ud834 "); // invalid surrogate pair replacement
|
||||
Assert.AreEqual (expected, actual, "#7");
|
||||
}
|
||||
|
||||
[Test] // Test GetChars(byte[])
|
||||
public void TestGetChars1 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
char[] chars = latin1_encoding.GetChars(testbytes);
|
||||
for (int i = 0; i < testbytes.Length; i++)
|
||||
Assert.AreEqual (testbytes[i], (byte) chars[i]);
|
||||
}
|
||||
|
||||
[Test] // Test GetChars(byte[], int, int)
|
||||
public void TestGetChars2 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
char[] chars = latin1_encoding.GetChars(testbytes, 1, 1);
|
||||
Assert.AreEqual (1, chars.Length, "#1");
|
||||
Assert.AreEqual (testbytes [1], (byte) chars [0], "#2");
|
||||
}
|
||||
|
||||
[Test] // Test GetChars(byte[], int, int, char[], int)
|
||||
public void TestGetChars4 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
char[] chars = new char[1];
|
||||
int cnt = latin1_encoding.GetChars(testbytes, 1, 1, chars, 0);
|
||||
Assert.AreEqual (1, cnt, "#1");
|
||||
Assert.AreEqual (testbytes [1], (byte) chars [0], "#2");
|
||||
}
|
||||
|
||||
[Test] // Test GetString(char[])
|
||||
public void TestGetString1 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
string str = latin1_encoding.GetString(testbytes);
|
||||
Assert.AreEqual ("Test", str);
|
||||
}
|
||||
|
||||
[Test] // Test GetString(char[], int, int)
|
||||
public void TestGetString2 ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
string str = latin1_encoding.GetString(testbytes, 1, 2);
|
||||
Assert.AreEqual ("es", str);
|
||||
}
|
||||
|
||||
[Test] // Test Decoder
|
||||
public void TestDecoder ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
char[] chars = new char[1];
|
||||
int cnt = latin1_encoding.GetDecoder().GetChars(testbytes, 1, 1, chars, 0);
|
||||
Assert.AreEqual (1, cnt, "#1");
|
||||
Assert.AreEqual (testbytes [1], (byte) chars [0], "#2");
|
||||
}
|
||||
|
||||
[Test] // Test Decoder
|
||||
public void TestEncoder ()
|
||||
{
|
||||
Encoding latin1_encoding = Encoding.GetEncoding ("latin1");
|
||||
byte[] bytes = new Byte[1];
|
||||
int cnt = latin1_encoding.GetEncoder().GetBytes(testchars, 1, 1, bytes, 0, false);
|
||||
Assert.AreEqual (1, cnt, "#1");
|
||||
Assert.AreEqual (testchars [1], (char) bytes [0], "#2");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestZero ()
|
||||
{
|
||||
Encoding encoding = Encoding.GetEncoding ("latin1");
|
||||
Assert.AreEqual (string.Empty, encoding.GetString (new byte [0]), "#1");
|
||||
Assert.AreEqual (string.Empty, encoding.GetString (new byte [0], 0, 0), "#2");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException (typeof (EncoderFallbackException))]
|
||||
public void EncoderFallback ()
|
||||
{
|
||||
Encoding e = Encoding.GetEncoding ("latin1").Clone () as Encoding;
|
||||
e.EncoderFallback = new EncoderExceptionFallback ();
|
||||
e.GetBytes ("\u24c8");
|
||||
}
|
||||
|
||||
[Test]
|
||||
// [ExpectedException (typeof (ArgumentException))]
|
||||
public void DecoderFallback2 ()
|
||||
{
|
||||
var bytes = new byte[] {
|
||||
0x30, 0xa0, 0x31, 0xa8
|
||||
};
|
||||
var enc = (Encoding)Encoding.GetEncoding ("latin1").Clone ();
|
||||
enc.DecoderFallback = new TestFallbackDecoder ();
|
||||
|
||||
var chars = new char [7];
|
||||
var ret = enc.GetChars (bytes, 0, bytes.Length, chars, 0);
|
||||
Console.WriteLine (ret);
|
||||
|
||||
for (int i = 0; i < chars.Length; i++) {
|
||||
Console.Write ("{0:x2} ", (int)chars [i]);
|
||||
}
|
||||
Console.WriteLine ();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DecoderFallback3 ()
|
||||
{
|
||||
var bytes = new byte[] {
|
||||
0x30, 0xa0, 0x31, 0xa8
|
||||
};
|
||||
var enc = (Encoding)Encoding.GetEncoding ("latin1").Clone ();
|
||||
enc.DecoderFallback = new TestFallbackDecoder ();
|
||||
|
||||
var chars = new char[] { '9', '8', '7', '6', '5' };
|
||||
var ret = enc.GetChars (bytes, 0, bytes.Length, chars, 0);
|
||||
|
||||
Assert.That (ret, Is.EqualTo (4), "ret");
|
||||
Assert.That (chars [0], Is.EqualTo ('0'), "chars[0]");
|
||||
Assert.That (chars [1], Is.EqualTo ((char)0xA0), "chars[1]");
|
||||
Assert.That (chars [2], Is.EqualTo ('1'), "chars[2]");
|
||||
Assert.That (chars [3], Is.EqualTo ((char)0xA8), "chars[3]");
|
||||
Assert.That (chars [4], Is.EqualTo ('5'), "chars[4]");
|
||||
}
|
||||
|
||||
class TestFallbackDecoder : DecoderFallback {
|
||||
const int count = 2;
|
||||
|
||||
public override int MaxCharCount {
|
||||
get { return count; }
|
||||
}
|
||||
|
||||
public override DecoderFallbackBuffer CreateFallbackBuffer ()
|
||||
{
|
||||
return new Buffer ();
|
||||
}
|
||||
|
||||
class Buffer : DecoderFallbackBuffer {
|
||||
char[] queue;
|
||||
int index;
|
||||
|
||||
public override int Remaining {
|
||||
get {
|
||||
return queue.Length - index;
|
||||
}
|
||||
}
|
||||
|
||||
public override char GetNextChar ()
|
||||
{
|
||||
return index < queue.Length ? queue [index++] : '\0';
|
||||
}
|
||||
|
||||
public override bool Fallback (byte[] bytes, int unused)
|
||||
{
|
||||
queue = new char[bytes.Length * count];
|
||||
index = 0;
|
||||
for (int i = 0; i < bytes.Length; i++) {
|
||||
for (int j = 0; j < count; j++)
|
||||
queue [index++] = (char)(bytes [i]+j);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool MovePrevious ()
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public override void Reset ()
|
||||
{
|
||||
base.Reset ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -615,7 +615,6 @@ System.Security/NamedPermissionSet.cs
|
||||
System.Security/PermissionBuilder.cs
|
||||
System.Security/PermissionSet.cs
|
||||
System.Security/PolicyLevelType.cs
|
||||
System.Security/SafeAccessTokenHandle.cs
|
||||
System.Security/SecureString.cs
|
||||
System.Security/SecurityElement.cs
|
||||
System.Security/SecurityFrame.cs
|
||||
@ -1393,6 +1392,7 @@ ReferenceSources/SecurityContext.cs
|
||||
../referencesource/mscorlib/system/security/attributes.cs
|
||||
../referencesource/mscorlib/system/security/securitycontext.cs
|
||||
../referencesource/mscorlib/system/security/securitydocument.cs
|
||||
../referencesource/mscorlib/system/security/safesecurityhandles.cs
|
||||
|
||||
../referencesource/mscorlib/system/security/claims/Claim.cs
|
||||
../referencesource/mscorlib/system/security/claims/ClaimsIdentity.cs
|
||||
|
@ -405,6 +405,7 @@ System.Text/EncoderTest.cs
|
||||
System.Text/EncodingTest.cs
|
||||
System.Text/EncodingTester.cs
|
||||
System.Text/EncodingInfoTest.cs
|
||||
System.Text/Latin1EncodingTest.cs
|
||||
System.Text/StringBuilderTest.cs
|
||||
System.Text/TestEncoding.cs
|
||||
System.Text/UnicodeEncodingTest.cs
|
||||
|
@ -501,6 +501,44 @@ namespace System.Dynamic {
|
||||
binder.ReturnType
|
||||
);
|
||||
|
||||
#if MONO // referencesource version
|
||||
Expression condition;
|
||||
// If the return type can not be assigned null then just check for type assignablity otherwise allow null.
|
||||
if (binder.ReturnType.IsValueType && Nullable.GetUnderlyingType(binder.ReturnType) == null) {
|
||||
condition = Expression.TypeIs(resultMO.Expression, binder.ReturnType);
|
||||
}
|
||||
else {
|
||||
condition = Expression.OrElse(
|
||||
Expression.Equal(resultMO.Expression, Expression.Constant(null)),
|
||||
Expression.TypeIs(resultMO.Expression, binder.ReturnType));
|
||||
}
|
||||
|
||||
var checkedConvert = Expression.Condition(
|
||||
condition,
|
||||
convert,
|
||||
Expression.Throw(
|
||||
Expression.New(typeof(InvalidCastException).GetConstructor(new Type[]{typeof(string)}),
|
||||
Expression.Call(
|
||||
typeof(string).GetMethod("Format", new Type[] {typeof(string), typeof(object[])}),
|
||||
Expression.Constant(convertFailed),
|
||||
Expression.NewArrayInit(typeof(object),
|
||||
Expression.Condition(
|
||||
Expression.Equal(resultMO.Expression, Expression.Constant(null)),
|
||||
Expression.Constant("null"),
|
||||
Expression.Call(
|
||||
resultMO.Expression,
|
||||
typeof(object).GetMethod("GetType")
|
||||
),
|
||||
typeof(object)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
binder.ReturnType
|
||||
),
|
||||
binder.ReturnType
|
||||
);
|
||||
#else
|
||||
var checkedConvert = Expression.Condition(
|
||||
Expression.TypeIs(resultMO.Expression, binder.ReturnType),
|
||||
convert,
|
||||
@ -524,6 +562,7 @@ namespace System.Dynamic {
|
||||
),
|
||||
binder.ReturnType
|
||||
);
|
||||
#endif
|
||||
|
||||
resultMO = new DynamicMetaObject(checkedConvert, resultMO.Restrictions);
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
0e58c3fba67bf21766014677b5f894f7637162d9
|
||||
c490c7433c000c0ca9ff7be0753080941738fdbc
|
@ -1 +1 @@
|
||||
8ad53def268a4750474dee2731ef4039642458aa
|
||||
c3bbfb8e3d0bb1d4648a456800a8f616d8a28016
|
@ -1 +1 @@
|
||||
4ed6e201e6785a6e9e44a113d2be4c9fd569673c
|
||||
8410f10f87dea9524681b3f688dab2f70afbf9b5
|
@ -1 +1 @@
|
||||
9d728aa18a9d89c58a94469c86f374658f784ccd
|
||||
d2b12594e92c61982d88980ec4bfaeb7c3bdf9ab
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user