{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/comments/38093317","id":38093317,"diff_hunk":"@@ -0,0 +1,130 @@\n+// Copyright (c) Microsoft. All rights reserved.\n+// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n+\n+using System.Collections.Concurrent;\n+using System.Data.Common;\n+using System.Diagnostics;\n+using System.Globalization;\n+using System.Runtime.InteropServices;\n+using System.Text;\n+\n+namespace System.Data\n+{\n+    internal static class LocaleInterop\n+    {\n+        // Maps between LCIDs and LocaleName+AnsiCodePages+Encodings\n+        private static readonly ConcurrentDictionary<int, Tuple<string, int, Encoding>> s_cachedEncodings = new ConcurrentDictionary<int, Tuple<string, int, Encoding>>();\n+\n+        private const string ApiWinCoreLocalization = \"api-ms-win-core-localization-l1-2-0.dll\";\n+        private const string ApiWinCoreLocalizationObsolete = \"api-ms-win-core-localization-obsolete-l1-2-0.dll\";\n+\n+        private const int LOCALE_NAME_MAX_LENGTH = 85;\n+        private const int ERROR_INVALID_PARAMETER = 0x57;\n+        private const uint LOCALE_IDEFAULTANSICODEPAGE = 0x00001004;\n+        private const uint LOCALE_RETURN_NUMBER = 0x20000000;\n+\n+        [DllImport(ApiWinCoreLocalization, SetLastError = true, CharSet = CharSet.Unicode)]\n+        private static extern int GetLocaleInfoEx(string lpLocaleName, uint LCType, [Out] out uint lpLCData, int cchData);\n+\n+        [DllImport(ApiWinCoreLocalizationObsolete, SetLastError = true, CharSet = CharSet.Unicode)]\n+        private static extern int LCIDToLocaleName(uint Locale, StringBuilder lpName, int cchName, int dwFlags);\n+\n+        [DllImport(ApiWinCoreLocalization, SetLastError = true, CharSet = CharSet.Unicode)]\n+        private static extern uint LocaleNameToLCID(string lpName, uint dwFlags);\n+\n+        static LocaleInterop()\n+        {\n+            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);\n+        }\n+\n+        private static string LcidToLocaleNameInternal(int lcid)\n+        {\n+            StringBuilder localName = new StringBuilder(LOCALE_NAME_MAX_LENGTH);\n+\n+            if (LCIDToLocaleName(unchecked((uint)lcid), localName, localName.Capacity, 0) != 0)\n+            {\n+                return localName.ToString();\n+            }\n+            else\n+            {\n+                // LCIDToLocaleName should not return any other errors if we have sufficient buffer space\n+                int win32Error = Marshal.GetLastWin32Error();\n+                Debug.Assert(win32Error == ERROR_INVALID_PARAMETER, string.Format(\"Unknown error returned by LCIDToLocaleName: {0}. Lcid: {1}\", win32Error, lcid));\n+\n+                throw new CultureNotFoundException(\"lcid\", lcid.ToString(), message: null);\n+            }\n+        }\n+\n+        private static int LocaleNameToAnsiCodePage(string localeName)\n+        {\n+            uint ansiCodePage;\n+            if (GetLocaleInfoEx(localeName, LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE, out ansiCodePage, sizeof(uint)) != 0)\n+            {\n+                return unchecked((int)ansiCodePage);\n+            }\n+            else\n+            {\n+                // GetLocaleInfoEx should not return any other errors if we have sufficient buffer space\n+                int win32Error = Marshal.GetLastWin32Error();\n+                Debug.Assert(win32Error == ERROR_INVALID_PARAMETER, string.Format(\"Unknown error returned by GetLocaleInfoEx: {0}. LocaleName: {1}\", win32Error, localeName));\n+\n+                throw new CultureNotFoundException(\"localeName\", localeName, message: null);\n+            }\n+        }\n+\n+        private static Tuple<string, int, Encoding> GetDetailsInternal(int lcid)\n+        {\n+            string localeName = LcidToLocaleNameInternal(lcid);\n+            int ansiCodePage = LocaleNameToAnsiCodePage(localeName);\n+            return Tuple.Create(localeName, ansiCodePage, Encoding.GetEncoding(ansiCodePage));\n+        }\n+\n+        private static Tuple<string, int, Encoding> GetDetailsForLcid(int lcid)\n+        {\n+            if (lcid < 0)\n+            {\n+                throw ADP.ArgumentOutOfRange(\"lcid\");\n+            }\n+            return s_cachedEncodings.GetOrAdd(lcid, GetDetailsInternal);","path":"src/System.Data.SqlClient/src/Interop/LocaleInterop.cs","position":88,"original_position":88,"commit_id":"33cba52d6f17911d84b1b48d119fa4735911a454","original_commit_id":"33cba52d6f17911d84b1b48d119fa4735911a454","user":{"login":"stephentoub","id":2642209,"avatar_url":"https://avatars.githubusercontent.com/u/2642209?v=3","gravatar_id":"","url":"https://api.github.com/users/stephentoub","html_url":"https://github.com/stephentoub","followers_url":"https://api.github.com/users/stephentoub/followers","following_url":"https://api.github.com/users/stephentoub/following{/other_user}","gists_url":"https://api.github.com/users/stephentoub/gists{/gist_id}","starred_url":"https://api.github.com/users/stephentoub/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stephentoub/subscriptions","organizations_url":"https://api.github.com/users/stephentoub/orgs","repos_url":"https://api.github.com/users/stephentoub/repos","events_url":"https://api.github.com/users/stephentoub/events{/privacy}","received_events_url":"https://api.github.com/users/stephentoub/received_events","type":"User","site_admin":false},"body":"Due to the C# compiler's current inability to cache delegates for delegate inference from method groups, this is going to allocate a new delegate on every call.  While counter-intuitive, it'd be better to do:\r\n```C#\r\nreturn s_cachedEncodings.GetOrAdd(lcid, lcid => GetDetailsInternal(lcid));\r\n```","created_at":"2015-08-27T13:17:26Z","updated_at":"2015-08-27T13:17:26Z","html_url":"https://github.com/dotnet/corefx/pull/2986#discussion_r38093317","pull_request_url":"https://api.github.com/repos/dotnet/corefx/pulls/2986","_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments/38093317"},"html":{"href":"https://github.com/dotnet/corefx/pull/2986#discussion_r38093317"},"pull_request":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/2986"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/2986","id":43473102,"html_url":"https://github.com/dotnet/corefx/pull/2986","diff_url":"https://github.com/dotnet/corefx/pull/2986.diff","patch_url":"https://github.com/dotnet/corefx/pull/2986.patch","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/2986","number":2986,"state":"open","locked":false,"title":"Add System.Data.SqlClient source","user":{"login":"saurabh500","id":1623701,"avatar_url":"https://avatars.githubusercontent.com/u/1623701?v=3","gravatar_id":"","url":"https://api.github.com/users/saurabh500","html_url":"https://github.com/saurabh500","followers_url":"https://api.github.com/users/saurabh500/followers","following_url":"https://api.github.com/users/saurabh500/following{/other_user}","gists_url":"https://api.github.com/users/saurabh500/gists{/gist_id}","starred_url":"https://api.github.com/users/saurabh500/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/saurabh500/subscriptions","organizations_url":"https://api.github.com/users/saurabh500/orgs","repos_url":"https://api.github.com/users/saurabh500/repos","events_url":"https://api.github.com/users/saurabh500/events{/privacy}","received_events_url":"https://api.github.com/users/saurabh500/received_events","type":"User","site_admin":false},"body":"Adding the source code for System.Data.SqlClient source code.","created_at":"2015-08-27T02:18:54Z","updated_at":"2015-08-27T13:17:26Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0775eb4d59e0a0f5af8ba5d9ae3cd864989b0356","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dotnet/corefx/pulls/2986/commits","review_comments_url":"https://api.github.com/repos/dotnet/corefx/pulls/2986/comments","review_comment_url":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/2986/comments","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/33cba52d6f17911d84b1b48d119fa4735911a454","head":{"label":"saurabh500:sqlclient","ref":"sqlclient","sha":"33cba52d6f17911d84b1b48d119fa4735911a454","user":{"login":"saurabh500","id":1623701,"avatar_url":"https://avatars.githubusercontent.com/u/1623701?v=3","gravatar_id":"","url":"https://api.github.com/users/saurabh500","html_url":"https://github.com/saurabh500","followers_url":"https://api.github.com/users/saurabh500/followers","following_url":"https://api.github.com/users/saurabh500/following{/other_user}","gists_url":"https://api.github.com/users/saurabh500/gists{/gist_id}","starred_url":"https://api.github.com/users/saurabh500/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/saurabh500/subscriptions","organizations_url":"https://api.github.com/users/saurabh500/orgs","repos_url":"https://api.github.com/users/saurabh500/repos","events_url":"https://api.github.com/users/saurabh500/events{/privacy}","received_events_url":"https://api.github.com/users/saurabh500/received_events","type":"User","site_admin":false},"repo":{"id":41459213,"name":"corefx","full_name":"saurabh500/corefx","owner":{"login":"saurabh500","id":1623701,"avatar_url":"https://avatars.githubusercontent.com/u/1623701?v=3","gravatar_id":"","url":"https://api.github.com/users/saurabh500","html_url":"https://github.com/saurabh500","followers_url":"https://api.github.com/users/saurabh500/followers","following_url":"https://api.github.com/users/saurabh500/following{/other_user}","gists_url":"https://api.github.com/users/saurabh500/gists{/gist_id}","starred_url":"https://api.github.com/users/saurabh500/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/saurabh500/subscriptions","organizations_url":"https://api.github.com/users/saurabh500/orgs","repos_url":"https://api.github.com/users/saurabh500/repos","events_url":"https://api.github.com/users/saurabh500/events{/privacy}","received_events_url":"https://api.github.com/users/saurabh500/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/saurabh500/corefx","description":"This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others.","fork":true,"url":"https://api.github.com/repos/saurabh500/corefx","forks_url":"https://api.github.com/repos/saurabh500/corefx/forks","keys_url":"https://api.github.com/repos/saurabh500/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/saurabh500/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/saurabh500/corefx/teams","hooks_url":"https://api.github.com/repos/saurabh500/corefx/hooks","issue_events_url":"https://api.github.com/repos/saurabh500/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/saurabh500/corefx/events","assignees_url":"https://api.github.com/repos/saurabh500/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/saurabh500/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/saurabh500/corefx/tags","blobs_url":"https://api.github.com/repos/saurabh500/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/saurabh500/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/saurabh500/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/saurabh500/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/saurabh500/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/saurabh500/corefx/languages","stargazers_url":"https://api.github.com/repos/saurabh500/corefx/stargazers","contributors_url":"https://api.github.com/repos/saurabh500/corefx/contributors","subscribers_url":"https://api.github.com/repos/saurabh500/corefx/subscribers","subscription_url":"https://api.github.com/repos/saurabh500/corefx/subscription","commits_url":"https://api.github.com/repos/saurabh500/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/saurabh500/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/saurabh500/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/saurabh500/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/saurabh500/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/saurabh500/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/saurabh500/corefx/merges","archive_url":"https://api.github.com/repos/saurabh500/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/saurabh500/corefx/downloads","issues_url":"https://api.github.com/repos/saurabh500/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/saurabh500/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/saurabh500/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/saurabh500/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/saurabh500/corefx/labels{/name}","releases_url":"https://api.github.com/repos/saurabh500/corefx/releases{/id}","created_at":"2015-08-27T01:41:34Z","updated_at":"2015-08-27T01:41:53Z","pushed_at":"2015-08-27T03:19:24Z","git_url":"git://github.com/saurabh500/corefx.git","ssh_url":"git@github.com:saurabh500/corefx.git","clone_url":"https://github.com/saurabh500/corefx.git","svn_url":"https://github.com/saurabh500/corefx","homepage":"http://dotnet.github.io/core/","size":65161,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dotnet:master","ref":"master","sha":"a41674d770233261f5afb748aa91fea83ef6c57d","user":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"repo":{"id":26295345,"name":"corefx","full_name":"dotnet/corefx","owner":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dotnet/corefx","description":"This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others.","fork":false,"url":"https://api.github.com/repos/dotnet/corefx","forks_url":"https://api.github.com/repos/dotnet/corefx/forks","keys_url":"https://api.github.com/repos/dotnet/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotnet/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotnet/corefx/teams","hooks_url":"https://api.github.com/repos/dotnet/corefx/hooks","issue_events_url":"https://api.github.com/repos/dotnet/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/dotnet/corefx/events","assignees_url":"https://api.github.com/repos/dotnet/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/dotnet/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/dotnet/corefx/tags","blobs_url":"https://api.github.com/repos/dotnet/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotnet/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotnet/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotnet/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/dotnet/corefx/languages","stargazers_url":"https://api.github.com/repos/dotnet/corefx/stargazers","contributors_url":"https://api.github.com/repos/dotnet/corefx/contributors","subscribers_url":"https://api.github.com/repos/dotnet/corefx/subscribers","subscription_url":"https://api.github.com/repos/dotnet/corefx/subscription","commits_url":"https://api.github.com/repos/dotnet/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotnet/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotnet/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotnet/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotnet/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/dotnet/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotnet/corefx/merges","archive_url":"https://api.github.com/repos/dotnet/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotnet/corefx/downloads","issues_url":"https://api.github.com/repos/dotnet/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/dotnet/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/dotnet/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/dotnet/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotnet/corefx/labels{/name}","releases_url":"https://api.github.com/repos/dotnet/corefx/releases{/id}","created_at":"2014-11-06T23:42:48Z","updated_at":"2015-08-27T09:07:22Z","pushed_at":"2015-08-27T13:09:38Z","git_url":"git://github.com/dotnet/corefx.git","ssh_url":"git@github.com:dotnet/corefx.git","clone_url":"https://github.com/dotnet/corefx.git","svn_url":"https://github.com/dotnet/corefx","homepage":"http://dotnet.github.io/core/","size":65161,"stargazers_count":8253,"watchers_count":8253,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1750,"mirror_url":null,"open_issues_count":550,"forks":1750,"open_issues":550,"watchers":8253,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/2986"},"html":{"href":"https://github.com/dotnet/corefx/pull/2986"},"issue":{"href":"https://api.github.com/repos/dotnet/corefx/issues/2986"},"comments":{"href":"https://api.github.com/repos/dotnet/corefx/issues/2986/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/2986/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/2986/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/corefx/statuses/33cba52d6f17911d84b1b48d119fa4735911a454"}}}}