/** \file
 *
 *  Contains the CodedStr class implementation.
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 */

#include "CodedStr.h"

/**
 *  Extends the Str class, adding an unsigned short code
 *  (actually, the codes are limited to 14 bits, for
 *  a range of 0 to 16383)
 *
 *  \ingroup utils
 */
CodedStr::CodedStr( const Str& strIn, unsigned short code )
    : Str( strIn ),
      code_( code )
{}

unsigned int CodedStr::write( OutStream& outStream ) const
{
    unsigned int bytesWritten( 0 );

    bytesWritten += outStream.write( " code=" ).bytesWritten();
    bytesWritten += outStream.writeShortHex( code_ ).bytesWritten();

    bytesWritten += outStream.write( " name=\"" ).bytesWritten();
    bytesWritten += outStream.write( cStr() ).bytesWritten();
    bytesWritten += outStream.write( "\"" ).bytesWritten();

    bytesWritten += outStream.write( "\n" ).bytesWritten();

    return bytesWritten;
}

CodedStr* CodedStr::Read( InStream& inStream )
{
    short code;
    char name[256];
    bool ok = true;
    char dummy[16];

    // read " code="
    ok = inStream.read( dummy, 6 ).bytesRead() == 6 && strncmp( dummy, " code=", 6 ) == 0;
    if( ok )
    {
        // read code
        ok = inStream.readShortHex( code ).bytesRead() == 4;
    }

    if( ok )
    {
        // read " name=\""
        ok = inStream.read( dummy, 7 ).bytesRead() == 7 && strncmp( dummy, " name=\"", 7 ) == 0;
    }
    if( ok )
    {
        // read name
        ok = inStream.readUntil( name, 255, '\"' ).bytesRead() > 0;
        ok &= inStream.bytesRead() < 255;
        if( ok )  // remove the trailing quote
        {
            name[ inStream.bytesRead() - 1 ] = 0;
        }
    }

    if( ok )
    {
        // read "\n" (OK if '\n' missing)
        inStream.read( dummy, 1 );
    }

    if( ok )
    {
        return new CodedStr( name, code );
    }

    return NULL;
}
