/*----------------------------------------------------------------------------*/
/*                                                                            */
/* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved.             */
/* Copyright (c) 2005-2014 Rexx Language Association. All rights reserved.    */
/*                                                                            */
/* This program and the accompanying materials are made available under       */
/* the terms of the Common Public License v1.0 which accompanies this         */
/* distribution. A copy is also available at the following address:           */
/* https://www.oorexx.org/license.html                                        */
/*                                                                            */
/* Redistribution and use in source and binary forms, with or                 */
/* without modification, are permitted provided that the following            */
/* conditions are met:                                                        */
/*                                                                            */
/* Redistributions of source code must retain the above copyright             */
/* notice, this list of conditions and the following disclaimer.              */
/* Redistributions in binary form must reproduce the above copyright          */
/* notice, this list of conditions and the following disclaimer in            */
/* the documentation and/or other materials provided with the distribution.   */
/*                                                                            */
/* Neither the name of Rexx Language Association nor the names                */
/* of its contributors may be used to endorse or promote products             */
/* derived from this software without specific prior written permission.      */
/*                                                                            */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS        */
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT          */
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS          */
/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT   */
/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,      */
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED   */
/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,        */
/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY     */
/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING    */
/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS         */
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.               */
/*                                                                            */
/*----------------------------------------------------------------------------*/

#ifndef RxString_HPP_INCLUDED
#define RxString_HPP_INCLUDED

#include "rexx.h"
#include "ServiceException.hpp"
#include "SysAPIManager.hpp"

class Rxstring
{
public:
    size_t strlength;                // length of the string
    char * strptr;                   // the string data
};

class ManagedRxstring : public Rxstring
{
public:
    inline ManagedRxstring()
    {
        strlength = 0;
        strptr = NULL;
    }

    inline ManagedRxstring(size_t size)
    {
        setStringSize(size);
    }

    inline ~ManagedRxstring()
    {
        if (strptr != NULL)
        {
            SysAPIManager::releaseMemory(strptr);
        }
    }

    void setStringSize(size_t size)
    {
        strlength = size;
        allocateResult(size);
    }


    void ensureCapacity(size_t size)
    {
        if (strlength < size || strptr == NULL)
        {
            if (strptr != NULL)
            {
                SysAPIManager::releaseMemory(strptr);
                strptr = NULL;
            }
            setStringSize(size);
        }
    }

    char *allocateResult(size_t size)
    {
        strptr = (char *)SysAPIManager::allocateMemory(size);
        if (strptr == NULL)
        {
            throw new ServiceException(MEMORY_ERROR, "Error allocating result data");
        }
        return strptr;
    }
};

#endif
