javascript - जावास्क्रिप्ट टाइप एरियर और एंडियनस




endianness webgl typed-arrays arraybuffer (5)

मैं बाइनरी एन्कोडेड मेष फ़ाइल रेंडर करने के लिए WebGL का उपयोग कर रहा हूं। बाइनरी फ़ाइल को बड़े-एंडियन प्रारूप में लिखा गया है (मैं हेक्स संपादक में फ़ाइल को खोलकर या फ़िडलर का उपयोग करके नेटवर्क ट्रैफ़िक को देखकर इसे सत्यापित कर सकता हूं)। जब मैं फ्लोट 32 एरे या इंट 32 एरे का उपयोग करके बाइनरी प्रतिक्रिया को पढ़ने की कोशिश करता हूं, तो बाइनरी को छोटे-एंडियन के रूप में व्याख्या किया जाता है और मेरे मूल्य गलत हैं:

// Interpret first 32bits in buffer as an int
var wrongValue = new Int32Array(binaryArrayBuffer)[0];

मुझे http://www.khronos.org/registry/typedarray/specs/latest/ में टाइप किए गए सरणियों के डिफ़ॉल्ट धीरज का कोई संदर्भ नहीं मिल रहा है, इसलिए मैं सोच रहा हूं कि सौदा क्या है? क्या मुझे यह मान लेना चाहिए कि टाइप किए गए सरणियों का उपयोग करते समय सभी बाइनरी डेटा थोड़ा-सा एंडियन होना चाहिए?

समस्या के चारों ओर जाने के लिए मैं एक DataView ऑब्जेक्ट (पिछले लिंक में चर्चा की गई) और कॉल का उपयोग कर सकता हूं:

// Interpret first 32bits in buffer as an int
var correctValue = new DataView(binaryArrayBuffer).getInt32(0);

DataView फ़ंक्शन "getInt32" डिफ़ॉल्ट रूप से बड़े-एंडियन मानों को पढ़ता है।

(नोट: मैंने Google Chrome 15 और Firefox 8 का उपयोग करके परीक्षण किया है और वे दोनों समान व्यवहार करते हैं)


Answers

अन्य उत्तर मुझे कुछ पुराने लगते हैं, इसलिए यहाँ नवीनतम युक्ति का लिंक दिया गया है:

http://www.khronos.org/registry/typedarray/specs/latest/#2.1

विशेष रूप से:

टाइप किए गए व्यू व्यू प्रकार होस्ट कंप्यूटर की समाप्ति के साथ काम करते हैं।

DataView प्रकार डेटा पर एक निर्दिष्ट एंडियननेस (बिग-एंडियन या लिटिल-एंडियन) के साथ काम करता है।

इसलिए यदि आप बिग एंडियन (नेटवर्क बाइट ऑर्डर) में डेटा पढ़ना / लिखना चाहते हैं, तो देखें: http://www.khronos.org/registry/typedarray/specs/latest/#DATAVIEW

// For multi-byte values, the optional littleEndian argument
// indicates whether a big-endian or little-endian value should be
// read. If false or undefined, a big-endian value is read.

वर्तमान व्यवहार, कुछ हद तक दुख की बात है, कि अंतःकरण अंतर्निहित हार्डवेयर का है। जैसा कि लगभग सभी डेस्कटॉप कंप्यूटर x86 हैं, इसका मतलब थोड़ा-सा एंडियन है। अधिकांश एआरएम ओएस छोटे-एंडियन मोड का उपयोग करते हैं (एआरएम प्रोसेसर द्वि-एंडियन हैं और इस प्रकार दोनों में काम कर सकते हैं)।

इसका कारण कुछ हद तक दुखद है कि इसका मतलब है कि लगभग कोई भी यह परीक्षण नहीं करेगा कि उनका कोड बड़े-एंडियन हार्डवेयर पर काम करता है या नहीं, इससे क्या नुकसान होता है, और यह तथ्य कि पूरे वेब प्लेटफॉर्म को कार्यान्वयन और प्लेटफार्मों पर समान रूप से काम करने वाले कोड के आसपास डिज़ाइन किया गया था, जो यह टूट जाता है।


यहां से लिया गया http://www.khronos.org/registry/typedarray/specs/latest/ (जब वह कल्पना पूरी तरह से लागू हो जाए) आप उपयोग कर सकते हैं:

new DataView(binaryArrayBuffer).getInt32(0, true) // For little endian
new DataView(binaryArrayBuffer).getInt32(0, false) // For big endian

