1 jls.loader.provide('jls.util.StringCodec'); 2 3 /** 4 * @namespace Provides utility classes for the jls language. 5 * @name jls.util 6 */ 7 8 /** 9 * @class This class provides various String related codecs. 10 */ 11 jls.util.StringCodec = jls.lang.Class.create({}); 12 13 Object.extend(jls.util.StringCodec, /** @lends jls.util.StringCodec */ 14 { 15 /** 16 * Encodes a specified buffer and returns the encoded base64 string. 17 * 18 * @param {jls.lang.ByteBuffer} buffer The buffer to encode. 19 * @param {String} [b64pad] The padding character to use. 20 * @returns {String} The encoded string. 21 */ 22 base64Encode : function(buffer, b64pad) { 23 // 64 = 2^6, 6*4 = 24, 24 = 8*3 24 b64pad = b64pad || '='; 25 var map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 26 var s = ''; 27 /*var logByte = function() { 28 for (var i = 0; i < arguments.length; i++) { 29 var b = arguments[i]; 30 jls.logger.info('byte: ' + b.toPaddedString(3) + ' - 0x' + b.toPaddedString(2, 16) + ' - ' + b.toPaddedString(8, 2)); 31 } 32 };*/ 33 while (buffer.remaining() > 0) { 34 var r = buffer.remaining(); 35 var b1 = buffer.getByte(); 36 var b2 = buffer.remaining() > 0 ? buffer.getByte() : 0; 37 var b3 = buffer.remaining() > 0 ? buffer.getByte() : 0; 38 //logByte(b1, b2, b3); 39 var i1 = b1 >>> 2; 40 var i2 = ((b1 & 0x03) << 4) | (b2 >>> 4); 41 var i3 = ((b2 & 0x0f) << 2) | (b3 >>> 6); 42 var i4 = b3 & 0x3f; 43 //logByte(i1, i2, i3, i4); 44 s += map.charAt(i1) + map.charAt(i2) + (r > 1 ? map.charAt(i3) : b64pad) + (r > 2 ? map.charAt(i4) : b64pad); 45 } 46 return s; 47 }, 48 base64DecodeCharCode : function(c) { 49 if ((c >= 0x41) && (c <= 0x5a)) { // A to Z 50 return c - 0x41; 51 } else if ((c >= 0x61) && (c <= 0x7a)) { // a to a 52 return c - 0x61 + 26; 53 } else if ((c >= 0x30) && (c <= 0x39)) { // 0 to 9 54 return c - 0x30 + 52; 55 } else if (c == 0x2b) { // + 56 return 62; 57 } else if (c == 0x2f) { // slash 58 return 63; 59 } else if (c == 0x3d) { // = 60 return 0; 61 } else { 62 throw new jls.lang.Exception('Illegal base64 character code (' + c + ', 0x' + c.toPaddedString(2, 16) + ')'); 63 } 64 }, 65 /** 66 * Decodes a specified base64 string and returns the decoded buffer. 67 * 68 * @param {String} s The string to decode. 69 * @param {jls.lang.ByteBuffer} [buffer] The buffer to use. 70 * @returns {jls.lang.ByteBuffer} The decoded buffer. 71 */ 72 base64Decode : function(s, buffer) { 73 var length = s.length; 74 if ((length == 0) || (length % 4 != 0)) { 75 throw new jls.lang.Exception('Invalid string length (' + length + ')'); 76 } 77 buffer = buffer || jls.lang.ByteBuffer.allocate(length / 4 * 3); 78 for (var i = 0; i < length; i += 4) { 79 var c1 = s.charCodeAt(i); 80 var c2 = s.charCodeAt(i + 1); 81 var c3 = s.charCodeAt(i + 2); 82 var c4 = s.charCodeAt(i + 3); 83 var i1 = jls.util.StringCodec.base64DecodeCharCode(c1); 84 var i2 = jls.util.StringCodec.base64DecodeCharCode(c2); 85 var i3 = jls.util.StringCodec.base64DecodeCharCode(c3); 86 var i4 = jls.util.StringCodec.base64DecodeCharCode(c4); 87 var b1 = (i1 << 2) | (i2 >>> 4); 88 var b2 = ((i2 & 0x0f) << 4) | (i3 >>> 2); 89 var b3 = ((i3 & 0x03) << 6) | i4; 90 buffer.putByte(b1); 91 if (c3 == 0x3d) { 92 break; 93 } 94 buffer.putByte(b2); 95 if (c4 == 0x3d) { 96 break; 97 } 98 buffer.putByte(b3); 99 } 100 return buffer; 101 }, 102 /** 103 * Encodes a specified buffer and returns the encoded hexadecimal string. 104 * 105 * @param {jls.lang.ByteBuffer} buffer The buffer to encode. 106 * @param {String} [b64pad] The padding character to use. 107 * @returns {String} The encoded string. 108 */ 109 hexEncode : function(buffer, upperCase) { 110 var map = upperCase ? "0123456789ABCDEF" : "0123456789abcdef"; 111 var s = ''; 112 while (buffer.remaining() > 0) { 113 var b = buffer.getByte(); 114 s += map.charAt((b >>> 4) & 0x0f) + map.charAt(b & 0x0f); 115 } 116 return s; 117 }, 118 /** 119 * Decodes a specified hexadecimal string and returns the decoded buffer. 120 * 121 * @param {String} s The string to decode. 122 * @param {jls.lang.ByteBuffer} [buffer] The buffer to use. 123 * @returns {jls.lang.ByteBuffer} The decoded buffer. 124 */ 125 hexDecode : function(s, buffer) { 126 var length = s.length; 127 if ((length == 0) || (length % 2 != 0)) { 128 throw new jls.lang.Exception('Invalid string length (' + length + ')'); 129 } 130 buffer = buffer || jls.lang.ByteBuffer.allocate(length / 2); 131 for (var i = 0; i < length; i += 2) { 132 buffer.putByte(parseInt(s.substr(i, 2), 16)); 133 } 134 return buffer; 135 } 136 }); 137