field-access-proxy

🔍 A C++23 header-only library for accessing and formatting regular, bit and flexible array fields within C-style structures in a reusable way.(使用C++23开发的C语言结构字段访问库,支持以灵活的方式访问和格式化常规字段、比特位字段和柔性数组字段。)

https://github.com/zhuagenborn/field-access-proxy

Science Score: 44.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (8.9%) to scientific vocabulary

Keywords

bit-field cpp23
Last synced: 4 months ago · JSON representation ·

Repository

🔍 A C++23 header-only library for accessing and formatting regular, bit and flexible array fields within C-style structures in a reusable way.(使用C++23开发的C语言结构字段访问库,支持以灵活的方式访问和格式化常规字段、比特位字段和柔性数组字段。)

Basic Info
  • Host: GitHub
  • Owner: Zhuagenborn
  • License: mit
  • Language: C++
  • Default Branch: main
  • Homepage:
  • Size: 15.6 KB
Statistics
  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • Open Issues: 0
  • Releases: 0
Topics
bit-field cpp23
Created 8 months ago · Last pushed 7 months ago
Metadata Files
Readme License Citation

README.md

C-Style Field Access Proxy

C++ CMake GitHub Actions License

Introduction

A header-only library written in C++23 for accessing and formatting fields within C-style structures in a flexible and reusable way, supporting:

  • Accessing and modifying regular fields, bit fields, and flexible arrays.
  • Formatting fields as strings (optionally using custom formatters).
  • Grouping fields together and print them in a structured format.

Unit Tests

Prerequisites

  • Install GoogleTest.
  • Install CMake.

Building

Go to the project folder and run:

bash mkdir -p build cd build cmake -DFIELD_ACCESS_PROXY_BUILD_TESTS=ON .. cmake --build .

Running

Go to the build folder and run:

bash ctest -VV

Examples

Accessing Existing C-Style Structures

Suppose we have C-style structures.

```c++ using String = std::array;

struct Item { String msg; };

struct Packet { std::uint16t majorminorverions; String type; std::sizet itemcount; Item firstitem[1]; };

// Simulate a flexible array with additional elements. struct PacketItems : Packet { Item remain_items[9]; }; ```

First, we need to create field proxies.

```c++ namespace vt {

// Regular fields. const auto version {MakeField("The version", &Packet::majorminorverions)}; const auto itemcount {MakeField("The number of items", &Packet::itemcount)};

// Bit fields. const auto majorversion {MakeBitField("The major version", version, CHARBIT, CHARBIT)}; const auto minorversion {MakeBitField("The minor version", version, 0, CHAR_BIT)};

// Flexible array fields. const auto flexibleitems {MakeFlexibleArrayField("Items", &Packet::firstitem, item_count)};

} // namespace vt ```

Then we can access fields in objects with proxies.

c++ PacketItems pkg_items; auto& pkg {static_cast<Packet&>(pkg_items)};

See more examples in tests/c_style_tests.cpp.

Retrieving Values

  • Regular fields.

    c++ EXPECT_EQ(vt::item_count.Get(pkg), pkg.item_count); EXPECT_EQ(vt::version.Get(pkg), pkg.major_minor_verions);

  • Bit fields.

    c++ EXPECT_EQ(vt::major_version.Get(pkg), bit::GetHighByte(pkg.major_minor_verions)); EXPECT_EQ(vt::minor_version.Get(pkg), bit::GetLowByte(pkg.major_minor_verions));

  • Flexible array fields.

    c++ FlexibleArray<Item> items {pkg_items.first_item[0]}; std::ranges::copy(pkg_items.remain_items, std::back_inserter(items)); EXPECT_EQ(vt::flexible_items.GetAt(pkg, 0), items.front()); EXPECT_EQ(vt::flexible_items.GetAll(pkg), items);

