2016-07-19 22 views
0

我和我的朋友前段時間一起工作過。它意味着與js-ctypes一起使用。在Linux中有這些宏用於處理向字節數組添加文件描述符(uint32's)的列表:FD_SETFD_IS_SET。該文檔在這裏 - http://linux.die.net/man/2/select用javascript編寫的FD_SET和FD_ISSET宏

我想知道是否有人能夠檢查,如果我這樣做的權利或有人知道任何人在JavaScript中做過?我需要完成對大小端的32位/ 64位支持,但如果它已經存在,我很想看到它,因爲當我們開展這項工作時,我們有很多不確定因素。

這裏是代碼,fd_set_get_idx是這一切的輔助功能。

var MACROS = { 
     fd_set_set: function(fdset, fd) { 
      let { elem8, bitpos8 } = MACROS.fd_set_get_idx(fd); 
      console.info('elem8:', elem8.toString()); 
      console.info('bitpos8:', bitpos8.toString()); 
      fdset[elem8] = 1 << bitpos8; 
     }, 
     fd_set_isset: function(fdset, fd) { 
      let { elem8, bitpos8 } = MACROS.fd_set_get_idx(fd); 
      console.info('elem8:', elem8.toString()); 
      console.info('bitpos8:', bitpos8.toString()); 
      return !!(fdset[elem8] & (1 << bitpos8)); 
     }, 
    fd_set_get_idx: function(fd) { 
      if (osname == 'darwin' /*is_mac*/) { 
       // We have an array of int32. This should hopefully work on Darwin 
       // 32 and 64 bit. 
       let elem32 = Math.floor(fd/32); 
       let bitpos32 = fd % 32; 
       let elem8 = elem32 * 8; 
       let bitpos8 = bitpos32; 
       if (bitpos8 >= 8) {  // 8 
        bitpos8 -= 8; 
        elem8++; 
       } 
       if (bitpos8 >= 8) {  // 16 
        bitpos8 -= 8; 
        elem8++; 
       } 
       if (bitpos8 >= 8) {  // 24 
        bitpos8 -= 8; 
        elem8++; 
       } 

       return {'elem8': elem8, 'bitpos8': bitpos8}; 
      } else { // else if (osname == 'linux' /*is_linux*/) { // removed the else if so this supports bsd and solaris now 
       // :todo: add 32bit support 
       // Unfortunately, we actually have an array of long ints, which is 
       // a) platform dependent and b) not handled by typed arrays. We manually 
       // figure out which byte we should be in. We assume a 64-bit platform 
       // that is little endian (aka x86_64 linux). 
       let elem64 = Math.floor(fd/64); 
       let bitpos64 = fd % 64; 
       let elem8 = elem64 * 8; 
       let bitpos8 = bitpos64; 
       if (bitpos8 >= 8) {  // 8 
        bitpos8 -= 8; 
        elem8++; 
       } 
       if (bitpos8 >= 8) {  // 16 
        bitpos8 -= 8; 
        elem8++; 
       } 
       if (bitpos8 >= 8) {  // 24 
        bitpos8 -= 8; 
        elem8++; 
       } 
       if (bitpos8 >= 8) {  // 32 
        bitpos8 -= 8; 
        elem8++; 
       } 
       if (bitpos8 >= 8) {  // 40 
        bitpos8 -= 8; 
        elem8++; 
       } 
       if (bitpos8 >= 8) {  // 48 
        bitpos8 -= 8; 
        elem8++; 
       } 
       if (bitpos8 >= 8) {  // 56 
        bitpos8 -= 8; 
        elem8++; 
       } 

       return {'elem8': elem8, 'bitpos8': bitpos8}; 
      } 
     } 
}; 
+1

好的舊'''','<<'和'&','|' –

+1

有什麼問題另外,可以使用'for'循環... –

+1

我不明白如果你只是想模擬'FD_XXX'函數或者如果你必須符合某些東西。JS,特別是ES6,有[DataView](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/DataView)和[typed arrays](https://developer.mozilla.org/ en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray)如果你想使用它們。無論如何,如果'FD_SET(i,set)'的語義只是'set [i] = i',我從頭開始看不出任何問題。你能澄清嗎?此外'fdset [elem8] = 1 << bitpos8'可能是錯誤的。 –

回答

1

我給你留下了識別字節順序和字大小的負擔。
下面的代碼模擬了FD_XXX函數,並允許您指定字節順序和大小。

<!doctype> 
<html> 
    <head> 
     <script> 
      var SIZE_32 = 4 
      var SIZE_64 = 8 

      var LITTLE_ENDIAN = [0, 1, 2, 3, 4, 5, 6, 7]; 
      var BIG_ENDIAN = [7, 6, 5, 4, 3, 2, 1, 0]; 

      function fdset(setSize, endianness, size) 
      { 
       var buffer = new Uint8Array(div(setSize + 7, 8)); 



       function div(a, b) 
       { 
        return Math.floor(a/b); 
       } 

       function make_index(index) 
       { 
        return div(index, 8 * size) * size + endianness[div(index % (8 * size), 8)] % size; 
       } 

       buffer.set_bit = function(index) 
       { 
        buffer[make_index(index)] |= 1 << (index % 8); 
       }; 

       buffer.clear_bit = function(index) 
       { 
        buffer[make_index(index)] &= ~(index % 8); 
       }; 

       buffer.get_bit = function(index) 
       { 
        return buffer[make_index(index)] & 1 << (index % 8); 
       }; 

       buffer.zero = function() 
       { 
        buffer.fill(0); 
       } 


       return buffer; 
      } 

      function FD_SET(fd, fdset) 
      { 
       fdset.set_bit(fd); 
      } 

      function FD_ISSET(fd, fdset) 
      { 
       return !!fdset.get_bit(fd); 
      } 

      function FD_CLR(fd, fdset) 
      { 
       return fdset.clear_bit(fd); 
      } 

      function FD_ZERO(fdset) 
      { 
       return fdset.zero(); 
      } 


     </script> 
    </head> 
    <body> 
     <script> 
      var s = fdset(128, LITTLE_ENDIAN, SIZE_64); 

      //s in an Uint8Array 

      console.log(s); 

      FD_SET(0, s); //Byte 0 = 1 
      FD_SET(9, s); //Byte 1 = 2 
      FD_SET(18, s); //Byte 2 = 4 
      FD_SET(27, s); //Byte 3 = 8 
      FD_SET(36, s); //Byte 4 = 16 
      FD_SET(45, s); //Byte 5 = 32 
      FD_SET(54, s); //Byte 6 = 64 
      FD_SET(63, s); //Byte 7 = 128 

      FD_SET(120, s); //Byte 15 = 1 
      FD_SET(113, s); //Byte 14 = 2 
      FD_SET(106, s); //Byte 13 = 4 
      FD_SET(99, s); //Byte 12 = 8 
      FD_SET(92, s); //Byte 11 = 16 
      FD_SET(85, s); //Byte 10 = 32 
      FD_SET(78, s); //Byte 9 = 64 
      FD_SET(71, s); //Byte 8 = 128 

      console.log(s); 

      //64 bits, BE: [128, 64, 32, 16, 8, 4, 2, 1, 1, 2, 4, 8, 16, 32, 64, 128] 
      //64 bits, LE: [1, 2, 4, 8, 16, 32, 64, 128, 128, 64, 32, 16, 8, 4, 2, 1] 
      //32 bits, BE: [8, 4, 2, 1, 128, 64, 32, 16, 16, 32, 64, 128, 1, 2, 4, 8] 
      //32 bits, LE: [1, 2, 4, 8, 16, 32, 64, 128, 128, 64, 32, 16, 8, 4, 2, 1] 
     </script> 
    </body> 
</html> 

fdset函數返回一個Uint8Array可以傳遞到本地函數或進一步闡述。
setSize設置支持的最大文件描述符。


注意JS ctypes的已有的陣列型和通常[U]intXX_t類型在本地端序,唉沒有一個類型映射到基於平臺32/64位整數,並且不存在一個sizeof運營商,所以你仍然需要執行外部檢查來檢測字的大小。使用ctypes會更自然。
供參考用途here是官方執行的FD_XXX功能。

您可以定義一個struct,其中array的單個字段爲uint32/64_t
然後模仿C源代碼的行爲,小心在需要時使用UInt64 並避免shifts


JS僅具有雙號,這些號碼具有尾數的53個比特,指數的10位和符號的1個比特。當使用位運算符時,雙數轉換爲整數,因爲它是指定精度的尾數(指數僅僅是一個比例,只是一個反轉),該數字最多可以攜帶53位的信息數。

我知道,我不是js ctypes的專家。

+0

哇!真誠的感謝你的努力!我記得上次在工作時,我在閱讀這些鏈接時淹死了 - https://gist.github.com/Noitidart/5ddc5fe43dd9b0d5a207d0f70d72efc4 - 我現在查看你的代碼! :) – Noitidart

+1

@Noitidart不客氣。仔細檢查一下,我不確定我是否真的瞭解你的需求! –

+0

我不得不承認,我實際上不知道上面的代碼在做什麼。我從另一個js-ctypes項目複製它。我像我和一位朋友一樣做了這樣的表述,因爲我擔心這會關閉,我找不到任何幫助。我是一個js編碼器,如果它是1對1的話,它可以將C的東西移植到js中。我不明白endianess,32位和64位的東西。你會有30分鐘免費有時使用stackoverflow聊天有關此代碼?我在ctypes中使用它,所以我將它傳遞給實際的平臺C apis,所以緩衝區就是我所需要的。但是我從開始就感到困惑,包括設置大小。 :( – Noitidart