2011-06-17 8 views
1

私は、データベースがAdobe AIR経由で操作されているときに、任意のBLOBフィールドに挿入されたランダムな一連のバイトを特定しました。 (私の結果からは常にバイト[12、...]で始まると思われますが、私はそれが分かりません)BLOB列の最初のバイトは何ですか?SQlite Adob​​e AIR?ブロブSizeinfo?

私はそれがバイトのsizeinfoだと思います結論。

まず私のコンテキスト:私はでいっぱいSqliteをデシベルを読めば、私はSystem.data.sqliteでのAdobe AIR(クライアント側)とSystem.data.sqlite(C#のサーバ側)

てsqliteのデータベースを操作しますBLOB by Adob​​e AIR私は最初にAIRによって付加されたバイトを乗り越えなければなりません。そして、私はバイナリデータをすべて整形しました。完璧!

Adob​​e AIRでは、System.data.SqliteによってBLOBで満たされたsqlite dbを読み込もうとすると、データが破損してエラーが発生します。明らかに私はAIRが研究していない欠けているバイトを持っていないからです。

もちろん、最初のケースで削除した一連の3バイトをコピーしてから、それらのバイトを追加しようとしましたが、部分的にデータが返されました。画像の場合、最後のピクセル行はすべて灰色になりますいくつかの画像私は多かれ少なかれグレーラインを持っています。データは同じ〜4kサイズの一連の画像に対応していたので、そのうち3バイトを追加してこの結果を得ました。

と空気も時々、このエラーがスローされます。

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

だから、明らかにこれらのバイトは、サイズ上の情報を与えるが、私は本当にそれがないか取得しません!?!

私は長さ4kのbytearrayを追加しようとしましたが、3バイトを追加する傾向がありましたが、4Mを追加しようとしましたが、それは5バイトになります。

私はこの質問How do you convert 3 bytes into a 24 bit number in C#?を見つけました、そして、私はサイズ情報がどのように格納されるのかと考えました。

しかし、私はまだそれを得ることはありません... FluorineFX

+0

オハイオ州私は私がそれを試して答えを投稿すると思う何かを見つけた:http://stackoverflow.com/questions/3345553/how-do-you-convert-3-bytes-into-a -24-bit-in-c – nrako

答えて

1

おかげで(AMFは、.NET用)オープンソースプロジェクトここで答えです。

私のAdobe AIRプロジェクトでは、air.ByteArrayオブジェクトをパラメータとして渡す必要があるため、すべてをsqlite BLOBフィールドに格納する必要があります。 AIRは、コンパイルされたバイナリのActionScript形式のメッセージであるAMFにすべてをシリアル化します。

ページ11 Secion 3.14 ByteArrayのタイプ

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

ドキュメントが規定:

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.

しかし、すべてではないthatsの、私はAMF NETのオープンソースプロジェクトを検索しFluorineFXを設立しました。

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

さらに検索して、もう一度私はFluorineFX源AMFReaderで見つかった:私はすべてのAMFバイナリがByteArrayのためあるバイト型コードが付いていることが確認されたコードの中に探しています。ReadAMF3ByteArray()AMFWriter.WriteByteArray()私はすぐに私が必要なものを構築するのに役立つ

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)); 
       } 
    } 

私はそれが他の誰かを助けることを願っています。

0

ありがとう、私は問題を解決するのに役立ちました。ここでは、Javaコードでそれを行う方法です:

は、プロジェクトに私の例では

定型コードで初期GDS

GraniteConfig graniteConfig = new GraniteConfig(null, null, null, null); 
ServicesConfig servicesConfig = new ServicesConfig(null, null, false); 
Map<String, Object> applicationMap = new HashMap<String, Object>(); 
SimpleGraniteContext.createThreadIntance(graniteConfig, servicesConfig, applicationMap); 

をorg.granite花崗岩コアの依存関係を追加し、私は、画像ファイルを読み込みます魔法のように

fis = new FileInputStream(file); 
ps = connection.prepareStatement(INSERT_PICTURE); 
ps.setString(1, key); 
byte[] fileBytes = FileUtils.readFileToByteArray(file); 
ByteArrayOutputStream out = new ByteArrayOutputStream(); 
AMF3Serializer ser = new AMF3Serializer(out); 
ser.writeObject(fileBytes); 
ser.flush(); 
ps.setBytes(2, out.toByteArray()); 

作品、ヒント:)

に感謝:私は、BLOBに挿入すること

Fabien

+0

素晴らしいそれは助けることができてうれしい!そして、あなたのJavaソリューションを持ってきてくれてありがとう! – nrako