Host library for controlling a WiConnect enabled Wi-Fi module.

Dependents:   wiconnect-ota_example wiconnect-web_setup_example wiconnect-test-console wiconnect-tcp_server_example ... more

internal/types/File.cpp

Committer:
dan_ackme
Date:
2014-08-11
Revision:
0:ea85c4bb5e1f
Child:
1:6ec9998427ad

File content as of revision 0:ea85c4bb5e1f:

/*
 * Copyright 2014, ACKme Networks
 * All Rights Reserved.
 *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks;
 * the contents of this file may not be disclosed to third parties, copied
 * or duplicated in any form, in whole or in part, without the prior
 * written permission of ACKme Networks.
 */


#include <assert.h>
#include "Wiconnect.h"
#include "internal/common.h"

#define CHECK_OPENED_FOR_READING() if(!readEnabled) return WICONNECT_NOT_OPENED_FOR_READING




/*************************************************************************************************/
File::File(int rxBufferLen, void *rxBuffer_)
{
    wiconnect = Wiconnect::getInstance();

    memset(&rxBuffer, 0, sizeof(Buffer));

    rxBuffer.size = !wiconnect->nonBlocking ? rxBufferLen : 0;
    rxBuffer.buffer = (uint8_t*)rxBuffer_;

    if(rxBuffer.size > 0)
    {
        if(rxBuffer_ == NULL)
        {
#ifdef WICONNECT_ENABLE_MALLOC
            assert(wiconnect->_malloc != NULL);
            rxBuffer.buffer = (uint8_t*)wiconnect->_malloc(rxBufferLen);
            assert(rxBuffer.buffer != NULL);
            rxBuffer.allocated = true;
#else
            assert(0);
#endif
        }
    }

    previous = next = NULL;
    handle = 0xff;
    readEnabled = false;
    *name = 0;
    size = 0;
    type = FILE_TYPE_UNKNOWN;
    version = 0;
    flags = FILE_FLAG_NONE;
}

/*************************************************************************************************/
File::~File()
{
    while(close() == WICONNECT_PROCESSING)
    {
    }

#ifdef WICONNECT_ENABLE_MALLOC
    if(rxBuffer.allocated && rxBuffer.size > 0)
    {
        assert(wiconnect->_free != NULL);
        wiconnect->_free(rxBuffer.buffer);
    }
#endif
}

/*************************************************************************************************/
WiconnectResult File::openForRead(uint8_t handle_, const char *filename)
{
    handle = handle_;
    readEnabled = true;
    strcpy(name, filename);

    return WICONNECT_SUCCESS;
}

/*************************************************************************************************/
WiconnectResult File::initWithListing(const char *typeStr, const char *flagsStr, const char* sizeStr, const char *versionStr, const char *nameStr)
{
    uint32_t tmp;

    if(!StringUtil::strHexToUint32(&typeStr[2], &tmp))
    {
        return WICONNECT_RESPONSE_PARSE_ERROR;
    }
    type = (FileType)tmp;

    if(!StringUtil::strHexToUint32(flagsStr, &tmp))
    {
        return WICONNECT_RESPONSE_PARSE_ERROR;
    }
    flags = (FileFlags)tmp;

    if(!StringUtil::strToUint32(sizeStr, &tmp))
    {
        return WICONNECT_RESPONSE_PARSE_ERROR;
    }
    size = (uint32_t)tmp;

    if(!FileInterface::fileVersionStrToInt(versionStr, &version))
    {
        return WICONNECT_RESPONSE_PARSE_ERROR;
    }

    strcpy(name, nameStr);

    return WICONNECT_SUCCESS;
}

/*************************************************************************************************/
void* File::operator new(size_t size)
{
    assert(Wiconnect::getInstance()->_malloc != NULL);
    return Wiconnect::getInstance()->_malloc(size);
}

/*************************************************************************************************/
void File::operator delete(void* ptr)
{
    assert(Wiconnect::getInstance()->_free != NULL);
    Wiconnect::getInstance()->_free(ptr);
}


/*************************************************************************************************/
WiconnectResult File::close()
{
    WiconnectResult result;
    CHECK_OPENED_FOR_READING();
    CHECK_OTHER_COMMAND_EXECUTING();

    if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("close %d", handle)))
    {
        readEnabled = false;
    }

    CHECK_CLEANUP_COMMAND();

    return result;
}

/*************************************************************************************************/
const char* File::getName() const
{
    return name;
}

/*************************************************************************************************/
uint32_t File::getSize() const
{
    return size;
}

/*************************************************************************************************/
FileType File::getType() const
{
    return type;
}

/*************************************************************************************************/
FileFlags File::getFlags() const
{
    return flags;
}

/*************************************************************************************************/
uint32_t File::getVersion() const
{
    return version;
}

/*************************************************************************************************/
const char* File::getVersionStr(char *buffer) const
{
    return FileInterface::fileVersionIntToStr(version, true, buffer);
}

/*************************************************************************************************/
const File* File::getNext() const
{
    return next;
}

/*************************************************************************************************/
const File* File::getPrevious() const
{
    return previous;
}


/*************************************************************************************************/
WiconnectResult File::read(void* buffer, uint16_t maxLength, uint16_t *bytesRead)
{
    WiconnectResult result;

    CHECK_OPENED_FOR_READING();
    CHECK_OTHER_COMMAND_EXECUTING();

    if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand((char*)buffer, maxLength, "read %d %d", handle, maxLength-2)))
    {
        *bytesRead = wiconnect->getLastCommandResponseLength();
    }

    CHECK_CLEANUP_COMMAND();

    return result;
}

/*************************************************************************************************/
WiconnectResult File::read(uint8_t **bufferPtr, uint16_t *bytesReadPtr)
{
    WiconnectResult result = WICONNECT_SUCCESS;

    CHECK_OPENED_FOR_READING();

    if(rxBuffer.size == 0)
    {
        return WICONNECT_UNSUPPORTED;
    }
    else if(bufferPtr != NULL && bytesReadPtr == NULL)
    {
        return WICONNECT_BAD_ARG;
    }
    else if(rxBuffer.bytesPending < rxBuffer.size - 2)
    {
        const int bytesToRead = rxBuffer.size - rxBuffer.bytesPending - 2;
        char* ptr = (char*)&rxBuffer.buffer[rxBuffer.bytesPending];
        if(!WICONNECT_FAILED(result, wiconnect->sendCommand(ptr, bytesToRead+2, "read %d %d", handle, bytesToRead)))
        {
            rxBuffer.bytesPending += wiconnect->getLastCommandResponseLength();
        }
    }

    if(bufferPtr != NULL)
    {
        *bufferPtr = rxBuffer.buffer;
        *bytesReadPtr = rxBuffer.bytesPending;
        clearRxBuffer();
    }

    return result;
}

/*************************************************************************************************/
WiconnectResult File::getc(uint8_t *c)
{
    WiconnectResult result;

    if(rxBuffer.size == 0)
    {
        return WICONNECT_UNSUPPORTED;
    }

    read_data:
    if(rxBuffer.bytesPending == 0 &&
      WICONNECT_FAILED(result, read()))
    {
        return result;
    }
    else if(rxBuffer.ptr < &rxBuffer.buffer[rxBuffer.bytesPending])
    {
        *c = *rxBuffer.ptr;
        ++rxBuffer.ptr;
        return WICONNECT_SUCCESS;
    }
    else
    {
        clearRxBuffer();
        goto read_data;
    }
}

/*************************************************************************************************/
void File::clearRxBuffer()
{
    rxBuffer.bytesPending = 0;
    rxBuffer.ptr = rxBuffer.buffer;
}