376 lines
11 KiB
C++
376 lines
11 KiB
C++
/*
|
|
*
|
|
* @APPLE_LICENSE_HEADER_START@
|
|
*
|
|
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
|
*
|
|
* This file contains Original Code and/or Modifications of Original Code
|
|
* as defined in and that are subject to the Apple Public Source License
|
|
* Version 2.0 (the 'License'). You may not use this file except in
|
|
* compliance with the License. Please obtain a copy of the License at
|
|
* http://www.opensource.apple.com/apsl/ and read it before using this
|
|
* file.
|
|
*
|
|
* The Original Code and all software distributed under the License are
|
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
|
* Please see the License for the specific language governing rights and
|
|
* limitations under the License.
|
|
*
|
|
* @APPLE_LICENSE_HEADER_END@
|
|
*
|
|
*/
|
|
/*
|
|
File: QTSSDataConverter.cpp
|
|
|
|
Contains: Utility routines for converting to and from
|
|
QTSS_AttrDataTypes and text
|
|
|
|
Written By: Denis Serenyi
|
|
|
|
Change History (most recent first):
|
|
|
|
*/
|
|
|
|
#include "QTSSDataConverter.h"
|
|
#include "StrPtrLen.h"
|
|
#include "OSMemory.h"
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
|
|
static const StrPtrLen kEnabledStr("true");
|
|
static const StrPtrLen kDisabledStr("false");
|
|
|
|
static char* kDataTypeStrings[] =
|
|
{
|
|
"Unknown",
|
|
"CharArray",
|
|
"Bool16",
|
|
"SInt16",
|
|
"UInt16",
|
|
"SInt32",
|
|
"UInt32",
|
|
"SInt64",
|
|
"UInt64",
|
|
"QTSS_Object",
|
|
"QTSS_StreamRef",
|
|
"Float32",
|
|
"Float64",
|
|
"VoidPointer",
|
|
"QTSS_TimeVal"
|
|
};
|
|
|
|
static const char* kHEXChars={ "0123456789ABCDEF" };
|
|
|
|
static const UInt8 sCharToNums[] =
|
|
{
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0-9
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10-19
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20-29
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //30-39
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, //40-49 - 48 = '0'
|
|
2, 3, 4, 5, 6, 7, 8, 9, 0, 0, //50-59
|
|
0, 0, 0, 0, 0, 10, 11, 12, 13, 14, //60-69 A-F
|
|
15, 0, 0, 0, 0, 0, 0, 0, 0, 0, //70-79
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //80-89
|
|
0, 0, 0, 0, 0, 0, 0, 10, 11, 12, //90-99 a-f
|
|
13, 14, 15, 0, 0, 0, 0, 0, 0, 0, //100-109
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //110-119
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //120-129
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //130-139
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140-149
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150-159
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160-169
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170-179
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180-189
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190-199
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200-209
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210-219
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220-229
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230-239
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240-249
|
|
0, 0, 0, 0, 0, 0 //250-255
|
|
};
|
|
|
|
char* QTSSDataConverter::TypeToTypeString( QTSS_AttrDataType inType)
|
|
{
|
|
if (inType < qtssAttrDataTypeNumTypes)
|
|
return kDataTypeStrings[inType];
|
|
return kDataTypeStrings[qtssAttrDataTypeUnknown];
|
|
}
|
|
|
|
QTSS_AttrDataType QTSSDataConverter::TypeStringToType( char* inTypeString)
|
|
{
|
|
for (UInt32 x = 0; x < qtssAttrDataTypeNumTypes; x++)
|
|
{
|
|
StrPtrLen theTypeStrPtr(inTypeString);
|
|
if (theTypeStrPtr.EqualIgnoreCase(kDataTypeStrings[x], ::strlen(kDataTypeStrings[x])))
|
|
return x;
|
|
}
|
|
return qtssAttrDataTypeUnknown;
|
|
}
|
|
|
|
QTSS_Error QTSSDataConverter::StringToValue( char* inValueAsString,
|
|
QTSS_AttrDataType inType,
|
|
void* ioBuffer,
|
|
UInt32* ioBufSize)
|
|
{
|
|
UInt32 theBufSize = 0;
|
|
char* theFormat = NULL;
|
|
|
|
if ( inValueAsString == NULL || ioBufSize == NULL)
|
|
return QTSS_BadArgument;
|
|
|
|
if ( inType == qtssAttrDataTypeCharArray )
|
|
{
|
|
//
|
|
// If this data type is a string, copy the string into
|
|
// the destination buffer
|
|
UInt32 theLen = ::strlen(inValueAsString);
|
|
|
|
//
|
|
// First check to see if the destination is big enough
|
|
if ((ioBuffer == NULL) || (*ioBufSize < theLen))
|
|
{
|
|
*ioBufSize = theLen;
|
|
return QTSS_NotEnoughSpace;
|
|
}
|
|
|
|
//
|
|
// Do the string copy. Use memcpy for speed.
|
|
::memcpy(ioBuffer, inValueAsString, theLen);
|
|
*ioBufSize = theLen;
|
|
return QTSS_NoErr;
|
|
}
|
|
|
|
if (inType == qtssAttrDataTypeBool16)
|
|
{
|
|
//
|
|
// The text "enabled" means true, anything else means false
|
|
if (*ioBufSize < sizeof(Bool16))
|
|
{
|
|
*ioBufSize = sizeof(Bool16);
|
|
return QTSS_NotEnoughSpace;
|
|
}
|
|
|
|
Bool16* it = (Bool16*)ioBuffer;
|
|
StrPtrLen theValuePtr(inValueAsString);
|
|
if (kEnabledStr.EqualIgnoreCase(inValueAsString, ::strlen(inValueAsString)))
|
|
*it = true;
|
|
else
|
|
*it = false;
|
|
|
|
*ioBufSize = sizeof(Bool16);
|
|
return QTSS_NoErr;
|
|
}
|
|
|
|
//
|
|
// If this is another type, format the string into that type
|
|
switch ( inType )
|
|
{
|
|
case qtssAttrDataTypeUInt16:
|
|
{
|
|
theBufSize = sizeof(UInt16);
|
|
theFormat = "%hu";
|
|
}
|
|
break;
|
|
|
|
case qtssAttrDataTypeSInt16:
|
|
{
|
|
theBufSize = sizeof(SInt16);
|
|
theFormat = "%hd";
|
|
}
|
|
break;
|
|
|
|
case qtssAttrDataTypeSInt32:
|
|
{
|
|
theBufSize = sizeof(SInt32);
|
|
theFormat = "%d";
|
|
}
|
|
break;
|
|
|
|
case qtssAttrDataTypeUInt32:
|
|
{
|
|
theBufSize = sizeof(UInt32);
|
|
theFormat = "%u";
|
|
}
|
|
break;
|
|
|
|
case qtssAttrDataTypeSInt64:
|
|
{
|
|
theBufSize = sizeof(SInt64);
|
|
theFormat = "%"_64BITARG_"d";
|
|
}
|
|
break;
|
|
|
|
case qtssAttrDataTypeUInt64:
|
|
{
|
|
theBufSize = sizeof(UInt64);
|
|
theFormat = "%"_64BITARG_"u";
|
|
}
|
|
break;
|
|
|
|
case qtssAttrDataTypeFloat32:
|
|
{
|
|
theBufSize = sizeof(Float32);
|
|
theFormat = "%f";
|
|
}
|
|
break;
|
|
|
|
case qtssAttrDataTypeFloat64:
|
|
{
|
|
theBufSize = sizeof(Float64);
|
|
theFormat = "%f";
|
|
}
|
|
break;
|
|
|
|
case qtssAttrDataTypeTimeVal:
|
|
{
|
|
theBufSize = sizeof(SInt64);
|
|
theFormat = "%"_64BITARG_"d";
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return ConvertCHexStringToBytes(inValueAsString,ioBuffer,ioBufSize);
|
|
}
|
|
|
|
if (( ioBuffer == NULL) || (*ioBufSize < theBufSize ))
|
|
{
|
|
*ioBufSize = theBufSize;
|
|
return QTSS_NotEnoughSpace;
|
|
}
|
|
*ioBufSize = theBufSize;
|
|
::sscanf(inValueAsString, theFormat, ioBuffer);
|
|
|
|
return QTSS_NoErr;
|
|
}
|
|
|
|
QTSS_Error QTSSDataConverter::ConvertCHexStringToBytes( char* inValueAsString,
|
|
void* ioBuffer,
|
|
UInt32* ioBufSize)
|
|
{
|
|
UInt32 stringLen = ::strlen(inValueAsString) ;
|
|
UInt32 dataLen = (stringLen + (stringLen & 1 ? 1 : 0)) / 2;
|
|
|
|
// First check to see if the destination is big enough
|
|
if ((ioBuffer == NULL) || (*ioBufSize < dataLen))
|
|
{
|
|
*ioBufSize = dataLen;
|
|
return QTSS_NotEnoughSpace;
|
|
}
|
|
|
|
UInt8* dataPtr = (UInt8*) ioBuffer;
|
|
UInt8 char1, char2;
|
|
while (*inValueAsString)
|
|
{
|
|
char1 = sCharToNums[(UInt8) (*inValueAsString++) ] * 16;
|
|
if (*inValueAsString != 0)
|
|
char2 = sCharToNums[(UInt8) (*inValueAsString++)];
|
|
else
|
|
char2 = 0;
|
|
*dataPtr++ = char1 + char2;
|
|
}
|
|
|
|
*ioBufSize = dataLen;
|
|
return QTSS_NoErr;
|
|
}
|
|
|
|
char* QTSSDataConverter::ConvertBytesToCHexString( void* inValue, const UInt32 inValueLen)
|
|
{
|
|
UInt8* theDataPtr = (UInt8*) inValue;
|
|
UInt32 len = inValueLen *2;
|
|
|
|
char *theString = NEW char[len+1];
|
|
char *resultStr = theString;
|
|
if (theString != NULL)
|
|
{
|
|
UInt8 temp;
|
|
UInt32 count = 0;
|
|
for (count = 0; count < inValueLen; count++)
|
|
{
|
|
temp = *theDataPtr++;
|
|
*theString++ = kHEXChars[temp >> 4];
|
|
*theString++ = kHEXChars[temp & 0xF];
|
|
}
|
|
*theString = 0;
|
|
}
|
|
return resultStr;
|
|
}
|
|
|
|
char* QTSSDataConverter::ValueToString( void* inValue,
|
|
const UInt32 inValueLen,
|
|
const QTSS_AttrDataType inType)
|
|
{
|
|
if (inValue == NULL)
|
|
return NULL;
|
|
|
|
if ( inType == qtssAttrDataTypeCharArray )
|
|
{
|
|
StrPtrLen theStringPtr((char*)inValue, inValueLen);
|
|
return theStringPtr.GetAsCString();
|
|
}
|
|
if (inType == qtssAttrDataTypeBool16)
|
|
{
|
|
Bool16* theBoolPtr = (Bool16*)inValue;
|
|
if (*theBoolPtr)
|
|
return kEnabledStr.GetAsCString();
|
|
else
|
|
return kDisabledStr.GetAsCString();
|
|
}
|
|
|
|
//
|
|
// With these other types, its impossible to tell how big they'll
|
|
// be, so just allocate some buffer and hope we fit.
|
|
char* theString = NEW char[128];
|
|
|
|
//
|
|
// If this is another type, format the string into that type
|
|
switch ( inType )
|
|
{
|
|
case qtssAttrDataTypeUInt16:
|
|
qtss_sprintf(theString, "%hu", *( UInt16*)inValue);
|
|
break;
|
|
|
|
case qtssAttrDataTypeSInt16:
|
|
qtss_sprintf(theString, "%hd", *( SInt16*)inValue);
|
|
break;
|
|
|
|
case qtssAttrDataTypeSInt32:
|
|
qtss_sprintf(theString, "%"_S32BITARG_, *( SInt32*)inValue);
|
|
break;
|
|
|
|
case qtssAttrDataTypeUInt32:
|
|
qtss_sprintf(theString, "%"_U32BITARG_, *( UInt32*)inValue);
|
|
break;
|
|
|
|
case qtssAttrDataTypeSInt64:
|
|
qtss_sprintf(theString, "%"_64BITARG_"d", *( SInt64*)inValue);
|
|
break;
|
|
|
|
case qtssAttrDataTypeUInt64:
|
|
qtss_sprintf(theString, "%"_64BITARG_"u", *( UInt64*)inValue);
|
|
break;
|
|
|
|
case qtssAttrDataTypeFloat32:
|
|
qtss_sprintf(theString, "%f", *( Float32*)inValue);
|
|
break;
|
|
|
|
case qtssAttrDataTypeFloat64:
|
|
qtss_sprintf(theString, "%f", *( Float64*)inValue);
|
|
break;
|
|
|
|
case qtssAttrDataTypeTimeVal:
|
|
qtss_sprintf(theString, "%"_64BITARG_"d", *( SInt64*)inValue);
|
|
break;
|
|
|
|
default:
|
|
delete theString;
|
|
theString = ConvertBytesToCHexString(inValue, inValueLen);
|
|
}
|
|
|
|
return theString;
|
|
}
|