Modifying Values

  • Regular fields.

    c++ vt::item_count.Set(pkg, 2); EXPECT_EQ(pkg.item_count, 2);

  • Bit fields.

    c++ constexpr std::uint8_t new_major_version {0xFF}; constexpr std::uint8_t new_minor_version {0xAA}; vt::major_version.Set(pkg, new_major_version); vt::minor_version.Set(pkg, new_minor_version); EXPECT_EQ(pkg.major_minor_verions, bit::CombineBytes(new_major_version, new_minor_version));

  • Flexible array fields.

    ```c++ constexpr Item newitem {'t', 'e', 's', 't'}; const FlexibleArray newitems(3, new_item);

    // Modifying the first two elements. vt::flexibleitems.SetAt(pkg, 0, newitem); EXPECTEQ(pkgitems.firstitem[0], newitem);

    vt::flexibleitems.SetAt(pkg, 1, newitem); EXPECTEQ(pkgitems.remainitems[0], newitem);

    // Modifying all elements and update the count field. vt::flexibleitems.SetAll(pkg, newitems, true); EXPECTEQ(pkg.itemcount, new_items.size());

    const FlexibleArray readitems {pkgitems.firstitem[0], pkgitems.remainitems[0], pkgitems.remainitems[1]}; EXPECTEQ(readitems, newitems); ```

Formatting Values

When creating proxies, we can provide an optional callable method for custom formatting. Otherwise, std::format is used as default formatting {name}: {value}.

```c++ std::string FormatItems(const Packet&, const FlexibleArray&) noexcept { return "{ items... }"; }

const auto flexibleitems {MakeFlexibleArrayField("Items", &Packet::firstitem, item_count, 0, FormatItems)}; ```

Defining New Structures with Proxies

We can also define new structures directly with getters and setters.

c++ struct Packet { DEFINE_UNDERLYING_FIELD_WITH_PROXY(Packet, private, std::uint16_t, major_minor_verions, {0x1234}) DEFINE_FIELD_WITH_PROXY(Packet, std::size_t, public, ByteCount, private, byte_count, {10}) DEFINE_BIT_FIELD_WITH_PROXY(Packet, major_minor_verions, public, std::uint8_t, MajorVerion, CHAR_BIT, CHAR_BIT) DEFINE_BIT_FIELD_WITH_PROXY(Packet, major_minor_verions, public, std::uint8_t, MinorVerion, 0, CHAR_BIT) DEFINE_BOOL_FIELD_WITH_PROXY(Packet, major_minor_verions, public, IsFirstVersionBitSet, SetFirstVersionBit, first_version_bit, 0) DEFINE_FLEXIBLE_ARRAY_FIELD_WITH_PROXY(Packet, std::byte, public, Bytes, private, bytes, byte_count, 0) };

See more examples in tests/macro_defined_tests.cpp.

License

Distributed under the MIT License. See LICENSE for more information.

Owner

  • Name: Zhuagenborn
  • Login: Zhuagenborn
  • Kind: organization
  • Location: Ireland

Software Development | Artificial Intelligence | Reverse Engineering.

Citation (CITATION.cff)

cff-version: 1.2.0
authors:
- family-names: Chen
  given-names: Zhenshuo
  orcid: https://orcid.org/0000-0003-2091-4160
title: C-Style Field Access Proxy
date-released: 2025-05-15
url: https://github.com/Zhuagenborn/Field-Access-Proxy

GitHub Events

Total
  • Push event: 19
  • Public event: 2
Last Year
  • Push event: 19
  • Public event: 2

Committers

Last synced: 6 months ago

All Time
  • Total Commits: 7
  • Total Committers: 1
  • Avg Commits per committer: 7.0
  • Development Distribution Score (DDS): 0.0
Past Year
  • Commits: 7
  • Committers: 1
  • Avg Commits per committer: 7.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
Chenzs108 c****8@o****m 7

Issues and Pull Requests

Last synced: 6 months ago

All Time
  • Total issues: 0
  • Total pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Total issue authors: 0
  • Total pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 0
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 0
  • Pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
Pull Request Authors
Top Labels
Issue Labels
Pull Request Labels

Dependencies

.github/workflows/cmake-gtest.yaml actions
  • actions/checkout main composite
  • actions/download-artifact main composite
  • actions/upload-artifact main composite