{"action":"created","comment":{"url":"https://api.github.com/repos/UAVCAN/libuavcan/pulls/comments/42941792","id":42941792,"diff_hunk":"@@ -1,121 +1,62 @@\n /*\n- * Fast bit array copy algorithm.\n- * Source: http://stackoverflow.com/questions/3534535/whats-a-time-efficient-algorithm-to-copy-unaligned-bit-arrays\n- * Pavel Kirienko <pavel.kirienko@gmail.com>\n+ * Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>\n  */\n \n #include <uavcan/marshal/bit_stream.hpp>\n #include <climits>\n #include <cstring>\n #include <cstddef>\n+\n namespace uavcan\n {\n \n-static const unsigned char reverse_mask[]     = { 0x00U, 0x80U, 0xC0U, 0xE0U, 0xF0U, 0xF8U, 0xFCU, 0xFEU, 0xFFU };\n-static const unsigned char reverse_mask_xor[] = { 0xFFU, 0x7FU, 0x3FU, 0x1FU, 0x0FU, 0x07U, 0x03U, 0x01U, 0x00U };\n-\n-#define PREPARE_FIRST_COPY()                                       \\\n-    do {                                                           \\\n-    if (src_len >= (CHAR_BIT - dst_offset_modulo)) {               \\\n-        *dst &= reverse_mask[dst_offset_modulo];                   \\\n-        src_len -= CHAR_BIT - dst_offset_modulo;                   \\\n-    } else {                                                       \\\n-        *dst &= reverse_mask[dst_offset_modulo] |                  \\\n-                reverse_mask_xor[dst_offset_modulo + src_len];     \\\n-        c &= reverse_mask[dst_offset_modulo + src_len];            \\\n-        src_len = 0;                                               \\\n-    } } while (0)\n \n-\n-void bitarrayCopy(const unsigned char* src_org, unsigned src_offset, unsigned src_len,\n-                  unsigned char* dst_org, unsigned dst_offset)\n+void bitarrayCopy(const unsigned char* src, size_t src_offset, size_t src_len,\n+                  unsigned char* dst, size_t dst_offset)\n {\n-    if (src_len > 0U)\n-    {\n-        const unsigned char *src = src_org + (src_offset / CHAR_BIT);\n-        unsigned char *dst = dst_org + (dst_offset / CHAR_BIT);\n-\n-        const unsigned src_offset_modulo = src_offset % CHAR_BIT;\n-        const unsigned dst_offset_modulo = dst_offset % CHAR_BIT;\n-\n-        if (src_offset_modulo == dst_offset_modulo)\n-        {\n-            if (src_offset_modulo > 0U)\n-            {\n-                unsigned char c = reverse_mask_xor[dst_offset_modulo] & *src++;\n-                PREPARE_FIRST_COPY();\n-                *dst++ |= c;\n-            }\n-\n-            const unsigned byte_len = src_len / CHAR_BIT;\n-            const unsigned src_len_modulo = src_len % CHAR_BIT;\n-\n-            if (byte_len > 0U)\n-            {\n-                (void)std::memcpy(dst, src, byte_len);\n-                src += byte_len;\n-                dst += byte_len;\n-            }\n-            if (src_len_modulo > 0U)\n-            {\n-                *dst &= reverse_mask_xor[src_len_modulo];\n-                *dst |= reverse_mask[src_len_modulo] & *src;\n-            }\n-        }\n-        else\n-        {\n-            unsigned bit_diff_ls = 0U;\n-            unsigned bit_diff_rs = 0U;\n-            unsigned char c = 0U;\n-            /*\n-             * Begin: Line things up on destination.\n-             */\n-            if (src_offset_modulo > dst_offset_modulo)\n-            {\n-                bit_diff_ls = src_offset_modulo - dst_offset_modulo;\n-                bit_diff_rs = CHAR_BIT - bit_diff_ls;\n-\n-                c = static_cast<unsigned char>(*src++ << bit_diff_ls);\n-                c = static_cast<unsigned char>(c | (*src >> bit_diff_rs));\n-                c &= reverse_mask_xor[dst_offset_modulo];\n-            }\n-            else\n-            {\n-                bit_diff_rs = dst_offset_modulo - src_offset_modulo;\n-                bit_diff_ls = CHAR_BIT - bit_diff_rs;\n-\n-                c = static_cast<unsigned char>(*src >> bit_diff_rs & reverse_mask_xor[dst_offset_modulo]);\n-            }\n-            PREPARE_FIRST_COPY();\n-            *dst++ |= c;\n-\n-            /*\n-             * Middle: copy with only shifting the source.\n-             */\n-            int byte_len = int(src_len / CHAR_BIT);\n-\n-            while (--byte_len >= 0)\n-            {\n-                c = static_cast<unsigned char>(*src++ << bit_diff_ls);\n-                c = static_cast<unsigned char>(c | (*src >> bit_diff_rs));\n-                *dst++ = c;\n-            }\n-\n-            /*\n-             * End: copy the remaing bits;\n-             */\n-            unsigned src_len_modulo = src_len % CHAR_BIT;\n-            if (src_len_modulo > 0U)\n-            {\n-                c = static_cast<unsigned char>(*src++ << bit_diff_ls);\n-                c = static_cast<unsigned char>(c | (*src >> bit_diff_rs));\n-                c &= reverse_mask[src_len_modulo];\n-\n-                *dst &= reverse_mask_xor[src_len_modulo];\n-                *dst |= c;\n-            }\n-        }\n+    /*\n+     * Should never be called on a zero-length buffer. The caller will also ensure that the bit\n+     * offsets never exceed one byte.\n+     */\n+\n+    UAVCAN_ASSERT(src_len > 0U);\n+    UAVCAN_ASSERT(src_offset < 8U && dst_offset < 8U);\n+\n+    const size_t last_bit = src_offset + src_len;\n+    while (last_bit - src_offset) {","path":"libuavcan/src/marshal/uc_bit_array_copy.cpp","position":null,"original_position":131,"commit_id":"2d9374044b7b6b175d4a5e28490b20d83f48d67d","original_commit_id":"1bf121a6165acbf32f05f96bdeb76a2070e179ff","user":{"login":"pavel-kirienko","id":3298404,"avatar_url":"https://avatars.githubusercontent.com/u/3298404?v=3","gravatar_id":"","url":"https://api.github.com/users/pavel-kirienko","html_url":"https://github.com/pavel-kirienko","followers_url":"https://api.github.com/users/pavel-kirienko/followers","following_url":"https://api.github.com/users/pavel-kirienko/following{/other_user}","gists_url":"https://api.github.com/users/pavel-kirienko/gists{/gist_id}","starred_url":"https://api.github.com/users/pavel-kirienko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pavel-kirienko/subscriptions","organizations_url":"https://api.github.com/users/pavel-kirienko/orgs","repos_url":"https://api.github.com/users/pavel-kirienko/repos","events_url":"https://api.github.com/users/pavel-kirienko/events{/privacy}","received_events_url":"https://api.github.com/users/pavel-kirienko/received_events","type":"User","site_admin":false},"body":"Minor style issue:\r\n\r\n```c++\r\nwhile (last_bit - src_offset)\r\n{\r\n```","created_at":"2015-10-25T06:46:05Z","updated_at":"2015-10-25T06:46:05Z","html_url":"https://github.com/UAVCAN/libuavcan/pull/78#discussion_r42941792","pull_request_url":"https://api.github.com/repos/UAVCAN/libuavcan/pulls/78","_links":{"self":{"href":"https://api.github.com/repos/UAVCAN/libuavcan/pulls/comments/42941792"},"html":{"href":"https://github.com/UAVCAN/libuavcan/pull/78#discussion_r42941792"},"pull_request":{"href":"https://api.github.com/repos/UAVCAN/libuavcan/pulls/78"}}},"pull_request":{"url":"https://api.github.com/repos/UAVCAN/libuavcan/pulls/78","id":48673109,"html_url":"https://github.com/UAVCAN/libuavcan/pull/78","diff_url":"https://github.com/UAVCAN/libuavcan/pull/78.diff","patch_url":"https://github.com/UAVCAN/libuavcan/pull/78.patch","issue_url":"https://api.github.com/repos/UAVCAN/libuavcan/issues/78","number":78,"state":"open","locked":false,"title":"Replace bitarrayCopy with a smaller, from-scratch version (resolves #63)","user":{"login":"bendyer","id":148661,"avatar_url":"https://avatars.githubusercontent.com/u/148661?v=3","gravatar_id":"","url":"https://api.github.com/users/bendyer","html_url":"https://github.com/bendyer","followers_url":"https://api.github.com/users/bendyer/followers","following_url":"https://api.github.com/users/bendyer/following{/other_user}","gists_url":"https://api.github.com/users/bendyer/gists{/gist_id}","starred_url":"https://api.github.com/users/bendyer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bendyer/subscriptions","organizations_url":"https://api.github.com/users/bendyer/orgs","repos_url":"https://api.github.com/users/bendyer/repos","events_url":"https://api.github.com/users/bendyer/events{/privacy}","received_events_url":"https://api.github.com/users/bendyer/received_events","type":"User","site_admin":false},"body":"Compiled with this and `-Os`, vectorcontrol goes from 17008 down to 16676 bytes (332 bytes saved).\r\n","created_at":"2015-10-25T06:41:03Z","updated_at":"2015-10-25T06:46:05Z","closed_at":null,"merged_at":null,"merge_commit_sha":"606a61f5b0234c9153fa899173d56a933a4aafc7","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/UAVCAN/libuavcan/pulls/78/commits","review_comments_url":"https://api.github.com/repos/UAVCAN/libuavcan/pulls/78/comments","review_comment_url":"https://api.github.com/repos/UAVCAN/libuavcan/pulls/comments{/number}","comments_url":"https://api.github.com/repos/UAVCAN/libuavcan/issues/78/comments","statuses_url":"https://api.github.com/repos/UAVCAN/libuavcan/statuses/2d9374044b7b6b175d4a5e28490b20d83f48d67d","head":{"label":"UAVCAN:issue-63","ref":"issue-63","sha":"2d9374044b7b6b175d4a5e28490b20d83f48d67d","user":{"login":"UAVCAN","id":10167381,"avatar_url":"https://avatars.githubusercontent.com/u/10167381?v=3","gravatar_id":"","url":"https://api.github.com/users/UAVCAN","html_url":"https://github.com/UAVCAN","followers_url":"https://api.github.com/users/UAVCAN/followers","following_url":"https://api.github.com/users/UAVCAN/following{/other_user}","gists_url":"https://api.github.com/users/UAVCAN/gists{/gist_id}","starred_url":"https://api.github.com/users/UAVCAN/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/UAVCAN/subscriptions","organizations_url":"https://api.github.com/users/UAVCAN/orgs","repos_url":"https://api.github.com/users/UAVCAN/repos","events_url":"https://api.github.com/users/UAVCAN/events{/privacy}","received_events_url":"https://api.github.com/users/UAVCAN/received_events","type":"Organization","site_admin":false},"repo":{"id":16183388,"name":"libuavcan","full_name":"UAVCAN/libuavcan","owner":{"login":"UAVCAN","id":10167381,"avatar_url":"https://avatars.githubusercontent.com/u/10167381?v=3","gravatar_id":"","url":"https://api.github.com/users/UAVCAN","html_url":"https://github.com/UAVCAN","followers_url":"https://api.github.com/users/UAVCAN/followers","following_url":"https://api.github.com/users/UAVCAN/following{/other_user}","gists_url":"https://api.github.com/users/UAVCAN/gists{/gist_id}","starred_url":"https://api.github.com/users/UAVCAN/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/UAVCAN/subscriptions","organizations_url":"https://api.github.com/users/UAVCAN/orgs","repos_url":"https://api.github.com/users/UAVCAN/repos","events_url":"https://api.github.com/users/UAVCAN/events{/privacy}","received_events_url":"https://api.github.com/users/UAVCAN/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/UAVCAN/libuavcan","description":"Portable reference implementation of the UAVCAN protocol stack in C++ for embedded systems and Linux.","fork":false,"url":"https://api.github.com/repos/UAVCAN/libuavcan","forks_url":"https://api.github.com/repos/UAVCAN/libuavcan/forks","keys_url":"https://api.github.com/repos/UAVCAN/libuavcan/keys{/key_id}","collaborators_url":"https://api.github.com/repos/UAVCAN/libuavcan/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/UAVCAN/libuavcan/teams","hooks_url":"https://api.github.com/repos/UAVCAN/libuavcan/hooks","issue_events_url":"https://api.github.com/repos/UAVCAN/libuavcan/issues/events{/number}","events_url":"https://api.github.com/repos/UAVCAN/libuavcan/events","assignees_url":"https://api.github.com/repos/UAVCAN/libuavcan/assignees{/user}","branches_url":"https://api.github.com/repos/UAVCAN/libuavcan/branches{/branch}","tags_url":"https://api.github.com/repos/UAVCAN/libuavcan/tags","blobs_url":"https://api.github.com/repos/UAVCAN/libuavcan/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/UAVCAN/libuavcan/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/UAVCAN/libuavcan/git/refs{/sha}","trees_url":"https://api.github.com/repos/UAVCAN/libuavcan/git/trees{/sha}","statuses_url":"https://api.github.com/repos/UAVCAN/libuavcan/statuses/{sha}","languages_url":"https://api.github.com/repos/UAVCAN/libuavcan/languages","stargazers_url":"https://api.github.com/repos/UAVCAN/libuavcan/stargazers","contributors_url":"https://api.github.com/repos/UAVCAN/libuavcan/contributors","subscribers_url":"https://api.github.com/repos/UAVCAN/libuavcan/subscribers","subscription_url":"https://api.github.com/repos/UAVCAN/libuavcan/subscription","commits_url":"https://api.github.com/repos/UAVCAN/libuavcan/commits{/sha}","git_commits_url":"https://api.github.com/repos/UAVCAN/libuavcan/git/commits{/sha}","comments_url":"https://api.github.com/repos/UAVCAN/libuavcan/comments{/number}","issue_comment_url":"https://api.github.com/repos/UAVCAN/libuavcan/issues/comments{/number}","contents_url":"https://api.github.com/repos/UAVCAN/libuavcan/contents/{+path}","compare_url":"https://api.github.com/repos/UAVCAN/libuavcan/compare/{base}...{head}","merges_url":"https://api.github.com/repos/UAVCAN/libuavcan/merges","archive_url":"https://api.github.com/repos/UAVCAN/libuavcan/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/UAVCAN/libuavcan/downloads","issues_url":"https://api.github.com/repos/UAVCAN/libuavcan/issues{/number}","pulls_url":"https://api.github.com/repos/UAVCAN/libuavcan/pulls{/number}","milestones_url":"https://api.github.com/repos/UAVCAN/libuavcan/milestones{/number}","notifications_url":"https://api.github.com/repos/UAVCAN/libuavcan/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/UAVCAN/libuavcan/labels{/name}","releases_url":"https://api.github.com/repos/UAVCAN/libuavcan/releases{/id}","created_at":"2014-01-23T19:41:25Z","updated_at":"2015-10-23T02:10:49Z","pushed_at":"2015-10-25T06:45:48Z","git_url":"git://github.com/UAVCAN/libuavcan.git","ssh_url":"git@github.com:UAVCAN/libuavcan.git","clone_url":"https://github.com/UAVCAN/libuavcan.git","svn_url":"https://github.com/UAVCAN/libuavcan","homepage":"http://uavcan.org","size":5980,"stargazers_count":30,"watchers_count":30,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":194,"mirror_url":null,"open_issues_count":8,"forks":194,"open_issues":8,"watchers":30,"default_branch":"master"}},"base":{"label":"UAVCAN:master","ref":"master","sha":"99f084d0131099f12c6c6f3c6a477f86e375948e","user":{"login":"UAVCAN","id":10167381,"avatar_url":"https://avatars.githubusercontent.com/u/10167381?v=3","gravatar_id":"","url":"https://api.github.com/users/UAVCAN","html_url":"https://github.com/UAVCAN","followers_url":"https://api.github.com/users/UAVCAN/followers","following_url":"https://api.github.com/users/UAVCAN/following{/other_user}","gists_url":"https://api.github.com/users/UAVCAN/gists{/gist_id}","starred_url":"https://api.github.com/users/UAVCAN/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/UAVCAN/subscriptions","organizations_url":"https://api.github.com/users/UAVCAN/orgs","repos_url":"https://api.github.com/users/UAVCAN/repos","events_url":"https://api.github.com/users/UAVCAN/events{/privacy}","received_events_url":"https://api.github.com/users/UAVCAN/received_events","type":"Organization","site_admin":false},"repo":{"id":16183388,"name":"libuavcan","full_name":"UAVCAN/libuavcan","owner":{"login":"UAVCAN","id":10167381,"avatar_url":"https://avatars.githubusercontent.com/u/10167381?v=3","gravatar_id":"","url":"https://api.github.com/users/UAVCAN","html_url":"https://github.com/UAVCAN","followers_url":"https://api.github.com/users/UAVCAN/followers","following_url":"https://api.github.com/users/UAVCAN/following{/other_user}","gists_url":"https://api.github.com/users/UAVCAN/gists{/gist_id}","starred_url":"https://api.github.com/users/UAVCAN/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/UAVCAN/subscriptions","organizations_url":"https://api.github.com/users/UAVCAN/orgs","repos_url":"https://api.github.com/users/UAVCAN/repos","events_url":"https://api.github.com/users/UAVCAN/events{/privacy}","received_events_url":"https://api.github.com/users/UAVCAN/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/UAVCAN/libuavcan","description":"Portable reference implementation of the UAVCAN protocol stack in C++ for embedded systems and Linux.","fork":false,"url":"https://api.github.com/repos/UAVCAN/libuavcan","forks_url":"https://api.github.com/repos/UAVCAN/libuavcan/forks","keys_url":"https://api.github.com/repos/UAVCAN/libuavcan/keys{/key_id}","collaborators_url":"https://api.github.com/repos/UAVCAN/libuavcan/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/UAVCAN/libuavcan/teams","hooks_url":"https://api.github.com/repos/UAVCAN/libuavcan/hooks","issue_events_url":"https://api.github.com/repos/UAVCAN/libuavcan/issues/events{/number}","events_url":"https://api.github.com/repos/UAVCAN/libuavcan/events","assignees_url":"https://api.github.com/repos/UAVCAN/libuavcan/assignees{/user}","branches_url":"https://api.github.com/repos/UAVCAN/libuavcan/branches{/branch}","tags_url":"https://api.github.com/repos/UAVCAN/libuavcan/tags","blobs_url":"https://api.github.com/repos/UAVCAN/libuavcan/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/UAVCAN/libuavcan/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/UAVCAN/libuavcan/git/refs{/sha}","trees_url":"https://api.github.com/repos/UAVCAN/libuavcan/git/trees{/sha}","statuses_url":"https://api.github.com/repos/UAVCAN/libuavcan/statuses/{sha}","languages_url":"https://api.github.com/repos/UAVCAN/libuavcan/languages","stargazers_url":"https://api.github.com/repos/UAVCAN/libuavcan/stargazers","contributors_url":"https://api.github.com/repos/UAVCAN/libuavcan/contributors","subscribers_url":"https://api.github.com/repos/UAVCAN/libuavcan/subscribers","subscription_url":"https://api.github.com/repos/UAVCAN/libuavcan/subscription","commits_url":"https://api.github.com/repos/UAVCAN/libuavcan/commits{/sha}","git_commits_url":"https://api.github.com/repos/UAVCAN/libuavcan/git/commits{/sha}","comments_url":"https://api.github.com/repos/UAVCAN/libuavcan/comments{/number}","issue_comment_url":"https://api.github.com/repos/UAVCAN/libuavcan/issues/comments{/number}","contents_url":"https://api.github.com/repos/UAVCAN/libuavcan/contents/{+path}","compare_url":"https://api.github.com/repos/UAVCAN/libuavcan/compare/{base}...{head}","merges_url":"https://api.github.com/repos/UAVCAN/libuavcan/merges","archive_url":"https://api.github.com/repos/UAVCAN/libuavcan/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/UAVCAN/libuavcan/downloads","issues_url":"https://api.github.com/repos/UAVCAN/libuavcan/issues{/number}","pulls_url":"https://api.github.com/repos/UAVCAN/libuavcan/pulls{/number}","milestones_url":"https://api.github.com/repos/UAVCAN/libuavcan/milestones{/number}","notifications_url":"https://api.github.com/repos/UAVCAN/libuavcan/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/UAVCAN/libuavcan/labels{/name}","releases_url":"https://api.github.com/repos/UAVCAN/libuavcan/releases{/id}","created_at":"2014-01-23T19:41:25Z","updated_at":"2015-10-23T02:10:49Z","pushed_at":"2015-10-25T06:45:48Z","git_url":"git://github.com/UAVCAN/libuavcan.git","ssh_url":"git@github.com:UAVCAN/libuavcan.git","clone_url":"https://github.com/UAVCAN/libuavcan.git","svn_url":"https://github.com/UAVCAN/libuavcan","homepage":"http://uavcan.org","size":5980,"stargazers_count":30,"watchers_count":30,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":194,"mirror_url":null,"open_issues_count":8,"forks":194,"open_issues":8,"watchers":30,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/UAVCAN/libuavcan/pulls/78"},"html":{"href":"https://github.com/UAVCAN/libuavcan/pull/78"},"issue":{"href":"https://api.github.com/repos/UAVCAN/libuavcan/issues/78"},"comments":{"href":"https://api.github.com/repos/UAVCAN/libuavcan/issues/78/comments"},"review_comments":{"href":"https://api.github.com/repos/UAVCAN/libuavcan/pulls/78/comments"},"review_comment":{"href":"https://api.github.com/repos/UAVCAN/libuavcan/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/UAVCAN/libuavcan/pulls/78/commits"},"statuses":{"href":"https://api.github.com/repos/UAVCAN/libuavcan/statuses/2d9374044b7b6b175d4a5e28490b20d83f48d67d"}}}}