हालाँकि, यदि आप उन विधियों का उपयोग नहीं कर सकते हैं क्योंकि वे कार्यान्वित नहीं किए जाते हैं, तो आप हेडर पर हमेशा फ़ाइल के जादू मूल्य (लगभग हर प्रारूप में एक जादू मूल्य है) की जांच कर सकते हैं यह देखने के लिए कि क्या आपको अपने एंडियन के अनुसार उल्टा करने की आवश्यकता है।

इसके अलावा, आप एंडियननेस-विशिष्ट फ़ाइलों को अपने सर्वर पर सहेज सकते हैं और पता लगाए गए होस्ट एंडियन के अनुसार उनका उपयोग कर सकते हैं।


FYI करें आप मशीन की समाप्ति का निर्धारण करने के लिए निम्नलिखित जावास्क्रिप्ट फ़ंक्शन का उपयोग कर सकते हैं, जिसके बाद आप क्लाइंट को एक उचित स्वरूपित फ़ाइल पास कर सकते हैं (आप सर्वर पर फ़ाइल के दो संस्करणों को स्टोर कर सकते हैं, बड़ा एंडियन और थोड़ा एंडियन:

function checkEndian() {
    var arrayBuffer = new ArrayBuffer(2);
    var uint8Array = new Uint8Array(arrayBuffer);
    var uint16array = new Uint16Array(arrayBuffer);
    uint8Array[0] = 0xAA; // set first byte
    uint8Array[1] = 0xBB; // set second byte
    if(uint16array[0] === 0xBBAA) return "little endian";
    if(uint16array[0] === 0xAABB) return "big endian";
    else throw new Error("Something crazy just happened");
}

आपके मामले में आपको फ़ाइल को या तो थोड़ा एंडियन में फिर से बनाना होगा, या इसे थोड़ा एंडियन बनाने के लिए संपूर्ण डेटा संरचना के माध्यम से चलाना होगा। उपरोक्त विधि के एक मोड़ का उपयोग करके आप उड़ने पर धीरज की अदला-बदली कर सकते हैं (वास्तव में अनुशंसित नहीं है और केवल तभी समझ में आता है यदि पूरी संरचना समान रूप से समान रूप से पैक है, वास्तव में आप एक स्टब फ़ंक्शन बना सकते हैं जो आवश्यकतानुसार बाइट्स स्वैप करता है):

function swapBytes(buf, size) {
    var bytes = new Uint8Array(buf);
    var len = bytes.length;
    var holder;

    if (size == 'WORD') {
        // 16 bit
        for (var i = 0; i<len; i+=2) {
            holder = bytes[i];
            bytes[i] = bytes[i+1];
            bytes[i+1] = holder;
        }
    } else if (size == 'DWORD') {
        // 32 bit
        for (var i = 0; i<len; i+=4) {
            holder = bytes[i];
            bytes[i] = bytes[i+3];
            bytes[i+3] = holder;
            holder = bytes[i+1];
            bytes[i+1] = bytes[i+2];
            bytes[i+2] = holder;
        }
    }
}

डेवलपर्स का उपयोग क्यों करना चाहिए मुख्य कारण "use strict"हैं:

  1. वैश्विक चर के आकस्मिक घोषणा को रोकता है । उपयोग "use strict()"करने varसे पहले यह सुनिश्चित होगा कि चर के उपयोग के साथ घोषित किया गया है । उदाहरण के लिए:

    function useStrictDemo(){
     'use strict';
     //works fine
     var a = 'No Problem';
    
     //does not work fine and throws error
     k = "problem"
    
     //even this will throw error
     someObject = {'problem': 'lot of problem'};
    }
    
  2. एनबी: "use strict"निर्देश केवल एक स्क्रिप्ट या एक समारोह की शुरुआत में मान्यता प्राप्त है।
  3. स्ट्रिंग "arguments"को एक चर के रूप में उपयोग नहीं किया जा सकता है:

    "use strict";
    var arguments = 3.14;    // This will cause an error
    
  4. चर के रूप में कीवर्ड के उपयोग प्रतिबंधित करेगा। उनका उपयोग करने की कोशिश करने से त्रुटियां फेंक जाएंगी।

संक्षेप में आपके कोड को कम त्रुटि प्रवण कर देगा और बदले में आप अच्छे कोड लिखेंगे।

इसके बारे में अधिक पढ़ने के लिए आप यहां देख सकते हैं ।





javascript endianness webgl typed-arrays arraybuffer