Skip to content

Commit

Permalink
Testing with antiHashIndex being reset.
Browse files Browse the repository at this point in the history
  • Loading branch information
RealTimeChris committed Dec 25, 2024
1 parent a4a22ff commit 70b20cf
Show file tree
Hide file tree
Showing 44 changed files with 2,054 additions and 1,762 deletions.
158 changes: 158 additions & 0 deletions Documentation/Parsing_Arbitrary_Data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
## Using `jsonifier` for Parsing Unknown or Arbitrary JSON Structures

`jsonifier` offers powerful tools for handling JSON data with flexibility and efficiency. This document explains how to use the library to parse JSON when the structure is unknown at runtime or to verify the presence of values at specific keys.

### Key Components

#### 1. **Custom Structure (`custom_struct_raw`)**

This structure models the data we wish to serialize or deserialize:

```cpp
struct custom_struct_raw {
std::string testString{ "test_string" };
int64_t testInt{ 234234 };
bool testBool{true};
std::vector<std::string> testVector{ "test01", "test02", "test03", "test04" };
};
```
#### 2. **Mapping the Structure**
The `jsonifier::core` template specialization enables automatic parsing and serialization of `custom_struct_raw`:
```cpp
template<> struct jsonifier::core<custom_struct_raw> {
static constexpr auto parseValue = createValue<
&custom_struct_raw::testBool,
&custom_struct_raw::testInt,
&custom_struct_raw::testString,
&custom_struct_raw::testVector
>();
};
```

This mapping specifies how the structure's fields map to JSON keys.

#### 3. **`jsonifier::raw_json_data`**

This flexible data structure can:
- Parse and hold arbitrary JSON data, allowing dynamic exploration of its contents.
- Be used to verify that certain keys or values exist, regardless of the schema.

#### 4. **`jsonifier::jsonifier_core`**

This is the core parser and serializer for handling JSON data. It:
- Serializes structures into JSON strings.
- Parses JSON strings into the target data structure or `raw_json_data` for dynamic exploration.

---

### Parsing Arbitrary JSON Structures

#### Example Workflow

The following example demonstrates how to parse JSON with an unknown structure or validate key existence.

#### Example 1: Serialize a Custom Structure

Use `jsonifier_core` to serialize a `custom_struct_raw` instance:

```cpp
custom_struct_raw testData{};
jsonifier::jsonifier_core parser{};
std::string testString{};
parser.serializeJson(testData, testString);
std::cout << "CURRENT DATA: " << testString << std::endl;
```

Output:

```json
{
"testString": "test_string",
"testInt": 234234,
"testBool": true,
"testVector": ["test01", "test02", "test03", "test04"]
}
```

#### Example 2: Parse JSON into `raw_json_data`

```cpp
jsonifier::raw_json_data testRawData{};
parser.parseJson(testRawData, testString);
std::cout << "CURRENT VALUES: " << testRawData.rawJson() << std::endl;
```

This populates `testRawData` with a dynamic representation of the JSON.

#### Example 3: Dynamic Exploration of JSON Data

Using `getObject` and `getArray`, explore the parsed JSON dynamically:

```cpp
for (auto& [key, value] : testRawData.getObject()) {
if (value.getType() == jsonifier::json_type::array) {
for (auto& valueNew : value.getArray()) {
std::cout << "Array Value: " << valueNew.rawJson() << std::endl;
}
} else if (value.getType() != jsonifier::json_type::unset) {
std::cout << "Key " << key << " was parsed successfully." << std::endl;
}
std::cout << "Key: " << key << ", Value: " << value.rawJson() << std::endl;
}
```

#### Output Verification

For the given JSON:

```json
{
"testString": "test_string",
"testInt": 234234,
"testBool": true,
"testVector": ["test01", "test02", "test03", "test04"]
}
```

The output might be:

```
Key: testString, Value: "test_string"
Key testString was parsed successfully.
Key: testInt, Value: 234234
Key testInt was parsed successfully.
Key: testBool, Value: true
Key testBool was parsed successfully.
Array Value: "test01"
Array Value: "test02"
Array Value: "test03"
Array Value: "test04"
Key: testVector, Value: ["test01", "test02", "test03", "test04"]
```

---

### Applications

#### 1. **Parsing Arbitrary JSON**

The `raw_json_data` structure is ideal when the JSON schema is unknown. It provides dynamic access to JSON contents and type information.

#### 2. **Validation of Key-Value Pairs**

This approach ensures that certain keys are present in the parsed JSON and allows verification of their types and values.

#### 3. **Interoperability**

Integrate `jsonifier` into systems that require flexible JSON handling without prior knowledge of the schema.

---

### Conclusion

The `jsonifier` library and its `raw_json_data` structure provide a robust way to parse, validate, and explore JSON data dynamically. By combining serialization with dynamic parsing, it allows developers to handle both known and unknown JSON structures efficiently.

