什么是Blob列的SQLite的Adobe AIR的第一个字节?斑点Sizeinfo? [英] What is the first bytes in a Blob column SQlite Adobe AIR? Blob Sizeinfo?

查看:154
本文介绍了什么是Blob列的SQLite的Adobe AIR的第一个字节?斑点Sizeinfo?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了一个随机序列插入任何BLOB字段时,数据库通过Adobe AIR操纵字节。 (从我的结果它似乎总是开始的字节[12,...] 的,但我不肯定这一点)

I have identified a random series of bytes inserted into any blob field when the database is manipulated via Adobe AIR. (from my results it appear to always start with bytes[12, ...] but I'm not sure of that)

我认为这是一个字节sizeinfo,让我解释一下我是如何得出这一结论。

I think it's a sizeinfo of the bytes, let me explain how I came to this conclusion.

首先我的背景:我通过Adobe AIR(客户端)和System.data.sqlite(C#服务器端)

First my context : I manipulate sqlite databases through Adobe AIR (client-side) and System.data.sqlite (C# server-side)

使用System.data.sqlite如果我读一个SQLite数据库是由Adobe AIR充满BLOB我得搭附加在一开始就受到AIR这些字节,然后我有二进制数据的所有井字形。完善!

With System.data.sqlite if I read a Sqlite db filled with BLOB by Adobe AIR I have to get ride of those bytes appended in the beginning by AIR and then I have the binary data all well shaped. PERFECT!

使用Adobe AIR的,如果我试图读取一个SQLite数据库由System.data.Sqlite数据充满BLOB被破坏我得到一个错误!很显然,因为我没有通过AIR研究的缺失字节。

With Adobe AIR if I tried to read a sqlite db filled with BLOB by System.data.Sqlite the data are corrupted I get an error! Obviously because I don't have the missing bytes researched by AIR.

当然,我试图通过只复制了一系列的3个字节,我在我的第一个案例中删除,但随后部分返回的数据和图像的情况下,最后一排像素的去添加这些字节都是灰色的,在某些图片我有或多或少的灰色线条。由于数据相对应的一系列一样的〜4K大小的图像,我加了3个字节其中之一,我有这样的结果。

Of course I tried to add those bytes by just copying a series of 3 bytes that I removed in my first case but then it returned the data partially and in the cases of images the last rows of pixels go all gray and in some images I have more or less grays lines. Because the data were corresponding to a series of images of the same ~4k size and I added 3 bytes from one of them and I had this result.

和空气有时也会抛出这个错误:

And Air will also sometimes throw this error :

错误:错误#2030:文件结尾是   遇到过。

Error: Error #2030: End of file was encountered.

所以,很显然这些字节给出有关尺寸的信息,但我真的不明白怎么做!?!

So obviously those bytes give an info on the size but I don't really get how it does!?!

我尝试添加与4K长度也容易增加3个字节的ByteArray,但我试图添加4M,并上升到5个字节。

I tried to add a bytearray with 4k length it tends to add 3 bytes but I tried to add 4M and it goes up to 5 bytes.

我发现这个问题<一href="http://stackoverflow.com/questions/3345553/how-do-you-convert-3-bytes-into-a-24-bit-number-in-c">How你转​​换3个字节为一个24位的数字在C#?的,我认为这可能是如何的尺寸信息的存储位置。

I found this Question How do you convert 3 bytes into a 24 bit number in C#? and I thought that could be how the size info is stored.

但我还是不明白这一点......

But I still don't get it...

推荐答案

由于 FluorineFX (AMF的。 NET)开源项目在这里就是答案。

Thanks to FluorineFX (AMF for .NET) opensource project here is the answer.

由于我的Adobe AIR项目,我要通过我的air.ByteArray对象作为参数传递给存储中的所有sqlite的Blob字段; AIR将一切都序列化为AMF,紧凑的二进制动作消息格式。

Because in my Adobe AIR project I have to pass my air.ByteArray object as a parameter to store everything in the sqlite Blob field; AIR will serialize everything into AMF, a compact binary actionscript message format.

第11页Secion 3.14 ByteArray类型的

http://opensource.adobe.com/wiki/download/attachments/1114283/amf3_spec_05_05_08.pdf

该DOC规定:

AMF 3采用序列化这种类型   可变长度编码29位   对于字节长度preFIX整数   随后的原始字节   ByteArray中。

AMF 3 serializes this type using a variable length encoding 29-bit integer for the byte-length prefix followed by the raw bytes of the ByteArray.

不过那不是全部,我搜索了一个AMF .NET开源项目,并成立FluorineFX。展望code我确定了每个AMF的二进制文件是pfixed一个字节的类型code这是 12 作为的ByteArray $ P $:

But thats not all, I searched for an AMF .NET opensource project and founded FluorineFX. Looking into the code I identified that every AMF binaries is prefixed with a byte TypeCode which is 12 for a ByteArray:

   /// <summary>
   /// AMF ByteArray data type.
   /// </summary>
   public const byte ByteArray = 12;

进一步寻找我再次发现了FluorineFX来源的 AMFReader.ReadAMF3ByteArray() AMFWriter.WriteByteArray()

这有助于我快速地建立我所需要的:

Which help me to quickly build what I need :

private static byte[] RemoveAMF3ByteArrayPrefixBytes(byte[] ar)
    {
        var ms = new MemoryStream(ar);
        var br = new BinaryReader(ms);

        // if first byte is AMF TypeCode for ByteArray
        if (br.Read() != 12)
            return ar;

        int handle = ReadAMF3IntegerData(br);
        bool inline = ((handle & 1) != 0);
        handle = handle >> 1;
        if (inline)
        {
            int length = handle;
            byte[] buffer = br.ReadBytes(length);
            return buffer;
        }

        return ar;
    }

    private static byte[] AddAMF3ByteArrayPrefixBytes(byte[] ar)
    {
        var ms = new MemoryStream();
        var bw = new BinaryWriter(ms);

        bw.Write((byte)12); // AMF TypeCode for ByteArray
        var handle = (int)ar.Length;
        handle = handle << 1;
        handle = handle | 1;
        WriteAMF3IntegerData(bw, handle);

        bw.Write(ar);

        return ms.ToArray();
    }

    /// <summary>
    /// Handle decoding of the variable-length representation which gives seven bits of value per serialized byte by using the high-order bit 
    /// of each byte as a continuation flag.
    /// </summary>
    /// <returns></returns>
    private static int ReadAMF3IntegerData(BinaryReader br)
    {
        int acc = br.ReadByte();
        if(acc < 128)
            return acc;
        else
        {
            acc = (acc & 0x7f) << 7;
            int tmp = br.ReadByte();
            if(tmp < 128)
                acc = acc | tmp;
            else
            {
                acc = (acc | tmp & 0x7f) << 7;
                tmp = br.ReadByte();
                if(tmp < 128)
                    acc = acc | tmp;
                else
                {
                    acc = (acc | tmp & 0x7f) << 8;
                    tmp = br.ReadByte();
                    acc = acc | tmp;
                }
            }
        }

        //To sign extend a value from some number of bits to a greater number of bits just copy the sign bit into all the additional bits in the new format.
        //convert/sign extend the 29bit two's complement number to 32 bit
        int mask = 1 << 28; // mask
        int r = -(acc & mask) | acc;
        return r;

        //The following variation is not portable, but on architectures that employ an 
        //arithmetic right-shift, maintaining the sign, it should be fast. 
        //s = 32 - 29;
        //r = (x << s) >> s;
    }

    private static void WriteAMF3IntegerData(BinaryWriter bw, int value)
    {
        //Sign contraction - the high order bit of the resulting value must match every bit removed from the number
        //Clear 3 bits 
        value &= 0x1fffffff;
        if (value < 0x80)
            bw.Write((byte)value);
        else
            if (value < 0x4000)
            {
                bw.Write((byte)(value >> 7 & 0x7f | 0x80));
                bw.Write((byte)(value & 0x7f));
            }
            else
                if (value < 0x200000)
                {
                    bw.Write((byte)(value >> 14 & 0x7f | 0x80));
                    bw.Write((byte)(value >> 7 & 0x7f | 0x80));
                    bw.Write((byte)(value & 0x7f));
                }
                else
                {
                    bw.Write((byte)(value >> 22 & 0x7f | 0x80));
                    bw.Write((byte)(value >> 15 & 0x7f | 0x80));
                    bw.Write((byte)(value >> 8 & 0x7f | 0x80));
                    bw.Write((byte)(value & 0xff));
                }
    }

我希望这将帮助别人。

I hope that will help someone else.

这篇关于什么是Blob列的SQLite的Adobe AIR的第一个字节?斑点Sizeinfo?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