├── .editorconfig
├── .github
├── dependabot.yml
└── workflows
│ ├── codeql-analysis.yml
│ ├── test.yml
│ └── zizmor.yml
├── .gitignore
├── .gitmodules
├── LICENSE
├── MaxMind-logo.png
├── MaxMind.Db.Benchmark
├── MaxMind.Db.Benchmark.csproj
├── Program.cs
└── Properties
│ └── AssemblyInfo.cs
├── MaxMind.Db.Test
├── .runsettings
├── DecoderTest.cs
├── GlobalSuppressions.cs
├── Helper
│ ├── NoNetworkTypeHolder.cs
│ ├── NonSeekableStreamWrapper.cs
│ ├── TestUtils.cs
│ └── TypeHolder.cs
├── MaxMind.Db.Test.csproj
├── NetworkTest.cs
├── PointerTest.cs
├── Properties
│ └── AssemblyInfo.cs
├── ReaderTest.cs
├── ThreadingTest.cs
└── runsettings.txt
├── MaxMind.Db.sln
├── MaxMind.Db
├── ArrayBuffer.cs
├── Buffer.cs
├── CachedDictionary.cs
├── ConstructorAttribute.cs
├── CustomDictionary.xml
├── Decoder.cs
├── DeserializationException.cs
├── DictionaryActivatorCreator.cs
├── GlobalSuppressions.cs
├── InjectAttribute.cs
├── InjectableValues.cs
├── InvalidDatabaseException.cs
├── Key.cs
├── ListActivatorCreator.cs
├── MaxMind.Db.csproj
├── MaxMind.Db.ruleset
├── MemoryMapBuffer.cs
├── Metadata.cs
├── Network.cs
├── NetworkAttribute.cs
├── ParameterAttribute.cs
├── Properties
│ └── AssemblyInfo.cs
├── Reader.cs
├── ReflectionUtil.cs
└── TypeAcivatorCreator.cs
├── MaxMind.snk
├── NuGet.Config
├── README.dev.md
├── README.md
├── dev-bin
└── release.ps1
└── releasenotes.md
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Remove the line below if you want to inherit .editorconfig settings from higher directories
2 | root = true
3 |
4 | # C# files
5 | [*.cs]
6 |
7 | #### Core EditorConfig Options ####
8 |
9 | # Indentation and spacing
10 | indent_size = 4
11 | indent_style = space
12 | tab_width = 4
13 |
14 | # New line preferences
15 | end_of_line = crlf
16 | insert_final_newline = false
17 |
18 | #### .NET Coding Conventions ####
19 |
20 | # Organize usings
21 | dotnet_separate_import_directive_groups = false
22 | dotnet_sort_system_directives_first = false
23 | file_header_template = unset
24 |
25 | # this. and Me. preferences
26 | dotnet_style_qualification_for_event = false
27 | dotnet_style_qualification_for_field = false
28 | dotnet_style_qualification_for_method = false
29 | dotnet_style_qualification_for_property = false
30 |
31 | # Language keywords vs BCL types preferences
32 | dotnet_style_predefined_type_for_locals_parameters_members = true
33 | dotnet_style_predefined_type_for_member_access = true
34 |
35 | # Parentheses preferences
36 | dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
37 | dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
38 | dotnet_style_parentheses_in_other_operators = never_if_unnecessary
39 | dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
40 |
41 | # Modifier preferences
42 | dotnet_style_require_accessibility_modifiers = for_non_interface_members
43 |
44 | # Expression-level preferences
45 | dotnet_style_coalesce_expression = true
46 | dotnet_style_collection_initializer = true
47 | dotnet_style_explicit_tuple_names = true
48 | dotnet_style_namespace_match_folder = true
49 | dotnet_style_null_propagation = true
50 | dotnet_style_object_initializer = true
51 | dotnet_style_operator_placement_when_wrapping = beginning_of_line
52 | dotnet_style_prefer_auto_properties = true
53 | dotnet_style_prefer_compound_assignment = true
54 | dotnet_style_prefer_conditional_expression_over_assignment = true
55 | dotnet_style_prefer_conditional_expression_over_return = true
56 | dotnet_style_prefer_inferred_anonymous_type_member_names = true
57 | dotnet_style_prefer_inferred_tuple_names = true
58 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true
59 | dotnet_style_prefer_simplified_boolean_expressions = true
60 | dotnet_style_prefer_simplified_interpolation = true
61 |
62 | # Field preferences
63 | dotnet_style_readonly_field = true
64 |
65 | # Parameter preferences
66 | dotnet_code_quality_unused_parameters = all
67 |
68 | # Suppression preferences
69 | dotnet_remove_unnecessary_suppression_exclusions = none
70 |
71 | # New line preferences
72 | dotnet_style_allow_multiple_blank_lines_experimental = true
73 | dotnet_style_allow_statement_immediately_after_block_experimental = true
74 |
75 | #### C# Coding Conventions ####
76 |
77 | # var preferences
78 | csharp_style_var_elsewhere = true
79 | csharp_style_var_for_built_in_types = true
80 | csharp_style_var_when_type_is_apparent = true
81 |
82 | # Expression-bodied members
83 | csharp_style_expression_bodied_accessors = true
84 | csharp_style_expression_bodied_constructors = false
85 | csharp_style_expression_bodied_indexers = true
86 | csharp_style_expression_bodied_lambdas = true
87 | csharp_style_expression_bodied_local_functions = false
88 | csharp_style_expression_bodied_methods = false
89 | csharp_style_expression_bodied_operators = false
90 | csharp_style_expression_bodied_properties = true
91 |
92 | # Pattern matching preferences
93 | csharp_style_pattern_matching_over_as_with_null_check = true
94 | csharp_style_pattern_matching_over_is_with_cast_check = true
95 | csharp_style_prefer_not_pattern = true
96 | csharp_style_prefer_pattern_matching = true
97 | csharp_style_prefer_switch_expression = true
98 |
99 | # Null-checking preferences
100 | csharp_style_conditional_delegate_call = true
101 |
102 | # Modifier preferences
103 | csharp_prefer_static_local_function = true
104 | csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
105 |
106 | # Code-block preferences
107 | csharp_prefer_braces = true
108 | csharp_prefer_simple_using_statement = true
109 | csharp_style_namespace_declarations = block_scoped
110 |
111 | # Expression-level preferences
112 | csharp_prefer_simple_default_expression = true
113 | csharp_style_deconstructed_variable_declaration = true
114 | csharp_style_implicit_object_creation_when_type_is_apparent = true
115 | csharp_style_inlined_variable_declaration = true
116 | csharp_style_pattern_local_over_anonymous_function = true
117 | csharp_style_prefer_index_operator = true
118 | csharp_style_prefer_null_check_over_type_check = true
119 | csharp_style_prefer_range_operator = true
120 | csharp_style_throw_expression = true
121 | csharp_style_unused_value_assignment_preference = discard_variable
122 | csharp_style_unused_value_expression_statement_preference = discard_variable
123 |
124 | # 'using' directive preferences
125 | csharp_using_directive_placement = outside_namespace
126 |
127 | # New line preferences
128 | csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
129 | csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
130 | csharp_style_allow_embedded_statements_on_same_line_experimental = true
131 |
132 | #### C# Formatting Rules ####
133 |
134 | # New line preferences
135 | csharp_new_line_before_catch = true
136 | csharp_new_line_before_else = true
137 | csharp_new_line_before_finally = true
138 | csharp_new_line_before_members_in_anonymous_types = true
139 | csharp_new_line_before_members_in_object_initializers = true
140 | csharp_new_line_before_open_brace = all
141 | csharp_new_line_between_query_expression_clauses = true
142 |
143 | # Indentation preferences
144 | csharp_indent_block_contents = true
145 | csharp_indent_braces = false
146 | csharp_indent_case_contents = true
147 | csharp_indent_case_contents_when_block = true
148 | csharp_indent_labels = no_change
149 | csharp_indent_switch_labels = true
150 |
151 | # Space preferences
152 | csharp_space_after_cast = false
153 | csharp_space_after_colon_in_inheritance_clause = true
154 | csharp_space_after_comma = true
155 | csharp_space_after_dot = false
156 | csharp_space_after_keywords_in_control_flow_statements = true
157 | csharp_space_after_semicolon_in_for_statement = true
158 | csharp_space_around_binary_operators = before_and_after
159 | csharp_space_around_declaration_statements = false
160 | csharp_space_before_colon_in_inheritance_clause = true
161 | csharp_space_before_comma = false
162 | csharp_space_before_dot = false
163 | csharp_space_before_open_square_brackets = false
164 | csharp_space_before_semicolon_in_for_statement = false
165 | csharp_space_between_empty_square_brackets = false
166 | csharp_space_between_method_call_empty_parameter_list_parentheses = false
167 | csharp_space_between_method_call_name_and_opening_parenthesis = false
168 | csharp_space_between_method_call_parameter_list_parentheses = false
169 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
170 | csharp_space_between_method_declaration_name_and_open_parenthesis = false
171 | csharp_space_between_method_declaration_parameter_list_parentheses = false
172 | csharp_space_between_parentheses = false
173 | csharp_space_between_square_brackets = false
174 |
175 | # Wrapping preferences
176 | csharp_preserve_single_line_blocks = true
177 | csharp_preserve_single_line_statements = true
178 |
179 | #### Naming styles ####
180 |
181 | # Naming rules
182 |
183 | dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
184 | dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
185 | dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
186 |
187 | dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
188 | dotnet_naming_rule.types_should_be_pascal_case.symbols = types
189 | dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
190 |
191 | dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
192 | dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
193 | dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
194 |
195 | # Symbol specifications
196 |
197 | dotnet_naming_symbols.interface.applicable_kinds = interface
198 | dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
199 | dotnet_naming_symbols.interface.required_modifiers =
200 |
201 | dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
202 | dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
203 | dotnet_naming_symbols.types.required_modifiers =
204 |
205 | dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
206 | dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
207 | dotnet_naming_symbols.non_field_members.required_modifiers =
208 |
209 | # Naming styles
210 |
211 | dotnet_naming_style.pascal_case.required_prefix =
212 | dotnet_naming_style.pascal_case.required_suffix =
213 | dotnet_naming_style.pascal_case.word_separator =
214 | dotnet_naming_style.pascal_case.capitalization = pascal_case
215 |
216 | dotnet_naming_style.begins_with_i.required_prefix = I
217 | dotnet_naming_style.begins_with_i.required_suffix =
218 | dotnet_naming_style.begins_with_i.word_separator =
219 | dotnet_naming_style.begins_with_i.capitalization = pascal_case
220 |
221 | # Options
222 |
223 | roslynator_accessibility_modifiers = explicit
224 | # Applicable to: rcs1018
225 |
226 | roslynator_accessor_braces_style = multi_line
227 | # Default: multi_line
228 | # Applicable to: rcs0020
229 |
230 | roslynator_array_creation_type_style = implicit
231 | # Applicable to: rcs1014
232 |
233 | roslynator_arrow_token_new_line = before
234 | # Applicable to: rcs0032
235 |
236 | roslynator_binary_operator_new_line = before
237 | # Applicable to: rcs0027
238 |
239 | roslynator_blank_line_between_closing_brace_and_switch_section = true
240 | # Applicable to: rcs0014, rcs1036
241 |
242 | roslynator_blank_line_between_single_line_accessors = true
243 | # Applicable to: rcs0011
244 |
245 | roslynator_blank_line_between_using_directives = separate_groups
246 | # Applicable to: rcs0015
247 |
248 | roslynator_body_style = expression
249 | # Applicable to: rcs1016
250 |
251 | roslynator_conditional_operator_condition_parentheses_style = omit_when_condition_is_single_token
252 | # Applicable to: rcs1051
253 |
254 | roslynator_conditional_operator_new_line = before
255 | # Applicable to: rcs0028
256 |
257 | roslynator_configure_await = true
258 | # Applicable to: rcs1090
259 |
260 | roslynator_empty_string_style = literal
261 | # Applicable to: rcs1078
262 |
263 | roslynator_enum_has_flag_style = operator
264 | # Applicable to: rcs1096
265 |
266 | roslynator_equals_token_new_line = before
267 | # Applicable to: rcs0052
268 |
269 | roslynator_new_line_at_end_of_file = true
270 | # Applicable to: rcs0058
271 |
272 | roslynator_new_line_before_while_in_do_statement = false
273 | # Applicable to: rcs0051
274 |
275 | roslynator_null_conditional_operator_new_line = before
276 | # Applicable to: rcs0059
277 |
278 | roslynator_null_check_style = pattern_matching
279 | # Applicable to: rcs1248
280 |
281 | roslynator_object_creation_parentheses_style = omit
282 | # Applicable to: rcs1050
283 |
284 | roslynator_object_creation_type_style = implicit_when_type_is_obvious
285 | # Applicable to: rcs1250
286 |
287 | roslynator_prefix_field_identifier_with_underscore = true
288 |
289 | roslynator_suppress_unity_script_methods = true
290 | # Applicable to: rcs1213
291 |
292 | roslynator_use_anonymous_function_or_method_group = anonymous_function
293 | # Applicable to: rcs1207
294 |
295 | roslynator_use_block_body_when_declaration_spans_over_multiple_lines = true
296 | # Applicable to: rcs1016
297 |
298 | roslynator_use_block_body_when_expression_spans_over_multiple_lines = true
299 | # Applicable to: rcs1016
300 |
301 | roslynator_use_var_instead_of_implicit_object_creation = true
302 | # Applicable to: rcs1250
303 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: nuget
4 | directories:
5 | - "**/*"
6 | schedule:
7 | interval: daily
8 | open-pull-requests-limit: 10
9 | - package-ecosystem: "github-actions"
10 | directory: "/"
11 | schedule:
12 | interval: daily
13 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | name: "Code scanning - action"
2 |
3 | on:
4 | push:
5 | branches-ignore:
6 | - 'dependabot/**'
7 | pull_request:
8 | schedule:
9 | - cron: '0 14 * * 6'
10 |
11 | jobs:
12 | CodeQL-Build:
13 |
14 | runs-on: ubuntu-latest
15 |
16 | permissions:
17 | security-events: write
18 |
19 | steps:
20 | - name: Checkout repository
21 | uses: actions/checkout@v4
22 | with:
23 | # We must fetch at least the immediate parents so that if this is
24 | # a pull request then we can checkout the head.
25 | fetch-depth: 2
26 | persist-credentials: false
27 |
28 | # If this run was triggered by a pull request event, then checkout
29 | # the head of the pull request instead of the merge commit.
30 | - run: git checkout HEAD^2
31 | if: ${{ github.event_name == 'pull_request' }}
32 |
33 | - name: Setup .NET
34 | uses: actions/setup-dotnet@v4
35 | with:
36 | dotnet-version: |
37 | 8.0.x
38 | 9.0.x
39 |
40 | # Initializes the CodeQL tools for scanning.
41 | - name: Initialize CodeQL
42 | uses: github/codeql-action/init@v3
43 | # Override language selection by uncommenting this and choosing your languages
44 | # with:
45 | # languages: go, javascript, csharp, python, cpp, java
46 |
47 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
48 | # If this step fails, then you should remove it and run the build manually (see below)
49 | - name: Autobuild
50 | uses: github/codeql-action/autobuild@v3
51 |
52 | # ℹ️ Command-line programs to run using the OS shell.
53 | # 📚 https://git.io/JvXDl
54 |
55 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
56 | # and modify them (or add more) to build your code if your project
57 | # uses a compiled language
58 |
59 | #- run: |
60 | # make bootstrap
61 | # make release
62 |
63 | - name: Perform CodeQL Analysis
64 | uses: github/codeql-action/analyze@v3
65 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Run tests
2 | on:
3 | push:
4 | pull_request:
5 | schedule:
6 | - cron: '3 20 * * SUN'
7 |
8 | permissions: {}
9 |
10 | jobs:
11 | build:
12 | strategy:
13 | matrix:
14 | platform: [ubuntu-latest, macos-latest, windows-latest]
15 | runs-on: ${{ matrix.platform }}
16 | name: Dotnet on ${{ matrix.platform }}
17 | steps:
18 | - uses: actions/checkout@v4
19 | with:
20 | submodules: true
21 | persist-credentials: false
22 |
23 | - name: Setup .NET
24 | uses: actions/setup-dotnet@v4
25 | with:
26 | dotnet-version: |
27 | 8.0.x
28 | 9.0.x
29 |
30 | - name: Build
31 | run: |
32 | dotnet build MaxMind.Db
33 | dotnet build MaxMind.Db.Benchmark
34 | dotnet build MaxMind.Db.Test
35 |
36 | - name: Run benchmark
37 | run: dotnet run -f net8.0 --project MaxMind.Db.Benchmark/MaxMind.Db.Benchmark.csproj
38 | env:
39 | MAXMIND_BENCHMARK_DB: ${{ github.workspace }}/MaxMind.Db.Test/TestData/MaxMind-DB/test-data/GeoIP2-City-Test.mmdb
40 |
41 | - name: Run tests
42 | run: dotnet test MaxMind.Db.Test/MaxMind.Db.Test.csproj
43 | env:
44 | MAXMIND_TEST_BASE_DIR: ${{ github.workspace }}/MaxMind.Db.Test
45 |
--------------------------------------------------------------------------------
/.github/workflows/zizmor.yml:
--------------------------------------------------------------------------------
1 | name: GitHub Actions Security Analysis with zizmor
2 |
3 | on:
4 | push:
5 | branches: ["main"]
6 | pull_request:
7 | branches: ["**"]
8 |
9 | jobs:
10 | zizmor:
11 | name: zizmor latest via PyPI
12 | runs-on: ubuntu-latest
13 | permissions:
14 | security-events: write
15 | # required for workflows in private repositories
16 | contents: read
17 | actions: read
18 | steps:
19 | - name: Checkout repository
20 | uses: actions/checkout@v4
21 | with:
22 | persist-credentials: false
23 |
24 | - name: Install the latest version of uv
25 | uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # 6.1.0
26 | with:
27 | enable-cache: false
28 |
29 | - name: Run zizmor
30 | run: uvx zizmor@1.7.0 --format plain .
31 | env:
32 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
2 | [Bb]in/
3 | [Oo]bj/
4 |
5 | # dotnet CLI stuff
6 | .dotnetcli/
7 | scripts/
8 |
9 | # mstest test results
10 | TestResults
11 |
12 | ## Ignore Visual Studio temporary files, build results, and
13 | ## files generated by popular Visual Studio add-ons.
14 |
15 | # Visual Studo 2015 cache/options directory
16 | .vs/
17 |
18 | # User-specific files
19 | *.suo
20 | *.user
21 | *.sln.docstates
22 |
23 | # Build results
24 | [Dd]ebug/
25 | [Rr]elease/
26 | x64/
27 | *_i.c
28 | *_p.c
29 | *.ilk
30 | *.meta
31 | *.nupkg
32 | *.obj
33 | *.pch
34 | *.pdb
35 | *.pgc
36 | *.pgd
37 | *.rsp
38 | *.sbr
39 | *.tlb
40 | *.tli
41 | *.tlh
42 | *.tmp
43 | *.log
44 | *.vspscc
45 | *.vssscc
46 | .builds
47 |
48 | # Visual C++ cache files
49 | ipch/
50 | *.aps
51 | *.ncb
52 | *.opensdf
53 | *.sdf
54 |
55 | # Visual Studio profiler
56 | *.psess
57 | *.vsp
58 | *.vspx
59 |
60 | # Guidance Automation Toolkit
61 | *.gpState
62 |
63 | # ReSharper is a .NET coding add-in
64 | _ReSharper*
65 | *.DotSettings
66 |
67 | # NCrunch
68 | *.ncrunch*
69 | .*crunch*.local.xml
70 |
71 | # Installshield output folder
72 | [Ee]xpress
73 |
74 | # DocProject is a documentation generator add-in
75 | DocProject/buildhelp/
76 | DocProject/Help/*.HxT
77 | DocProject/Help/*.HxC
78 | DocProject/Help/*.hhc
79 | DocProject/Help/*.hhk
80 | DocProject/Help/*.hhp
81 | DocProject/Help/Html2
82 | DocProject/Help/html
83 |
84 | # Click-Once directory
85 | publish
86 |
87 | # Publish Web Output
88 | *.Publish.xml
89 |
90 | # NuGet Packages Directory
91 | packages
92 | *.lock.json
93 |
94 | # Windows Azure Build Output
95 | csx
96 | *.build.csdef
97 |
98 | # Windows Store app package directory
99 | AppPackages/
100 |
101 | # Others
102 | [Bb]in
103 | [Oo]bj
104 | artifacts
105 | sql
106 | TestResults
107 | [Tt]est[Rr]esult*
108 | *.Cache
109 | ClientBin
110 | [Ss]tyle[Cc]op.*
111 | ~$*
112 | *.dbmdl
113 | Generated_Code #added for RIA/Silverlight projects
114 |
115 | # Backup & report files from converting an old project file to a newer
116 | # Visual Studio version. Backup files are not needed, because we have git ;-)
117 | _UpgradeReport_Files/
118 | Backup*/
119 | UpgradeLog*.XML
120 | UPgradeLog.htm
121 |
122 | # MonoDevelop
123 | *.userprefs
124 | test-results
125 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "MaxMind.Db.Test/TestData/MaxMind-DB"]
2 | path = MaxMind.Db.Test/TestData/MaxMind-DB
3 | url = https://github.com/maxmind/MaxMind-DB.git
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction, and
10 | distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright
13 | owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all other entities
16 | that control, are controlled by, or are under common control with that entity.
17 | For the purposes of this definition, "control" means (i) the power, direct or
18 | indirect, to cause the direction or management of such entity, whether by
19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
20 | outstanding shares, or (iii) beneficial ownership of such entity.
21 |
22 | "You" (or "Your") shall mean an individual or Legal Entity exercising
23 | permissions granted by this License.
24 |
25 | "Source" form shall mean the preferred form for making modifications, including
26 | but not limited to software source code, documentation source, and configuration
27 | files.
28 |
29 | "Object" form shall mean any form resulting from mechanical transformation or
30 | translation of a Source form, including but not limited to compiled object code,
31 | generated documentation, and conversions to other media types.
32 |
33 | "Work" shall mean the work of authorship, whether in Source or Object form, made
34 | available under the License, as indicated by a copyright notice that is included
35 | in or attached to the work (an example is provided in the Appendix below).
36 |
37 | "Derivative Works" shall mean any work, whether in Source or Object form, that
38 | is based on (or derived from) the Work and for which the editorial revisions,
39 | annotations, elaborations, or other modifications represent, as a whole, an
40 | original work of authorship. For the purposes of this License, Derivative Works
41 | shall not include works that remain separable from, or merely link (or bind by
42 | name) to the interfaces of, the Work and Derivative Works thereof.
43 |
44 | "Contribution" shall mean any work of authorship, including the original version
45 | of the Work and any modifications or additions to that Work or Derivative Works
46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work
47 | by the copyright owner or by an individual or Legal Entity authorized to submit
48 | on behalf of the copyright owner. For the purposes of this definition,
49 | "submitted" means any form of electronic, verbal, or written communication sent
50 | to the Licensor or its representatives, including but not limited to
51 | communication on electronic mailing lists, source code control systems, and
52 | issue tracking systems that are managed by, or on behalf of, the Licensor for
53 | the purpose of discussing and improving the Work, but excluding communication
54 | that is conspicuously marked or otherwise designated in writing by the copyright
55 | owner as "Not a Contribution."
56 |
57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf
58 | of whom a Contribution has been received by Licensor and subsequently
59 | incorporated within the Work.
60 |
61 | 2. Grant of Copyright License.
62 |
63 | Subject to the terms and conditions of this License, each Contributor hereby
64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
65 | irrevocable copyright license to reproduce, prepare Derivative Works of,
66 | publicly display, publicly perform, sublicense, and distribute the Work and such
67 | Derivative Works in Source or Object form.
68 |
69 | 3. Grant of Patent License.
70 |
71 | Subject to the terms and conditions of this License, each Contributor hereby
72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
73 | irrevocable (except as stated in this section) patent license to make, have
74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where
75 | such license applies only to those patent claims licensable by such Contributor
76 | that are necessarily infringed by their Contribution(s) alone or by combination
77 | of their Contribution(s) with the Work to which such Contribution(s) was
78 | submitted. If You institute patent litigation against any entity (including a
79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a
80 | Contribution incorporated within the Work constitutes direct or contributory
81 | patent infringement, then any patent licenses granted to You under this License
82 | for that Work shall terminate as of the date such litigation is filed.
83 |
84 | 4. Redistribution.
85 |
86 | You may reproduce and distribute copies of the Work or Derivative Works thereof
87 | in any medium, with or without modifications, and in Source or Object form,
88 | provided that You meet the following conditions:
89 |
90 | You must give any other recipients of the Work or Derivative Works a copy of
91 | this License; and
92 | You must cause any modified files to carry prominent notices stating that You
93 | changed the files; and
94 | You must retain, in the Source form of any Derivative Works that You distribute,
95 | all copyright, patent, trademark, and attribution notices from the Source form
96 | of the Work, excluding those notices that do not pertain to any part of the
97 | Derivative Works; and
98 | If the Work includes a "NOTICE" text file as part of its distribution, then any
99 | Derivative Works that You distribute must include a readable copy of the
100 | attribution notices contained within such NOTICE file, excluding those notices
101 | that do not pertain to any part of the Derivative Works, in at least one of the
102 | following places: within a NOTICE text file distributed as part of the
103 | Derivative Works; within the Source form or documentation, if provided along
104 | with the Derivative Works; or, within a display generated by the Derivative
105 | Works, if and wherever such third-party notices normally appear. The contents of
106 | the NOTICE file are for informational purposes only and do not modify the
107 | License. You may add Your own attribution notices within Derivative Works that
108 | You distribute, alongside or as an addendum to the NOTICE text from the Work,
109 | provided that such additional attribution notices cannot be construed as
110 | modifying the License.
111 | You may add Your own copyright statement to Your modifications and may provide
112 | additional or different license terms and conditions for use, reproduction, or
113 | distribution of Your modifications, or for any such Derivative Works as a whole,
114 | provided Your use, reproduction, and distribution of the Work otherwise complies
115 | with the conditions stated in this License.
116 |
117 | 5. Submission of Contributions.
118 |
119 | Unless You explicitly state otherwise, any Contribution intentionally submitted
120 | for inclusion in the Work by You to the Licensor shall be under the terms and
121 | conditions of this License, without any additional terms or conditions.
122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of
123 | any separate license agreement you may have executed with Licensor regarding
124 | such Contributions.
125 |
126 | 6. Trademarks.
127 |
128 | This License does not grant permission to use the trade names, trademarks,
129 | service marks, or product names of the Licensor, except as required for
130 | reasonable and customary use in describing the origin of the Work and
131 | reproducing the content of the NOTICE file.
132 |
133 | 7. Disclaimer of Warranty.
134 |
135 | Unless required by applicable law or agreed to in writing, Licensor provides the
136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
138 | including, without limitation, any warranties or conditions of TITLE,
139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
140 | solely responsible for determining the appropriateness of using or
141 | redistributing the Work and assume any risks associated with Your exercise of
142 | permissions under this License.
143 |
144 | 8. Limitation of Liability.
145 |
146 | In no event and under no legal theory, whether in tort (including negligence),
147 | contract, or otherwise, unless required by applicable law (such as deliberate
148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be
149 | liable to You for damages, including any direct, indirect, special, incidental,
150 | or consequential damages of any character arising as a result of this License or
151 | out of the use or inability to use the Work (including but not limited to
152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or
153 | any and all other commercial damages or losses), even if such Contributor has
154 | been advised of the possibility of such damages.
155 |
156 | 9. Accepting Warranty or Additional Liability.
157 |
158 | While redistributing the Work or Derivative Works thereof, You may choose to
159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or
160 | other liability obligations and/or rights consistent with this License. However,
161 | in accepting such obligations, You may act only on Your own behalf and on Your
162 | sole responsibility, not on behalf of any other Contributor, and only if You
163 | agree to indemnify, defend, and hold each Contributor harmless for any liability
164 | incurred by, or claims asserted against, such Contributor by reason of your
165 | accepting any such warranty or additional liability.
166 |
167 | END OF TERMS AND CONDITIONS
168 |
169 | APPENDIX: How to apply the Apache License to your work
170 |
171 | To apply the Apache License to your work, attach the following boilerplate
172 | notice, with the fields enclosed by brackets "[]" replaced with your own
173 | identifying information. (Don't include the brackets!) The text should be
174 | enclosed in the appropriate comment syntax for the file format. We also
175 | recommend that a file or class name and description of purpose be included on
176 | the same "printed page" as the copyright notice for easier identification within
177 | third-party archives.
178 |
179 | Copyright [yyyy] [name of copyright owner]
180 |
181 | Licensed under the Apache License, Version 2.0 (the "License");
182 | you may not use this file except in compliance with the License.
183 | You may obtain a copy of the License at
184 |
185 | http://www.apache.org/licenses/LICENSE-2.0
186 |
187 | Unless required by applicable law or agreed to in writing, software
188 | distributed under the License is distributed on an "AS IS" BASIS,
189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
190 | See the License for the specific language governing permissions and
191 | limitations under the License.
192 |
--------------------------------------------------------------------------------
/MaxMind-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maxmind/MaxMind-DB-Reader-dotnet/d78205669bf782f27ffc3033367c29b0459713ae/MaxMind-logo.png
--------------------------------------------------------------------------------
/MaxMind.Db.Benchmark/MaxMind.Db.Benchmark.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Benchmark project to validate .NET reader for the MaxMind DB file format
5 | 4.0.0
6 | net9.0;net8.0;net481
7 | net9.0;net8.0
8 | MaxMind.Db.Benchmark
9 | Exe
10 | MaxMind.Db.Benchmark
11 | https://github.com/maxmind/MaxMind-DB-Reader-dotnet
12 | Apache-2.0
13 | false
14 | false
15 | false
16 | false
17 | false
18 | false
19 | false
20 | false
21 | 13.0
22 | enable
23 | latest
24 | true
25 | true
26 | true
27 |
28 |
29 |
30 | AnyCPU
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/MaxMind.Db.Benchmark/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Attributes;
2 | using BenchmarkDotNet.Configs;
3 | using BenchmarkDotNet.Running;
4 | using MaxMind.Db;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Collections.ObjectModel;
8 | using System.Linq;
9 | using System.Net;
10 |
11 | BenchmarkRunner.Run(new DebugInProcessConfig());
12 |
13 | [MemoryDiagnoser]
14 | public class CityBenchmark
15 | {
16 | // A random IP that has city info.
17 | private Reader _reader = null!;
18 | private IPAddress[] _ipAddresses = [];
19 |
20 | [GlobalSetup]
21 | public void GlobalSetup()
22 | {
23 | const string dbPathVarName = "MAXMIND_BENCHMARK_DB";
24 | string dbPath = Environment.GetEnvironmentVariable(dbPathVarName) ??
25 | throw new InvalidOperationException($"{dbPathVarName} was not set");
26 | _reader = new Reader(dbPath);
27 |
28 | const string ipAddressesVarName = "MAXMIND_BENCHMARK_IP_ADDRESSES";
29 | string ipAddressesStr = Environment.GetEnvironmentVariable(ipAddressesVarName) ?? "";
30 | _ipAddresses = ipAddressesStr
31 | .Split([','], StringSplitOptions.RemoveEmptyEntries)
32 | .Select(IPAddress.Parse)
33 | .ToArray();
34 | if (_ipAddresses.Length == 0)
35 | {
36 | Random random = new(Seed: 0);
37 | List list = [];
38 | for (int i = 0; i < 1_000; i += 1)
39 | {
40 | list.Add(new IPAddress(random.Next()));
41 | }
42 |
43 | _ipAddresses = list.ToArray();
44 | }
45 | }
46 |
47 | [GlobalCleanup]
48 | public void GlobalCleanup()
49 | {
50 | _reader.Dispose();
51 | }
52 |
53 | [Benchmark]
54 | public int City()
55 | {
56 | int x = 0;
57 | foreach (var ipAddress in _ipAddresses)
58 | {
59 | if (_reader.Find(ipAddress) != null)
60 | {
61 | x += 1;
62 | }
63 | }
64 |
65 | return x;
66 | }
67 | }
68 |
69 | public abstract class AbstractCountryResponse
70 | {
71 | protected AbstractCountryResponse(
72 | Continent? continent = null,
73 | Country? country = null,
74 | Country? registeredCountry = null)
75 | {
76 | Continent = continent ?? new Continent();
77 | Country = country ?? new Country();
78 | RegisteredCountry = registeredCountry ?? new Country();
79 | }
80 |
81 | public Continent Continent { get; internal set; }
82 | public Country Country { get; internal set; }
83 | public Country RegisteredCountry { get; internal set; }
84 | }
85 |
86 | public abstract class AbstractCityResponse : AbstractCountryResponse
87 | {
88 | protected AbstractCityResponse(
89 | City? city = null,
90 | Continent? continent = null,
91 | Country? country = null,
92 | Location? location = null,
93 | Country? registeredCountry = null,
94 | IReadOnlyList? subdivisions = null)
95 | : base(continent, country, registeredCountry)
96 | {
97 | City = city ?? new City();
98 | Location = location ?? new Location();
99 | Subdivisions = subdivisions ?? new List().AsReadOnly();
100 | }
101 |
102 | public City City { get; internal set; }
103 | public Location Location { get; internal set; }
104 | public IReadOnlyList Subdivisions { get; internal set; }
105 | }
106 |
107 | public class CityResponse : AbstractCityResponse
108 | {
109 | [Constructor]
110 | public CityResponse(
111 | City? city = null,
112 | Continent? continent = null,
113 | Country? country = null,
114 | Location? location = null,
115 | [Parameter("registered_country")] Country? registeredCountry = null)
116 | : base(city, continent, country, location, registeredCountry)
117 | {
118 | }
119 | }
120 |
121 | public class City : NamedEntity
122 | {
123 | [Constructor]
124 | public City(int? confidence = null,
125 | [Parameter("geoname_id")] long? geoNameId = null,
126 | IReadOnlyDictionary? names = null,
127 | IReadOnlyList? locales = null)
128 | : base(geoNameId, names, locales)
129 | {
130 | Confidence = confidence;
131 | }
132 |
133 | public int? Confidence { get; internal set; }
134 | }
135 |
136 | public abstract class NamedEntity
137 | {
138 | [Constructor]
139 | protected NamedEntity(long? geoNameId = null, IReadOnlyDictionary? names = null,
140 | IReadOnlyList? locales = null)
141 | {
142 | Names = names ?? new ReadOnlyDictionary(new Dictionary());
143 | GeoNameId = geoNameId;
144 | Locales = locales ?? new List { "en" }.AsReadOnly();
145 | }
146 |
147 | public IReadOnlyDictionary Names { get; internal set; }
148 | public long? GeoNameId { get; internal set; }
149 | protected internal IReadOnlyList Locales { get; set; }
150 | public string? Name
151 | {
152 | get
153 | {
154 | var locale = Locales.FirstOrDefault(l => Names.ContainsKey(l));
155 | return locale == null ? null : Names[locale];
156 | }
157 | }
158 | }
159 |
160 | public class Continent : NamedEntity
161 | {
162 | [Constructor]
163 | public Continent(
164 | string? code = null,
165 | [Parameter("geoname_id")] long? geoNameId = null,
166 | IReadOnlyDictionary? names = null,
167 | IReadOnlyList? locales = null)
168 | : base(geoNameId, names, locales)
169 | {
170 | Code = code;
171 | }
172 |
173 | public string? Code { get; internal set; }
174 | }
175 |
176 | public class Country : NamedEntity
177 | {
178 | [Constructor]
179 | public Country(
180 | int? confidence = null,
181 | [Parameter("geoname_id")] long? geoNameId = null,
182 | [Parameter("is_in_european_union")] bool isInEuropeanUnion = false,
183 | [Parameter("iso_code")] string? isoCode = null,
184 | IReadOnlyDictionary? names = null,
185 | IReadOnlyList? locales = null)
186 | : base(geoNameId, names, locales)
187 | {
188 | Confidence = confidence;
189 | IsoCode = isoCode;
190 | IsInEuropeanUnion = isInEuropeanUnion;
191 | }
192 |
193 | public int? Confidence { get; internal set; }
194 | public bool IsInEuropeanUnion { get; internal set; }
195 | public string? IsoCode { get; internal set; }
196 | }
197 |
198 | public class Location
199 | {
200 | [Constructor]
201 | public Location(
202 | [Parameter("accuracy_radius")] int? accuracyRadius = null,
203 | double? latitude = null,
204 | double? longitude = null,
205 | [Parameter("time_zone")] string? timeZone = null)
206 | {
207 | AccuracyRadius = accuracyRadius;
208 | Latitude = latitude;
209 | Longitude = longitude;
210 | TimeZone = timeZone;
211 | }
212 |
213 | public int? AccuracyRadius { get; internal set; }
214 | public int? AverageIncome { get; internal set; }
215 | public bool HasCoordinates => Latitude.HasValue && Longitude.HasValue;
216 | public double? Latitude { get; internal set; }
217 | public double? Longitude { get; internal set; }
218 | public int? PopulationDensity { get; internal set; }
219 | public string? TimeZone { get; internal set; }
220 | }
221 |
222 | public class Subdivision : NamedEntity
223 | {
224 | [Constructor]
225 | public Subdivision(
226 | int? confidence = null,
227 | [Parameter("geoname_id")] long? geoNameId = null,
228 | [Parameter("iso_code")] string? isoCode = null,
229 | IReadOnlyDictionary? names = null,
230 | IReadOnlyList? locales = null)
231 | : base(geoNameId, names, locales)
232 | {
233 | Confidence = confidence;
234 | IsoCode = isoCode;
235 | }
236 |
237 | public int? Confidence { get; internal set; }
238 | public string? IsoCode { get; internal set; }
239 | }
--------------------------------------------------------------------------------
/MaxMind.Db.Benchmark/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | #region
2 |
3 | using System.Reflection;
4 | using System.Runtime.InteropServices;
5 |
6 | #endregion
7 |
8 | // General Information about an assembly is controlled through the following
9 | // set of attributes. Change these attribute values to modify the information
10 | // associated with an assembly.
11 |
12 | [assembly: AssemblyTitle("Test")]
13 | [assembly: AssemblyDescription("")]
14 | [assembly: AssemblyConfiguration("")]
15 | [assembly: AssemblyCompany("Microsoft")]
16 | [assembly: AssemblyProduct("Test")]
17 | [assembly: AssemblyCopyright("Copyright © Microsoft 2015")]
18 | [assembly: AssemblyTrademark("")]
19 | [assembly: AssemblyCulture("")]
20 |
21 | // Setting ComVisible to false makes the types in this assembly not visible
22 | // to COM components. If you need to access a type in this assembly from
23 | // COM, set the ComVisible attribute to true on that type.
24 |
25 | [assembly: ComVisible(false)]
26 |
27 | // The following GUID is for the ID of the typelib if this project is exposed to COM
28 |
29 | [assembly: Guid("44f6ab62-9326-4383-9954-1357a8160621")]
30 |
31 | // Version information for an assembly consists of the following four values:
32 | //
33 | // Major Version
34 | // Minor Version
35 | // Build Number
36 | // Revision
37 | //
38 | // You can specify all the values or you can default the Build and Revision Numbers
39 | // by using the '*' as shown below:
40 | // [assembly: AssemblyVersion("1.0.*")]
41 |
42 | [assembly: AssemblyVersion("1.0.1.0")]
43 | [assembly: AssemblyFileVersion("1.0.1.0")]
--------------------------------------------------------------------------------
/MaxMind.Db.Test/.runsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | x64
5 |
6 |
7 |
--------------------------------------------------------------------------------
/MaxMind.Db.Test/DecoderTest.cs:
--------------------------------------------------------------------------------
1 | #region
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Numerics;
6 | using System.Text;
7 | using Xunit;
8 |
9 | #endregion
10 |
11 | namespace MaxMind.Db.Test
12 | {
13 | public static class DecoderTest
14 | {
15 | [Theory]
16 | [MemberData(nameof(TestUInt16))]
17 | [MemberData(nameof(TestUInt32))]
18 | [MemberData(nameof(TestInt32s))]
19 | [MemberData(nameof(TestUInt64s))]
20 | [MemberData(nameof(TestBigIntegers))]
21 | [MemberData(nameof(TestDoubles))]
22 | [MemberData(nameof(TestFloats))]
23 | [MemberData(nameof(TestPointers))]
24 | [MemberData(nameof(TestStrings))]
25 | [MemberData(nameof(TestBooleans))]
26 | [MemberData(nameof(TestBytes))]
27 | [MemberData(nameof(TestMaps))]
28 | [MemberData(nameof(TestArrays))]
29 | public static void TestTypeDecoding(Dictionary tests) where T : class
30 | {
31 | foreach (var entry in tests)
32 | {
33 | var expect = entry.Key;
34 | var input = entry.Value;
35 |
36 | using var database = new ArrayBuffer(input);
37 | var decoder = new Decoder(database, 0, false);
38 | var val = decoder.Decode(0, out _);
39 | Assert.Equal(expect, val);
40 | }
41 | }
42 |
43 | public static IEnumerable