Characters like { " take bytes when transporting to and from the server
This is faster:
var BENZ={
enc:function(i){
var s='';
for(var v in i){
s=(s==='')?v+'^'+i[v]:s+'¬'+v+'^'+i[v];
}return s;
},
dec:function(p){
var o={};
p=p.split('¬');
for(var n=0;n<p.length;n++){
var k=p[n].split('^');
var v=k[1];
k=k[0];
o[k]=(/^\d+$/.test(v))?parseInt(v):v;
}return o;}
};
BENZ.enc({'my':'object','num':100}); // makes a string
BENZ.dec('my^object¬num^100'); // makes an object
The only problem is that afterward things like arrays have to be split (then if the parts are numbers then you have to parseInt() each)
is binary faster?
msgpack does something like this (less raw), What I don't get is that they hex encode everything which adds twice the bytes (turns each char into 2 digits)
Why do they do this?
With my way I am comparing types as a rule of thumb, for some strange reason this feels more productive.
What do you think?
Related
Is it possible to work out utilisation of session storage?
Ideally to return current size of site session storage contents
http://www.w3schools.com/html/html5_webstorage.asp
I used this and it matched the local storage size here.
function getLocalStorageSize() {
var key, item, bytes = 0, keys = Object.keys(localStorage);
for (var i = 0; i < keys.length; i++) {
key = keys[i];
item = localStorage[key];
bytes += key.length + item.length;
}
return bytes;
}
To get a somewhat relevant result you can do this:
var size = JSON.stringify(localStorage).length; // size in bytes
This works because localStorage returns the Object containing all data stored in it. If you stringify it you can easily get the length (in bytes) of the string.
I say "somewhat relevant" because when stringifying the Object quotes are added around the keys and this affects the result. You could otherwise, simply iterate through all the keys in localStorage and sum the lengts of the strings found at those keys.
var fData:ByteArray = new ByteArray();
I need to remove some bytes in this array, but can't find any public method in Flash to do that.
I searched something like fData.remove(start,length) but with no success.
here is a code
function _dlProgressHandler(evt:ProgressEvent):void { //this is progressEvent for URLStream
............... ///some code
var ff:ByteArray = new ByteArray();
stream.readBytes(ff,0,stream.bytesAvailable);
fileData.writeBytes(ff,0,ff.length); //stream writes into fileData byteArray
//and here is cutter:
fileData.position=0;
fileData.writeBytes(ff,100,fileData.length);
fileData.length=fileData.length-100);
}
So, fileData cut itself unpredictably sometimes.
Sometimes old blocks're found twice, sometimes they're not found at all.
You can always just only read the bytes that you want, which will have the same effect as discarding the bytes that you don't want. As a very simple example, assume you have a ByteArray that is 10 bytes long and you want to discard the first 3 bytes:
var newBytes:ByteArray = new ByteArray();
newBytes.writeBytes(fData, 2, 7);
So instead of removing the bytes that you don't want from fData, you just create a new ByteArray and only get they bytes that you want from fData.
Obviously, if the sequence of bytes you want to remove is not just a sequence from the beginning or end of fData it will be a little more complicated, but the method remains the same: read the bytes that you want, instead of removing the ones you don't.
AS-3 is actually very nice sometimes. This removes bytes from your array anywhere you want. Beginning, middle or the end. Just need to check indices to avoid IndexOutOfBounds
var array: ByteArray = ...; // create the byte array or load one
var index: int = 4;
var count: int = 5;
array.position = index;
array.writeBytes(array, index + count, array.length - (index + count));
array.length = array.length - count;
I tested this and it works well, just the checks are missing
a byte array can write to itself
I am trying to understand the significance of null bytes in a ByteArray. Do they act like a terminator? I mean, can we not write further into the ByteArray once a null byte has been written?
For instance,
import flash.utils.*;
public class print3r{
public function print3r{
Util.print(nullout());
}
public function nullout:ByteArray (){
var bytes:ByteArray = new ByteArray();
bytes.writeInt(((403705888 + 1) - 1)); // Non Printable Characters
bytes.writeInt(((403705872 - 1) + 1)); // Non Printable Characters
bytes.writeInt(0x18101000); // Notice the NullByte in this DWORD
bytes.writeInt(0x41424344); // ASCII Characters ABCD
return bytes;
}
}
new print3r;
This gives a blank output.
Now, if I replace the DWORD, 0x18101000 with 0x18101010, this time I can see the ASCII padding, ABCD in the output.
My question is that, is it possible to write past the null byte into the ByteArray()?
The reason I ask is because I have seen in an ActionScript code, that a lot of writeInt and writeByte operations are performed on the ByteArray even after the null byte is written.
Thanks.
is it possible to write past the null byte into the ByteArray()?
Of course it is. ByteArray -- is a chunk of raw data. You can write whatever you like there, and you can read in whatever way you like (using zero bytes as delimiters or whatever else you may want to do).
What you see when you send your bytes to standard output with trace(), depends solely on what you actually do with your data to convert it to a string. There are several ways of converting an array of bytes to string. So, your question is missing the explanation of what Util.print() method does.
Here are several options for converting bytes to a string:
Loop through bytes and output characters, encoding is up to you.
Read a string with ByteArray.readUTFBytes(). This method reads utf-encoded symbols; it stops when zero character is encountered.
Read a string with ByteArray.readUTF(). This method expects your string to be prefixed with unsigned short indicating its length. In other terms it is the same as ByteArray.readUTFBytes().
Use ByteArray.toString(). This is what happens when you simply do trace(byteArray);. This method ignores zero bytes and outputs the rest. This method uses System.useCodePage setting to decide on the encoding, and can use UTF BOM if the data begins with it.
Here are some tests that illustrate the above:
var test:ByteArray = new ByteArray();
// latin (1 byte per character)
test.writeUTFBytes("ABC");
// zero byte
test.writeByte(0);
// cyrillic (2 bytes per character)
test.writeUTFBytes("\u0410\u0411\u0412");
trace(test); // ABCАБВ
trace(test.toString()); // ABCАБВ
test.position = 0;
trace(test.readUTFBytes(test.length)); // ABC
// simple loop
var output:String = "";
var byte:uint;
for (var i:uint = 0; i<test.length; i+=1) {
byte = uint(test[i]);
if (output.length && i%4 == 0) {
output += " ";
}
output += (byte > 0xF ? "" : "0") + byte.toString(16);
}
trace(output); // 41424300 d090d091 d092
Writing a null to a byte array has no significance as far as I know. The print function might however use it as a string terminator.
So let's say i have T, T = 1200. I also have A, A is an array that contains 1000s of entries and these are numerical entries that range from 1000-2000 but does not include an entry for 1200.
What's the fastest way of finding the nearest neighbour (closest value), let's say we ceil it, so it'll match 1201, not 1199 in A.
Note: this will be run on ENTER_FRAME.
Also note: A is static.
It is also very fast to use Vector.<int>instead of Arrayand do a simple for-loop:
var vector:Vector.<int> = new <int>[ 0,1,2, /*....*/ 2000];
function seekNextLower( searchNumber:int ) : int {
for (var i:int = vector.length-1; i >= 0; i--) {
if (vector[i] <= searchNumber) return vector[i];
}
}
function seekNextHigher( searchNumber:int ) : int {
for (var i:int = 0; i < vector.length; i++) {
if (vector[i] >= searchNumber) return vector[i];
}
}
Using any array methods will be more costly than iterating over Vector.<int> - it was optimized for exactly this kind of operation.
If you're looking to run this on every ENTER_FRAME event, you'll probably benefit from some extra optimization.
If you keep track of the entries when they are written to the array, you don't have to sort them.
For example, you'd have an array where T is the index, and it would have an object with an array with all the indexes of the A array that hold that value. you could also put the closest value's index as part of that object, so when you're retrieving this every frame, you only need to access that value, rather than search.
Of course this would only help if you read a lot more than you write, because recreating the object is quite expensive, so it really depends on use.
You might also want to look into linked lists, for certain operations they are quite a bit faster (slower on sort though)
You have to read each value, so the complexity will be linear. It's pretty much like finding the smallest int in an array.
var closestIndex:uint;
var closestDistance:uint = uint.MAX_VALUE;
var currentDistance:uint;
var arrayLength:uint = A.length;
for (var index:int = 0; index<arrayLength; index++)
{
currentDistance = Math.abs(T - A[index]);
if (currentDistance < closestDistance ||
(currentDistance == closestDistance && A[index] > T)) //between two values with the same distance, prefers the one larger than T
{
closestDistance = currentDistance;
closestIndex = index;
}
}
return T[closestIndex];
Since your array is sorted you could adapt a straightforward binary search (such as explained in this answer) to find the 'pivot' where the left-subdivision and the right-subdivision at a recursive step bracket the value you are 'searching' for.
Just a thought I had... Sort A (since its static you can just sort it once before you start), and then take a guess of what index to start guessing at (say A is length 100, you want 1200, 100*(200/1000) = 20) so guess starting at that guess, and then if A[guess] is higher than 1200, check the value at A[guess-1]. If it is still higher, keep going down until you find one that is higher and one that is lower. Once you find that determine what is closer. if your initial guess was too low, keep going up.
This won't be great and might not be the best performance wise, but it would be a lot better than checking every single value, and will work quite well if A is evenly spaced between 1000 and 2000.
Good luck!
public function nearestNumber(value:Number,list:Array):Number{
var currentNumber:Number = list[0];
for (var i:int = 0; i < list.length; i++) {
if (Math.abs(value - list[i]) < Math.abs(value - currentNumber)){
currentNumber = list[i];
}
}
return currentNumber;
}
var bytes:ByteArray = new ByteArray;
bytes.writeInt(0);
trace(bytes.length); // prints 4
trace(bytes.toString().length); // prints 4
When I run the above code the output suggests that every character in the string returned by toString contains one byte from the ByteArray. This is of course great if you want to display the content of the ByteArray, but not so great if you want to send its content encoded in a string and the size of the string matters.
Is it possible to get a string from the ByteArray where every character in the string contains two bytes from the ByteArray?
You can reinterpret your ByteArray as containing only shorts. This lets you read two bytes at a time and get a single number value representing them both. Next, you can take these numbers and reinterpret them as being character codes. Finally, create a String from these character codes and you're done.
public static function encode(ba:ByteArray):String {
var origPos:uint = ba.position;
var result:Array = new Array();
for (ba.position = 0; ba.position < ba.length - 1; )
result.push(ba.readShort());
if (ba.position != ba.length)
result.push(ba.readByte() << 8);
ba.position = origPos;
return String.fromCharCode.apply(null, result);
}
There is one special circumstance to pay attention to. If you try reading a short from a ByteArray when there is only one byte remaining in it, an exception will be thrown. In this case, you should call readByte with the value shifted 8 bits instead. This is the same as if the original ByteArray had an extra 0 byte at the end. (making it even in length)
Now, as for decoding this String... Get the character code of each character, and place them into a new ByteArray as shorts. It will be identical to the original, except if the original had an odd number of bytes, in which case the decoded ByteArray will have an extra 0 byte at the end.
public static function decode(str:String):ByteArray {
var result:ByteArray = new ByteArray();
for (var i:int = 0; i < str.length; ++i) {
result.writeShort(str.charCodeAt(i));
}
result.position = 0;
return result;
}
In action:
var ba:ByteArray = new ByteArray();
ba.writeInt(47);
ba.writeUTF("Goodbye, cruel world!");
var str:String = encode(ba);
ba = decode(str);
trace(ba.readInt());
trace(ba.readUTF());
Your question is a bit confusing. You have written a 4 byte int to your ByteArray. You haven't written any characters (unicode or other) to it. If you want to pass text, write text and pass it as UTF8. It will take less space than having two bytes for every character, at least for most western languages.
But honestly, I'm not sure I understood what you are trying to accomplish. Do you want to send numbers or text? What backend are you talking to? Do you need a ByteArray at all?