All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.crankuptheamps.client.CompositeMessageParser Maven / Gradle / Ivy

There is a newer version: 5.3.4.0
Show newest version
////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2010-2021 60East Technologies Inc., All Rights Reserved.
//
// This computer software is owned by 60East Technologies Inc. and is
// protected by U.S. copyright laws and other laws and by international
// treaties.  This computer software is furnished by 60East Technologies
// Inc. pursuant to a written license agreement and may be used, copied,
// transmitted, and stored only in accordance with the terms of such
// license agreement and with the inclusion of the above copyright notice.
// This computer software or any other copies thereof may not be provided
// or otherwise made available to any other person.
//
// U.S. Government Restricted Rights.  This computer software: (a) was
// developed at private expense and is in all respects the proprietary
// information of 60East Technologies Inc.; (b) was not developed with
// government funds; (c) is a trade secret of 60East Technologies Inc.
// for all purposes of the Freedom of Information Act; and (d) is a
// commercial item and thus, pursuant to Section 12.212 of the Federal
// Acquisition Regulations (FAR) and DFAR Supplement Section 227.7202,
// Government's use, duplication or disclosure of the computer software
// is subject to the restrictions set forth by 60East Technologies Inc..
//
////////////////////////////////////////////////////////////////////////////
package com.crankuptheamps.client;

import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;

import com.crankuptheamps.client.fields.Field;

/**
 * Used to retrieve individual message parts from AMPS composite messages,
 * which are messages where the data contains a number of parts and each part
 * is a complete message of a specific message type.
 * For example, a composite message type of "composite-json-binary" may be
 * declared on the server that combines a set of JSON headers with
 * an opaque binary payload. CompositeMessageParser makes it easy to retrieve
 * the parts of a composite message from the composite message payload.
 * 
 */
public class CompositeMessageParser
{
    /**
     * Creates a new CompositeMessageParser, with 0 valid parts.
     */
    public CompositeMessageParser()
    {
        _metadata = new int[MAX_PARTS * 2];
        _validCount = 0;
    }
    /**
     * Creates a new CompositeMessageParser and parses the provided message body.
     * @param body_ The composite body (returned from Message.getDataRaw()).
     */
    public CompositeMessageParser(Field body_)
    {
        _metadata = new int[MAX_PARTS * 2];
        parse(body_);
    }
    
    /**
     * Creates a new CompositeMessageParser and parses a message's body.
     * @param message_ The message containing a composite body.
     */
    public CompositeMessageParser(Message message_)
    {
        _metadata = new int[MAX_PARTS * 2];
        parse(message_.getDataRaw());
    }
    
    /**
     * Parses a composite message.
     * @param message_ The message with a composite body.
     * @return The number of message parts found in message_
     */
    public final int parse(Message message_)
    {
        return parse(message_.getDataRaw());
    }
    /**
     * Parses a composite message's body.
     * @param body_ The composite body (returned from Message.getDataRaw()).
     * @return The number of message parts found in body_
     */
    public final int parse(Field body_)
    {
        _validCount = 0;
        // Skip through the body buffer, and write offsets to our internal _offset array.
        int position = body_.position;
        int end      = position + body_.length;
        byte[]  buf  = body_.buffer;
        int metaIndex = 0;
        while(position+4 <= end)
        {
            // extract part length
            int partlength = (buf[position++]&0xFF) << 24;
            partlength |= (buf[position++]&0xFF) << 16;
            partlength |= (buf[position++]&0xFF) << 8;
            partlength |= (buf[position++]&0xFF);
            
            _metadata[metaIndex++] = position;
            _metadata[metaIndex++] = partlength;
            position += partlength;
        }
        _data = buf;
        _validCount = metaIndex/2;
        return _validCount;
    }

    /**
     * Returns a part from a composite message body.
     * @param index_ The part index to retrieve (0-based index)
     * @return The data of this body part, decoded as UTF-8.
     */
    public String getString(int index_)
    {
        return getString(index_,UTF8);
    }
    
    /**
     * Returns a part from a composite message body.
     * @param index_ The part index to retrieve (0-based index)
     * @param charset The Charset to decode this body with.
     * @return The data of this body part.
     */
    public String getString(int index_,Charset charset)
    {
        if(index_ < _validCount)
        {
            return new String(_data,_metadata[index_*2],_metadata[(index_*2)+1],charset);
        }
        throw new RuntimeException("index out of bounds.");
    }
    
    
    /**
     * Returns a part from a composite message body.
     * @param index_ The part index to retrieve (0-based index)
     * @param field_ The Field to update with the buffer, index, and length of this part.
     * @return The field passed as field_.
     */
    public Field getPart(int index_,Field field_)
    {
        if(index_ < _validCount)
        {
            field_.buffer = _data;
            field_.position = _metadata[index_*2];
            field_.length = _metadata[(index_*2)+1];
            return field_;
        }
        throw new RuntimeException("index out of bounds.");
    }
    
    //Private Methods

    private static int MAX_PARTS = 1024;
    private static Charset UTF8 = Charset.forName("UTF-8");
    private int[]  _metadata = null;
    private byte[] _data = null;
    private int    _validCount;
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy