Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7991679
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T13:21:40+00:00 2026-06-04T13:21:40+00:00

I am trying to develop a Web-Client based Online game using GWT. The game

  • 0

I am trying to develop a Web-Client based Online game using GWT.

The game mechanics work quite fine by now and I’d really like to go on with my next step in my development plan, but now I am stuck with a simple encoding/decoding function I created to store my data for the client into a string.

The steps I took are not that complicated. During runtime, my server creates “ImageStates” of the game Objects to be drawn on a Canvas on my client. Each ImageState contains a number of Layers, which contain Details of what has to be drawn where at what specific time and so on.

I tried ObjectInput/OutputStream, combined with GZip-Compression and ByteInputStreams, but I could not find any GWT implementation of the first two so I had to think about another solution and came across gwt-lzma.

My goal is to encode those details into a single string, compress it on the server, send the compressed Data to the client, decompress and decode it there so it can be “read” by the client. To do so, I created an encoding and a decoding function:

The encoder:

public static String encodeImageStateContainer(HashMap<String,HashMap<Long,ImageState>> imageStateContainer){
    StringBuilder mainStringBuilder = new StringBuilder();

    Iterator<Entry<String,HashMap<Long,ImageState>>> imageStateContainerIterator = imageStateContainer.entrySet().iterator();
    while(imageStateContainerIterator.hasNext()){
        Entry<String,HashMap<Long,ImageState>> tempImageStateManagerMetadata = imageStateContainerIterator.next();

        HashMap<Long,ImageState> tempImageStateManager = tempImageStateManagerMetadata.getValue();

        if(tempImageStateManager.size() > 0){

            if(mainStringBuilder.length() > 0){
                mainStringBuilder.append('}');  //Divisor between Image State Managers
            }

            mainStringBuilder.append(tempImageStateManagerMetadata.getKey());
            mainStringBuilder.append('|');  //Divisor between Name and following Data

            StringBuilder subOneStringBuilder = new StringBuilder();            

            Iterator<Entry<Long,ImageState>> tempImageStateManagerIterator = tempImageStateManager.entrySet().iterator();
            while(tempImageStateManagerIterator.hasNext()){
                Entry<Long,ImageState> tempImageStateMetaData = tempImageStateManagerIterator.next();

                if(subOneStringBuilder.length() > 0){
                    subOneStringBuilder.append(')');    //Divisor between Image Objects
                }

                subOneStringBuilder.append(tempImageStateMetaData.getKey());
                subOneStringBuilder.append('-');    //Divisor between Object Id and Image State Data

                StringBuilder subTwoStringBuilder = new StringBuilder();
                ImageState tempImageState = tempImageStateMetaData.getValue();
                subOneStringBuilder.append(tempImageState.getFirstFrameId());   //1. => First Frame Id
                subOneStringBuilder.append(';');    //Divisor between Image State data types
                subOneStringBuilder.append(tempImageState.getFramesPerLayer()); //2. => Total Frame Count
                subOneStringBuilder.append(';');
                subOneStringBuilder.append(tempImageState.getMinumimScaleFactor()); //3. => Minimum Scale Factor
                subOneStringBuilder.append(';');

                ImageStateLayer[] tempImageStateLayers = tempImageState.getImageStateLayers();
                for(int layerId = 0; layerId < tempImageStateLayers.length; ++layerId){

                    if(subTwoStringBuilder.length() > 0){
                        subTwoStringBuilder.append('/');    //Divisor between Image State Layers
                    }

                    //Frame Arrays
                    String[] imageNativePath = tempImageStateLayers[layerId].getImageNativePath();
                    short[] offsetX = tempImageStateLayers[layerId].getOffsetX();
                    short[] offsetY = tempImageStateLayers[layerId].getOffsetY();
                    short[] orientation = tempImageStateLayers[layerId].getOrientation();

                    //Finalization Arrays
                    byte[] imagePathChange = tempImageStateLayers[layerId].getImagePathChange();
                    byte[] offsetXChange = tempImageStateLayers[layerId].getOffsetXChange();
                    byte[] offsetYChange = tempImageStateLayers[layerId].getOffsetYChange();
                    byte[] orientationChange = tempImageStateLayers[layerId].getOrientationChange();


                    //Image Path Data
                    StringBuilder subThreeStrignBuilder = new StringBuilder();
                    for(int imagePathId = 0; imagePathId < imageNativePath.length; ++imagePathId){

                        if(subThreeStrignBuilder.length() > 0){
                            subThreeStrignBuilder.append('#');  //Divisor between Frame Data Sets
                        }

                        subThreeStrignBuilder.append(imageNativePath[imagePathId]);
                        subThreeStrignBuilder.append(',');  //Divisor between Frame Data Set Data
                        subThreeStrignBuilder.append(imagePathChange[imagePathId]);
                    }

                    subTwoStringBuilder.append(subThreeStrignBuilder.toString());
                    subTwoStringBuilder.append('[');    //Divisor between Frame Data Types

                    //OffsetX Data
                    subThreeStrignBuilder = new StringBuilder();
                    for(int offsetXId = 0; offsetXId < offsetX.length; ++offsetXId){

                        if(subThreeStrignBuilder.length() > 0){
                            subThreeStrignBuilder.append('#');  //Divisor between Frame Data Sets
                        }

                        subThreeStrignBuilder.append(offsetX[offsetXId]);
                        subThreeStrignBuilder.append(',');  //Divisor between Frame Data Set Data
                        subThreeStrignBuilder.append(offsetXChange[offsetXId]);
                    }

                    subTwoStringBuilder.append(subThreeStrignBuilder.toString());
                    subTwoStringBuilder.append('[');    //Divisor between Frame Data Types

                    //OffsetY Data
                    subThreeStrignBuilder = new StringBuilder();
                    for(int offsetYId = 0; offsetYId < offsetY.length; ++offsetYId){

                        if(subThreeStrignBuilder.length() > 0){
                            subThreeStrignBuilder.append('#');  //Divisor between Frame Data Sets
                        }

                        subThreeStrignBuilder.append(offsetY[offsetYId]);
                        subThreeStrignBuilder.append(',');  //Divisor between Frame Data Set Data
                        subThreeStrignBuilder.append(offsetYChange[offsetYId]);
                    }

                    subTwoStringBuilder.append(subThreeStrignBuilder.toString());
                    subTwoStringBuilder.append('[');    //Divisor between Frame Data Types

                    //Orientation Data
                    subThreeStrignBuilder = new StringBuilder();
                    for(int orientationId = 0; orientationId < orientation.length; ++orientationId){

                        if(subThreeStrignBuilder.length() > 0){
                            subThreeStrignBuilder.append('#');  //Divisor between Frame Data Sets
                        }

                        subThreeStrignBuilder.append(orientation[orientationId]);
                        subThreeStrignBuilder.append(',');  //Divisor between Frame Data Set Data
                        subThreeStrignBuilder.append(orientationChange[orientationId]);
                    }

                    subTwoStringBuilder.append(subThreeStrignBuilder.toString());

                }
                subOneStringBuilder.append(subTwoStringBuilder.toString());             
            }
            mainStringBuilder.append(subOneStringBuilder.toString());
        }
    }

    return mainStringBuilder.toString();
}

The decoder:

public static HashMap<String,HashMap<Long,ImageState>> decodeImageStateContainer(String data){      

    String[] imageStateManagerArray = data.split("\\}");
    HashMap<String,HashMap<Long,ImageState>> imageStateManagerContainer = new HashMap<String,HashMap<Long,ImageState>>(imageStateManagerArray.length);

    for(int managerId = 0; managerId < imageStateManagerArray.length; ++managerId){
        String[] tempImageStateData = imageStateManagerArray[managerId].split("\\|");

        HashMap<Long,ImageState> tempImageStateManager = new HashMap<Long,ImageState>();
        imageStateManagerContainer.put(tempImageStateData[0], tempImageStateManager);

        String[] tempImageStateManagerObjects = tempImageStateData[1].split("\\)");

        for(int objectId = 0; objectId < tempImageStateManagerObjects.length; ++objectId){
            String[] tempImageObjectData = tempImageStateManagerObjects[objectId].split("\\-");

            long imageObjectId = Long.parseLong(tempImageObjectData[0]);
            String[] imageStateMetaData = tempImageObjectData[1].split("\\;");              
            ImageState tempImageState = new ImageState(Integer.parseInt(imageStateMetaData[1]), Integer.parseInt(imageStateMetaData[0]), Integer.parseInt(imageStateMetaData[2]));
            tempImageStateManager.put(imageObjectId, tempImageState);

            String[] tempImageStateLayerMetaData = imageStateMetaData[3].split("\\/");
            ImageStateLayer[] tempImageStateLayers = new ImageStateLayer[tempImageStateLayerMetaData.length];

            for(int layerId = 0; layerId < tempImageStateLayerMetaData.length; ++layerId){
                String[] layerElements = tempImageStateLayerMetaData[layerId].split("\\[");     

                String[] imageNativePathDetails = layerElements[0].split("\\#");
                String[] offsetXDetails = layerElements[1].split("\\#");
                String[] offsetYDetails = layerElements[2].split("\\#");
                **String[] orientationDetails = layerElements[3].split("\\#");**

                //Image Path Data
                String[] imageNativePaths = new String[imageNativePathDetails.length];
                byte[] imagePathChange = new byte[imageNativePathDetails.length];
                for(int id = 0; id < imageNativePathDetails.length; ++id){                      
                    String[] imagePathDetailElements = imageNativePathDetails[id].split("\\,");
                    imageNativePaths[id] = imagePathDetailElements[0];
                    imagePathChange[id] = Byte.parseByte(imagePathDetailElements[1]);
                }

                //OffsetX Data
                short[] offsetX = new short[offsetXDetails.length];
                byte[] offsetXChange = new byte[offsetXDetails.length];
                for(int id = 0; id < offsetXDetails.length; ++id){
                    String[] offsetXDetailElements = offsetXDetails[id].split("\\,");
                    offsetX[id] = Short.parseShort(offsetXDetailElements[0]);
                    offsetXChange[id] = Byte.parseByte(offsetXDetailElements[1]);
                }

                //OffsetY Data
                short[] offsetY = new short[offsetYDetails.length];
                byte[] offsetYChange = new byte[offsetYDetails.length];
                for(int id = 0; id < offsetYDetails.length; ++id){
                    String[] offsetYDetailElements = offsetYDetails[id].split("\\,");
                    offsetY[id] = Short.parseShort(offsetYDetailElements[0]);
                    offsetYChange[id] = Byte.parseByte(offsetYDetailElements[1]);
                }

                //Orientation Data
                short[] orientation = new short[orientationDetails.length];
                byte[] orientationChange = new byte[orientationDetails.length];
                for(int id = 0; id < orientationDetails.length; ++id){
                    String[] orientationDetailElements = orientationDetails[id].split("\\,");
                    orientation[id] = Short.parseShort(orientationDetailElements[0]);
                    orientationChange[id] = Byte.parseByte(orientationDetailElements[1]);
                }

                //Create the Layer and Add it to the Array
                tempImageStateLayers[layerId] = new ImageStateLayer(imageNativePaths,new short[][]{offsetX,offsetY,orientation}, new byte[][]{imagePathChange,offsetXChange,offsetYChange,orientationChange});

            }

            //Connect the Reference to the layers with the Image State
            tempImageState.setImageStateLayers(tempImageStateLayers);

        }           

    }       

    return imageStateManagerContainer;
}

