0

I'm getting a compressed string from my .net web service. In eclipse I want to decompress the sting.

Compressing the string in web service:

public static string Compress(string text)
 {
    byte[] buffer = Encoding.UTF8.GetBytes(text);
    MemoryStream ms = new MemoryStream();
    using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true))
    {
        zip.Write(buffer, 0, buffer.Length);
    }

    ms.Position = 0;
    MemoryStream outStream = new MemoryStream();

    byte[] compressed = new byte[ms.Length];
    ms.Read(compressed, 0, compressed.Length);

    byte[] gzBuffer = new byte[compressed.Length + 4];
    System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);
    System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);
    return Convert.ToBase64String(gzBuffer);
}

Web Service response in android using async:

  resultJsonString = new AsyncGetProductIdResults().execute(link).get();


  String temp = unZip(resultJsonString);

Async:

  class AsyncGetProductIdResults extends AsyncTask<String, Void, String>
  {
  @SuppressWarnings("null")       
 @Override
 protected String doInBackground(String... params) 
 {   
    String url = params[0];
    HttpClient httpClient = new DefaultHttpClient();
    HttpGet httpPost = new HttpGet(url);

    try 
    {          
        HttpResponse response = httpClient.execute(httpPost);

        return EntityUtils.toString(response.getEntity());
    } 

    catch (ClientProtocolException e)
    {
        e.printStackTrace();            
    } 

    catch (IOException e)
    {           
        e.printStackTrace();            
    }

    return null;
 }

 @Override
 protected void onPostExecute(String idResult) 
 {           
    if (idResult == null)
  public static byte[] ZipStr(string str)
    {
    {
        return;         
    }
 }
}

Decompress in android:

public String unZip(String zipped) throws DataFormatException, IOException 
{
byte[] bytes = zipped.getBytes();
Inflater decompressed = new Inflater();
decompressed.setInput(bytes);

byte[] result = new byte[1000];
ByteArrayOutputStream buffer = new ByteArrayOutputStream();

while (decompressed.inflate(result) != 0)
    buffer.write(result);

decompressed.end();

return buffer.toString();
}

Logcat:

01-08 11:07:59.016: E/AndroidRuntime(1327): FATAL EXCEPTION: main
01-08 11:07:59.016: E/AndroidRuntime(1327): java.lang.IllegalStateException: Could not execute method of the activity
01-08 11:07:59.016: E/AndroidRuntime(1327):     at android.view.View$1.onClick(View.java:3591)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at android.view.View.performClick(View.java:4084)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at android.view.View$PerformClick.run(View.java:16966)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at android.os.Handler.handleCallback(Handler.java:615)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at android.os.Handler.dispatchMessage(Handler.java:92)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at android.os.Looper.loop(Looper.java:137)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at android.app.ActivityThread.main(ActivityThread.java:4745)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at java.lang.reflect.Method.invokeNative(Native Method)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at java.lang.reflect.Method.invoke(Method.java:511)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at dalvik.system.NativeStart.main(Native Method)
01-08 11:07:59.016: E/AndroidRuntime(1327): Caused by: java.lang.reflect.InvocationTargetException
01-08 11:07:59.016: E/AndroidRuntime(1327):     at java.lang.reflect.Method.invokeNative(Native Method)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at java.lang.reflect.Method.invoke(Method.java:511)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at android.view.View$1.onClick(View.java:3586)
01-08 11:07:59.016: E/AndroidRuntime(1327):     ... 11 more
01-08 11:07:59.016: E/AndroidRuntime(1327): Caused by: java.util.zip.DataFormatException: data error
01-08 11:07:59.016: E/AndroidRuntime(1327):     at java.util.zip.Inflater.inflateImpl(Native Method)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at java.util.zip.Inflater.inflate(Inflater.java:228)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at java.util.zip.Inflater.inflate(Inflater.java:205)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at com.example.testp.SecondActivity.unZip(SecondActivity.java:184)
01-08 11:07:59.016: E/AndroidRuntime(1327):     at com.example.testp.SecondActivity.JSONDataSync(SecondActivity.java:83)
01-08 11:07:59.016: E/AndroidRuntime(1327):     ... 14 more

My web service and response worked before I started to implement the compression and decompression. Any help will be appreciated. Even if you can just point me to material I can read up on.

Edit 1

After apply the changes proposed in https://stackoverflow.com/a/21016711/1587302

  public static byte[] ZipStr(string str)
    {
        using (MemoryStream output = new MemoryStream())
        {
            using (DeflateStream gzip =
              new DeflateStream(output, CompressionMode.Compress))
            {
                using (StreamWriter writer =
                  new StreamWriter(gzip, System.Text.Encoding.UTF8))
                {
                    writer.Write(str);
                }
            }

            return output.ToArray();
        }
    }

Asynctask on android:

class AsyncGetProductIdResultsBytes extends AsyncTask<String, Void, byte[]>
{
    @SuppressWarnings("null")       
    @Override
    protected byte[] doInBackground(String... params) 
    {   
        String url = params[0];
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpPost = new HttpGet(url);

        try 
        {         
            HttpResponse response = httpClient.execute(httpPost);

            return EntityUtils.toByteArray(response.getEntity());
        } 

        catch (ClientProtocolException e)
        {
            e.printStackTrace();            
        } 

        catch (IOException e)
        {           
            e.printStackTrace();            
        }

        return null;
    }

    @Override
    protected void onPostExecute(byte[] idResult) 
    {           
        if (idResult == null)
        {
            return;         
        }
    }
}

Decompress in android: Still busy with decompression.

Content of byte[] on webservice side after compression: [1,97,0,0,31,139, ...]

Content of byte[] on android side before decompression: [123,34,103,101,116,65, ...]

Just wanting to know if im doing the compression right on webservice side? Should the content of the byte[] change when its received on android side?

Community
  • 1
  • 1
user3074196
  • 35
  • 1
  • 9
  • Well, could exists a problem with the endianness: if you read the first four bytes of the data in java is the same than in c#? – Narkha Jan 08 '14 at 14:29
  • The compressed string from in web service:{"getAllProjectsByIDResult":"AWEAAB+LCAAAAAAABADsvQdgHEmWJSYvbcp7f0r1StfgdKEIgGATJNiQQBDswYjN5pLsHWlHIymrKoHKZVZlXWYWQMztnbz33nvvvffee++997o7nU4n99"} – user3074196 Jan 09 '14 at 05:49
  • The received string in eclipse{"getAllProjectsByIDResult":"AWEAAB+LCAAAAAAABADsvQdgHEmWJSYvbcp7f0r1StfgdKEIgGATJNiQQBDswYjN5pLsHWlHIymrKoHKZVZlXWYWQMztnbz33nvvvffee++997o7nU4n99"} – user3074196 Jan 09 '14 at 05:49
  • I just wrote the byte array before conversion to string to a text file from the web service side. this is its content: ‹ ì½`I–%&/mÊ{JõJ×àt¡€`$Ø@ìÁˆÍæ’ìiG#)«*ÊeVe]f@Ìí¼÷Þ{ï½÷Þ{ï½÷º;N'÷ßÿ?\fdlöÎJÚÉž!€ªÈ?~|?"¾÷‹?zYW?OÛ³§=Ú¿72¾ÈùG>:9y–ž¼>K_·ëÙõG£žæÍ´.VmQ-ñíºi«E^§¯³¶hγ)>OÏ–³ü}ãu›ÕíÓ¬´ß÷.~ÙÚÝ{ðàá½û{;xîü¾w©ÕiÓúnvºœußÛy¸ÿ`×o|r=-óæ£G÷ô×7׫œÿzQ}yn¾Ü}ôÝì2o^æ5$ÍË"_òP÷vµu} – user3074196 Jan 09 '14 at 06:15
  • 1
    I strongly doubt you "decompress string in Eclipse"... – Marcin Orlowski Jan 09 '14 at 09:53

1 Answers1

0

I see two problems:

The first is that you are encoding the data in base 64 in c# but you are not decoding it in java, at least in the code that you have posted.

The second is that you are decompressing a byte[] who contains the length of the compressed data and the compressed data, which is normal that give an error.

Here you have an example of that you are trying to do: https://stackoverflow.com/a/18606270/1587302

And there another thing that i am not sure that if can cause problems: in c# you are compressing with GZipStream, who does not use zlib; in java decompressing with Inflater , who use zlib. As i said i am not really sure if it is a problem, but i recommend use the same in both sides: in c# DeflateStream uses zlib and in java GZIPInputStream uses gzip. Edit: as user3074196 confirm is his comment this is a problem too.

Response to Edit 1

I think that the problem is that you are sending binary data which interfiere with the data of protocol http. I can think two solutions:

The first is send a string encoded in base 64, as in you first version and decode it in java.

The second is use stream request and transmit binary data.

Community
  • 1
  • 1
Narkha
  • 1,197
  • 2
  • 12
  • 30
  • I made changes as per the link you posted. Now I get a new error: IOException: unknown format (magic number eb53) at java.util.zip.GZIPInputStream.(GZIPInputStream.java:101) – user3074196 Jan 09 '14 at 10:32
  • Look the las parragraph of my answer: you comment confirm it. So, i will use in c# DeflateStream instead GZipStream. – Narkha Jan 09 '14 at 10:41
  • Im using DeflateStream on the webservice side. But now im sending a byte[] [1,97,0,0,31,139, ...] and not a string. On the receiving side on android im using the async task but changed it to receive a byte[]. But the content of the byte array on android is:[123,34,103,101,116,65, ...]. Do you maybe know why the content has changed? – user3074196 Jan 10 '14 at 08:10
  • could you post the changes? – Narkha Jan 10 '14 at 08:53