كيفية تحويل ArrayBuffer إلى سلسلة ومنها

تُستخدَم ArrayBuffers لنقل البيانات الأولية، وتعتمد عليها عدة واجهات برمجة تطبيقات جديدة، بما في ذلك WebSockets و Web Intents 2](https://www.html5rocks.com/en/tutorials/file/xhr2/) و WebWorkers. ومع ذلك، ولأنّها ظهرت مؤخرًا في بيئة تطوير برمجة تطبيقات برمجة ‎JavaScript، يتم أحيانًا إساءة تفسيرها أو إساءة استخدامها.

من الناحية الدلالية، ArrayBuffer هو ببساطة صفيف من البايتات يتم عرضها من خلال قناع معيّن. يحدِّد هذا القناع، وهو مثيل لـ ArrayBufferView، كيفية محاذاة البايتات لمطابقة البنية المتوقّعة للمحتوى. على سبيل المثال، إذا كنت تعرف أنّ البايتات في ArrayBuffer تمثّل صفيفًا من الأعداد الصحيحة غير الموقعة بسعة 16 بت، ما عليك سوى لف ArrayBuffer في عرض Uint16Array ويمكنك التلاعب بعناصره باستخدام بنية الأقواس كما لو كان Uint16Array صفيفًا من الأعداد الصحيحة:

// suppose buf contains the bytes [0x02, 0x01, 0x03, 0x07]
// notice the multibyte values respect the hardware endianess, which is little-endian in x86
var bufView = new Uint16Array(buf);
if (bufView[0]===258) {   // 258 === 0x0102
    console.log("ok");
}
bufView[0] = 255;    // buf now contains the bytes [0xFF, 0x00, 0x03, 0x07]
bufView[0] = 0xff05; // buf now contains the bytes [0x05, 0xFF, 0x03, 0x07]
bufView[1] = 0x0210; // buf now contains the bytes [0x05, 0xFF, 0x10, 0x02]

من الأسئلة العملية الشائعة حول ArrayBuffer هو كيفية تحويل String إلى ArrayBuffer والعكس. بما أنّ ArrayBuffer هو في الواقع صفيف بايت، تتطلّب عملية التحويل هذه أن يتفق الطرفان على كيفية تمثيل الأحرف في السلسلة على أنّها بايت. من المرجّح أنّك رأيت هذه "الاتّفاقية" من قبل: وهي ترميز أحرف السلسلة (و"أحكام الاتفاقية" المعتادة هي، مثلاً، Unicode UTF-16 وiso8859-1). وبالتالي، على افتراض أنّك أنت والطرف الآخر اتفقتما على ترميز UTF-16، يمكن أن يكون رمز التحويل على النحو التالي:

function ab2str(buf) {
    return String.fromCharCode.apply(null, new Uint16Array(buf));
}
function str2ab(str) {
    var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
    var bufView = new Uint16Array(buf);
    for (var i=0, strLen=str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
    }
    return buf;
}

يُرجى ملاحظة استخدام Uint16Array. هذا عرض ArrayBuffer الذي ينسِّق وحدات البايت في ArrayBuffers كعناصر 16 بت. ولا يعالج ترميز الأحرف نفسه، والذي يعالجه String.fromCharCode و str.charCodeAt كترميز Unicode.

أحد الأسئلة الشائعة على StackOverflow بشأن هذا الموضوع يتضمن إجابة حصلت على أصوات كثيرة وحلًا معقّدًا إلى حد ما لعملية التحويل: أنشئ FileReader ليعمل كمحوِّل وأدخِل Blob يحتوي على السلسلة إليه. على الرغم من أنّ هذه الطريقة فعّالة، إلا أنّها تتسم بإمكانية قراءة ضعيفة وأعتقد أنّها بطيئة. بما أنّ الشكوك غير المُستندة إلى أساس من الصحة أدّت إلى ارتكاب العديد من الأخطاء في تاريخ البشرية، لنعتمد نهجًا علميًا أكثر هنا. لقد اختبرت الطريقتَين باستخدام jsperf وتؤكّد النتيجة من شكوكي، ويمكنك الاطّلاع على العرض الترويجي هنا.

في الإصدار 20 من Chrome، يكون استخدام رمز التلاعب المباشر ArrayBuffer في هذه المقالة أسرع بنحو 27 مرة من استخدام طريقة FileReader/Blob.