{"id":20201378,"url":"https://github.com/voronar/ctype-js","last_synced_at":"2026-03-06T08:33:58.811Z","repository":{"id":88301543,"uuid":"48034597","full_name":"Voronar/ctype-js","owner":"Voronar","description":"JavaScript library for easy working with C data types like primitive type arrays and structures.","archived":false,"fork":false,"pushed_at":"2018-04-04T18:36:48.000Z","size":245,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-24T09:38:34.488Z","etag":null,"topics":["c","data-structures","javascript","websocket"],"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/Voronar.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":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-15T10:00:45.000Z","updated_at":"2023-08-01T18:27:05.000Z","dependencies_parsed_at":null,"dependency_job_id":"b9e9f506-c7c8-4bf8-8033-c47199749bfd","html_url":"https://github.com/Voronar/ctype-js","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Voronar/ctype-js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Voronar%2Fctype-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Voronar%2Fctype-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Voronar%2Fctype-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Voronar%2Fctype-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Voronar","download_url":"https://codeload.github.com/Voronar/ctype-js/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Voronar%2Fctype-js/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30167963,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T07:56:45.623Z","status":"ssl_error","status_checked_at":"2026-03-06T07:55:55.621Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["c","data-structures","javascript","websocket"],"created_at":"2024-11-14T04:50:51.392Z","updated_at":"2026-03-06T08:33:58.786Z","avatar_url":"https://github.com/Voronar.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ctype\nJavaScript library for easy working with C data types like primitive type arrays and structures.\n\n\u003e ## ⚠️ Warning ⚠️\n\u003e ## It is very old code and I need to do a big refactoring as soon as it be needed.\n\n\u003e **Exported library(ES5) requirements:**\n\u003e - typed arrays, ```ArrayBuffer```, ```DataView```\n\n\u003e **Native library(ES6) requirements:**\n\u003e - typed arrays, ```ArrayBuffer```, ```DataView```\n\u003e - modules\n\u003e - default function parameters\n\u003e - block scoping\n\n### Features\n- extracts C-structures and primitive type arrays to JavaScript objects and typed arrays\n- extracts JavaScript structures(objects) and typed arrays to C-structures and primitive type arrays\n\n\u003e **Limitations:**\n- C-structures with primitive type fields only(```char```, ```int```, etc.)\n- Fixed length C-arrays only(```char a[n]```, ```int a[n]```, etc.)\n- No pointers, no methods, no bit fields\n\n### API Documentation: [voronar.github.io/ctype-js-docs](https://voronar.github.io/ctype-js-docs)\n\n### Installation\n**ES5 version(global variable)**\n\nES5 version of the library consists two versions: native(with a native typed arrays compability) and polyfilled(without a native typed arrays compability).\u003cbr\u003e\nFor native version just include ```build/release/ctype.js``` script to your HTML-file and ```build/release/ctype.polyfilled.js``` for polyfilled one. And then use ```ctype``` global object.\n\u003e **Library name conflict:**\n\u003e This version of the library exports ```ctype``` CommonJS module to a global scope(```window``` object). In case of existed ```ctype``` name the library will be renamed to ```libctypejs```.\n\n**ES6 version(module)**\n\nES6 version of the library is exported module. Just import module(```src/ctype.js```) and use it.\n``` js\nimport * as ctype from \"./ctype\";\n\nlet structure = ctype.struct(\n{\n  field: ctype.int32(100)\n});\n\nlet s = ctype.bufferToStruct(buffer, structure);\n```\n\n### Examples\n\n\u003e **Note:**\n\u003e In all examples I working with a little-endian binary buffer order.\nIn case of a big-endian binary buffer order using you need to set it in all used extracting function. Just set last argument of extraction function to 'false' value.\u003cbr\u003e\n\u003e See function signatures in the [documentation](https://voronar.github.io/ctype-js-docs).\n\n**Extracts C-structure to JavaScript object**\n\nFor extracting data from C to JavaScript firstable we need to convert C structure or an array to a byte array(```char*``` or ```unsigned char*```) for data transmission via web-socket.\nIn this example I use Qt web-socket protocol implementation.\n\u003e **Warning:**\n\u003e C-structures must be 1-byte aligned.\n\nServer side(C++):\n``` cpp\n// Qt C++\n// Web-socket server implementation - QWebSocket(Qt websockets module)\n#pragma pack(push, 1)\n struct SubStructure2\n {\n   int sint;\n };\n struct SubStructure1\n {\n   int sint;\n   SubStructure2 s2;\n };\n struct UnsignedArrays\n {\n   unsigned char  uchar [2]; //UInt8Array\n   unsigned short ushort[2]; //UInt16Array\n   unsigned int   uint  [2]; //UInt32Array\n };\n struct SignedArrays\n {\n   char   schar  [2]; //Int8Array\n   short  sshort [2]; //Int16Array\n   int    sint   [2]; //Int32Array\n   float  sfloat [2]; //Float32Array\n   double sdouble[2]; //Float64Array\n };\n struct Structure\n {\n   UnsignedArrays ua[2];\n   SignedArrays   sa;\n   SubStructure1  s1;\n };\n #pragma pack(pop)\n\n Structure s[2];\n s[0].s1.s2.sint = 2015;\n\n QByteArray raw = QByteArray((char*)\u0026s, sizeof(Structure) * 2);\n\n webSocket-\u003esendBinaryMessage(raw);\n```\n\u003e **Web-socket test application:**\n\u003e See testing Qt web-socket application sources in ```src/qt-websocket```.\n\nClient side(JavaScript):\n\n``` js\nlet SubStructure2 = ctype.struct(\n{\n  sint: ctype.int32()\n});\n\nlet SubStructure1 = ctype.struct(\n{\n  sint: ctype.int32(),\n  s2  : ctype.struct(SubStructure2)\n});\n\nlet UnsignedArrays = ctype.struct(\n{\n  uchar : ctype.uint8 (2),\n  ushort: ctype.uint16(2),\n  uint  : ctype.uint32(2)\n});\n\nlet SignedArrays = ctype.struct(\n{\n  schar  : ctype.int8   (2),\n  sshort : ctype.int16  (2),\n  sint   : ctype.int32  (2),\n  sfloat : ctype.float32(2),\n  sdouble: ctype.float64(2),\n});\n\nlet Structure = ctype.struct(\n{\n  ua: ctype.struct(UnsignedArrays, 2),\n  sa: ctype.struct(SignedArrays),\n  s1: ctype.struct(SubStructure1)\n});\n\nwebSocket.onmessage = function(e)\n{\n  let data = e.data;\n\n  let s1   = ctype.struct(Structure, 2);\n  let rec1 = ctype.bufferToStruct(data,//source binary buffer\n                                  s1); //destination structure or array of structures\n\n  console.log(rec1[0].s1.s2.sint[0]); //2015\n}\n```\n\u003e **Variables and arrays:**\n\u003e C-structure single field like ```int i;``` equals to ```i: int32(1)``` typed array in JavaScript.\n\n**Extracts C-structure to JavaScript object with an offset from a source binary buffer**\n\nIn this example we extract a second structure from array of two structures.\n``` js\n//data preparation...\nlet s2   = ctype.struct(Structure);\nlet rec2 = ctype.bufferToStruct(data,                 //source binary buffer\n                                s2,                   //destination structure\n                                Structure.byteLength);//byte offset\n```\n\u003e **JavaScript structure feature:**\n\u003e All ```struct``` structures has ```byteLength``` field is a total byte length of the structure.\n\u003e Then you dynamically add structure property you need to repack the updated structure in order to update ```byteLength``` property.\u003cbr\u003e\n\u003e``` js\n\u003elet structure = ctype.struct(\n\u003e{\n\u003e  field1: ctype.int32(100)\n\u003e});\n\u003e\n\u003estructure.field2 = ctype.float32(10); //Invalid 'byteLength' value. Structure need to be updated.\n\u003elet updatedStructure = ctype.struct(structure);\n```\n\n**Extracts C-array to JavaScript typed array**\n\nIn this example we extract C-array to JavaScript typed array with an offset from a source binary buffer and with a specified byte length value of a source binary buffer.\n``` js\n//data preparation...\nlet sfloatArray = ctype.float32(2);\nlet offset      = UnsignedArrays.byteLength * 2 + SignedArrays.schar.byteLength * 2 + SignedArrays.sshort.byteLength * 2 + SignedArrays.byteLength * 2;\nlet length      = 2 * ctype.FLOAT32_SIZE;\nlet rec3        = ctype.bufferToArray(data,       //source binary buffer\n                                      sfloatArray,//destination array\n                                      offset,     //byte offset\n                                      length);    //byte length\n```\n\u003e**'bufferToArray' function using:**\n\u003eWe can extract an array without specified offset and length.\nIn this case the offset value will be equal to zero and the length will be automatically calculated by a special algorithm.\u003cbr\u003e\n\u003eIf a source buffer byte length more than a destination array byte length or equal to it then the byte length value will be equal to the destination array byte length.\u003cbr\u003e\n\u003eElse the byte length value will be equal to the source buffer byte length.\n\n\u003e**JavaScript typed array limitation:**\n\u003eWhen we use multidimensional C-arrays(```int array[x][y][z];```) we can't use the same array accessing notation with JavaScript typed arrays.\n```console.log(array[0][0][0]);``` will not work correctly.\u003cbr\u003e\n\u003eIn this case we can manually calculate a required array index or use some libraries like [ndarray](https://github.com/scijs/ndarray).\n\n**Extracts JavaScript structure to C-structure(without an existed binary buffer)**\n\nClient side(JavaScript):\n``` js\n//data preparation...\nlet s             = ctype.struct(Structure, 2);\ns[1].sa.sfloat[0] = 3.1415;\nlet sendData      = ctype.structToBuffer(s/*source structure*/);\nwebSocket.send(sendData);\n```\nServer side(C++):\n``` cpp\nvoid MainWindow::processBinaryMessage(QByteArray message)\n{\n  QWebSocket *pClient = qobject_cast\u003cQWebSocket*\u003e(sender());\n\n  Structure s[2];\n\n  memcpy(\u0026s, message.constData(), sizeof(Structure) * 2);\n  qDebug() \u003c\u003c s1[1].sa.sfloat[0]; //3.1415\n}\n```\n**Extracts JavaScript structure to C-structure(with an existed binary buffer)**\n``` js\n//data preparation...\nlet existedBuffer = new ArrayBuffer(Structure.byteLength * 2);\n\nlet sendData = ctype.structToBuffer(rec2,                 //source structure or array of structures\n                                    existedBuffer,        //existed binary buffer\n                                    Structure.byteLength);//byte offset from an existed binary buffer\n\nwebSocket.send(sendData);\n```\n**Extracts JavaScript typed array to C-array(without an existed binary buffer)**\n\nClient side(JavaScript):\n``` js\nlet array = ctype.float64(10 * 10 * 10);\narray.map(function(value, index, array)\n{\n  array[index] = -200.200;\n});\nlet sendData = ctype.arrayToBuffer(array/*source array*/);\nwebSocket.send(sendData);\n```\nServer side(C++):\n``` cpp\nvoid MainWindow::processBinaryMessage(QByteArray message)\n{\n  QWebSocket *pClient = qobject_cast\u003cQWebSocket*\u003e(sender());\n\n  double array[10][10][10];\n\n  memcpy(array, message.constData(), sizeof(array));\n  qDebug() \u003c\u003c array[9][9][9]; //-200.200\n}\n```\n**Extracts JavaScript typed array to C-array(with an existed binary buffer)**\n\nIn this example we extract JavaScript typed array to C-array with an offset from a source typed array and with a specified byte length value of a source JavaScript typed array.\n\nClient side(JavaScript):\n``` js\nlet existedBuffer = new ArrayBuffer(1000 * ctype.FLOAT64_SIZE);\nlet array = ctype.float64(1000);\narray.map(function(value, index, array)\n{\n  if(index \u003e 499)\n  {\n    array[index] = -200.200;\n  }\n  else\n  {\n    array[index] = - 100.100;\n  }\n});\n\nctype.arrayToBuffer(array,                     //source array\n                    existedBuffer,             //existed binary buffer\n                    0,                         //byte offset\n                    500 * ctype.FLOAT64_SIZE);//byte length\n\nctype.arrayToBuffer(array, existedBuffer, 500 * ctype.FLOAT64_SIZE, 500 * ctype.FLOAT64_SIZE);\nlet sendData = existedBuffer;\nsocket.send(sendData);\n```\n\u003e**'arrayToBuffer' function using:**\n\u003eWe can extract an array without specified offset and length.\nIn this case the offset value will be equal to zero and the length will be automatically calculated by a special algorithm.\u003cbr\u003e\n\u003eIf a source array byte length more than a destination buffer byte length or equal to it then the byte length value will be equal to the destination buffer byte length.\u003cbr\u003e\n\u003eElse the byte length value will be equal to the source array byte length.\n\nServer side(C++):\n``` cpp\nvoid MainWindow::processBinaryMessage(QByteArray message)\n{\n  QWebSocket *pClient = qobject_cast\u003cQWebSocket*\u003e(sender());\n\n  double array[1000];\n\n  memcpy(array, message.constData(), sizeof(array));\n  qDebug() \u003c\u003c array[0];   //-100.100\n  qDebug() \u003c\u003c array[500]; //-200.200\n}\n```\n### Have a nice code!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoronar%2Fctype-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvoronar%2Fctype-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoronar%2Fctype-js/lists"}