---
14 changes: 7 additions & 7 deletions Include/jsonifier/Allocator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

namespace jsonifier_internal {

template<auto multiple, typename value_type = decltype(multiple)> JSONIFIER_ALWAYS_INLINE constexpr value_type roundUpToMultiple(value_type value) noexcept {
template<auto multiple, typename value_type = decltype(multiple)> JSONIFIER_FORCE_INLINE constexpr value_type roundUpToMultiple(value_type value) noexcept {
if constexpr ((multiple & (multiple - 1)) == 0) {
return (value + (multiple - 1)) & ~(multiple - 1);
} else {
Expand All @@ -38,7 +38,7 @@ namespace jsonifier_internal {
}
}

template<auto multiple, typename value_type = decltype(multiple)> JSONIFIER_ALWAYS_INLINE constexpr value_type roundDownToMultiple(value_type value) noexcept {
template<auto multiple, typename value_type = decltype(multiple)> JSONIFIER_FORCE_INLINE constexpr value_type roundDownToMultiple(value_type value) noexcept {
if constexpr ((multiple & (multiple - 1)) == 0) {
return value & ~(multiple - 1);
} else {
Expand All @@ -53,7 +53,7 @@ namespace jsonifier_internal {
using size_type = size_t;
using allocator_traits = std::allocator_traits<alloc_wrapper<value_type>>;

JSONIFIER_ALWAYS_INLINE pointer allocate(size_type count) noexcept {
JSONIFIER_FORCE_INLINE pointer allocate(size_type count) noexcept {
if JSONIFIER_UNLIKELY (count == 0) {
return nullptr;
}
Expand All @@ -64,7 +64,7 @@ namespace jsonifier_internal {
#endif
}

JSONIFIER_ALWAYS_INLINE void deallocate(pointer ptr, size_t = 0) noexcept {
JSONIFIER_FORCE_INLINE void deallocate(pointer ptr, size_t = 0) noexcept {
if JSONIFIER_LIKELY (ptr) {
#if defined(JSONIFIER_MSVC)
_aligned_free(ptr);
Expand All @@ -74,15 +74,15 @@ namespace jsonifier_internal {
}
}

template<typename... arg_types> JSONIFIER_ALWAYS_INLINE void construct(pointer ptr, arg_types&&... args) noexcept {
template<typename... arg_types> JSONIFIER_FORCE_INLINE void construct(pointer ptr, arg_types&&... args) noexcept {
new (ptr) value_type(std::forward<arg_types>(args)...);
}

JSONIFIER_ALWAYS_INLINE static size_type maxSize() noexcept {
JSONIFIER_FORCE_INLINE static size_type maxSize() noexcept {
return allocator_traits::max_size(alloc_wrapper{});
}

JSONIFIER_ALWAYS_INLINE void destroy(pointer ptr) noexcept {
JSONIFIER_FORCE_INLINE void destroy(pointer ptr) noexcept {
ptr->~value_type();
}
};
Expand Down
44 changes: 22 additions & 22 deletions Include/jsonifier/Array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,51 +46,51 @@ namespace jsonifier_internal {
}
}

JSONIFIER_ALWAYS_INLINE constexpr iterator begin() noexcept {
JSONIFIER_FORCE_INLINE constexpr iterator begin() noexcept {
return iterator(values);
}

JSONIFIER_ALWAYS_INLINE constexpr const_iterator begin() const noexcept {
JSONIFIER_FORCE_INLINE constexpr const_iterator begin() const noexcept {
return const_iterator(values);
}

JSONIFIER_ALWAYS_INLINE constexpr iterator end() noexcept {
JSONIFIER_FORCE_INLINE constexpr iterator end() noexcept {
return iterator(values + sizeNew);
}

JSONIFIER_ALWAYS_INLINE constexpr const_iterator end() const noexcept {
JSONIFIER_FORCE_INLINE constexpr const_iterator end() const noexcept {
return const_iterator(values + sizeNew);
}

JSONIFIER_ALWAYS_INLINE constexpr reverse_iterator rbegin() noexcept {
JSONIFIER_FORCE_INLINE constexpr reverse_iterator rbegin() noexcept {
return reverse_iterator(end());
}

JSONIFIER_ALWAYS_INLINE constexpr const_reverse_iterator rbegin() const noexcept {
JSONIFIER_FORCE_INLINE constexpr const_reverse_iterator rbegin() const noexcept {
return const_reverse_iterator(end());
}

JSONIFIER_ALWAYS_INLINE constexpr reverse_iterator rend() noexcept {
JSONIFIER_FORCE_INLINE constexpr reverse_iterator rend() noexcept {
return reverse_iterator(begin());
}

JSONIFIER_ALWAYS_INLINE constexpr const_reverse_iterator rend() const noexcept {
JSONIFIER_FORCE_INLINE constexpr const_reverse_iterator rend() const noexcept {
return const_reverse_iterator(begin());
}

JSONIFIER_ALWAYS_INLINE constexpr const_reference operator[](size_type index) const noexcept {
JSONIFIER_FORCE_INLINE constexpr const_reference operator[](size_type index) const noexcept {
return values[index];
}

JSONIFIER_ALWAYS_INLINE constexpr reference operator[](size_type index) noexcept {
JSONIFIER_FORCE_INLINE constexpr reference operator[](size_type index) noexcept {
return values[index];
}

JSONIFIER_ALWAYS_INLINE constexpr const value_type* data() const noexcept {
JSONIFIER_FORCE_INLINE constexpr const value_type* data() const noexcept {
return values;
}

JSONIFIER_ALWAYS_INLINE constexpr value_type* data() noexcept {
JSONIFIER_FORCE_INLINE constexpr value_type* data() noexcept {
return values;
}

Expand All @@ -100,7 +100,7 @@ namespace jsonifier_internal {
}
}

JSONIFIER_ALWAYS_INLINE constexpr size_type size() const noexcept {
JSONIFIER_FORCE_INLINE constexpr size_type size() const noexcept {
return sizeNew;
}

Expand All @@ -123,39 +123,39 @@ namespace jsonifier_internal {
constexpr array(std::initializer_list<value_type>) {
}

JSONIFIER_ALWAYS_INLINE constexpr const_pointer data() const noexcept {
JSONIFIER_FORCE_INLINE constexpr const_pointer data() const noexcept {
return nullptr;
}

JSONIFIER_ALWAYS_INLINE constexpr pointer data() noexcept {
JSONIFIER_FORCE_INLINE constexpr pointer data() noexcept {
return nullptr;
}

JSONIFIER_ALWAYS_INLINE constexpr size_type size() const noexcept {
JSONIFIER_FORCE_INLINE constexpr size_type size() const noexcept {
return 0;
}

JSONIFIER_ALWAYS_INLINE constexpr const_reference operator[](size_type index) const noexcept {
JSONIFIER_FORCE_INLINE constexpr const_reference operator[](size_type index) const noexcept {
return dataVal[index];
}

JSONIFIER_ALWAYS_INLINE constexpr reference operator[](size_type index) noexcept {
JSONIFIER_FORCE_INLINE constexpr reference operator[](size_type index) noexcept {
return dataVal[index];
}

JSONIFIER_ALWAYS_INLINE constexpr iterator begin() noexcept {
JSONIFIER_FORCE_INLINE constexpr iterator begin() noexcept {
return nullptr;
}

JSONIFIER_ALWAYS_INLINE constexpr iterator end() noexcept {
JSONIFIER_FORCE_INLINE constexpr iterator end() noexcept {
return nullptr;
}

JSONIFIER_ALWAYS_INLINE constexpr const_iterator begin() const noexcept {
JSONIFIER_FORCE_INLINE constexpr const_iterator begin() const noexcept {
return nullptr;
}

JSONIFIER_ALWAYS_INLINE constexpr const_iterator end() const noexcept {
JSONIFIER_FORCE_INLINE constexpr const_iterator end() const noexcept {
return nullptr;
}

Expand Down
4 changes: 2 additions & 2 deletions Include/jsonifier/Compare.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace jsonifier_internal {

template<char valueNewer, typename char_type> struct char_comparison {
static constexpr char value{ valueNewer };
JSONIFIER_ALWAYS_INLINE static const char_type* memchar(const char_type* data, size_t lengthNew) noexcept {
JSONIFIER_FORCE_INLINE static const char_type* memchar(const char_type* data, size_t lengthNew) noexcept {
#if JSONIFIER_CHECK_FOR_INSTRUCTION(JSONIFIER_AVX512)
if (lengthNew >= 64) {
using simd_type = typename get_type_at_index<simd_internal::avx_list, 2>::type::type;
Expand Down Expand Up @@ -177,7 +177,7 @@ namespace jsonifier_internal {
};

struct comparison {
template<typename char_type01, typename char_type02> JSONIFIER_ALWAYS_INLINE static bool compare(const char_type01* lhs, char_type02* rhs, size_t lengthNew) noexcept {
template<typename char_type01, typename char_type02> JSONIFIER_FORCE_INLINE static bool compare(const char_type01* lhs, char_type02* rhs, size_t lengthNew) noexcept {
#if JSONIFIER_CHECK_FOR_INSTRUCTION(JSONIFIER_AVX512)
if (lengthNew >= 64) {
using simd_type = typename get_type_at_index<simd_internal::avx_list, 2>::type::type;
Expand Down
Loading

0 comments on commit 70b20cf

Please sign in to comment.