Now my problem: If I encode it on the server and decode it directly afterwards It takes about three cycles of Encoding until I get an IndexOutofBoundsException at this specific position in the decoder, the last line is the line where the error seems to be according to stacktrace:

for(int layerId = 0; layerId < tempImageStateLayerMetaData.length; ++layerId){
                String[] layerElements = tempImageStateLayerMetaData[layerId].split("\\[");     

                String[] imageNativePathDetails = layerElements[0].split("\\#");
                String[] offsetXDetails = layerElements[1].split("\\#");
                String[] offsetYDetails = layerElements[2].split("\\#");
                String[] orientationDetails = layerElements[3].split("\\#");

I would not say I’m an expert, but after testing the encoder I can definitely say that the string generated by it is always valid, the string at which I get this error is complete as well. There must be something wrong with my decoding function, but I have no idea what it could be.

As I said, the first three cycles are encoded and decoded properly and the data to encode did not change dramatically. There is no way that the encoded string could lead to having a String array smaller than 4 elements. Basically, this error can’t exist as far as I understand my code.

I think it could be some kind of memory allocation problem that prevents the string from being split properly, but thats just an idea of a clueless programmer.

Any help is deeply appreciated!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-04T13:21:42+00:00Added an answer on June 4, 2026 at 1:21 pm

    I found the solution to my problem:

    While encoding, I was printing Numeric types to my string. While selecting my Seperator symbols I didn’t take negative values, resulting in a ‘-‘ before the digit into consideration, which led to an uncontrolled splitting of my String when I tryed to split by ‘-‘. I replaced the minus with another character and everything works fine now!

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to develop a Java web based application that can work flow different
I am trying to develop a web-based (and could work on portable devices like
trying to develop web form using jquery. all i need is to have several
I’m trying to develop a online shopping web service with RESTful. However, I’m so
i'm trying to develop a simple Hello World web service using Axis2 v1.5, Tomcat6
I'm trying to develop android web apps using html 5.I'm using dreamviewer 5 with
I am trying to develop a web project using Hibernate 4 and spring 3.1.
I'm trying to develop a web based digital asset management application. I'm planning to
I'm trying to develop a standalone Java web service client with JAX-WS (Metro) that
I am trying to develop a web bassed FTP client for my NAS. When

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.