{"id":24761854,"url":"https://github.com/aokihu/quick-struct","last_synced_at":"2025-10-11T09:31:14.171Z","repository":{"id":57210162,"uuid":"476758508","full_name":"aokihu/quick-struct","owner":"aokihu","description":"Parse c struct and translate binary data to javascrip object","archived":false,"fork":false,"pushed_at":"2024-08-28T02:24:54.000Z","size":283,"stargazers_count":12,"open_issues_count":5,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-10T15:58:14.469Z","etag":null,"topics":["big-endian","binary","buffer","convert","decoder","decoding","javascript","json","little-endian","parser","struct","typescript"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aokihu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-01T14:43:40.000Z","updated_at":"2024-11-19T01:54:25.000Z","dependencies_parsed_at":"2024-08-28T03:22:05.178Z","dependency_job_id":"51184a2c-fdf4-4c82-88b2-fbcd8dc341a5","html_url":"https://github.com/aokihu/quick-struct","commit_stats":{"total_commits":122,"total_committers":1,"mean_commits":122.0,"dds":0.0,"last_synced_commit":"d59fae04ff4f40b984319a0da383f9bb1074f95f"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aokihu%2Fquick-struct","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aokihu%2Fquick-struct/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aokihu%2Fquick-struct/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aokihu%2Fquick-struct/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aokihu","download_url":"https://codeload.github.com/aokihu/quick-struct/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236072284,"owners_count":19090409,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["big-endian","binary","buffer","convert","decoder","decoding","javascript","json","little-endian","parser","struct","typescript"],"created_at":"2025-01-28T19:19:44.902Z","updated_at":"2025-10-11T09:31:08.812Z","avatar_url":"https://github.com/aokihu.png","language":"JavaScript","readme":"![quick-struct banner](https://github.com/aokihu/quick-struct/blob/main/banner.jpg?raw=true)\n\n# quick-struct\n\n**quick-struct** is the tools for parsing and unpacking binary data formats into data formats that JavaScript can easily handle. The developer can define the data format using a string definition similar to the C language style. In order to eliminate the defect of inconsistent byte length between different CPU architectures and operating systems, the data type keyword of the **Rust** language is used to define the data type.\n\nBelow is the example of struct definition\n\n```c\nstruct {\n         u8 a;\n         u8 b;\n         u16 c;\n}\n```\n\nIt's very easy, **u8** is an unsigned byte(8 bit) and **u16** is 2 unsinged bytes.\n\nType and byte length\n\n| Byte length  | signed | unsigned | Support |\n| :----------: | :----: | :------: | :-----: |\n|    8-bit     |   i8   |    u8    |   Yes   |\n|    16-bit    |  i16   |   u16    |   Yes   |\n|    32-bit    |  i32   |   u32    |   Yes   |\n|    64-bit    |  i64   |   u64    |   Yes   |\n|   128-bit    |  i128  |   u128   |   No    |\n|     arch     | isize  |  usize   |   No    |\n| float-32-bit |  f32   |    -     |   Yes   |\n| float-64-bit |  f64   |    -     |   Yes   |\n|    8-bit     |  char  |  uchar   |   Yes   |\n\n## Install\n\nYou can use `npm` or `yarn` install.\n\n```bash\n# use yarn\nyarn add quick-struct\n\n#use npm\nnpm install quick-struct\n```\n\n## Usage\n\n### Basic\n\nYou can use `qs` template string function to create a new `QStruct` instance.\n\n```javascript\nimport { qs } from \"quick-struct\";\n\nconst struct = qs`\n    struct {\n        u8 a;\n    }\n`;\n\n// Create a UInt8 array\nconst buffer = new Uint8Array([12]);\n\n// Decode buffer\nconst result = struct.decode(buffer).toJson();\n\n// Print decoded result\nconsole.log(result.a);\n```\n\nYou can also use `JSSctruct` to create instance. Becase this is library is called **\"js-cstruct\"** before, so the calss name is **\"QStruct\"**. Two ways is the same, but I'd like template string function version.\n\n```javascript\nimport { QStruct } from \"quick-struct\";\n\nconst structDescriptor = `\n    struct {\n        u8 a;\n    }\n`;\n\nconst struct = new QStruct(structDescriptor);\n\n// Create a UInt8 array\nconst buffer = new Uint8Array([12]);\n\n// Decode buffer\nconst result = struct.decode(buffer).toJson();\n\n// Print decoded result\nconsole.log(result.a); // 12\n```\n\n### Multi fields\n\n**quick-struct** support define multi fields, the result of _JSON_ will combin field's name and value automatic, you can use the result as normal JavaScript object.\n\n```javascript\nimport { qs } from \"quick-struct\";\n\nconst struct = qs`\n    struct {\n        u8 a;\n        u8 b;\n        u8 c;\n    }\n`;\n\n// Create a UInt8 array\nconst buffer = new Uint8Array([12, 16, 32]);\n\n// Decode buffer\nconst result = struct.decode(buffer).toJson();\n\n// Print decoded result\nconsole.log(result.a); // 12\nconsole.log(result.b); // 16\nconsole.log(result.c); // 32\n```\n\n### Digital Array and string\n\n**quick-struct** can automatically identify numeric arrays and strings, and it is similar to the C language declaration when used. For numeric arrays, the array form will be automatically generated, and the strings will be automatically merged into the String type.quick-struct can automatically identify numeric arrays and strings, and it is similar to the C language declaration when used. For numeric arrays, the array form will be automatically generated, and the strings will be automatically merged into the String type.\n\nWhen a numeric type is declared as an array, it will be counted as an array type, regardless of whether the array length is 1.\n\n```javascript\nimport { qs } from \"quick-struct\";\n\nconst struct = qs`\n    struct {\n        u8 a[3];\n     uchar b[5];\n    }\n`;\n\n// Create a UInt8 array\nconst text = new TextEncoder().encode(\"hello\");\nconst buffer = new Uint8Array([12, 13, 14, ...text]);\n\n// Decode buffer\nconst result = struct.decode(buffer).toJson();\n\n// Print decoded result\nconsole.log(result.a); // [12, 13, 14]\nconsole.log(result.b); // \"hello\"\n```\n\n### Variable length array and string\n\n**quick-struct** supports automatic parsing of variable-length arrays or strings. The usage method is also very simple. Just change the fixed length of the array to the field name with the array length. The first character of the field name must be the **'\\$'** symbol , indicating that this is a variable-length array or string, and the field must be declared before the variable array or string\n\n```javascript\n// Correct way\nconst struct = qs`\n       struct {\n           u8 a;\n         char b[$a];\n       }\n `;\nconst text = \"hello\";\nconst arr = [text.length, ...new TextEncoder().encode(text)];\nconst buf = new Uint8Array(arr);\nconst result = struct.decode(buf).toJson();\n\n// print output\nconsole.log(result.a); // 5 \u003c- string length\nconsole.log(result.b); // 'hello'\n\n// Incorrect way\nconst struct = qs`\n      struct {\n          char a[$b];\n            u8 b;\n      }\n `;\n```\n\n### Encode object to ArrayBuffer\n\n`quick-struct` also support encode `object` to `ArrayBuffer`, below is the example.\n\n```javascript\nconst struct = qs`\n    \u003cautoflush\u003e\n    struct {\n        u8 head;\n        u32 groupToken;\n        u32 deviceToken;\n        u8 addressType;\n        u8 addressLength;\n        uchar address[$addressLength];\n    }\n`;\n\nconst msg = {\n  head: 209,\n  groupToken: 0,\n  deviceToken: 1,\n  addressType: 0,\n  addressLength: 9,\n  address: \"234.0.0.1\",\n};\n\nconst buf = struct.encode(msg);\n```\n\nThe endianness of output binary was decieded by your computer arch or OS, it is `little-endian` in mostly on `Intel` or `AMD` CPU.\nYou can also set `big-endian` with `quick-struct` with method `setBigEndian()` like decode binary.\n\n```javascript\nconst struct = qs`\n    \u003cautoflush\u003e\n    struct {\n        u8 head;\n        u32 groupToken;\n        u32 deviceToken;\n        u8 addressType;\n        u8 addressLength;\n        uchar address[$addressLength];\n    }\n`;\n\nconst msg = {\n  head: 209,\n  groupToken: 0,\n  deviceToken: 1,\n  addressType: 0,\n  addressLength: 9,\n  address: \"234.0.0.1\",\n};\n\nconst buf = struct.setBigEndian().encode(msg);\n```\n\nYou can use **struct attribute** `\u003cendian: little | big\u003e` to set endianness.\n\n```javascript\nconst struct = qs`\n    \u003cautoflush\u003e\n    \u003cendian: big\u003e\n    struct {\n        u8 head;\n        u32 groupToken;\n        u32 deviceToken;\n        u8 addressType;\n        u8 addressLength;\n        uchar address[$addressLength];\n    }\n`;\n\nconst msg = {\n  head: 209,\n  groupToken: 0,\n  deviceToken: 1,\n  addressType: 0,\n  addressLength: 9,\n  address: \"234.0.0.1\",\n};\n\nconst buf = struct.encode(msg); // struct.setBigEndian().encode(msg);\n```\n\n### Endianness\n\n**quick-struct** uses DataView for binary data parsing. The input binary is in big-endian mode, which is no problem for network communication, but the computers we use are usually in little-endian mode. We can parse by setting the endianness mode. binary data in little endian mode. Default mode is big-endian, so you don't need change it normaly.\n\n```javascript\nimport { qs } from \"quick-struct\";\n\nconst struct = qs`\n    struct {\n        u8 a[3];\n     uchar b[5];\n    }\n`;\n\n// Create a UInt8 array\nconst text = new TextEncoder().encode(\"hello\");\nconst buffer = new Uint8Array([12, 13, 14, ...text]);\n\n// Set little-endian mode\nconst result = struct.setLittleEndian().decode(buffer).toJson();\n\n// set big-endian mode\nconst result = struci.setBigEndian().decode(buffer).toJson();\n\n// Print decoded result\nconsole.log(result.a); // [12, 13, 14]\nconsole.log(result.b); // \"hello\"\n```\n\n## Export and import struct layout\n\nIn order to keep the data structure information confidential, **quick-struct** provides export and import of parsed structure data, which is saved in Base64 string format. Users can use other encryption and decryption methods to do secondary processing on the output string.\n\n```javascript\n// Export structer\nconst struct = qs`\n   struct {\n       u8 a;\n      u32 b;\n   }\n`;\nlayout = struct.exportStructs();\n\n// Import structor\nconst struct = new QStruct();\nstruct.importStructs(layout);\n```\n\n## Flush\n\nDecoded buffer data will stored till `flush()` trigger, so if you want decode different binary data with one `quick-struct` instance, you must `flush` cache after `toJson()` or `toJSON()`\n\n```javascript\nimport { qs } from \"quick-struct\";\n\nconst struct = qs`\n    struct {\n        u8 a;\n    }\n`;\n\n// Create the first UInt8 array\nconst buffer = new UInt8Array([12]);\n\n// Decode buffer\nconst result = struct.decode(buffer).toJson();\n\n// Print decoded result\nconsole.log(result.a); // print '12'\n\n// Create the second Uint8 array\nconst buffer2 = new Uint8Array([32]);\nconst result2 = struct.decode(buffer2).toJson();\n\n// Without flush()\nconsole.log(result2.a); // print '12'\n\n// With flush()\nstruct.flush();\nconsole.log(result2.a); // print '32'\n```\n\nYou can use instance method `autoFlush()` to flush cache when output `toJson()` executed automaticly.\n\n```javascript\nimport { qs } from \"quick-struct\";\n\n/* ----------- TWO WAYS ------------ */\n\n/* 1. Instance method */\nconst struct = qs`\n    struct {\n        u8 a;\n    }\n`.autoFlush();\n\n/* 2. Struct attribute */\nconst struct = qs`\n    \u003cautoflush\u003e\n    struct {\n        u8 a;\n    }\n`;\n\n/* -------------------------------- */\n\n// Create the first Uint8 array\nconst buffer = new Uint8Array([12]);\n\n// Decode buffer\nconst result = struct.decode(buffer).toJson();\n\n// Print decoded result\nconsole.log(result.a); // print '12'\n\n// Create the second Uint8 array\nconst buffer2 = new Uint8Array([32]);\nconst result2 = struct.decode(buffer2).toJson();\n\nconsole.log(result2.a); // print '32'\n```\n\n## API\n\n`qs` template string function, it return a new **QStruct**\n\n`QStruct(structDescriptor: string)` Constructor, the parameter is the structure description string\n\n`QStruct.prototype.decode(buffer: ArrayBuffer)` Decode binary array data and store result in memory\n\n`QStruct.prototype.toJson()` Ouptu the result with JSON type, you can use `toJSON()`, it's a.k.a. `toJson()`\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faokihu%2Fquick-struct","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faokihu%2Fquick-struct","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faokihu%2Fquick-struct/lists"}